Run a large number of iterations without the use of a for loop

3 vues (au cours des 30 derniers jours)
Divye Kalra
Divye Kalra le 9 Jan 2022
Commenté : Divye Kalra le 12 Jan 2022
Hello everyone, I was trying to implement the brownian motion of a very large number (1536256) of particles in MATLAB. The following code works fine as it is, but takes a very long time to execute. Is there a way to vectorize the following program so that it can work without the use of a for loop?
N=1000;
x_brown=cumsum(randn(1,N));
y_brown=cumsum(randn(1,N));
z_brown=cumsum(randn(1,N));
r0=[x_brown(1) y_brown(1) z_brown(1)];
rf=[x_brown(end) y_brown(end) z_brown(end)];
t = rf-r0;
for i = 2:1:1536256
disp(i);
x_brown=cumsum(randn(1,N));
y_brown=cumsum(randn(1,N));
z_brown=cumsum(randn(1,N));
% Storing r0 and rf values of the previous iteration in m and n
m = r0;
n = rf;
r0=[x_brown(1) y_brown(1) z_brown(1)];
rf=[x_brown(end) y_brown(end) z_brown(end)];
t = cat(1,t,rf-r0);
end
It would be great if someone could help me out here, thanks!

Réponses (1)

per isakson
per isakson le 10 Jan 2022
Modifié(e) : per isakson le 12 Jan 2022
Preallocating the variable t will improve speed a lot.
Something like
t = nan( 1536256, 1 );
t(1) = rf-r0;
...
t(i) = rf-r0;
In response to comment
The word "bit" in your comment, "Yes, it did reduce the runtime a bit.", triggered me to make my own test on R2018b. My test shows that preallocation improves the speed 16 times for P=1e5 particles and more than twice as much for P=2e5. (I interupted the executions for P = 1536256. Too long to wait.) I guess you tested with a small value of P.
P = 100000. Improvement of speed: 16.0 times
P = 200000. Improvement of speed: 36.8 times
The results may vary with the hardware and the Matlab release.
% P = 1536256;
% P = 100000;
P = 200000;
tic, t2 = loop_pre( P ); e2 = toc;
tic, t1 = loop_cat( P ); e1 = toc;
fprintf( 1, 'P = %d. Improvement of speed: %4.1f times\n', P, e1/e2 )
%%
function t = loop_cat( P )
N=1000;
x_brown=cumsum(randn(1,N));
y_brown=cumsum(randn(1,N));
z_brown=cumsum(randn(1,N));
r0=[x_brown(1) y_brown(1) z_brown(1)];
rf=[x_brown(end) y_brown(end) z_brown(end)];
t = rf-r0;
for jj = 2:1:P
% disp(jj);
x_brown=cumsum(randn(1,N));
y_brown=cumsum(randn(1,N));
z_brown=cumsum(randn(1,N));
% Storing r0 and rf values of the previous iteration in m and n
m = r0;
n = rf;
r0=[x_brown(1) y_brown(1) z_brown(1)];
rf=[x_brown(end) y_brown(end) z_brown(end)];
t = cat(1,t,rf-r0);
end
end
function t = loop_pre( P )
N=1000;
x_brown=cumsum(randn(1,N));
y_brown=cumsum(randn(1,N));
z_brown=cumsum(randn(1,N));
r0=[x_brown(1) y_brown(1) z_brown(1)];
rf=[x_brown(end) y_brown(end) z_brown(end)];
t = nan( P, 3 );
t(1,:) = rf-r0;
for jj = 2:1:P
% disp(jj);
x_brown=cumsum(randn(1,N));
y_brown=cumsum(randn(1,N));
z_brown=cumsum(randn(1,N));
% Storing r0 and rf values of the previous iteration in m and n
m = r0;
n = rf;
r0=[x_brown(1) y_brown(1) z_brown(1)];
rf=[x_brown(end) y_brown(end) z_brown(end)];
t(jj,:) = rf-r0;
end
end
  3 commentaires
per isakson
per isakson le 12 Jan 2022
@Divye Kalra, see my reply to your comment in my answer.
Divye Kalra
Divye Kalra le 12 Jan 2022
@per isakson Thank you for the very well explained answer. Sorry if my other comment triggered you, wasn't my intention. However, as I said before, I was wondering if the same thing could be done without the use of a for loop (one where the iterating variable is not used inside it ) and where the vectorization of code doesn't seem like a very obvious choice.

Connectez-vous pour commenter.

Communautés

Plus de réponses dans  Power Electronics Control

Catégories

En savoir plus sur Loops and Conditional Statements dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by