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的n次方而言是最有效的。它还为不同大小的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

最有用的评论

这应该在numpy 1.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行李箱中。

里程碑由@mwiebe于2011-03-25更改为Unscheduled

在此过程中,建议对小素数进行填充
https://github.com/scipy/scipy/pull/3144
具有获得更好的填充大小的功能可能是numpys fftpack中的有用实用程序

是的,代替m = 2 ** nextpow2(2 * n - 1)可以更快使用next_regular功能

我还使用pymbar的detect_equilibration函数遇到了这个问题,该函数在许多越来越短的数组上通过

 np.fft.fftpack._fft_cache.clear()

确保内存需求不会危险地增长。 但是,这似乎不是理想的解决方案。 最好使用kwarg(例如“ memsafe = True”)和/或无需明确引用全局变量即可手动清除缓存的函数。

@juliantaylor填充不适用于纯FFT,对吗? 只是为了卷积/相关?

@rgommers Bluestein算法确实加快了素数大小的FFT,如https://github.com/scipy/scipy/issues/4288中所述,但是需要对复杂的pre进行预计算,并且在保留在内存中发出声,并在数据块上重复使用它。 所以我不确定这是否对numpy有用,也许只是推迟到scipy.fftpack.czt用于此应用程序?

无论如何,我认为可以将其作为https://github.com/numpy/numpy/issues/1177的副本关闭? 除非像Rader的算法这样的东西比Bluestein的算法更好?

@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的英尺英尺:1分钟和42秒

功能,不是错误。 当大小因子是数字2、3、4、5的乘积时,FFTPACK才是“快速”的。长期以来,人们一直希望对较大的素数使用更快的算法,但是尚未实现。 请注意100003是质数。

我不会称其为“功能”,但这是正常现象,而不是错误。 :)

https://github.com/scipy/scipy/issues/4288具有Bluestein的算法,但是它需要对复杂的线性调频器进行预计算,因此需要进行一些测试,以了解在哪些最佳大小上值得。

有趣。 我知道的主要事情是,Julia和Matlab的默认fft实现没有此行为。 我很好奇Julia的实现是如何避免这种行为的。

朱莉娅和Matlab呼叫FFTW,由于其许可证,我们无法执行此操作。

请注意,FFTW有Python绑定。 pyFFTW似乎是最新的。 如果需要考虑FFT速度,那可能是可行的方法。 FFTPACK当时是一个很好的实现,但是代码和硬件已经发展了。

@charris我非常感谢您提供的信息,这很不幸,但是对于许可证很有道理。

这应该在numpy 1.17中修复。

谢谢@mreineck ,关闭

此页面是否有帮助?
0 / 5 - 0 等级