Clear Filters
Clear Filters

Double for loop in a random walk. How do I loop over all particles simultaneously instead of looping the amount of steps for each separate particle one at a time?

3 views (last 30 days)
I currently have a script that utilizes a double for loop in order to create a random walk in 2D. It however is looping over all the steps of the random walk one particle at a time. That is, it loops over N steps for one particle, then it moves on to the M:th particle and loops it over all N. I want to loop all particles M simultaneously instead of one at a time. I don't know how to do this, tried implementing a zero vector and inserting all values of x_t and y_t in it and plotting it but it didn't work, the figure looked weird. Here is the code:
clear
clc
N = 300; % Length of the x-axis, also known as the length of the random walks.
M = 40; % The amount of random walks.
x_t(1) = 0;
y_t(1) = 0;
radie=50;
x=0;
y=0;
theta=linspace(0,2*pi);
for m=1:M
for n = 1:N % Looping all values of N into x_t(n).
A = sign(randn); % Generates either +1/-1 depending on the SIGN of RAND.
x_t(n+1) = x_t(n) + A;
A = sign(randn);
y_t(n+1) = y_t(n) + A;
distance = sqrt(x_t(n+1)^2 + y_t(n+1)^2);
while distance > radie % så att de ej passerar cirkeln.
A = sign(randn); % Generates either +1/-1 depending on the SIGN of RAND.
x_t(n+1) = x_t(n) + A;
A = sign(randn);
y_t(n+1) = y_t(n) + A;
% Compute distance again with new values.
distance = sqrt(x_t(n+1)^2 + y_t(n+1)^2);
end
end
plot(x_t, y_t,'Markersize',10)
hold on
plot(x+radie*cos(theta),y+radie*sin(theta));
axis equal
end
grid on
I want all of the M particles to start moving N steps at the same time instead of looping all of N over each of the inputs M contains.
  2 Comments
Guillaume
Guillaume on 22 Feb 2018
I don't fully understand your question, is it related to the plotting or to the calculation of x_t or y_t? What should be different from what you have already?
Unrelated to your question:
A = sign(randn); % Generates either +1/-1 depending on the SIGN of RAND.
Technically, this can also generate 0 although very unlikely. A guaranteed way to just generate +-1:
A = (-1).^randi(2);
Also,
somevalue = somelongcalculation
while somevalue > somethreshold
somevalue = somelongcalculationlc;
end
is more elegantly written as:
somevalue = inf;
while somevalue > somethreshold
somevalue = somelongcalculationlc;
end
Delshad Ayoubi
Delshad Ayoubi on 22 Feb 2018
Basically, when running the script, it will run the for loop that contains N amount of "steps", that is the length of the random walk, how many steps each particle takes.
Then there's the double for loop which represents each particle, it will run M amount of times, that is M amount of particles.
What I want to do is run EVERY particle at once with N steps, instead of having the double for loop put all of the values of N in one particle, then to particle nr 2, then nr 3 to M. I want all particles M to start at one point, and then move all at once instead of one at a time.

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 22 Feb 2018
If you want to change the order of the loops, then your x_t and y_t need to be 2d matrices
x_t = zeros(M, N+1);
y_t = zeros(M, N+1);
for n = 1:N
for m = 1:M
distance = inf;
while distance > radie
x_t(m, n+1) = x_t(m, n) + (-1).^randi(2);
y_t(m, n+1) = y_t(m, n) + (-1).^randi(2);
distance = hypot(x_t(m, n+1), y_t(m, n+1));
end
end
end
plot(x_t, y_t, 'Markersize', 10);
  6 Comments
Delshad Ayoubi
Delshad Ayoubi on 22 Feb 2018
For some reason the code is running extremely slowly for me. These are the changes I did
clear
clc
N = 300;
M = 40;
radie = 50;
x_t(1) = 0;
y_t(1) = 0;
x=0;
y=0;
theta=linspace(0,2*pi);
x_t = zeros(M, N+1);
y_t = zeros(M, N+1);
tic
for n = 1:N
for m = 1:M
distance = inf;
while distance > radie % så att de ej passerar cirkeln.
x_t(m, n+1) = x_t(m, n) + (-1).^randi(2);
y_t(m, n+1) = y_t(m, n) + (-1).^randi(2);
distance = hypot(x_t(m, n+1), y_t(m, n+1));
end
end
plot(x_t.', y_t.','.', 'MarkerSize', 5);
hold on
plot(x+radie*cos(theta),y+radie*sin(theta));
axis equal
end
toc
grid on
I'm not sure why but it sometimes takes more than 30 sec.
Guillaume
Guillaume on 23 Feb 2018
It's not for some reason, it's because you're replotting all the points at each step of the loop, including the ones you've plotted on the previous steps. Instead of plotting MxN = 1200 points, you're plotting MxNx(N+1)/2 = 2257500 points, so yes it's going to be slow.
You either need to move all the plotting out of the loops, as I'd written or if you want it in the loop so you can see the progress:
for n = 1:N
for m = 1:M
distance = inf;
while distance > radie % så att de ej passerar cirkeln.
x_t(m, n+1) = x_t(m, n) + (-1).^randi(2);
y_t(m, n+1) = y_t(m, n) + (-1).^randi(2);
distance = hypot(x_t(m, n+1), y_t(m, n+1));
end
end
plot(x_t(:, 1:n+1)', y_t(:, 1:n+1).','.', 'MarkerSize', 5);
hold on
plot(x+radie*cos(theta),y+radie*sin(theta));
axis equal
hold off
drawnow
end
The hold off and drawnow I've added are both critical. It's still going to be slower than doing the plotting after the loops because at each step you're erasing the previous plot and replotting everything.

Sign in to comment.

More Answers (1)

James Tursa
James Tursa on 22 Feb 2018
If you want to walk all of the particles simultaneously, then simply reverse the order of your for-loops:
for n = 1:N % Looping all values of N into x_t(n).
for m=1:M
You will also need to modify all of the interior loop code to account for M particles. Currently the x_t and y_t variables are only dimensioned for 1 particle. So maybe turn them into arrays so you are using x_t(n,m) and y_t(n,m) etc within the loop.
Also this test doesn't look correct:
while distance > radie % så att de ej passerar cirkeln.
It will always fail at the start of your run. Maybe you meant to use < instead?
  1 Comment
Delshad Ayoubi
Delshad Ayoubi on 22 Feb 2018
How would I change the for loop?
for n=1:N
for m = 1:M % Looping all values of N into x_t(n).
A = sign(randn); % Generates either +1/-1 depending on the SIGN
of RAND.
x_t(n+1) = x_t(n) + A;
A = sign(randn);
y_t(n+1) = y_t(n) + A;
distance = sqrt(x_t(n+1)^2 + y_t(n+1)^2);
while distance > radie % så att de ej passerar cirkeln.
A = sign(randn); % Generates either +1/-1 depending on the
SIGN of RAND.
x_t(n+1) = x_t(n) + A;
A = sign(randn);
y_t(n+1) = y_t(n) + A;
% Compute distance again with new values.
distance = sqrt(x_t(n+1)^2 + y_t(n+1)^2);
end
end
plot(x_t, y_t,'Markersize',10)
I'm specifically talking about changing the order of the two for loops but I'm not sure how I'm supposed to change all of the x_t and y_t inside.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!