【问题标题】:NumPy Convolution TheoremNumPy 卷积定理
【发布时间】:2019-11-22 09:38:35
【问题描述】:

我是卷积的新手,因此想通过使用 FFT 将两个 1D 信号卷积在一起来向自己证明卷积定理。但是我的代码和np.convolve得到的结果不一致。

我使用了来自 solution 的幼稚实现:

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.]

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

【问题讨论】:

  • 您在自己的实现中进行循环卷积 - 您需要用零填充以获得正确的卷积。 (或者我弄错了,你实际上在这两种情况下都想要循环卷积?)
  • 要详细说明 Paul 的答案,您可以在此处找到与您类似的问题/答案:mathworks.com/matlabcentral/answers/… 代码在 matlab 中,但推理是相同的 :)

标签: python numpy signal-processing fft convolution


【解决方案1】:

@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()

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-11
        • 2017-02-24
        • 2013-11-30
        • 1970-01-01
        • 2021-06-12
        • 1970-01-01
        • 1970-01-01
        • 2019-09-28
        相关资源
        最近更新 更多