<p>上面的Numba方法是一个很好的技巧,但只对相对较小的N有利。无论实现的速度有多快,一个<em>O(N^6)</em>算法每次都会杀死你。在我的测试中,<code>fftconvolve</code>方法在N=20左右交叉更快,而在N=32时是10倍。省略上面<code>custom_convolution</code>的定义:</p>
<pre><code>from timeit import Timer
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import fftconvolve
from numba import jit, double
# Numba'ing the function with the JIT compiler
numba_convolution = jit(double[:, :, :](double[:, :, :],
double[:, :, :]))(custom_convolution)
def fft_convolution(A, B):
return fftconvolve(A, B, mode='full')
if __name__ == '__main__':
reps = 3
nt, ft = [], []
x = range(2, 34)
for N in x:
print N
A = np.random.rand(N, N, N)
B = np.random.rand(N, N, N)
C1 = numba_convolution(A, B)
C2 = fft_convolution(A, B)
assert np.allclose(C1[:-1, :-1, :-1], C2)
t = Timer(lambda: numba_convolution(A, B))
nt.append(t.timeit(number=reps))
t = Timer(lambda: fft_convolution(A, B))
ft.append(t.timeit(number=reps))
plt.plot(x, ft, x, nt)
plt.show()
</code></pre>
<p>它也非常依赖于N,因为对于2的幂次,FFT要快得多。对于N=17到N=32,FFT版本的时间基本上是恒定的,在N=33时,它仍然更快,此时它又开始快速发散。在</p>
<p>您可以尝试用Numba包装FFT实现,但不能直接用scipy版本实现。在</p>
<p>(很抱歉创建新答案,但我没有直接答复的要点。)</p>