Speeding up a for loop
2 ビュー (過去 30 日間)
古いコメントを表示
Alex Kozlov
2020 年 1 月 12 日
コメント済み: Alex Kozlov
2020 年 1 月 13 日
Hi,
I'm trying to speed up processing time of my code.
Can the next code be reduced to be processed using vectorization instead of using a for-loop? I usually manage fine with these things, but here there are some tricky matrix operations.
Give these inputs:
S1 = 5994;
S2 = 88;
S3 = 8;
A = 100*rand(S1,S3)-50;
B = 100*rand(S2,S3)-50;
C = 100*rand(S1,S2)-50;
Const1 = 1.1;
The loop:
for vv=1:size(A,1)
temp1 = A(vv,:)-Const1*B;
temp2 = C(vv,:).*(abs(temp1).^2).';
Sum = Sum + sum(temp2,'all');
end
Sum = Sum/(S1*S3);
1 件のコメント
採用された回答
Thiago Henrique Gomes Lobato
2020 年 1 月 12 日
If you don't mind having 3 dimensional arrays something like this can be used
rng(42)
S1 = 5994;
S2 = 88;
S3 = 8;
A = 100*rand(S1,S3)-50;
B = 100*rand(S2,S3)-50;
C = 100*rand(S1,S2)-50;
Const1 = 1.1;
Sum = 0;
tic
for vv=1:size(A,1)
temp1 = A(vv,:)-Const1*B;
temp2 = C(vv,:).*(abs(temp1).^2).';
Sum = Sum + sum(temp2,'all');
end
timeLoop = toc
% Vector alternative
tic
temp1Vec = reshape(A',1,size(A,2),size(A,1) )-Const1*B;
temp2Vec = sum(reshape(C',size(C,2),1,size(C,1)).* ((abs(temp1Vec).^2)) ,'all');
timeVec = toc
SumVec = sum(temp2Vec)/(S1*S3)
Sum = Sum/(S1*S3)
timeLoop =
0.0424
timeVec =
0.0228
SumVec =
6.6553e+03
Sum =
6.6553e+03
For your S1 I get sometimes faster results and some times slower ones, if I increase the S1 size I start to become consistent faster results.
その他の回答 (1 件)
Adam Danz
2020 年 1 月 12 日
編集済み: Adam Danz
2020 年 1 月 12 日
Idea 1
This single line does the same thing as the 2nd block of your code.
Sum2 = sum(arrayfun(@(i)sum(C(i,:) .* (abs(A(i,:)-Const1*B).^2).','all'), 1:size(A,1)))/(S1*S3);
isequal(Sum,Sum2) % Test that it matches the loop output (it does)
However, it's 0.01sec longer than your loop method.
Idea 2
Even if your loop is condensed by combining the variables, the improvement in speed is barely measurable and it comes at the expense of readability.
Sum2 = 0;
for vv=1:size(A,1)
Sum2 = Sum2 + sum(C(vv,:) .* (abs(A(vv,:)-Const1*B).^2).', 'all');
end
Sum2 = Sum2/(S1*S3);
isequal(Sum,Sum2) % Test that it matches the loop output (it does)
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Loops and Conditional Statements についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!