NumPy 卷积定理

NumPy Convolution Theorem

我是卷积的新手,因此想通过使用 FFT 将两个一维信号卷积在一起来向自己证明卷积定理。但是,我的代码与np.convolve.

得到的结果不一致

我使用了这个 :

中的简单实现
import numpy as np

def Convolution(array,kernel):
    return np.real(np.fft.ifft( np.fft.fft(array)*np.fft.fft(kernel) ))

 a_flat = [ 1., 2., 3., 0., 0., 4., 5., 6., 0., 0. , 7.,  8.,  9.]
 k_flat = [ 1,2 ,1 ,0,0 ,0 ,0,0 ,0 ,0,-1,-2,-1]

 my_convolution = Convolution(a_flat, k_flat)
 np_convolution = np.convolve(a_flat, k_flat)

 print(my_convolution)
 print("") 
 print(np_convolution)

输出为:

[ 19.  10.   4.  -5. -17. -13.   7.  13.  -5. -26. -20.   9.  24.]

[  1.   4.   8.   8.   3.   4.  13.  20.  17.   6.   6.  18.  24.  18.   6.  -4. -13. -20. -17.  -6.  -7. -22. -32. -26.  -9.]

我显然遗漏了一些东西。有人可以指出我的疏忽吗?

注意你的锚点在内核中的位置,通常是中位数,在你的情况下是中间的 0,你仍然应该确保它是正确的。 参考@Paul R 的回答,决定您要使用哪种填充(零填充、复制边界区域等),因为这会影响您的输出。

一个卷积的结果是N+M-1,例如长于任一输入。所以你的 FFT 需要那么长或更长。

一个FFT/IFFT会将快速卷积结果包裹起来,并将其混合成循环卷积。但是,如果您在末尾用大量零填充数据,则混合将很容易取消混合。

@hotpaw2 说的。总是更好地绘制它:

import numpy as np
import matplotlib.pyplot as p
%matplotlib inline

def Convolution(array,kernel):
    return np.real(np.fft.ifft( np.fft.fft(array)*np.fft.fft(kernel) ))

a_flat = [ 1., 2., 3., 0., 0., 4., 5., 6., 0., 0. , 7.,  8.,  9.]
k_flat = [ 1,2,1,0,0,0,0,0,0,0,-1,-2,-1]

a_flat= np.pad(a_flat, (25, 25), 'constant', constant_values=(0, 0)).tolist()
k_flat= np.pad(k_flat, (25, 25), 'constant', constant_values=(0, 0)).tolist()


my_convolution = Convolution(a_flat, k_flat)
np_convolution = np.convolve(a_flat, k_flat)

fig,ax = p.subplots(3,figsize=(12,5))     

ax[0].plot(a_flat)
ax[1].plot(k_flat)
ax[2].plot(np.roll(my_convolution, 30),'.-',lw=0.5,label='myconv');  # arbitrary shift here
ax[2].plot(np.roll(np_convolution,  0),'.-',lw=3,alpha=0.3,label='npconv');
p.legend()

很好的例子,顺便说一句。