NumPy: matrix dot product incompatible with MATLAB - python

I'm trying to proceed some simple calculation in NumPy.
But it suddenly gives the results different with MATLAB calculations.
Here is the MATLAB example:
load temp; % here are the source matrices located
resp = ang_stv' * tmp;
respC = resp.'; % this is our variable to compare with Python
cd(fileparts(mfilename('fullpath')));
save('arythm_test.mat');
And here I try to calculate the same in Python:
dump_data = sp.io.loadmat("arythm_test.mat")
tmp = dump_data["tmp"]
ang_stv = dump_data["ang_stv"]
ref_resp = dump_data["respC"]
our_resp = np.dot(ang_stv.swapaxes(0, 1), tmp).swapaxes(0, 1)
np.testing.assert_allclose(our_resp, ref_resp)
Cannot you tell me, what am I doing wrong? And how to cope with it?
P.S. Here are temp.mat and arythm_test.mat

The answer was simple: the .' operator in MATLAB means simple transpose, and ' operator means transpose with complex conjugation. Oy vey...
tmp = dump_data["tmp"]
ang_stv = dump_data["ang_stv"]
print "tmp.shape", tmp.shape
print "ang_stv.shape", ang_stv.shape
ref_resp = dump_data["respC"]
our_resp = np.dot(np.conj(ang_stv.swapaxes(0, 1)), tmp).swapaxes(0, 1)

Related

What is the equivalent of coo_matrix in Matlab?

I'm trying to translatethe following lines of code from Python to MATLAB. V, Id, and J are of size (6400,) which in MATLAB are 1 -by- 6400 row vectors. pts is of size 242.
My Python code
A = coo_matrix((V, (Id, J)), shape=(pts.size, pts.size)).tocsr()
A = A.tobsr(blocksize=(2, 2))
I translated the first line as follows to MATLAB
A = sparse(V,Id,J,242,242);
However, I got the error
Error using sparse
Index into matrix must be an integer.
How can I translate this code to MATLAB?
The MATLAB sparse function has several forms:
S = sparse(A)
S = sparse(m,n)
S = sparse(i,j,v)
S = sparse(i,j,v,m,n)
S = sparse(i,j,v,m,n,nz)
The form you are most likely looking for is the fourth one: S = sparse(i,j,v,m,n), and will want to call it (using your use case) as:
A = sparse(Id, J, V, 242, 242);
I think your error is that MATLAB wants the I and J indices first, followed by the value and you are making the value the first argument.

How can I get same results for fft2() in MATLAB and Python?

I am translating a MATLAB code to Python code but I get different results from numpy fft2() and MATLAB fft2(). Difference is not small. How can I get same result?
Where S is (10,10,3) array
In Python:
Normin1 = fft2(S)
print("Normin is\n",Normin1[:,:,0])
Output(Just first row):
Normin is
[[ 1.29098039e+01+0.00000000e+00j
-8.14368936e-01-4.02146547e-01j
4.57184468e-01+4.59545965e-01j
2.37898348e-01-1.58643666e-01j
-6.89491738e-02+1.65467814e-01j
3.29411765e-01-1.38777878e-17j
-6.89491738e-02-1.65467814e-01j
2.37898348e-01+1.58643666e-01j
4.57184468e-01-4.59545965e-01j
-8.14368936e-01+4.02146547e-01j]
But in MATLAB:
Normin1 = fft2(S);
Output of first row
44.27451 + 0.00000i
-1.04275 - 3.36765i
0.72446 - 1.92128i
0.02706 + 0.09694i
0.70692 + 0.28154i
-0.90980 + 0.00000i
0.70692 - 0.28154i
0.02706 - 0.09694i
0.72446 + 1.92128i
-1.04275 + 3.36765i
I solved my problem. Python does array operations row-wise. In contrast, Matlab/Octave does array operations column-wise. That why, it should be as follows to get same result,
MATLAB code:
Normin1 = fft2(S);
Python equivalent:
Normin1 = np.fft2(S.T).T

Two consecutive parentheses after name in Matlab

Please excuse me for this amateurish question,
I'm trying to convert some Matlab code to Python, I don't have any experience with Matlab but so far I have been able to deduce what the Matlab code does and the conversion so far has been successful.
But now I am stuck at these lines of code;
SERAstart = []
for n=1:length(bet)
alf = -bet(n) * 1e-2;
SERAstart = [SERAstart(alf - i * bet(n))(alf + i * bet(n))];
end
What I don't understand is this line;
SERAstart(alf - i * bet(n))(alf + i * bet(n))
Two consecutive parentheses after "SERAstart", are they nested array indexing? are they indexing and then function call to return of indexing? are they function call and then function call again to return value of first call?
Please help me understand what is going on here so that I can convert it to Python.
I realize that it might not be possible just from the piece of code I have posted to say definitively what it does, but otherwise if you can help guide me to how to figure it out (without the use of Matlab) then I would also be very grateful.
Thanks a lot for any help!.
EDIT:
This is my own attempt at a conversion, but I don't know if this makes sense;
# SERAstart = [];
SERAstart = [[]]
# for n=1:length(bet)
for n in range(len(bet)):
# alf = -bet(n) * 1e-2;
alf = -bet[n] * 1e-2
# SERAstart = [SERAstart(alf - i * bet(n))(alf + i * bet(n))];
SERAstart = [SERAstart[alf - 1j * bet[n]][alf + 1j * bet[n]]]
# end
EDIT2:
I just noticed this line in the documentation relating to SERAstart:
% SERAstart(N,1) : vector of starting poles [rad/sec]

Converting Matlab code into Python - FFT

I need to convert a piece of MATLAB code to Python and I'm bad at both. The code in MATLAB uses fft and fftshift. I tried to use NumPy in Python. The code runs but when I compare the outcome they are not matching. I appreciate your help.
Here is the MATLAB code:
h(1,1:Modes_number) = -1i*S;
hfft = fft(h);
hft0 = fftshift(hfft);
and here is the Python code which I wrote:
h = np.zeros((1,self.cfg.Modes_number+1),dtype=complex)
for i in range(0, self.cfg.Modes_number+1):
h[0,i] = -1j*S;
hfft = np.fft.fft(h)
hft0 = np.fft.fftshift(hfft)
Here is the values for S and Modes_number:
S = 12.5022214424;
Modes_number = 200;
Here is also an example of the results I get in MATLAB and Python:
MATLAB:
hfft(1,1)
ans =
1.1857e-13 - 2.5129e+03i
Python:
hfft[0]
0. -2.52544873e+03j
Cheers.
The error in your Python code is that you define h to be of size Modes_number+1, which is one more than the size in the MATLAB code. The first value in hfft is the sum of all input values. In MATLAB this is -1j*S*200 = -2500.4j, and in your Python code this is -1j*S*201 = -2512.9j. These are the values that you are seeing.
This bit of Python code produces the same as your bit of MATLAB code, up to numerical precision (I see some values like -1.68388521e-15 +6.55829989e-15j in Python, which are forced to 0 by MATLAB's algorithms). I am creating h as a one-dimensional vector, rather than a 2D array with one dimension of size 1.
import numpy as np
S = 12.5022214424
Modes_number = 200
h = np.zeros(Modes_number,dtype=complex)
for i in range(0,Modes_number):
h[i] = -1j*S;
hfft = np.fft.fft(h)
hft0 = np.fft.fftshift(hfft)
Python:
>>> hfft[0]
-2500.4442884800001j
MATLAB:
>> hfft(1)
ans =
0.000000000000000e+00 - 2.500444288480000e+03i`

Blitz code produces different output

I want to use weave.blitz to improve the performance of the following numpy code:
def fastIteration(self):
g = self.grid
nx,ny = g.ux.shape
uxold = g.old_ux
ux = g.ux
ux[0:,1:-1] = uxold[0:,1:-1] + ReI* (uxold[0:,2:] - 2*uxold[0:,1:-1] + uxold[0:,0:-2])
g.setBC()
g.old_ux = ux.copy()
In this code g is the computational grid. Which consist of two different fields ux and uxold. The old is simply used for temporary storage of the variables. In the complete Code around 95% of the runtime is spend in the fastIteration method, therefore even a simple performance gain would reduce the amount of hours spend executing this code significantly.
The output of the numpy method looks as if:
As this code is my bottleneck I want to improve the speed by using weave blitz. This method looks like:
def blitzIteration(self):
### does not work correct so far
g = self.grid
nx,ny = g.ux.shape
uxold = g.old_ux
ux = g.ux
expr = "ux[0:,1:-1] = uxold[0:,1:-1] + ReI* (uxold[0:,2:] - 2*uxold[0:,1:-1] + uxold[0:,0:-2])"
weave.blitz(expr, check_size=0)
g.setBC()
g.old_ux = ux.copy()
However this does not produce the correct output:
It looks like a bug in weave.blitz (reproduced, filed and fixed. There's more information about the actual bug there).
I thought it was odd to write 0: instead of the shorter : to get a full slice so I replaced all those slices and voilĂ , it worked.
I don't really know where the bug lies, but the expr_code generated by weave.blitz is slightly different:
When using 0:
ipdb> expr_code
'ux_blitz_buggy(blitz::Range(0,_end),blitz::Range(1,Nux_blitz_buggy(1)-1-1))=uxold(blitz::Range(0,_end),blitz::Range(1,Nuxold(1)-1-1))+ReI*(uxold(blitz::Range(0,_end),blitz::Range(2,_end))-2*uxold(blitz::Range(0,_end),blitz::Range(1,Nuxold(1)-1-1))+uxold(blitz::Range(0,_end),blitz::Range(0,Nuxold(1)-2-1)));\n'
When using :
ipdb> expr_code
'ux_blitz_not_buggy(_all,blitz::Range(1,Nux_blitz_not_buggy(1)-1-1))=uxold(_all,blitz::Range(1,Nuxold(1)-1-1))+ReI*(uxold(_all,blitz::Range(2,_end))-2*uxold(_all,blitz::Range(1,Nuxold(1)-1-1))+uxold(_all,blitz::Range(0,Nuxold(1)-2-1)));\n'
So, blitz::Range(0,_end) becomes _all and they behave in a different way.
For convenience, here is a complete script that reproduces the problem and will only succeed while the problem exists.
import numpy as np
from scipy.weave import blitz
def test_blitz_bug(N=4):
ReI = 1.2
ux_blitz_buggy, ux_blitz_not_buggy, ux_np = np.zeros((N, N)), np.zeros((N, N)), np.zeros((N, N))
uxold = np.random.randn(N, N)
ux_np[0:,1:-1] = uxold[0:,1:-1] + ReI* (uxold[0:,2:] - 2*uxold[0:,1:-1] + uxold[0:,0:-2])
expr_buggy = 'ux_blitz_buggy[0:,1:-1] = uxold[0:,1:-1] + ReI* (uxold[0:,2:] - 2*uxold[0:,1:-1] + uxold[0:,0:-2])'
expr_not_buggy = 'ux_blitz_not_buggy[:,1:-1] = uxold[:,1:-1] + ReI* (uxold[:,2:] - 2*uxold[:,1:-1] + uxold[:,0:-2])'
blitz(expr_buggy)
blitz(expr_not_buggy)
assert not np.allclose(ux_blitz_buggy, ux_np)
assert np.allclose(ux_blitz_not_buggy, ux_np)
if __name__ == '__main__':
test_blitz_bug()

Categories

Resources