I got a numpy.ndarray of electromagnetic samples as complex numbers, where the format is as follows:
ex1:
[[ 8.23133235e-15, -1.59200901e-15, -4.39818917e-13, 7.68089585e-13]
[ 6.98151957e-15, -1.20306059e-15, 9.83923013e-13, 1.64838108e-11]
[ 8.41053742e-15, -1.77702007e-15, -5.98961364e-13, 8.97436205e-13]
[ 7.08443026e-15, -1.25262430e-15, 1.11415868e-12, 1.69346186e-11]]
where rows make up real and imaginary part alternately:
[[z1Ex.real, z1Ey.real, z1Hx.real, z1Hy.real],
[z1Ex.imag, z1Ey.imag, z1Hx.imag, z1Hy.imag],
[z2Ex.real, z2Ey.real, z2Hx.real, z2Hy.real],
[z2Ex.imag, z2Ey.imag, z2Hx.imag, z2Hy.imag],
...etc.]
What I want is to create a new array which expresses the data in magnitude and phase, but keep the same format (i.e. replace real rows with magnitude rows and imaginary with phase rows).
I managed to put up list comprehensions for both calculations (which I´m fairly proud of, being an 2-week amateur, so please be gentle;)). The result for magnitude is what I´d expect, but the phase is terribly off and I don´t have any idea why...
My approach:
Slice the original array in real and imag sub-arrays:
import numpy, cmath
real = ex1[::2] #numpy.ndarray
imag = ex1[1::2] #numpy.ndarray
Define lambdas outside of list comprehension:
magcalc = lambda z, y: abs(complex(z, y))
phasecalc = lambda z,y: cmath.phase(complex(z, y))
Define list comprehension to do math on sub-arrays:
real[:] = np.array([[magcalc(z,y) for z, y in zip(real[x],imag[x])] for x in xrange(len(real))])
imag[:] = np.array([[phasecalc(z,y) for z, y in zip(real[x],imag[x])] for x in xrange(len(imag))])
Check results in original array:
print ex1[:4]
If I do that, the phase result for the first Ex sample is 0.574 rad. If I check the phase manually (i.e. cmath.phase(complex(z1Ex.real,z1Ex.imag))), then I get 0.703 rad. I would accept if there was smth wrong in my list comprehensions, but the magnitude results are completely correct, so I doubt that that´s it.
Where am I doing it wrong? I really tried to find out for 2 days straight now, no luck... Also, I can´t think of another way to achieve what I want.
Please help... (Using Python 2.7)
Thanks Nils
Oh jeez.. Now I saw the problem, can´t believe how dense I am... Credit goes to John, for making me re-think variable assignments.
In imag[:] = np.array([[phasecalc(z,y) for z, y in zip(real[x],imag[x])] for x in xrange(len(imag))]), I refer to real[], as if it was still populated with real values. But I changed real[] the line before to contain magnitude... So, just changing the variable names for the list comprehensions will do it:
Define list comprehension to do math on sub-arrays:
realcopy[:] = np.array([[magcalc(z,y) for z, y in zip(real[x],imag[x])] for x in xrange(len(real))])
imagcopy[:] = np.array([[phasecalc(z,y) for z, y in zip(real[x],imag[x])] for x in xrange(len(imag))])
And then re-assign to original mag, phase arrays:
Check original results
real[:] = realcopy
imag[:] = imagcopy
print ex1[:4]
Sorry for the waste of time and bytes...
Cheers Nils
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With