【问题标题】:FFT convolution not being faster than the cannonical convolution computationFFT 卷积不比标准卷积计算快
【发布时间】:2016-02-21 05:57:38
【问题描述】:

几个月前,我发现使用 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 编译速度快得令人难以置信。

【问题讨论】:

    标签: python numba


    【解决方案1】:

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

    【讨论】:

    • 有没有办法使用 FFT 算法来取我需要的值?它会产生任何收益吗?
    • 如果你只需要第n个值,那真的没有意义。您可以按照您的方式进行操作,但使用 FFT 算法您必须计算数组中的所有值。
    【解决方案2】:

    您应该能够使用这种类型的语法创建更少的临时数组,这应该会使其更快。

    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
    

    【讨论】:

    • 谢谢,我会测试一下,然后回到问题
    • 我没有包含 len(X 检查,不确定是否需要。您也可以直接使用 fftpack 的 convolve...
    • 我已经对其进行了测试,但 FFT 仍然较慢(虽然当然比以前快一点),为了记录,我测量了 100 次执行的平均值
    • fftpack convolve 功能有帮助吗?
    • 信号的长度是多少?
    猜你喜欢
    • 2019-12-01
    • 2012-12-10
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-25
    • 2011-08-27
    • 2013-12-31
    相关资源
    最近更新 更多