While loop in if and for loop

2 views (last 30 days)
Samuel Bofferding
Samuel Bofferding on 28 Feb 2021
Hi all,
I am trying to combine a while loop in an if and for loop but I am having some problems with the results of my matlab code.
I am trying to recognize in a for and if loop wether a variable is true and as long as this variable is true I want it to execute a part of the code. As soon as this condition is not true, I want my code to go back to the for loop, with the new value of i. Here is an example of my code:
for i = 2:N
if Gyr_2(i,3) ~= 0 % Checks wether this condition is true for the value of i
[Output] = RBK2(Input); % Self created function
elseif Gyr_2(i,1) ~= 0 || Gyr_2(i,2) ~= 0 || Ori_2(i,1) ~= 0 || Ori_2(i,2) ~= 0 % Checks wether this condition is true for the value of i
[Output] = RBS2(Input); % Self created function
elseif Acc_2(i,3) ~= 0 % Checks wether this condition is true for the value of i
[Output] = RBH2(Input); % Self created function
else % If none of the conditions are true
[Output] = RBL2(Input); % Self created function
if Diagonal5(i) == 1 && Acc_3(i,1) ~= 0 && Acc_3(i,2) ~= 0 % Checks again if this condition is true
if abs(Vel_3(i-1,1)) > abs(Vel_3(i-1,2)) && Acc_2(i,2) ~= 0
while Diagonal5(i) == 1 %Value is either 1 or 0
[Output] = RBD2x(Input) % Self created function
i = i + 1;
end
else
while Diagonal5(i) == 1 && Acc_2(i,1) ~= 0
[Output] = RBD2y(Input) % Self created function
i = i + 1;
end
end
end
end
end
So basically, when it does the "while Diagonal5(i) == 1" I want the code to stay within this loop until Diagonal5(i) == 0. However it seems like it always jumps out of the while loop and goes back to the beginning of the for loop with the next value of i, instead of using the value of i when Diagonal5(i)==0. I have also done it without writing the "i = i+1;", but then when I start my code, it does not complete and takes a really long time to load.
Could you guys please tell me how i can fix that. I have read multiple different answers but have not found one that works for me. Should I otherwise write my code differently to solve this problem?
Thanks in advance
Sam :)

Answers (1)

dpb
dpb on 28 Feb 2021
Edited: dpb on 28 Feb 2021
for i = 2:N
if Gyr_2(i,3)
Output=RBK2(Input);
elseif Gyr_2(i,1) || Gyr_2(i,2) || Ori_2(i,1) || Ori_2(i,2)
Output=RBS2(Input);
elseif Acc_2(i,3)
Output=RBH2(Input);
else % If none of the conditions are true
Output=RBL2(Input);
if Diagonal5(i)==1 && Acc_3(i,1) && Acc_3(i,2)
if abs(Vel_3(i-1,1)) > abs(Vel_3(i-1,2)) && Acc_2(i,2)
while Diagonal5(i) == 1 %Value is either 1 or 0
Output=RBD2x(Input);
i = i + 1;
end
else
while Diagonal5(i) == 1 && Acc_2(i,1) ~= 0
Output=RBD2y(Input);
i = i + 1;
end
end
end
end
end
I rearranged your code a little, removing the comments that really didn't add anything to understanding the code to be less cluttered. I also removed the "~=0" RHS of comparison as it is superfluous in MATLAB where False==0; anything else == True.
After that, comments on the logic relative to the Q? -- in the section
if Diagonal5(i)==1 && Acc_3(i,1) && Acc_3(i,2)
if abs(Vel_3(i-1,1)) > abs(Vel_3(i-1,2)) && Acc_2(i,2)
while Diagonal5(i) == 1 %Value is either 1 or 0
Output=RBD2x(Input);
i = i + 1;
end
else
while Diagonal5(i) == 1 && Acc_2(i,1)
Output=RBD2y(Input);
i = i + 1;
end
end
the condition
while Diagonal5(i)==1
is also superfluous; you can't be inside the enclosing if block unless Diagonal5(i) is 1. So, that can be removed entirely leaving only the case of
while Diagonal5(i) == 1 && Acc_2(i,1)
but again you can't be here unless Diagonal5(i)==1 and you've already assigned RBD2x.
The above looks more like
if Diagonal5(i)==1 && Acc_3(i,1) && Acc_3(i,2)
if abs(Vel_3(i-1,1)) > abs(Vel_3(i-1,2)) && Acc_2(i,2)
if Acc_2(i,1)
Output=RBD2y(Input);
else
Output=RBD2x(Input);
end
continue % go on to next iteration
end
end
I really don't follow what is the intent here, but the above looks like what the code was probably intended to do.
You can't overwrite the values of for...end loop indices inside the loop; they'll just be overwritten by the stored values on the iteration anyways. continue is the way to short-circuit the rest of a loop and go on to the next iteration.
  3 Comments
dpb
dpb on 28 Feb 2021
" Vel_3(i,1) and Vel_3(i,2) are changed within the function"
Well, yes, the local variable named Vel_3 inside the functions is changed, but those have nothing whatsoever to do with whatever input and output are when the functions are called -- those are two completely separate variables.
As in other programming languages, functions in MATLAB have their own context so "whatever is change in Vegas stays in Vegas"
If you want to modify the local copy of the variables in this function, then you have to address those variables on the LHS of an assignment -- none of your code does that.
A possible way to share that context would be to include those to functions as internal functions which do share context/scope with the outer containing function. That's also fraught with danger(*) that goes along with global variables although they're at least contained within the scope of the outermost function, not totally global.
(*) I'm always in these cases reminded of a very early map of the known world at that time that had the annotation out in the midst of the Atlantic of "There be dragons!" A warning to be heeded.
Good luck, hopefully this wiill guide you towards figuring out a way to get the results you're after; I'm still not at all sure I understand the end result well enough to add more code -- in fact, I'm sure I don't.
Samuel Bofferding
Samuel Bofferding on 1 Mar 2021
Thanks for the further explanation and for the help understanding why my code was not working.
I have found a workaround for my problem. I have decided not to use the for ... end loop, as I cannot change the indices in the loop. I am now using a while loop instead. Here is my code with the workaround. I am guessing it is not the "prettiest" or "best" solution, but it gets the work done:
m = 2;
while m <= N
if Gyr_2(m,3)
Output = RBK2(Input);
m = m+1;
elseif Gyr_2(m,1) || Gyr_2(m,2) || Ori_2(m,1) || Ori_2(m,2)
Output = RBS2(Input);
m = m + 1;
elseif Acc_2(m,3)
Output = RBH2(Input);
m = m + 1;
else
[Output] = RBL2(Input);
if Diagonal5(m) == 1 && abs(Vel_3(m-1,1)) > abs(Vel_3(m-1,2)) && Acc_2(m,2)
while Diagonal5(m) == 1 % Does the code as long as the condition is true
Acc_3(m,1) = 0;
Acc_3(m,2) = Acc_2(m,2);
Acc_3(m,3) = 0;
Vel_3(m,1) = 0;
Vel_3(m,2) = Vel_3(m-1,2) + Acc_3(m,2)*dt;
Vel_3(m,3) = 0;
Gyr_3(m,:) = Gyr_2(m,:);
Ori_3(m,:) = Ori_2(m,:);
VectorJ1(m) = 2;
m = m + 1; % Change the indices manually
end
m = m - 1; % Some workaround I had to input so that it doesn't skip a value
elseif Diagonal5(m) == 1 && abs(Vel_3(m-1,2)) >= abs(Vel_3(m-1,1)) && Acc_2(m,1)
while Diagonal5(m) == 1
Acc_3(m,1) = Acc_2(m,1);
Acc_3(m,2) = 0;
Acc_3(m,3) = 0;
Vel_3(m,1) = Vel_3(m-1,1) + Acc_3(m,1)*dt;
Vel_3(m,2) = 0;
Vel_3(m,3) = 0;
Gyr_3(m,:) = Gyr_2(m,:);
Ori_3(m,:) = Ori_2(m,:);
VectorJ1(m) = 3;
m = m + 1;
end
m = m - 1; % Some workaround I had to input so that it doesn't skip a value
end
m = m + 1;
end
end
Thanks again for your input!
Sam

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products


Release

R2019b

Community Treasure Hunt

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

Start Hunting!