matlab卷积"相同"到numpy.convolve

STL*_*L93 5 python matlab numpy

我注意到当我在matlab中使用conv(a,b,'same')时,它将返回长度为200的M,但是当我使用numpy.convolve(a,b,'same')时,它将返回N的长度200,但与M相比移位了一个元素(N [1:]与M [0:-1]相同,M [-1]不在N,N [0]不在M),如何我能解决这个问题吗?

我可以切断N的第一个元素,但有没有办法可以获得M的最后一个元素而不会经历一些麻烦?

War*_*ser 7

我的猜测是较短输入数组的长度是偶数。在这种情况下,当方法“相同”时,应如何处理它是模棱两可的。显然Matlab和numpy采用了不同的约定。

在Matlab文档网页(http://www.mathworks.com/help/matlab/ref/conv.html)上有一个使用“ same”方法的示例:

> u = [-1 2 3 -2 0 1 2];
> v = [2 4 -1 1];
> w = conv(u,v,'same')

w =

    15     5    -9     7     6     7    -1
Run Code Online (Sandbox Code Playgroud)

第一项为15,为(1)*(0) + (-1)*(-1) + (4)*(2) + (2)*(3),最后一项为-1,为(1)*(1) + (-1)*(2) + (4)*(0) + (2)*(0)。您可以将其解释为u[0 -1 2 3 -2 0 1 2 0 0]的填充,然后使用“有效”方法。

使用numpy:

In [24]: u
Out[24]: array([-1,  2,  3, -2,  0,  1,  2])

In [25]: v
Out[25]: array([ 2,  4, -1,  1])

In [26]: np.convolve(u, v, 'same')
Out[26]: array([ 0, 15,  5, -9,  7,  6,  7])
Run Code Online (Sandbox Code Playgroud)

第一项为0,为(1)*(0) + (-1)*(0) + (4)*(-1) + (2)*(2),最后一项为7 (1)*(0) + (-1)*(1) + (4)*(2) + (2)*(0)。该结果可以解释为填充u为[0、0,-1、2、3,-2、0、1、2、0],然后使用“有效”方法。

通过将“相同”方法视为等效于将较长的参数填充p为零(其中p小于较短输入的长度的位置),然后应用“有效”方法,可以看到when p为奇数(即较短的长度是偶数),则需要选择哪个端点获得额外的0。Matlab和numpy使用不同的选择。

要实现Matlab版本的“ same”方法,您可以自己进行填充,并使用的“ valid”方法np.convolve。例如,

In [45]: npad = len(v) - 1

In [46]: u_padded = np.pad(u, (npad//2, npad - npad//2), mode='constant')

In [47]: np.convolve(u_padded, v, 'valid')
Out[47]: array([15,  5, -9,  7,  6,  7, -1])
Run Code Online (Sandbox Code Playgroud)

或者,您可以应用“完整”方法,然后切出与Matlab的“相同”方法等效的部分:

In [62]: npad = len(v) - 1

In [63]: full = np.convolve(u, v, 'full')

In [64]: first = npad - npad//2

In [65]: full[first:first+len(u)]
Out[65]: array([15,  5, -9,  7,  6,  7, -1])
Run Code Online (Sandbox Code Playgroud)

其他实施方式也是可能的。使用哪一个取决于要避免多大的复制,更多的内存使用和额外的计算量。

如果较短的输入数组的长度为奇数,则Matlab和numpy中的结果应该相同。