Speeding up a for loop
2 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Alex Kozlov
am 12 Jan. 2020
Kommentiert: Alex Kozlov
am 13 Jan. 2020
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 Kommentar
Akzeptierte Antwort
Thiago Henrique Gomes Lobato
am 12 Jan. 2020
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.
Weitere Antworten (1)
Adam Danz
am 12 Jan. 2020
Bearbeitet: Adam Danz
am 12 Jan. 2020
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 Kommentare
Siehe auch
Kategorien
Mehr zu Loops and Conditional Statements finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!