Speeding up a for loop
1 visualizzazione (ultimi 30 giorni)
Mostra commenti meno recenti
Alex Kozlov
il 12 Gen 2020
Commentato: Alex Kozlov
il 13 Gen 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 Commento
Risposta accettata
Thiago Henrique Gomes Lobato
il 12 Gen 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.
Più risposte (1)
Adam Danz
il 12 Gen 2020
Modificato: Adam Danz
il 12 Gen 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 Commenti
Vedere anche
Categorie
Scopri di più su Loops and Conditional Statements in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!