2016-03-13 53 views
3

我注意到numpy.convolve在足够复杂的信号上产生了奇怪的结果。下面是一个简单的测试,例如:Numpy卷积(卷积)似乎在复杂信号上产生巨大误差

import numpy as np 
import matplotlib.pyplot as plt 
from scipy import signal 

def conv_np(x, win): 
    return np.convolve(x, win, 'valid') 

def conv_dot(x, win): 
    Z = np.asarray([x[cnt:cnt+win.shape[0]] for cnt in range(x.shape[0]-win.shape[0]+1)]) 
    return np.dot(Z, win) 

# test 1 
x = np.repeat([0., 1., 0.], 300) 
win = signal.hamming(50) 

plt.subplot(2,1,1) 
plt.plot(conv_np(x, win) - conv_dot(x, win)) 

# test 2 
x = np.random.random(size=(10000,)) 
win = x[4000:5000] 

plt.subplot(2,1,2) 
plt.plot(conv_np(x, win) - conv_dot(x, win)) 

plt.show() 

而这里的结果: Difference between numpy and dot product implementation of convolution.

该图显示numpy.convolve和直接执行使用点产生卷积之间的差异。顶部图是一个简单的信号和窗口(一个步骤和一个汉恩窗口)。底部图是一个随机信号,窗口只是这个信号的一部分。

因此,对于简单的信号/窗口,卷积产品和卷积的numpy实现几乎没有区别,但复杂信号/窗口存在巨大差异。

由于点积实现可以被认为是一个基本事实,我把这个差异解释为numpy的错误。请让我知道如果我错了,或者如果有办法使numpy产生与点积相同的结果。

回答

2

为了正确使用点积产品you need to reflect the kernel进行卷积。如果重新定义conv_dot为:

def conv_dot(x, win): 
    Z = [x[cnt:cnt+win.size] for cnt in range(x.size-win.size+1)] 
    return np.dot(Z, win[::-1]) # the [::-1] is the only real change 

你会发现,这些错误是可以忽略不计,现在如预期,顶多2e-13在试运行我与你的第二个例子一样。

+0

确实。非常感谢! – alex