Numpy: numpy.fft.fftの非常に長いランタイム(Trac#1266)

作成日 2012年10月19日  ·  19コメント  ·  ソース: numpy/numpy

_不明に割り当てられたtracユーザーkoehlerによる2009-10-19の元のチケットhttp://projects.scipy.org/numpy/ticket/1266。_

numpy.fft.fftの文書には、次のように記載されていますが、
「これは、2の累乗の場合に最も効率的です。これは、さまざまなサイズのfftの作業メモリーのキャッシュも格納するため、これを何度も呼び出して、さまざまなnを多すぎると、理論的にはメモリーの問題が発生する可能性があります。」 、fftランタイムでこの奇妙なことを報告することが重要かもしれないと思います。
配列の長さに応じて、fftランタイムは非常に極端に異なります。

[ipython shell, from numpy import *]
In [1]: %time fft.fft(zeros(119516))
CPU times: user 22.83 s, sys: 0.39 s, total: 23.23 s
Wall time: 23.53 s

In [3]: %time fft.fft(zeros(119517))
CPU times: user 36.33 s, sys: 0.08 s, total: 36.40 s
Wall time: 36.51 s

In [5]: %time fft.fft(zeros(119518))
CPU times: user 4.88 s, sys: 0.08 s, total: 4.96 s
Wall time: 5.02 s

In [7]: %time fft.fft(zeros(119519))
CPU times: user 0.45 s, sys: 0.00 s, total: 0.45 s
Wall time: 0.45 s

In [9]: %time fft.fft(zeros(119515))
CPU times: user 0.07 s, sys: 0.00 s, total: 0.08 s
Wall time: 0.08 s

In [11]: %time fft.fft(zeros(119514))
CPU times: user 15.84 s, sys: 0.06 s, total: 15.90 s
Wall time: 15.95 s

In [13]: %time fft.fft(zeros(119513))
CPU times: user 272.75 s, sys: 1.03 s, total: 273.78 s
Wall time: 275.63 s
00 - Bug numpy.fft

最も参考になるコメント

これはnumpy1.17で修正する必要があります。

全てのコメント19件

_ @endolithは2009-11-20_に書き込みました

関連:#1177 http://projects.scipy.org/scipy/ticket/949

_ @rgommersは2011-03-01_に書き込みました

_ @rgommersは2011-03-01_に書き込みました

David C.は、必要に応じてBluestein変換を実装しています: https

うまくいけば、すぐにNumpyトランクに着陸するはずです。

マイルストーンは2011-03-25に@mwiebeによってUnscheduledされまし

このPRでは、小さな素数へのパディングが提案されています
https://github.com/scipy/scipy/pull/3144
より良いパディングサイズを取得する機能を持つことは、numpysfftpackで便利なユーティリティかもしれません

はい、 m = 2 ** nextpow2(2 * n - 1)代わりに、 next_regular関数のようなものを使用する方が高速です

また、 pymbarのdetect_equilibration関数を使用してこの問題に遭遇しました。この関数は、ますます短くなる多くの配列でnp.fftとnp.ifftを繰り返し呼び出します。 コードのプロファイリングを見つけたので、最終的にこのスレッドにたどり着きました。 これまでのところ唯一の回避策は、明示的に呼び出すことです

 np.fft.fftpack._fft_cache.clear()

メモリ要件が危険なほど大きくならないようにするため。 しかし、これは理想的な解決策ではないようです。 「memsafe = True」などのkwargや、グローバル変数を明示的に参照せずに手動でキャッシュをクリアする関数があると便利です。

@juliantaylorパディングはプレーンFFTには適用されませんよね? たたみ込み/相関だけですか?

@rgommers Bluesteinアルゴリズムは、 https://github.com/scipy/scipy/issues/4288で行われているように、プライムサイズのFFTを高速化し

とにかく、これはhttps://github.com/numpy/numpy/issues/1177の複製として閉じることができると思い

@smcantabの問題は異なりますか?

@endolithこれはずっと前のことです:)しかし、はい、もう一度見てみると、別の問題のようです。 私が報告した問題はまだ関連している可能性があり、それが機能するためには、pymbarで提案した回避策を実装する必要がありました。

参考までに、私はこの例を見せてくれたオーディオ会議で誰かに出くわしました。 再現が簡単で極端です。

%time np.fft.fft( np.random.randn(100000) )
Wall time: 16 ms
Out[16]: 
array([ 196.58599022  +0.j        ,  -88.38483360 +89.2507627j ,
       -166.72250316+339.27161306j, ...,   12.22959535 -64.01621313j,
       -166.72250316-339.27161306j,  -88.38483360 -89.2507627j ])

%time np.fft.fft( np.random.randn(100003) )
Wall time: 1min 42s
Out[17]: 
array([  13.36160617  +0.j        , -314.86472577-340.44686425j,
       -258.36716707-170.43805382j, ...,  -21.18014704+441.3618185j ,
       -258.36716707+170.43805382j, -314.86472577+340.44686425j])

長さ1e6のfft:16ミリ秒

長さ1e6 + 3のfft:1分および42秒

バグではなく機能。 FFTPACKは、サイズが2、3、4、5の積として因数分解される場合にのみ「高速」になります。大きな素数に対してより高速なアルゴリズムを使用したいという長年の要望がありましたが、実装されていません。 100003がプライムであることに注意してください。

私はそれを「機能」とは呼びませんが、それは正常であり、バグではありません。 :)

https://github.com/scipy/scipy/issues/4288にはBluesteinのアルゴリズムがありますが、複雑なチャープの事前計算が必要なため、どのプライムサイズで価値があるかを確認するためにいくつかのテストを行う必要があります。

面白い。 私が知っている主なことは、JuliaとMatlabのデフォルトのfft実装にはこの動作がないということです。 この動作を回避するためにJuliaの実装が何をするのか興味があります。

JuliaとMatlabはFFTWを呼び出しますが、ライセンスが原因でできません。

FFTWにはPythonバインディングがあることに注意してください。 pyFFTWはかなり最新のようです。 FFT速度が懸念される場合は、おそらくそれが最善の方法です。 FFTPACKは当時としては優れた実装でしたが、コードとハードウェアは進歩しました。

@charris私は間違いなく情報に感謝し、それは残念ですが、ライセンスに関しては理にかなっています。

これはnumpy1.17で修正する必要があります。

ありがとう@mreineck 、締めくくり

このページは役に立ちましたか?
0 / 5 - 0 評価