【问题标题】:matlab convolution "same" to numpy.convolvematlab 卷积“相同”到 numpy.convolve
【发布时间】:2025-12-09 18:55:01
【问题描述】:

我注意到当我在 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的最后一个元素?

【问题讨论】:

  • 在这里不要自以为是,但我只是想确定这不是索引问题,因为 python 索引为 0,matlab 索引为 1,而我相信 matlab 中的 M[0] 会越界。您是否在问题中考虑了这一点?

标签: python matlab numpy


【解决方案1】:

我的猜测是较短的输入数组的长度是偶数。在这种情况下,当方法“相同”时应如何处理存在歧义。显然 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

第一个词 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])

第一项 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 比较短输入的长度小一),然后应用“有效”方法,您可以看到,当p为奇数时(即较短的长度为偶数),需要选择哪一端得到额外的0。matlab和numpy使用不同的选择。

要实现 Matlab 版本的“相同”方法,您可以自己进行填充并将“有效”方法与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])

或者你可以应用 'full' 方法,然后切出相当于 Matlab 的 'same' 方法的部分:

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

其他实现也是可能的。使用哪一个取决于您希望避免多少额外的复制、额外的内存使用和额外的计算。

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

【讨论】:

  • 我最终使用了“完整”方法,并在“相同”方法的输出中找到了最后一个元素的索引,并在切掉第一个元素的同时将以下元素附加到该输出中
最近更新 更多