Use of findall with different conditions at the same time?

Hi guys.

I am trying to identify values on a matrix that are out of certain boundaries and extracting their positions within the matrix. I am using the function findall in the following way:

The input Matrix is “mat” and the output matrix with the indices is indx.

temp1=(findall(x->x>400, mat)); temp2=(findall(x->x<0, mat)); temp3=(findall(isequal(NaN), mat))
indx=[temp1; temp2; temp3].

Is there a way to include all the conditions in a single findall? I tried:

indx=(findall(x->x>400&&x<0&&isequal(NaN), mat));
indx=(findall(x->(x>400)&&(x<0)&&(isequal(NaN)), mat));
indx=(findall(x->400<x<0&&isequal(NaN), mat));

And its not working.

Any thoughts?

Thanks!

Do you mean to use ‘or’ (||) instead of ‘and’ (&&) in your conditions?

Thanks for your reply. Actually the three conditions must be met. x<0, x>400 ans x=NaN. The probles is that I had to create three temp files (one for each condition) and then merge them together.

I am wondering if there is a way to have all the three conditions using a single findall (so that I don’t have to create the temp files and merge them afterwards).

I don’t think you’ll find a number respecting all three conditions at once, but certainly find numbers respecting one of the conditions at a time (so try changing && to || in your findall).

I am sorry, actually what I meant to use was “or”, not “and”. Changing && by || now allows me to put x<0 and x>400 in the same findall (thanks for that), but I cannot include the isequal(NaN). I get the following error:

TypeError: non-boolean (Base.Fix2{typeof(isequal), Float64}) used in boolean context.

This is running well:
temp1=(findall(x->x>400||x<0,t2)); temp2=(findall(isequal(NaN), t2));

This gives the above mentioned error:
temp1=(findall(x->x>400||x<0||isequal(NaN),t2))

Yeah, should have noticed that one. Comparing with NaN is difficult (because NaN != NaN), but there is a special isnan available:

help?> isnan
search: isnan isinteractive issubnormal DimensionMismatch

  isnan(f) -> Bool

  Test whether a number value is a NaN, an indeterminate value which is neither an infinity nor a finite number ("not a number").

  See also: iszero, isone, isinf, ismissing.

Thanks for your comments!

The error is saying that isequal(NaN) returns a function, when you are trying to use it as a boolean. isequal(NaN) is a curried function (the Base.Fix2 type, which is equivalent to f(y) = isequal(y, NaN) ) and you are not giving it x (in the anonymous function for findall) as an argument.

The solution:

- findall(x->x>400||x<0||isequal(NaN),t2)
+ findall(x->x>400||x<0||isequal(x,NaN),t2)
+ findall(x->x>400||x<0||isnan(x),t2) # alternately

I have recently been in a similar situation and thought that defining & and | operations for Base.Fix1/Fix2 would be very convenient when multiple curried predicate functions are being used (theoretically also for single argument functions, eg isnan, but that would not be as simple to implement). Something along the lines of findall(>(400)|<(0)|isequal(NaN),t2).

1 Like

You can also use chained comparison:

findall(x->!(0<=x<=400)||isnan(x), mat) 
3 Likes

0<=x<=400 will return false for NaN, so it should suffice to do findall(x->!(0≤x≤400), mat).

5 Likes

Thank you so much! I used the second option and it was exactly what I was looking for!

Why not

?

1 Like