For loop with two conditions

31 views (last 30 days)
Saad Alqahtani
Saad Alqahtani on 5 Jul 2021
Commented: Saad Alqahtani on 6 Jul 2021
Hi,
I'm trying to run this code where it should stop as soon as one of the conditions has met and give me the index where it stops.
So, here is my code and it's taking so long to run and it also didn't stop utill the end which I'm sure one of those conditions should have been met far away from the end.
isOK1= (Discard2value<=target_value_30_P);
isOK2 =(Discard2value>=t2);
for N = datan(1:end)
while 1
if N == (Discard1value) || ((isOK1 && isOK2))
J = N;
break
end
end
end
I don't know what's missing? Any help would be appreciate it.
Also, I keep getting this error : "array indices must be positive integers or logical values"
Thanks in advance.

Accepted Answer

DGM
DGM on 5 Jul 2021
Edited: DGM on 5 Jul 2021
Considering all the comparisons that are being made between unknown variables, I'm not eager to guess at what should be expected. I doubt that any of these loops are necessary, given that all the test values appear to be scalar logicals defined outside the loops. In fact, since nothing changes within the loops, the inner loop serves no purpose and will either pass trivially, or it will get stuck. I also assume that it's unlikely that (presumably) floating point values in datan are exactly 1 or 0, so it's probably never going to do anything but get stuck.
If that doesn't reveal the problem, include enough supporting example data that the problem can be reproduced, or provide enough of the surrounding code that the intent is unambiguous.
  5 Comments
DGM
DGM on 6 Jul 2021
Edited: DGM on 6 Jul 2021
I did some things at it.
% don't know what datan range or size is
% this is just a test vector
datan = 100*rand(10000,1);
MVC= 100;
target_value= 0.30*MVC;
target_lowest_point = 0.70*target_value;
target_value_30_Percent = 0.30*target_value; % ... why is this even a variable?
% it literally takes up more space and is less clear than the code itself
% magic numbers that depend on some array size or resolution factor
% and will otherwise cause the code to break
% is fsamp = 2048? if so, use it.
t1 = 3*2048;
t2 = 2*2048;
% this could be compacted and clarified, but eh.
Discard1 = find(datan <= target_lowest_point,1);
Discard1value = datan(Discard1);
Discard2 = find(datan <= target_value_30_Percent,1);
Discard2value = datan(Discard2);
Discard2_to_end = datan(Discard2:end);
Discard3lasts = Discard2_to_end(1:t1);
isOK1 = Discard2value<=target_value_30_Percent;
isOK2 = Discard2value>=t2;
% i have no idea what this means, but it should do the same thing as the loop
% or rather, it does what i assume the loop was _supposed_ to do
Jidx = (datan == Discard1value) | (isOK1 && isOK2);
Discard3 = find(Jidx);
Discard_length3 = length(datan(Discard3:end));
Discard_length3_in_sec = (Discard_length3)/2048 ;
forceChoppped = datan(1:end-(Discard_length3_in_sec*2048));
timechopped = (0:length(Discard_length3_in_sec)-1)/fsamp; % let me guess. fsamp is 2048?
% if so, you should make it a parameter and use it
I only deleted the comments to make my own remarks visible. I'm not suggesting you remove yours. Having plenty of comments is good.
Saad Alqahtani
Saad Alqahtani on 6 Jul 2021
This works perfect. Thank you so much!

Sign in to comment.

More Answers (1)

Paul Hoffrichter
Paul Hoffrichter on 5 Jul 2021
>> this code where it should stop as soon as one of the conditions has met
But the break just gets you out of the while loop when one of the two conditions is met. You need to add a test after the while loop to see if you broke out, in which case you can add another break do get out of the for-loop.
But within the while loop, here are your constants:
  • N (is being tested, but not changing)
  • Discard1value (is being tested, but not changing)
  • isOK1, isOK2 (are being tested but not changing)
Within the for-loop, only one variable N changes.
If the first time you hit the if N... test, you have a false condition, then you will never break out - you will be in an infinite loop since all the variables in the if test are constant within the body of the if-statement.
isOK1= (Discard2value<=target_value_30_P);
isOK2 =(Discard2value>=t2);
for N = datan(1:end)
while 1
if N == (Discard1value) || ((isOK1 && isOK2))
J = N;
break
end
end % END while
end % END for
>> it's taking so long to run and it also didn't stop utill the end
Since you are not reporting an infinite loop, then one of the conditions in the if-test must be true the first time you hit it. If the isOK test true, then it remains true for all values of N.
I advise you to put a breakpoint at the if-test, and step through a few loops to better understand your two loops.
  4 Comments
Image Analyst
Image Analyst on 6 Jul 2021
This would be some more robust code, which breaks out of both the for loop and the while loop as well as having a failsafe to prevent an infinite loop
isOK1= (Discard2value<=target_value_30_P);
isOK2 =(Discard2value>=t2);
abort = false;
loopCounter = 1; % Failsafe
maxIterations = 1000; % A lot more than you EVER expect to have.
for N = datan(1:end)
while ~abort && loopCounter < maxIterations
if N == (Discard1value) || ((isOK1 && isOK2))
J = N;
abort = true;
break; % out of while loop
end
% Now update conditions N, Discard1value, isOK1, and/or isOK2 somehow
% or else it will never hit the break.
% TODO : update code, then increment the loop counter.
loopCounter = loopCounter + 1; % Failsafe
end
% You get here when the while loop breaks OR
% if you hit the max number of iterations.
if abort
break; % Out of for loop.
end
end
Saad Alqahtani
Saad Alqahtani on 6 Jul 2021
Thanks for the help.

Sign in to comment.

Categories

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

Community Treasure Hunt

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

Start Hunting!