【发布时间】:2016-08-31 09:33:48
【问题描述】:
在我的 matlab 程序中,我有几个需要创建矩阵的实例,其中的条目取决于它的索引并使用它执行矩阵向量运算。我想知道如何才能最有效地实现这一点。
比如我需要加速:
N = 1e4;
x = rand(N,1);
% Option 1
tic
I = 1:N;
J = 1:N;
S = zeros(N,N);
for i = 1:N
for j = 1:N
S(i,j) = (i+j)/(abs(i-j)+1);
end
end
a = x'*S*x
fprintf('Option 1 takes %.4f sec\n',toc)
clearvars -except x N
我试图加快速度,所以我尝试了以下选项:
% Option 2
tic
I = 1:N;
J = 1:N;
Sx = zeros(N,1);
for i = 1:N
Srow_i = (i+J)./(abs(i-J)+1);
Sx(i)= Srow_i*x;
end
a = x'*Sx
fprintf('Option 2 takes %.4f sec\n',toc)
clearvars -except x N
和
% Option 3
tic
I = 1:N;
J = 1:N;
S = bsxfun(@plus,I',J)./(abs(bsxfun(@minus,I',J))+1);
a = x'*S*x
fprintf('Option 3 takes %.4f sec\n',toc)
clearvars -except x N
和(感谢其中一个答案)
% options 4
tic
[I , J] = meshgrid(1:N,1:N);
S = (I+J) ./ (abs(I-J) + 1);
a = x' * S * x;
fprintf('Option 4 takes %.4f sec\n',toc)
clearvars -except x N
Otion 2 是最有效的。是否有更快的选择来执行此操作?
更新:
我也尝试过 Abhinav 的选项:
% Option 5 using Tony's Trick
tic
i = 1:N;
j = (1:N)';
I = i(ones(N,1),:);
J = j(:,ones(N,1));
S = (I+J)./(abs(I-J)+1);
a = x'*S*x;
fprintf('Option 5 takes %.4f sec\n',toc)
clearvars -except x N
似乎最有效的过程取决于 N 的大小。对于不同的 N,我得到以下输出:
N = 100:
Option 1 takes 0.00233 sec
Option 2 takes 0.00276 sec
Option 3 takes 0.00183 sec
Option 4 takes 0.00145 sec
Option 5 takes 0.00185 sec
N = 10000:
Option 1 takes 3.29824 sec
Option 2 takes 0.41597 sec
Option 3 takes 0.72224 sec
Option 4 takes 1.23450 sec
Option 5 takes 1.27717 sec
因此,对于较小的 N,选项 2 是最慢的,但对于较大的 N,它变得最有效。也许是因为内存?有人可以解释一下吗?
【问题讨论】:
-
您是否只对
a的值感兴趣? -
我将 a 的计算包括在内以进行公平比较,因为它在选项 2 中略有不同。
标签: matlab matrix-multiplication elementwise-operations