Performance 用MATLAB快速计算矩阵

Performance 用MATLAB快速计算矩阵,performance,matlab,matrix,Performance,Matlab,Matrix,我正在寻找一种使用MATLAB计算矩阵的更快方法: 给定一个m-by-n矩阵A,我想返回一个矩阵B,其中添加了所有Ith和jth行,使得j>=I。例如。, 让A=[1 2 3 4;2 3 4 5;3 4 5 6],则B可计算为 idx=1; nbrows=尺寸(A,1); B=零(nbrows*(nbrows+1)/2,大小(A,2));%B的大小可以确定 对于i=1:nbrows 对于j=i:nbrows B(idx,:)=A(i,:)+A(j,:); idx=idx+1; 结束 结束 现在

我正在寻找一种使用MATLAB计算矩阵的更快方法:

给定一个m-by-n矩阵
A
,我想返回一个矩阵
B
,其中添加了所有
I
th和
j
th行,使得
j>=I
。例如。, 让
A=[1 2 3 4;2 3 4 5;3 4 5 6]
,则
B
可计算为

idx=1;
nbrows=尺寸(A,1);
B=零(nbrows*(nbrows+1)/2,大小(A,2));%B的大小可以确定
对于i=1:nbrows
对于j=i:nbrows
B(idx,:)=A(i,:)+A(j,:);
idx=idx+1;
结束
结束
现在,我有一个非常大的
a
,我想知道如何更有效地计算矩阵
B


如何加快计算速度?

您可以预先计算行的索引并迭代列,而不是迭代行:

nbcols = size(A, 2);

[r, c] = find(tril(true(nbrows)));

rc = [r c];

for i = 1:nbcols
    B(:, i) = sum(reshape(A(rc, i), [], 2), 2);
end
等效的可能效率较低的解决方案:

for i = 1:nbcols
    B(:, i) = A(r, i) + A(c, i);
end
B = A(r,:) + A(c,:);
由于
A
非常大,因此完全矢量化的解决方案:

for i = 1:nbcols
    B(:, i) = A(r, i) + A(c, i);
end
B = A(r,:) + A(c,:);

不应该比循环版本更有效。

根据@rahnema1的建议,这里是关于三种可能方式的测试结果。让我们生成矩阵
A
as
A=rand(1e4,20)

方法1:使用索引和矢量化

tic
nbrows = size(A,1);
[r, c] = find(tril(true(nbrows)));
B = A(r,:) + A(c,:);
toc
12.8秒后终止

方法2:使用索引和循环

tic
nbrows = size(A,1);
nbcols = size(A, 2);
[r, c] = find(tril(true(nbrows)));
rc = [r c];
B=zeros(nbrows*(nbrows+1)/2,size(A,2)); 
for i = 1:nbcols
    B(:, i) = sum(reshape(A(rc, i), [], 2), 2);
end
toc
在34.8秒后终止

方法3:仅使用循环

tic
idx=1;
nbrows=size(A,1);
B=zeros(nbrows*(nbrows+1)/2,size(A,2)); 
for i = 1:nbrows
  for j = i:nbrows
    B(idx,:) = A(i,:) + A(j,:);
    idx = idx + 1;
  end
end
toc
在85.1秒后终止


总之,方法1(使用索引和矢量化)是最快的方法。再次感谢你的回答!如果有人找到比方法1更好的方法,我会很高兴看到这一点。

你的输入有多大,速度是个问题?@Wolfie作为一个不太大的例子,
a=rand(5e3,20)
,那么
B
的计算可能需要一段时间。事实上,这种计算必须在我的代码中重复,因此我需要这一步尽可能快。@rahema1非常感谢您的回复。使用索引时,这确实要好得多。我将添加一个示例来显示我的测试,如下所示。请注意,结果取决于
A
的大小。对于八度音阶上大小为
[5e3 x 20]
的矩阵,可通过以下方法获得最佳结果:
B=a(r,:);B+=A(c,:)
MATLAB等效版本可能不会比完整版本工作得更好:
B=A(r,:);B=B+A(c,:)我在MATLAB上测试过,
B=A(r,:);B=B+A(c,:)似乎和B=A(r,:)+A(c,:)
一样快。