Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - lambda in list comprehension gives wrong result

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:

  1. Slice the original array in real and imag sub-arrays:

    import numpy, cmath
    
    real = ex1[::2] #numpy.ndarray
    imag = ex1[1::2] #numpy.ndarray
    
  2. Define lambdas outside of list comprehension:

    magcalc = lambda z, y: abs(complex(z, y))
    phasecalc = lambda z,y: cmath.phase(complex(z, y))
    
  3. 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))])
    
  4. 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

like image 608
nilsnolde Avatar asked Feb 12 '26 09:02

nilsnolde


1 Answers

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:

  1. 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:

  1. Check original results

    real[:] = realcopy
    imag[:] = imagcopy
    
    print ex1[:4]
    

Sorry for the waste of time and bytes...

Cheers Nils

like image 139
nilsnolde Avatar answered Feb 14 '26 09:02

nilsnolde