在测试期间,我注意到一些奇怪的事情。
我正在对很多向量进行FFT,并且有时会出现numpy FFT函数崩溃的情况。
我简要地调试了这个,发现一些矢量长度触发了这种行为。
事件中,我保持一个脚本运行,令我惊讶的是,它没有崩溃,只是花了一点时间。
有没有人知道发生了什么,以及如何反击这一点。我已经看到了许多不同的FFT大小,下面只是一个例子。
import numpy as np
import time
a = np.zeros(166400)
start = time.time()
audio_fft = np.fft.fft(a,len(a))
print "it took %fs"%(time.time() -start)
a = np.zeros(165039)
start = time.time()
audio_fft = np.fft.fft(a,len(a))
print "it took %fs"%(time.time() -start)
a = np.zeros(165038)
start = time.time()
audio_fft = np.fft.fft(a,len(a))
print "it took %fs"%(time.time() -start)
a = np.zeros(165036)
start = time.time()
audio_fft = np.fft.fft(a,len(a))
print "it took %fs"%(time.time() -start)
a = np.zeros(165035)
start = time.time()
audio_fft = np.fft.fft(a,len(a))
print "it took %fs"%(time.time() -start)
a = np.zeros(165034)
start = time.time()
audio_fft = np.fft.fft(a,len(a))
print "it took %fs"%(time.time() -start)
a = np.zeros(165037)
start = time.time()
audio_fft = np.fft.fft(a,len(a))
print "it took %fs"%(time.time() -start)
print "done"
输出:
c:\Users\sol_sf\Desktop\math>fftTest.py
it took 0.029000s
it took 0.101000s
it took 0.176000s
it took 0.220000s
it took 0.671000s
it took 0.065000s
it took 369.132000s
done
c:\Users\sol_sf\Desktop\math>
答案 0 :(得分:11)
分割和征服FFT算法(例如Cooley-Tukey)在输入长度越多的因素下效果越好。 2的功率特别好,而素数(如165037)需要交替的,较慢的实现。如果您可以将输入填充到2的幂长度,则可以大幅加速慢速FFT。
答案 1 :(得分:2)
我认为阵列的2次填充有几个缺点:
我在这个topic中发现fft性能取决于数组大小素数因子分解。如果数组长度为素数,则会导致计算时间过长。因此,我建议使用以下代码来减少数组长度,以寻找最佳的分解。
from sympy.ntheory import factorint
FACTOR_LIMIT = 100
def bestFFTlength(n):
while max(factorint(n)) >= FACTOR_LIMIT:
n -= 1
return n
a = np.zeros(166400)
audio_fft = np.fft.fft(a,bestFFTlength(len(a)))
答案 2 :(得分:0)
解决此问题的一种简单方法(其他答案中未提及)是使用scipy.fftpack.next_fast_len填充数组。给定目标长度,它会为您提供下一个长度>目标,该目标由2、3和5组成。
正如其他答案所指出的那样,当数组的长度为质数时,FFT表现最差。它的效率随着主要因子数量的增加(2、3、5等)而增加。