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

41 ビュー (過去 30 日間)
Dobs
Dobs 2021 年 11 月 16 日
コメント済み: Jan 2021 年 11 月 17 日
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 件のコメント
dpb
dpb 2021 年 11 月 16 日
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 2021 年 11 月 16 日
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.

サインインしてコメントする。

回答 (3 件)

Awais Saeed
Awais Saeed 2021 年 11 月 16 日
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 件のコメント
Awais Saeed
Awais Saeed 2021 年 11 月 16 日
編集済み: Awais Saeed 2021 年 11 月 16 日
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.
Dobs
Dobs 2021 年 11 月 16 日
Ah ok, thank you for clarifying.

サインインしてコメントする。


Jan
Jan 2021 年 11 月 16 日
編集済み: Jan 2021 年 11 月 16 日
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 件のコメント
dpb
dpb 2021 年 11 月 16 日
>> 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.
Jan
Jan 2021 年 11 月 17 日
@dpb: I assume you mean isbetween(), https://www.mathworks.com/help/matlab/ref/datetime.isbetween.html , because I cannot find iswithin(). Then:
Index = find(isbetween(a, 0.42, 0.52, 'open'), 1);

サインインしてコメントする。


Image Analyst
Image Analyst 2021 年 11 月 16 日
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 件のコメント
Image Analyst
Image Analyst 2021 年 11 月 16 日
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 2021 年 11 月 16 日
" 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.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeMatrix Indexing についてさらに検索

製品


リリース

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by