Speeding up a for loop

조회 수: 1 (최근 30일)
Alex Kozlov
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
Adam Danz
Adam Danz 2020년 1월 12일
편집: Adam Danz 2020년 1월 13일
I assume Sum is initialized as the following (or something similar), prior to the loop.
Sum = 0;

댓글을 달려면 로그인하십시오.

채택된 답변

Thiago Henrique Gomes Lobato
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
Alex Kozlov
Alex Kozlov 2020년 1월 13일
Thanks, that did the trick. I improved the speed further by replacing
((abs(temp1Vec).^2)),'all');
by:
((real(temp1Vec).^2+imag(temp1Vec).^2)),'all');
In the original code, which i couldn't share, temp1 could contain complex numbers.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Adam Danz
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)

카테고리

Help CenterFile Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

제품


릴리스

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by