My loop does not produce the results I want, due to coding errors
You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Show older comments
0 votes
I have this code I am developing a random walks model for a mammal and analysing a receive level heard from this mammal, however when producing the loop code for several positions it does not show exactly what I need, as the for loop in my eyes is not completing.
A quick run throught the code:
clc;
clear;
x0 = 0;
y0 = 0;
Sr = [x0 y0]; %Source coordinates
a = 0.25; %Attenuation - FIND SOME VALUES
IL = 180; %Impact Level
v = 2; %Speed
t = 5; %seconds
T = 5400; %Total Time
s = v*t; %metres
iter = T/t; %number of positions
Tv = 0:t:(T-t);
SL = 212 + 10*log10(10);
X = zeros(iter,1);
Y = zeros(iter,1);
RL = zeros(iter,1);
Pre set parameters, although the X, Y and RL may be wrong, here I am trying to store values in these matrices to be used later in graphs and figures.
% starting condition - random position start
Z = [randi([-10 10]) randi([-10 10])];
d = sqrt((Z(1)-x0)^2+(Z(2)-y0)^2); % Pythagoras Theorem for distance between the Source and initial Reciever points
A random coordinate is generated for the first initial position and the distance between this position/ coordinate from the source (0,0).
%Random Walks Loop Code
for i = 1:iter
if i == 1
F = [randi([0 360])];
x = Z(1) + s*cos(F);
y = Z(2) + s*sin(F);
end
%Update for distance
s1 = sqrt((x-x0)^2+(y-y0)^2); % Pythagoras Theorem for distance between the 2 (Source and Reciever) point
TL = 20*log10(s1); %Transmission Loss
RL(i,:) = SL - TL; % Receive Level
% save result
X(i,:) = x(:,1);
Y(i,:) = y(:,2);
end
This is my loop, the F is a random number between 0 and 360 corresponding a degree to be used for a new position and coordinates the mammal will move towards to be used in the loop to calculate values for RL. I need this for every position / iter howver my code does not do this. The functions labelled x and y are the new positions and coordinates, but now going through it i see an error. The values for Z(1) and Z(2) need to change for each loop to be the previous x and y coordinates, rather than the initial random coordinates.
s1 shows the new distance between the coordinates, however I have just noticed the value for d earlier, also needs to be used here for the RL of the intial coordinates, so that itself has its own RL and TL, and then all the new coordinates within the loop has its own, all to be stored in a iter x 1 matrix, i.e., for each positional coordinates.
The save results shows all the results as a matrix to be used in figures and models. Also how do i sotre all the values from the function TL and s1 also.
figure
plot(x,y, '-*')
title('Random Walks')
xlabel('Distance from the Source (m)')
ylabel('Distance from the Source (m)')
ax = gca; %the change of the axes location to origin
ax.XAxisLocation = 'origin';
ax.YAxisLocation = 'origin';
A graph for the results which should showcase a random walks of a mammal moving based in different degree directions
Accepted Answer
Jon
on 3 Aug 2022
I have made numerous corrections in your code. I think this is now at least closer to what you want
clc;
clear;
x0 = 0;
y0 = 0;
Sr = [x0 y0]; %Source coordinates
a = 0.25; %Attenuation - FIND SOME VALUES
IL = 180; %Impact Level
v = 2; %Speed
t = 5; %seconds
T = 5400; %Total Time
s = v*t; %metres
iter = T/t; %number of positions
Tv = 0:t:(T-t);
SL = 212 + 10*log10(10);
X = zeros(iter,1);
Y = zeros(iter,1);
RL = zeros(iter,1);
% starting condition - random position start
Z = [randi([-10 10]) randi([-10 10])];
d = sqrt((Z(1)-x0)^2+(Z(2)-y0)^2); % Pythagoras Theorem for distance between the Source and initial Reciever points
%Random Walks Loop Code
for i = 1:iter
% % % if i == 1
F = [randi([0 360])];
x = Z(1) + s*cosd(F); % use cosd for angle in degrees
y = Z(2) + s*sind(F); % use sind for angle in degrees
Z = [x y]; % update current location
% % % end
%Update for distance
s1 = sqrt((x-x0)^2+(y-y0)^2); % Pythagoras Theorem for distance between the 2 (Source and Reciever) point
TL = 20*log10(s1); %Transmission Loss
% % % RL(i,:) = SL - TL; % Receive Level
RL(i) = SL - TL; % Receive Level
% save result
% % % X(i,:) = x(:,1);
% % % Y(i,:) = y(:,2);
X(i) = x;
Y(i) = y;
end
figure
% % % plot(x,y, '-*')
plot(X,Y, '-*')
title('Random Walks')
xlabel('Distance from the Source (m)')
ylabel('Distance from the Source (m)')
ax = gca; %the change of the axes location to origin
ax.XAxisLocation = 'origin';
ax.YAxisLocation = 'origin';

16 Comments
Adil Saeed
on 3 Aug 2022
this is perfect, thank you. It seems i over complicated it including an if loop within the for loop and the update of the coordinates makes sense.
Jon
on 3 Aug 2022
You can actually do it without any loops as follows
x0 = 0;
y0 = 0;
Sr = [x0 y0]; %Source coordinates
a = 0.25; %Attenuation - FIND SOME VALUES
IL = 180; %Impact Level
v = 2; %Speed
t = 5; %seconds
T = 5400; %Total Time
s = v*t; %metres
iter = T/t; %number of positions
Tv = 0:t:(T-t);
SL = 212 + 10*log10(10);
% starting condition - random position start
Z0 = [randi([-10 10]) randi([-10 10])];
% random incremental moves
F = randi([0,360],[iter,1]);
deltaZ = s*[cosd(F) sind(F)];
% sum up the moves to create overall walk
Z = cumsum(deltaZ,1);
% calculate position relative to receiver
Zr = Z - Sr;
% calcuate distance to receiver
d = sqrt(Z(:,1).^2 +Z(:,2).^2);
% transmission loss
TL = 20*log10(d);
% receive level
RL = SL - TL;
figure
plot(Z(:,1),Z(:,2), '-*')
title('Random Walks')
xlabel('Distance from the Source (m)')
ylabel('Distance from the Source (m)')
ax = gca; %the change of the axes location to origin
ax.XAxisLocation = 'origin';
ax.YAxisLocation = 'origin';

figure
plot(RL)
title('Receive Level');
xlabel('step number')
ylabel('Level db')

Jon
on 3 Aug 2022
You may also want to consider whether you really want to only have the animal move along whole number (integer degree headings) as you have with your line of code
F = [randi([0 360])];
instead you could move along a value which could take on any real value (uniformly distributed) between 0 and 360 using
F = 360*rand;
or in my vectorized (no loop) solution
F = 360*rand(iter,1)
Adil Saeed
on 3 Aug 2022
I appreciate the alternate approach in this, allows for coding comparison and learn further when i do this again. I was thinking about the real value approach and was going to look into this, but you have provided a solution here so thank you. I will definitely use this so thanks again
Adil Saeed
on 3 Aug 2022
I have another query, lets say i want the animal to move in a biased approach, i.e. to move away from the sound source (origin) on a random biased path for some time until a moment has been reached. So when RL > IL it moves in this random biased path away from the source until RL < IL and then moves randomly as achieved until RL > IL again and so on until the end. This random bias approach i had the idea of using degrees again but a range of degrees that ensure the animal moves away. so lets say the animal is at the coordinates (0,5) it would move upwards i.e. the range of angles would be of 0 - 180 degrees.
I hope this makes sense
Jon
on 3 Aug 2022
I'm sure there are many ways of modeling the fleeing behavior. I'm sorry, but at the moment I don't have time to think about the actual modelling approach. If you come up with a mathematical representation of how you want to model the fleeing behavior and need help figuring out how to implement it in MATLAB I (or others) could probably help you with that part.
Adil Saeed
on 3 Aug 2022
Absolutely no worries, I still have time to configure the model and I may just perfectly execute how I would like it, if not I will mesasge back on this thread. Thanks for the help
Adil Saeed
on 4 Aug 2022
back to the original code, i have just noticed the code below for the random initial coordinate is not included in the results, but only used to begin the model. is there a way it can be included, as well as its own RL based on its transmission loss?
% starting condition - random position start
Z = [randi([-10 10]) randi([-10 10])];
d = sqrt((Z(1)-x0)^2+(Z(2)-y0)^2); % Pythagoras Theorem for distance between the Source and initial Reciever points
Jon
on 4 Aug 2022
You could reorganize your code like this
x0 = 0;
y0 = 0;
Sr = [x0 y0]; %Source coordinates
a = 0.25; %Attenuation - FIND SOME VALUES
IL = 180; %Impact Level
v = 2; %Speed
t = 5; %seconds
T = 5400; %Total Time
s = v*t; %metres
iter = T/t; %number of positions
Tv = 0:t:(T-t);
SL = 212 + 10*log10(10);
X = zeros(iter,1);
Y = zeros(iter,1);
RL = zeros(iter,1);
% starting condition - random position start
Z = [randi([-10 10]) randi([-10 10])];
d = sqrt((Z(1)-x0)^2+(Z(2)-y0)^2); % Pythagoras Theorem for distance between the Source and initial Reciever points
%Random Walks Loop Code
for i = 1:iter
% assign position coordinates
x = Z(1);
y = Z(2);
% save current position
X(i) = x;
Y(i) = y;
%Update for distance
s1 = sqrt((x-x0)^2+(y-y0)^2); % Pythagoras Theorem for distance between the 2 (Source and Reciever) point
TL = 20*log10(s1); %Transmission Loss
RL(i) = SL - TL; % Receive Level
% calculate new position
F = [randi([0 360])];
x = Z(1) + s*cosd(F); % use cosd for angle in degrees
y = Z(2) + s*sind(F); % use sind for angle in degrees
Z = [x y]; % update current location
end
figure
% % % plot(x,y, '-*')
plot(X,Y, '-*')
title('Random Walks')
xlabel('Distance from the Source (m)')
ylabel('Distance from the Source (m)')
ax = gca; %the change of the axes location to origin
ax.XAxisLocation = 'origin';
ax.YAxisLocation = 'origin';
Jon
on 4 Aug 2022
You could also do something similar with the vectorized (no loop) version.
Adil Saeed
on 5 Aug 2022
I have managed to code that problem i had earlier to encorporate a flee response based on RL > IL, however i just wanted to double check it. The code to me looks correct however the results for RL does not suggest this as the RL rarely goes below the IL value.
clc;
clear;
x0 = 0;
y0 = 0;
Sr = [x0 y0]; %Source coordinates
a = 0.25; %Attenuation - FIND SOME VALUES
IL = 180; %Impact Level
v = 2; %Speed
t = 5; %seconds
T = 5400; %Total Time
s = v*t; %metres
iter = T/t; %number of positions
TV = 0:t:(T-t);
SL = 212 + 10*log10(10);
X = zeros(iter,1);
Y = zeros(iter,1);
RL = zeros(iter,1);
% starting condition - random position start
Z = [randi([-10 10]) randi([-10 10])];
d = sqrt((Z(1)-x0)^2+(Z(2)-y0)^2); % Pythagoras Theorem for distance between the Source and initial Reciever points
for i = 1:iter
% assign position coordinates
x = Z(1);
y = Z(2);
% save current position
X(i) = x;
Y(i) = y;
%Prpoagation Loss
s1 = sqrt((x-x0)^2+(y-y0)^2); % Pythagoras Theorem for distance between the 2 (Source and Reciever) point
theta = atand(y/x);
TL = 20*log10(s1); %Transmission Loss
RL(i) = SL - TL; % Receive Level
RL(i) = RL(i) + 10.*log10(t); %encorporate the energy exposure at the position for t(s), (assumption)
if RL > IL
%Update for position based on random biased flee direction
alpha = (-90-90) * rand + 90;
x = Z(1) + s*cosd(theta + alpha); % use cosd for angle in degrees
y = Z(2) + s*sind(theta + alpha); % use sind for angle in degrees
Z = [x y]; % update current location
else
%Update for position based on random direction
alpha = 360*rand;
x = Z(1) + s*cosd(theta + alpha); % use cosd for angle in degrees
y = Z(2) + s*sind(theta + alpha); % use sind for angle in degrees
Z = [x y]; % update current location
end
% save result
X(i) = x;
Y(i) = y;
end
Rlin = 10.^(RL./20); %Receive Linear
RlinS = cumsum(Rlin);
RLS = 20.*log10(RlinS);
CEE = RLS(end); %Cumalative Energy Exposure
%RANDOM WALKS MODEL
figure
plot(X,Y)
title('Random Walks')
xlabel('Distance from the Source (m)')
ylabel('Distance from the Source (m)')
ax = gca; %the change of the axes location to origin
ax.XAxisLocation = 'origin';
ax.YAxisLocation = 'origin';
Jon
on 5 Aug 2022
I haven't had a chance to look into your code in detail, but one quick thing to look at is your use of atand to get the direction to the source (and then I guess to determine the fleeing dirction, 180 degrees away). The function atand only returns answers in the range -90 to 90. I would suggest instead to use atan2d, which gives results in all 4 quadrants.
Adil Saeed
on 5 Aug 2022
oh yes of course, i had not even realised i was not working within the 4 quadrants but only 3. thank you for this spot. i am still trying to analyse my code and to see where it may have gone wrong. if i spot it before, i will add the code
Jon
on 5 Aug 2022
You also have an error on your if statement, you should compare the current value of RL, that is RL(i) to IL not the entire vector, so you should use
if RL(i) > IL
Jon
on 5 Aug 2022
when you compare the whole vector of RL to IL the if statement will only be evaluated as true if every element of RL is greater than IL, of course this won't be the case until possibly the very last step because otherwise most of the elements of RL will be zero
Adil Saeed
on 5 Aug 2022
ahhh yes, now this is where i went wrong, the graph now looks more to like what i wanted. thank you
More Answers (0)
Categories
Find more on Scopes and Data Logging in Help Center and File Exchange
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)