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

Algorithm 快速计算点(a(n:end),b(1:end-n))`,algorithm,matlab,vector,convolution,numerical-methods,Algorithm,Matlab,Vector,Convolution,Numerical Methods,假设我们有两个一维值数组a和b,它们都有长度N。我想创建一个新数组c,这样c(n)=点(a(n:n),b(1:n-n+1))我当然可以使用一个简单的循环: for n=1:N c(n)=dot(a(n:N), b(1:N-n+1)); end 但考虑到这是一个类似于卷积的简单操作,我想知道是否有更有效的方法(使用Matlab)来实现这一点。这是一个有趣的问题 我假设a和b是相同长度的列向量。让我们考虑一个简单的例子: a=[9;10;2;10;7]; b=[1;3;6;10;10];

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

for n=1:N
    c(n)=dot(a(n:N), b(1:N-n+1));
end

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

这是一个有趣的问题

我假设
a
b
是相同长度的列向量。让我们考虑一个简单的例子:

a=[9;10;2;10;7];
b=[1;3;6;10;10];
%收益率:
c=[221;146;74;31;7];
现在让我们看看当我们计算这些向量的卷积时会发生什么:

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 我们注意到,
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
所以现在它变成了一个矩阵对角线求和的问题,这是一个已有的解决方案,例如Andrei Bobrov的解决方案:

C=conv2(a',b);
p=总和(spdiags(C,0:size(C,2)-1));%这将给出与循环相同的结果。

使用1D卷积的解决方案
conv

out = conv(a, flip(b));
c = out(ceil(numel(out)/2):end);

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

性能方面如何?你能添加一个小的计时实验吗?我为
N=10^4
a=1:N
b=1:N
的解决方案计时。然后我做了:ticc=conv2(a',b);p1=总和(spdiags(C,0:size(C,2)-1));n=1:np2(i)=点(a(n:end),b(1:end-n+1));结束toc,第一种方法(我相信是您的解决方案)耗时2秒,而另一种方法耗时0.2秒。。我喜欢这个解决方案,它看起来很整洁,但可能不是很有效?@Darkwizie注意到
tic/toc
测量实际的挂钟时间,对于性能测试可能不准确。如果一个简单的循环对于大的
N
更快,那么使用instedi不会感到惊讶,因为它不涉及卷积和创建大矩阵(相对于原始1D向量)。。。循环在MATLAB中并不是天生的慢,而且很清楚在使用timeit()时会发生什么,它会产生类似的计时。