简体   繁体   English

matlab 卷积“相同”到 numpy.convolve

[英]matlab convolution “same” to numpy.convolve

I noticed that when I use conv(a, b, 'same') in matlab, it would return say M of length 200, but when I use numpy.convolve(a, b, 'same') it would return N of length 200, but shifted by one element compared to M (N[1:] would be the same as M[0:-1] and M[-1] would not be in N, N[0] not in M), how can I fix this?我注意到当我在 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 中),如何我可以解决这个问题吗?

I can cut off the first element of N, but is there a way I can get the last element of M without going through some hassles?我可以切断 N 的第一个元素,但是有没有办法可以在不经过一些麻烦的情况下获得 M 的最后一个元素?

My guess is that the length of the shorter input array is even.我的猜测是较短的输入数组的长度是偶数。 In this case, there is an ambiguity in how it should be handled when the method is "same".在这种情况下,当方法“相同”时应该如何处理存在歧义。 Apparently Matlab and numpy adopted different conventions.显然 Matlab 和 numpy 采用了不同的约定。

There is an example of the use of the 'same' method on the Matlab documentation web page ( http://www.mathworks.com/help/matlab/ref/conv.html ): Matlab 文档网页( http://www.mathworks.com/help/matlab/ref/conv.html )上有一个使用“相同”方法的示例:

> 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

The first term, 15, is (1)*(0) + (-1)*(-1) + (4)*(2) + (2)*(3) , and the last term, -1, is (1)*(1) + (-1)*(2) + (4)*(0) + (2)*(0) .第一项 15 是(1)*(0) + (-1)*(-1) + (4)*(2) + (2)*(3) ,最后一项 -1 是(1)*(1) + (-1)*(2) + (4)*(0) + (2)*(0) You can interpret that as padding u to be [0 -1 2 3 -2 0 1 2 0 0], and then using the 'valid' method.您可以将其解释为将u填充为 [0 -1 2 3 -2 0 1 2 0 0],然后使用“有效”方法。

With 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])

The first term, 0, is (1)*(0) + (-1)*(0) + (4)*(-1) + (2)*(2) , and the last term, 7, is (1)*(0) + (-1)*(1) + (4)*(2) + (2)*(0) .第一项 0 是(1)*(0) + (-1)*(0) + (4)*(-1) + (2)*(2) ,最后一项 7 是(1)*(0) + (-1)*(1) + (4)*(2) + (2)*(0) That result can be interpreted as padding u to be [0, 0, -1, 2, 3, -2, 0, 1, 2, 0] and then using the 'valid' method.该结果可以解释为将u填充为 [0, 0, -1, 2, 3, -2, 0, 1, 2, 0] 然后使用 'valid' 方法。

By thinking about the 'same' method as being equivalent to padding the longer argument with p zeros (where p is one less than the length of the shorter input) and then applying the 'valid' method, you can see that when p is odd (ie the shorter length is even), a choice is required for which end gets the extra 0. Matlab and numpy use different choices.通过将“相同”方法视为等效于用p零填充较长的参数(其中p比较短输入的长度少 1)然后应用“有效”方法,您可以看到当p为奇数时(即较短的长度是偶数),需要选择哪一端获得额外的 0。Matlab 和 numpy 使用不同的选择。

To implement the Matlab version of the 'same' method, you could do the padding yourself and use the 'valid' method with np.convolve .要实现“相同”方法的 Matlab 版本,您可以自己进行填充并使用“有效”方法和np.convolve For example,例如,

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

Or you could apply the 'full' method, and then slice out the part that is equivalent to Matlab's 'same' method:或者您可以应用“完整”方法,然后切出与 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])

Other implementations are possible.其他实现是可能的。 Which one to use depends on how much you want to avoid extra copying, extra memory use and extra computation.使用哪一个取决于您希望避免额外复制、额外内存使用和额外计算的程度。

If the shorter input array has an odd length, the results in Matlab and numpy should be the same.如果较短的输入数组的长度为奇数,则 Matlab 和 numpy 中的结果应该相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM