快速计算`dot(a(n:end),b(1:end-n))`

Dar*_*zie 4 algorithm matlab vector convolution numerical-methods

假设我们有两个一维的值数组,a并且b都有长度N.我想创建一个新的数组,c这样c(n)=dot(a(n:N), b(1:N-n+1))我当然可以使用一个简单的循环来做到这一点:

for n=1:N
    c(n)=dot(a(n:N), b(1:N-n+1));
end
Run Code Online (Sandbox Code Playgroud)

但鉴于这是一个类似于卷积的简单操作,我想知道是否有更有效的方法来做到这一点(使用Matlab).

rah*_*ma1 6

使用一维卷积的解决方案conv:

out = conv(a, flip(b));
c = out(ceil(numel(out)/2):end);
Run Code Online (Sandbox Code Playgroud)

conv第一个向量中乘以第二个向量的反转版本,因此我们需要计算卷积a和翻转b并修剪不必要的部分.


Dev*_*-iL 5

这是一个有趣的问题!

我要假设ab长度相同的列向量.让我们考虑一个简单的例子:

a = [9;10;2;10;7];
b = [1;3;6;10;10];
% yields:
c = [221;146;74;31;7];
Run Code Online (Sandbox Code Playgroud)

现在让我们看看当我们计算这些向量的卷积时会发生什么:

>> conv(a,b)
ans =
     9
    37
    86
   166
   239
   201
   162
   170
    70

>> conv2(a, b.')
ans =
     9    27    54    90    90
    10    30    60   100   100
     2     6    12    20    20
    10    30    60   100   100
     7    21    42    70    70
Run Code Online (Sandbox Code Playgroud)

我们注意到这c是结果的下对角线上的元素之和conv2.为了更清楚地显示,我们将转置以使对角线的顺序与以下值相同c:

>> triu(conv2(a.', b))
ans =
     9    10     2    10     7
     0    30     6    30    21
     0     0    12    60    42
     0     0     0   100    70
     0     0     0     0    70
Run Code Online (Sandbox Code Playgroud)

所以现在它成为一个总结矩阵对角线的问题,这是现有解决方案的一个更常见的问题,例如Andrei Bobrov的这个问题:

C = conv2(a.', b);
p = sum( spdiags(C, 0:size(C,2)-1) ).'; % This gives the same result as the loop.
Run Code Online (Sandbox Code Playgroud)