Numpy 与实空间卷积相比,FFT卷积的缺点是什么?
所以我知道FFT卷积比实空间卷积的计算复杂度要低。但是FFT卷积的缺点是什么Numpy 与实空间卷积相比,FFT卷积的缺点是什么?,numpy,scipy,signal-processing,fft,convolution,Numpy,Scipy,Signal Processing,Fft,Convolution,所以我知道FFT卷积比实空间卷积的计算复杂度要低。但是FFT卷积的缺点是什么 内核大小是否总是必须与映像大小相匹配,或者是否有函数处理此问题,例如在pythonnumpy和scipy包中?那么抗锯齿效果呢 FFT卷积基于,其中规定给定两个函数f和g,如果Fd()和Fi()表示直接和反向傅里叶变换,*和卷积和乘法,则: f*g = Fi(Fd(d).Fd(g)) 要将此应用于信号f和内核g,需要注意以下几点: f和g必须具有相同的大小,才能实现乘法步骤,因此需要对内核进行零填充(或者输入,如果
内核大小是否总是必须与映像大小相匹配,或者是否有函数处理此问题,例如在pythonnumpy和scipy包中?那么抗锯齿效果呢 FFT卷积基于,其中规定给定两个函数
f
和g
,如果Fd()
和Fi()
表示直接和反向傅里叶变换,*
和
卷积和乘法,则:
f*g = Fi(Fd(d).Fd(g))
要将此应用于信号f
和内核g
,需要注意以下几点:
和f
必须具有相同的大小,才能实现乘法步骤,因此需要对内核进行零填充(或者输入,如果内核比它长)g
- 当进行DFT时(FFT就是这样做的),函数的频域表示结果是周期性的。这意味着,默认情况下,在进行卷积时,内核会环绕边缘。如果你想要这个,那么一切都很好。但是如果没有,您必须添加一个额外的零填充来避免内核的大小
- 大多数(全部?)FFT软件包只在没有任何大的基本因子的情况下工作良好(性能方面)。将信号和内核大小四舍五入到下一个二次方是一种常见做法,可能会导致(非常)显著的速度提升
f_l
和g_l
,则在时域中进行直接卷积需要g_l*(f_l-g_l+1)
乘法和(g_l-1)*(f_l-g_l+1)
加法
对于FFT方法,您必须至少进行3次大小为f_l+g_l
的FFT,以及f_l+g_l
乘法
对于大尺寸的f
和g
,FFT的n*log(n)
复杂度明显优越。对于小内核,直接方法可能更快
scipy.signal
有两种方法供您使用。并且fftconvolve
为您透明地处理上述所有填充。而快速卷积比直接形式卷积具有更好的“大O”复杂度;有一些缺点或警告。我对这个话题做了一些思考,因为我之前写过
请注意,只有当内核超过一定大小时,频域中的卷积才更有效。对于相对较小的内核,直接卷积更为有效。“大多数(全部?)FFT包只适用于没有任何大的素数因子的大小。”:确切地说,你所说的只是速度,计算本身没有问题(至少在numpy和scipy中)。是的,在我的回答中添加了一个注释。典型的FFT算法递归地将大小为
N=a*b
的DFT分解为大小为b
的FFT。如果N
是prime,则需要加快速度。在我的电脑上:%timeit numpy.fft.fft(np.random.rand(1024));10000个回路,最好为3个:每个回路36.2 us;%timeit numpy.fft.fft(np.rand.rand(1021));100个循环,每个循环最好3:2.15毫秒
,一个x100的减速,这似乎表明质数大小的DFT是直接计算的,没有加速度。看起来FFTW有加速度:“质数因子小的尺寸是最好的,但FFTW使用O(N log N)算法,即使对于质数大小也是如此。”。Is也支持多处理。它可以从python与pyfftw一起使用。请注意,如果使用“重叠添加”或“重叠保存”方法(将输入信号分割为多个片段进行处理),内核不必进行零填充,以使其与信号大小相同。