How to vectorize for loops

2 views (last 30 days)
Evangelos Mitsokapas
Evangelos Mitsokapas on 15 Jan 2018
Answered: Jan on 4 Feb 2018
Hello, I am quite new to Matlab but I have typed down the following piece of code. It works as desired, but I have noticed the following:
  • Matlab spends a lot of time on exprnd(.). Is there a way to improve this flaw?
  • As it is quite visible I am using three 'for' loops but I know that Matlab is much more efficient when loops are vectorized. Is there any way you could help me achieve this?
%Random Walk
RW=10;
nsteps = 10;
X = -99999:99999;
L = length(X);
m = ['x','d','*','s','o','.','h','^','v','>','<','p','h'];
S1 = zeros(nsteps,1);
MSD1 = zeros(nsteps,1);
nstepss1 = zeros(nsteps,1);
for k=1:nsteps+1
K1 = zeros(RW,1);
V1 = zeros(RW,1);
for j=1:RW+1
position = 0;
Xright = 0;
Xleft = 0;
u_left = 0;
u_right = 0;
for i=1:nsteps+1
u = exprnd( 1 );
z = rand;
p = 0.1*(u_right)./(0.3)./0.2*(u_right)./(0.3)+0.1*(u_left)./(0.3)).*(k<(1/20)*nsteps) + 0.1*(u_right)./(3.0)./0.2*(u_right)./(3.0)+0.1*(u_left)./(3.0)).*(k>=(1/20)*nsteps);
left_step = -1.*(z<p);
right_step = 1.*(z>p);
n = left_step+right_step;
%Boundary Conditions
if position+n > X(L)
position = X(1);
elseif position+n < X(1)
position = X(L);
else
position = position+n;
end
% Choice of Step
if n == 1
Xright = Xright+1;
if u_right>=u
u_right = u_right;
else
u_right=u;
end
else
Xleft = Xleft+1;
if u_left>=u
u_left = u_left;
else
u_left=u;
end
end
end
K1(j) = position; %Final position of each RW
V1(j) = ((Xright-Xleft)/nsteps); %Average velocity of each RW
end
S1(k) = std(V1);
MSD1(k)=sqrt(S1(k)^2+(mean(V1))^2);
nstepss1(k) = k;
hold all;
PLO1 = scatter(nstepss1.', MSD1, '+');
end
hold off;
drawnow
Sorry for the long piece of code provided and thank you for your answers.
  3 Comments
Evangelos Mitsokapas
Evangelos Mitsokapas on 16 Jan 2018
Hello, thanks for taking the time to answer. Would you mind elaborating a little bit on what exactly you are suggesting? Like I mentioned in the beginning of the post, I am not yet quite familiar with the vectorizing concept.
Eric
Eric on 2 Feb 2018
What foboo means is doing
myexprnd = exprnd(1,[nsteps+1, RW+1, nsteps+1]);
before the first for loop to get all the random numbers at once, since doing it that way is faster. Later, you can retrieve the number by calling
u = myexprnd(k,j,i);

Sign in to comment.

Answers (1)

Jan
Jan on 4 Feb 2018
@Evangelos: Omit useless code like: u_right = u_right; This is a waste of time only and confusing. Better replace
if u_left>=u
u_left = u_left;
else
u_left=u;
end
by
u_left = min(u_lect, u);
Your code contains a bug the line:
p = 0.1*(u_right)./(0.3)./0.2*(u_right)./(0.3)+0.1*(u_left)./(0.3)) ...
There is a right parenthesis too much. After fixing this, this line should be cleaned massively: No parentheses around scalar numbers, (0.3)./0.2 is 1.5, etc.
Replace:
left_step = -1.*(z<p);
right_step = 1.*(z>p);
by
left_step = -(z<p);
right_step = (z>p);
and
if position+n > X(L)
position = X(1);
elseif position+n < X(1)
position = X(L);
else
position = position+n;
end
by:
position = position + n;
if position > X(L)
position = X(1);
elseif position < X(1)
position = X(L);
end
You can improve the code and accelerate it, but I do not think that it is a candidate for a vectorization.

Categories

Find more on Graphics Object Programming in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!