【问题标题】:scipy.fftpack's FFT freezingscipy.fftpack 的 FFT 冻结
【发布时间】:2018-10-25 00:57:18
【问题描述】:

在计算大小为约 150 万个项目的数组的 FFT 时:

import numpy as np
from scipy.fftpack import fft

x0 = np.ones(1492828, dtype=np.int32)
fft(x0)
print 'hello'

FFT 计算永远不会完成,程序正在冻结。如果我将1492828 更改为1492827,它似乎可以工作。但是如果我把1492828改成1492826,它还是会死机,这有点奇怪。

这是一个已知的错误吗?

注意:

  • CPU 保持在 25%(正常,我有一个 4 核 CPU),Python 进程的 RAM 使用率保持在 ~75 MB

  • 我在 Windows 7 64 位上使用 Python 2.7.15 64 位:

    print scipy.__version__     # 1.1.0
    print sys.version           # 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)]
    

【问题讨论】:

  • 你试过np.fft.fft吗?
  • @Brenlla 过去是的,但是对于这个项目,我已经用scipy.fftpack.fft 编码了所有内容,所以我想在转到np.fft.fft 之前看看这是否是一个已知的错误。你也能重现错误吗?
  • 这不是错误。根据实现的不同,FFT 算法对复合长度(小素数的幂的乘积)表现良好。 See here 了解更多信息。 1492828 的素数是 2 和 373207,而 1492827 的素数要小得多(3、7、67、1061),而 1492826 的素数又大了……
  • 是的,npsp fft 版本在我的电脑上出现同样的问题
  • 随意写一个答案——正如他们所说,cmets 是公平的游戏;)(但如果更深入的挖掘也会在网站上揭示这个答案——或者更好的答案,我不会感到惊讶。)

标签: python numpy scipy fft fftpack


【解决方案1】:

here 所述,对于具有较小素因数的长度,通常的 FFT 算法要​​快得多。

解决方案是将数组补零到 2 的下一个幂:

def zeropad_nextpoweroftwo(A):
    return np.concatenate([A, np.zeros(int(2 ** np.ceil(np.log2(len(A))))-len(A), 
        dtype=A.dtype)])

或者,一个更简单/更好的解决方案是使用next_fast_len 以及fftpack.fft 的第二个参数允许自动填充零的事实:

fftpack.fft(a, next_fast_len(len(a)))

【讨论】:

  • 可以使用scipy.fftpack.next_fast_len 填充到下一个5-smooth number,而不是填充到下一个2的幂。
  • 你不妨更新你的答案。我怀疑这个问题或多或少是重复的——同样的问题不时被重新发现——但我没有搜索过。
猜你喜欢
  • 1970-01-01
  • 2017-09-28
  • 2015-11-16
  • 1970-01-01
  • 2017-11-09
  • 1970-01-01
  • 2012-10-17
  • 2017-07-28
  • 2018-09-05
相关资源
最近更新 更多