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

4 ビュー (過去 30 日間)
Divye Kalra
Divye Kalra 2022 年 1 月 9 日
コメント済み: Divye Kalra 2022 年 1 月 12 日
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!

回答 (1 件)

per isakson
per isakson 2022 年 1 月 10 日
編集済み: per isakson 2022 年 1 月 12 日
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 件のコメント
per isakson
per isakson 2022 年 1 月 12 日
@Divye Kalra, see my reply to your comment in my answer.
Divye Kalra
Divye Kalra 2022 年 1 月 12 日
@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.

サインインしてコメントする。

コミュニティ

カテゴリ

Help Center および File ExchangeLoops and Conditional Statements についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by