I have a vector of complex numbers (the result of a FFT) and I would like to scale only the real part of the complex numbers by factors in another vector.
cplxarr= np.array([1+2j, 3+1j, 7-2j])
factarr= np.array([.5, .6, .2])
# desired result of cplxarr * factarr :
# np.array([.5+2j 1.8+1j 1.4-2j])
(Yes, it's about human-hearing frequency response in a very specific setting.)
Obviously the multiplication with the vectors as above scales the imaginary parts too.
How do I set up factarr
and what operation do I have to do in order to achieve the desired result? If it's possible at all, that is, without separating the real and imaginary parts, scaling the real parts and reassembling as a new complex vector.
This'll do it:
>>> factarr*cplxarr.real + (1j)*cplxarr.imag
array([ 0.5+2.j, 1.8+1.j, 1.4-2.j])
Not sure if it's the best way though.
It turns out that for me at least (OS-X 10.5.8, python 2.7.3, numpy 1.6.2) This version is about twice as fast as the other version which uses np.vectorize
:
>>> from timeit import timeit
>>> timeit('factarr*cplxarr.real+(1j)*cplxarr.imag',setup='from __main__ import factarr,cplxarr')
21.008132934570312
>>> timeit('f(cplxarr.real * factarr, cplxarr.imag)',setup='from __main__ import factarr,cplxarr; import numpy as np; f=np.vectorize(np.complex)')
46.52931499481201
It doesn't seem to make much of a difference between using np.complex
and complex
provided by python:
>>> timeit('f(cplxarr.real * factarr, cplxarr.imag)',setup='from __main__ import factarr,cplxarr; import numpy as np; f=np.vectorize(complex)')
44.87726283073425
THE CURRENT LEADER IN THE TIMINGS STANDINGS (proposed by eryksun in the comments below)
>>> timeit.timeit('a = cplxarr.copy(); a.real *= factarr ',setup='from __main__ import factarr,cplxarr')
8.336654901504517
And proof that it works:
>>> a = cplxarr.copy()
>>> a.real *= factarr
>>> a
array([ 0.5+2.j, 1.8+1.j, 1.4-2.j])
This obviously would be even faster if you wanted to do the operation in place (and could therefore leave the copy off).
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