FFT卷积不比经典卷积计算快

时间:2016-02-20 21:32:50

标签: python numba

几个月前,我发现使用FFT算法以最快的方式计算卷积(使用FFTW库更多)

使用以下代码我有争议的结果。

进口

from scipy import fftpack
from numba import jit

使用FFT进行卷积:

def conv_fft(X, R):
    n = len(X)   
    a = fftpack.fft(X)
    b = fftpack.fft(R)
    c = a * b
    e = fftpack.ifft(c)
    result = e[n]
    return result

使用公式进行卷积:

@jit(cache=True)
def conv(X, R):
    n = len(X)      
    result = complex_type(0)
    for i in range(n+1):
        result += X[n-i] * R[i]
    return result

这是一个复杂过程中的关键功能,只有使用一个版本或另一个版本才会产生差异。

       no FFT     with FFT   increment
Test1  0.028761   0.034139   0.0053780
Test2  0.098565   0.103180   0.0046150

** test2计算每次测试的更多卷积。*

测试显示带有FFT的代码较慢,我无法理解为什么因为fftpack显然调用了“西部最快”的FFTW库 ...

感谢任何指导。

我的结论是,numba JIT编译的速度令人难以置信。

2 个答案:

答案 0 :(得分:2)

您只返回卷积的单个值(第n个),而不是整个数组。使用FFT,您总是计算所有值,而在您的转换函数中,您只计算您所追求的值。复杂性方面,FFT为O(N * log(N)),您的conv实现为O(N)。如果你要实现一个返回完整卷积的朴素转换函数,它将是O(N ^ 2)。 所以,如果你想要完整的复杂阵列,你最好的选择就是采用FFT方式。如果您只想要第n个值,那么您的方法最好是复杂的。

答案 1 :(得分:0)

您应该能够使用这种类型的语法来创建更少的临时数组,这样可以加快它的速度。

def conv_fft(X, R):
    fftpack.fft(X, overwrite_x=True)
    b = fftpack.fft(R)
    X *= b
    fftpack.ifft(X, overwrite_x=True)
    return X