While loop to find index of first element to be less than and greater than in a vector

67 views (last 30 days)
Hi,
I have the following problem:
"Using a while loop, find the first element and its index in the variable "a" that is greater than 0.42 and less than 0.52. Make sure that your code does not evaluate indices greater than 20"
I wrote the following code:
clear;
clc;
a=rand(20,1);
index=[];
n=1;
while a(n) < 0.42 && a(n) > 0.52
n=n+1;
index=[index, n]
end
However, absolutely nothing happens (no output is dispalyed) and I don't understand why. Can somebody please explain to me what I'm doing wrong?
I also don't know how to write the code so that it doesn't evaluate indices greater than 20. Can I use an if statement inside the while loop? Although I'm not sure how to do that exactly. Does anybody have any hints maybe?
Many thanks,
Dobs
  2 Comments
dpb
dpb on 16 Nov 2021
Probably you get no output because you're asking for the impossible. If the first condition is True (the value is <0.42), then it can never satisfy the second (>0.52) and you've written it as an AND condition which is both being true.
What is the real condition you're looking for -- those between the two limits or those outside?
Dobs
Dobs on 16 Nov 2021
So the number has to be between 0.42 and 0.52. When I switch the operators, still nothing is happening though. And if it does the index provided is for a number that doesn't meet the conditions.

Sign in to comment.

Answers (3)

Awais Saeed
Awais Saeed on 16 Nov 2021
Is it necessary to use a while loop? For loop works fine
a = rand(20,1)
for itr = 1:1:length(a) % iterate thorugh a row vector
if (a(itr) > 0.42 && a(itr) < 0.52) % id condition meets
index = itr % get the index
element = a(itr) % get element
break;
end
end
  6 Comments
Awais Saeed
Awais Saeed on 16 Nov 2021
Edited: Awais Saeed on 16 Nov 2021
No. You cannot just swap words ("for" with "while" and vice versa). The syntax for "while" and "for" loops are different. You have to write the condition according to their syntax. However, you can use a for loop instead of while loop or vice versa. To understand better, use debug mode.
To be on point, for-loops are used when you know how many iterations are needed and while-loops are used when you don't know. It keeps running as long as your condition is true.

Sign in to comment.


Jan
Jan on 16 Nov 2021
Edited: Jan on 16 Nov 2021
It is impossible, that a number is smaller than 0.42 and greater than 0.52:
a(n) < 0.42 && a(n) > 0.52
% ^ ^ swap the operators...
Therefore this loop is not entered in any case.
The test for limiting n to 20 is missing. If any index is found, the loop can stop also. Both conditions match into the WHILE condition also:
while isempty(index) && n <= 20 && ... insert the fixed comparison
For completeness: An experienced Matlab programmer would write:
Index = find(0.42 < a & a < 0.52, 1);
Sometimes it is strange if a homework question forces you to use Matlab in a most unmatlabish way.
  6 Comments
dpb
dpb on 16 Nov 2021
>> help find
find Find indices of nonzero elements.
I = find(X) returns the linear indices corresponding to
the nonzero entries of the array X. X may be a logical expression.
Use IND2SUB(SIZE(X),I) to calculate multiple subscripts from
the linear indices I.
I = find(X,K) returns at most the first K indices corresponding to
the nonzero entries of the array X. K must be a positive integer,
but can be of any numeric type.
...
Always read the documentation first...and all of the documentation may be pertinent altho here only the first two syntax forms are needed.

Sign in to comment.


Image Analyst
Image Analyst on 16 Nov 2021
You need to use OR (||) not AND (&&):
clear;
clc;
a=rand(1, 20)
a = 1×20
0.6980 0.1126 0.6021 0.4275 0.7347 0.5402 0.5318 0.8620 0.5059 0.5107 0.2861 0.3228 0.6512 0.5997 0.2252 0.0143 0.8999 0.6835 0.4595 0.1881
index = 1;
outOfRange = a(index) < 0.42 || a(index) > 0.52
outOfRange = logical
1
while outOfRange && index < 20
index=index+1;
outOfRange = a(index) < 0.42 || a(index) > 0.52;
end
fprintf('Found %f at index %d.\n', a(index), index)
Found 0.427509 at index 4.
  3 Comments
Image Analyst
Image Analyst on 16 Nov 2021
You want to find out if a number is in the range 0.42 to 0.52. So if the value at the current index IS NOT in the range, you need to keep iterating until it becomes in range. So while it's out of range and the index is not more than 20 (or more robustly, less than or equal to the length of "a" minus 1), you need to keep looping. And it's "out of range" if the value is less than 0.42 OR if it's more than 0.52, right? As soon as outOfRange is false, then it's not out of range and is now in range and you can quit looping. Does that make sense? If so, can you click the "Accept this answer" link?
dpb
dpb on 16 Nov 2021
" why should I use OR instead of AND?"
Well, as pointed out before, it's not possible for a number to be BOTH greater than 0.52 AND less than 0.42 simultaneously, which is the condition you wrote initially --
while a(n) < 0.42 && a(n) > 0.52
outOfRange = a(index) < 0.42 || a(index) > 0.52
which is only TRUE when the particular a is NOT inside the range, but is a feasible condition because it is either condition that is true, not both, and that is certainly something that can happen; the other of simultaneously being at either extreme is simply not realizable.
Inside his loop he used an AND condition again with the count on the array size so that condition is True only if both are so -- hence, once either you have found a number in range OR the counter reaches the end of the array, the while loop exits. That means this logic finds only one value (and the first one positionally) in the array that satisfies the condition whether there may or may not be more. It also means that if the first element in the array satisfies the range that the while loop never executes.
In this case, you're actually testing the negative (logical NOT) of the condition you're looking for so the while loop will keep going looking for the other case. NB: the value of the logical variable before the loop begins in the exampe -- it's True, but you haven't yet found the wanted value.
The alternative solution using find and a logical test on the value is looking for the values that satisfy the condition in the positive sense of the logic test
find(iswithin(a,0.42,0.52))
using my wrapper, which boils down to
find((a>0.42) & (a<0.52))
where the logical expressions return logical vectors the size of the a vector whose value is True where the conditional is Ture -- but since this is testing on the values to keep instead of trying to keep on looking when they value isN'T the wanted one, then the test is an AND.
In short, it all depends on what you're searching for and how the result is being used.
In your case, depending upon the problem description, you may need to modify @Image Analyst solution to keep going to find any remaining elements of a that satisfy the condition instead of quitting after the first. That's what leaving off the trailing "1" above in find() will do...adding it will produce the same result as IA.

Sign in to comment.

Categories

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

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!