Logical AND in a for loop - matlab

I want to add an additional condition in the for loop.
for(i=1; (i<100)&&(something>0.001) ; i++)
{
//do something
}
How can I implement this in MATLAB?
The following isn't working:
for (y = 1:pI_present_y) && (max_sim_value > threshold)
% do something
end

In a for loop, the number of iterations and the values that the loop variable will have in those iterations are selected as soon as it is executed the first time.
Since you want to check the condition on every iteration, you cannot use a for loop without introducing an if condition inside the loop. This is what already suggested by souty.
However, it would be better to use break once the condition is not satisfied. In this way it will be a true replica of the C code. Otherwise the loop will keep executing till y equals pI_present_y. The result will be same but there will be unnecessary iterations and the value of the loop variable will be different at the end of the loop. i.e.
for y = 1:pI_present_y-1 %Subtracting 1 because you have i<100 in the C code, not i<=100
if max_sim_value <= threshold
break;
end
%do something
end
If you want to use that condition in the loop statement, it is only possible with a while loop.
y=1;
while(y<pI_present_y && max_sim_value>threshold)
% do something
y=y+1;
end

Logical conditions are expressed in if statements
for (y = 1:pI_present_y)
if (max_sim_value > threshold)
% do something
end
end
If one of max_sim_value and threshold is a vector of length pI_present_y, index it with y in the if statement, i.e. max_sim_value(y) or threshold(y).

Related

A conditional statement during a for loop in MATLAB

This is my attempt of a simple example (it seems pointless) but the idea is bigger than this simple code.
During a for loop, if something happens, I want to skip this step of the for loop and then add an extra step on the end.
I am trying to create a list of numbers, that do not include the number 8.
If the code creates an 8, this will mean that exitflag is equal to 1.
Can I adapt this program so that if the exitflag=1, the it will remove that result and add another loop.
The code:
for i = 1:1000
j = 1+round(rand*10)
if j == 8
exitflag = 1
else
exitflag = 0
end
storeexit(i)=exitflag;
storej(i)=j;
end
sum(storeexit)
I would ideally like a list of numbers, 1000 long which does not contain an 8.
If what you want to do is 1000 iterations of the loop, but repeat a loop iteration if you don't like its result, instead of tagging the repeat at the end, what you can do is loop inside the for loop until you do like the result of that iteration:
stores = zeros(1000,1); % Note that it is important to preallocate arrays, even in toy examples :)
for i = 1:1000
success = false; % MATLAB has no do..while loop, this is slightly more awkward....
while ~success
j = 1+round(rand*10);
success = j ~= 8;
end
storej(i) = j; % j guaranteed to not be 8
end
No.
With for loop, the number of loops is determined on the loop start and it is not dynamic.
For doing what you want, you need to use a while loop.

How to jump to a particular place in the for loop if the if condition is satisfied?

I have some image files. I'm trying to perform some calculations using each file and if a certain condition is met, I'd like to go back to a particular line in the code and run it from there once more. But only just once again. Regardless of whether the if condition is satisfied or not satisfied the second time, I want to go to the next iteration. But, MATLAB doesn't seem to have a goto function and also, using goto implies bad programming so I thought I'd just iterate the for loop twice for a particular 'i' value which satisfies the if condition.
file = dir('*.jpg');
n = length(file);
for i = 1:n
*perform some operations on the 'i'th file*
if 'condition'
*run the for loop again for the 'i'th file instead of going to the 'i+1'th file*
i=i-1;
else
*go to next iteration*
end
end
I have tried to code this by changing the loop variable 'i' inside the loop to 'i-1' so that on the next iteration, the 'i'th loop will be repeated again but doing so is giving the wrong output, though I don't know if there is some other error in my code or if the changing of the loop variable internally is the cause of the problem. Any help on this is appreciated.
Replace the for loop with a while loop to have a bit more flexibility. The only difference is that you have to manually increment i, hence this also allows you to not increment i.
Given your new requirement, you can keep track of the number of attempts, and easily change this if needed:
file = dir('*.jpg');
n = length(file);
i = 1;
attempts = 1;
while i <= n
% perform code on i'th file
success = doSomething(); % set success true or false;
if success
% increment to go to next file
i = i + 1;
elseif ~success && attempts <= 2 % failed, but gave it only one try
% increment number of attempts, to prevent performing
attempts = attempts + 1;
else % failed, and max attempts reached, increment to go to next file
i = i + 1;
% reset number of attempts
attempts = 1;
end
end
Given the new requirement, added after rinkert's answer, the simplest approach becomes separating out code from your loop in a separate function:
function main_function
file = dir('*.jpg');
n = length(file);
for i = 1:n
some_operations(i);
if 'condition'
some_operations(i);
end
end
function some_operations(i)
% Here you can access file(i), since this function has access to the variables defined in main_function
*perform some operations on the 'i'th file*
end
end % This one is important, it makes some_operations part of main_function

How to restart a for loop iteration in MATLAB?

I am trying to force a for loop to restart if a condition is not stratified. I can do it with while since I want the loop to run for a certain number of iterations. I tried to set iter=iter-1 inside the if statement but it did not work. Any suggestions?
R=2*10^3;
lamda= 0.00001;
h=100;
a = 9.6117;
b = 0.1581;
for iter=1:10
M=poissrnd(lamda*R^2);
xx=R*rand(1,M);
yy=R*rand(1,M);
zz=ones(1,M)*h;
BS=[xx' yy' zz'];
user=[0,0, 0];
s=pdist2(BS(:,1:2),user(1,1:2));
anga=atand(h./s);
PL=1./(1+(a*exp(b*(a-anga))));
berRV=binornd(1,PL);
if berRV(1)==1
% do something
else
% repeat
end
end
You can accomplish this by using a while loop, with a comparison to whether the number of needed results have been identified. See the comment about saving your found values, as you hadn't specified what needs to be done when the condition you're searching for is satisfied.
R=2*10^3;
lamda= 0.00001;
h=100;
a = 9.6117;
b = 0.1581;
total_results_found = 0;
needed_results_found = 10;
while total_results_found < needed_results_found
M=poissrnd(lamda*R^2);
xx=R*rand(1,M);
yy=R*rand(1,M);
zz=ones(1,M)*h;
BS=[xx' yy' zz'];
user=[0,0, 0];
s=pdist2(BS(:,1:2),user(1,1:2));
anga=atand(h./s);
PL=1./(1+(a*exp(b*(a-anga))));
berRV=binornd(1,PL);
if berRV(1)==1
% save the result here
% iterate the counter
total_results_found = total_results_found + 1;
end
end
The simplest approach here would be with a while loop inside the for loop:
for iter=1:10
berRV(1) = 0
while berRV(1)~=1
% original loop code here
end
% do something
end
[Sadly, MATLAB does not have a do...while loop, it would make the above a little cleaner.]
While the other two solutions are perfectly valid, I wanted to give you another solution, which I think is the closest to the logic you provided in the question.
for iter=1:10
while 1
% loop code here
if berRV(1) == 1
break
end
end
end
The idea is similar to the one Cris presents, namely that you repeat the body of the for-loop until some condition is met. The difference lies solely in how you terminate the while loop,

While Loop and Logical Operators

I want to use an OR statement in my while loop so that the loop terminates whenever either of the two conditions aren't satisfied.
The conditions: (1) i must be less or equal to nmax, and (2) absolute value of R(i,i)-R(i-1,i-1) is less than specified delta
Here's my code (everything seems to work fine except for the while condition as the function executes until nmax is reached every time):
function [R] = romberg(f,a,b,delta,nmax)
R=zeros(nmax,nmax);
R(1,1)=(f(a)+f(b))*(b-a)/2;
i=2;
while i<nmax || abs(R(i,i)-R(i-1,i-1))<delta
m=2^(i-1);
R(i,1)=trapez(f,a,b,m);
for j=2:i
R(i,j)=R(i,j-1)+(R(i,j-1)-R(i-1,j-1))/(4^j-1);
end
i=i+1;
end
R
Try this. There were a few issues with the abs(R(i,i)-R(i-1,i-1)) condition for the while loop.
function [R] = romberg(f,a,b,delta,nmax)
R=zeros(nmax,nmax);
R(1,1)=(f(a)+f(b))*(b-a)/2;
i=2;
E=2*delta;
while i<nmax && E>delta
m=2^(i-1);
R(i,1)=trapez(f,a,b,m);
for j=2:i
R(i,j)=R(i,j-1)+(R(i,j-1)-R(i-1,j-1))/(4^j-1);
end
E=abs(R(i,i)-R(i-1,i-1));
i=i+1;
end

continue statment not executing correctly within for loop+matlab

I have the following code:
for i=1:length(files)
for j=1:length(files(i,1).day)
if ((1:length(files(i,1).day(j).hour)) ~= 24)
continue
end
for h = 1:24
if ((1:length(files(i,1).day(j).hour(h).halfhour)) ~= 2)
continue
end
if isempty(1:length(files(i,1).day(j).hour))
continue
end
dayPSD = [];
for h2=1:2
dayPSD = [dayPSD; files(i,1).day(j).hour(h).halfhour(h2).data{8}'];
end
end
end
end
where
files=1x3 structure
files(i,1).day=1x335 structure that contains 1 field hour which is a 1x24 structure
files(i,1).day.hour=1x24 structure that contains 1 field halfhour which is a 1x2 structure
I am trying to loop through i and j, but when 1:length(files(i,1).day(j).hour) ~= 24 (so when the hours are less than 24) I would like to exit the loop and continue onto the next iteration of the for loop. I would also like it to exit the loop and continue onto the next iteration of the for loop if 1:length(files(i,1).day(j).hour(h).halfhour) ~= 2 (so when the half hours are less than 2) or if 1:length(files(i,1).day(j).hour is an empty cell (no data).
The current code I have written only seems to skip a loop index if 1:length(files(i,1).day(j).hour ~=24.
What am I doing wrong? Also how do I get it to continue onto the next iteration if any of those conditions are met? I've been banging my head on this for a while, and I know I'm probably making a simple mistake, but if anyone can point me in the right direction that would be great.
Thanks for your help in advance!
If I understand correctly, what you want is:
for i=1:length(files)
for j=1:length(files(i,1).day)
if ((1:length(files(i,1).day(j).hour)) ~= 24)
continue
end
for h = 1:24
if ((length(files(i,1).day(j).hour(h).halfhour)) ~= 2)
break
end
if isempty(files(i,1).day(j).hour)
break
end
dayPSD = [];
for h2=1:2
dayPSD = [dayPSD; files(i,1).day(j).hour(h).halfhour(h2).data{8}'];
end
end
end
end
so when either condition is met, the flow of execution will exit the for h=.. loop, and as there is no other statement in the for j=1... loop, the code will in effect skip that iteration.
Also note that if ((1:length(files(i,1).day(j).hour(h).halfhour)) ~= 2) is comparing a vector (1:length(..)) to a scalar 2 which results in a vector of booleans. The if part will only be executed if all its elements are true which is most likely never the case.