4

複素数のベクトル(FFTの結果)があり、別のベクトルの因子によって複素数の実数部分のみをスケーリングしたいと思います。

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])

(はい、それは非常に特定の設定での人間の可聴周波数応答に関するものです。)
明らかに、上記のようなベクトルとの乗算は、虚数部もスケーリングします。

希望する結果を得るには、どのように設定しfactarr、どのような操作を行う必要がありますか?可能であれば、つまり、実数部と虚数部を分離せずに、実数部をスケーリングし、新しい複素数ベクトルとして再組み立てします。

4

1 に答える 1

8

これはそれを行います:

>>> factarr*cplxarr.real + (1j)*cplxarr.imag
array([ 0.5+2.j,  1.8+1.j,  1.4-2.j])

しかし、それが最善の方法かどうかはわかりません。


少なくとも私にとっては(OS-X 10.5.8、python 2.7.3、numpy 1.6.2)このバージョンは、np.vectorize以下を使用する他のバージョンの約2倍の速度であることがわかりました。

>>> 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

np.complexPythonの使用とcomplex提供の違いはあまりないようです。

>>> timeit('f(cplxarr.real * factarr, cplxarr.imag)',setup='from __main__ import  factarr,cplxarr; import numpy as np; f=np.vectorize(complex)')
44.87726283073425

タイミング順位の現在のリーダー(以下のコメントでeryksunによって提案されました)

>>> timeit.timeit('a = cplxarr.copy(); a.real *= factarr ',setup='from __main__ import factarr,cplxarr')
8.336654901504517

そしてそれが機能することの証明:

>>> a = cplxarr.copy()
>>> a.real *= factarr 
>>> a
array([ 0.5+2.j,  1.8+1.j,  1.4-2.j])

操作を適切に実行したい場合(したがって、コピーをオフのままにしておくことができます)、これは明らかにさらに高速になります。

于 2012-11-26T14:44:02.673 に答える