keshav bantu
keshav bantu

Reputation: 27

Difference in outputs between numpy.sum() in python and sum() in matlab

I'm converting MATLAB code to Python

This is my code in python:

import numpy as np
import math

n=150
L=1
inter=L/n
y=np.linspace(inter/2,L-inter/2,n).transpose()
E=(210000000000)*np.ones(n)
Rho=7800*np.ones(n)
PI=math.pi
A=np.exp( 5+2*y*(np.sin(2*PI*y/L)) )*0.000001

This works fine up until this point with no difference in values or issues until I have to execute this piece of MATLAB code.

Mass=sum(Rho*inter.*A)

I tried the same using np.sum(Rho*inter*A) and just Rho*inter*A

The first case I got a single answer 1.0626206716847877 but MATLAB returns a 150 element array.

In the scond case I got an ndarray like I wanted but the values were not the same as what I got in MATLAB.

Values I got in MATLAB : matlab values pastebin

Values I got in python : python values pastebin

What am I doing wrong?

Upvotes: 1

Views: 495

Answers (3)

hpaulj
hpaulj

Reputation: 231540

(Rho[:,None]*inter*A).sum(axis=0) 

matches your MATLAB pastebin.

Or using einsum to sort out the axes:

np.einsum('i,j->j', Rho,inter*A)

which just reduces to:

Rho.sum() * inter*A

Is that really what you are trying to do in MATLAB?

It might help if you showed the actual MATLAB code used to create Rho, A etc.

Mass=sum(Rho*inter.*A)

What's the size of Rho and A in MATLAB? One may be [1x150], but the other? Is Rho [1x150] also, or [150x150]. The * is matrix multiplication, like @ in numpy, but .* is elementwise.

In the numpy code y, Rho and A all have shape (150,). The transpose on y does nothing. Rho*inter*A is elementwise multiplication producing a (150,) as well.

Upvotes: 1

Adriaan
Adriaan

Reputation: 18187

NumPy always sums all elements of a matrix. MATLAB's default is column-based, i.e. all of your 150 columns sum to a single total, hence the array. Use sum(matrix,'all'); in MATLAB to sum over all elements in a matrix. If you have a MATLAB older than 2018b, use sum(matrix(:)), i.e. store your matrix in a temporary variable, then flatten it to a column before summing.

To sum over columns in Python, specify the axis, being 0: np.sum(matrix,axis=0)

numpy.sum():

Axis or axes along which a sum is performed. The default, axis=None, will sum all of the elements of the input array.

sum() from MATLAB:

S = sum(A) returns the sum of the elements of A along the first array dimension whose size does not equal 1.
If A is a matrix, then sum(A) returns a row vector containing the sum of each column.
S = sum(A,'all') computes the sum of all elements of A. This syntax is valid for MATLAB® versions R2018b and later.

To prevent this kind of unclarities, I prefer to always specify which direction to sum over, i.e. sum(matrix,1) for MATLAB and np.sum(matrix,axis=0) for NumPy, regardless of the default.

Upvotes: 1

I think that in MATLAB using sum on a matrix you will get the sum of its individual columns and you will end up with an array with its number of elements equal to that of the columns. Use one more sum command in MATLAB: sum(sum(M)), which is the equivalent of np.sum(M) in Python.

Upvotes: -1

Related Questions