Python NumPy卷积定理

Python NumPy卷积定理,python,numpy,signal-processing,fft,convolution,Python,Numpy,Signal Processing,Fft,Convolution,我是卷积的新手,因此我想通过使用FFT将两个一维信号卷积在一起来证明卷积定理。然而,我的代码与从np.convolve获得的结果不一致 我使用了下面的朴素实现: 输出内容如下: [ 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. -1

我是卷积的新手,因此我想通过使用FFT将两个一维信号卷积在一起来证明卷积定理。然而,我的代码与从np.convolve获得的结果不一致

我使用了下面的朴素实现:

输出内容如下:

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

我显然错过了什么。有人能指出我的疏忽吗?

< P>注意你的锚在你的内核中,通常是中值,在你的情况下,中间的0,你仍然应该确保它是正确的。
参考@保罗R的答案,确定你想用哪种填充,使用零填充,复制边界区域等等,因为这会影响你的输出。

知道你的锚在你的内核中,通常是中间值,在你的情况下,中间的0,你仍然应该确保它是正确的。


参考@Paul R的答案,决定要使用哪种填充方式:零填充、复制边界区域等,因为这会影响输出。

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


FFT/IFFT将快速卷积结果包裹起来,并将其混合成循环卷积。但是,如果在数据的两端填充大量的零,则很容易进行混合。

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


FFT/IFFT将快速卷积结果包裹起来,并将其混合成循环卷积。但是,如果你在数据的两端加上大量的零,混合将很容易被分解。

What@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()
好例子,顺便说一句


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()
好例子,顺便说一句


您正在自己的实现中进行循环卷积-您需要用零填充以获得适当的卷积。或者我是不是搞错了,你真的想要两种情况下的循环卷积?为了详细说明Paul的答案,你可以在这里找到一个与你类似的问题/答案:代码在matlab中,但道理是一样的:你在自己的实现中做循环卷积——你需要用零来填充以得到正确的卷积。或者我是不是搞错了,而你在这两种情况下都需要循环卷积?为了详细说明Paul的答案,你可以在这里找到一个与你类似的问题/答案:代码在matlab中,但推理是相同的: