我正在寻找一种更快的方法来使用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=size(A,1);
B=zeros(nbrows*(nbrows+1)/2,size(A,2)); % the size of B can be determined
for i = 1:nbrows
for j = i:nbrows
B(idx,:) = A(i,:) + A(j,:);
idx = idx + 1;
end
end现在,我有一个非常大的A,我想知道如何更有效地计算矩阵B。
如何加快计算速度?
发布于 2020-10-19 11:00:39
您可以预先计算行的索引并对列进行迭代,而不是对行进行迭代:
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由于A非常大,所以完全矢量化的解决方案:
B = A(r,:) + A(c,:);不应该比循环版本更高效。
发布于 2020-10-19 15:37:15
根据@rahnema1 1的建议,这里有三种可能的测试结果。让我们将矩阵A生成为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更好的方法,我会非常高兴地看到这一点。
https://stackoverflow.com/questions/64423481
复制相似问题