Findall function

I have a question regarding the internal code of the findall function. I have an array and I want to find elements that satisfy two conditions. I know that I can use something like findall(f:function,A) where A is the array. I have the following code:

A = [1;2;3;4;5];
findall(x->1<x<4,A)
findall(x->x>1&&x<4,A)
findall(x->x>1&x<4,A)
findall(x->x<4&x>1,A)

The first two commands return the correct answer: 2,3. The third one returns 2,3,4,5 and the fourth one returns 0-element Array.
Why don’t the last two commands work?

This may be due to operator precedence. There is a table about this here
https://docs.julialang.org/en/v1/manual/mathematical-operations/#Operator-Precedence-and-Associativity-1

Have you tried adding backets?

findall(x->(x<4)&&(x>1),A)

Also you may want to try logical and, i.e. && instead of & (bitwise and)

3 Likes

You might also like this syntax:

A[1 .< A .< 4]
2 Likes

The logical and works with or without the brackets (command 2). I was just curious why the bitwise operation doesn’t work as I would imaging the function generates two bits for each element of the array and then computes the and operation, which should result in the correct answer. I found information on the precedence for && and || but not on bit wise operations.

Thank you, this works. But I was wondering why the bitwise operations don’t work in the findall function.

See Multiplication section.

Place to check operator priority for operators is also this file:

You can check there f. e. that ⅋ unicode symbol has the same priority as & and *.

Or just try:

julia> x=5
5

julia> x>1&x<4
true

julia> (x>1)&(x<4)
false
3 Likes

I finally understand it now. It evaluates 1&x as a quantity, since x is nonzero, the value is computed as 1, then the conditions read as x>1<4 which is true. Thus the result is true, when you put them in the bracket it evaluates it as two conditions and gives the right answer.
The same logic applied to my initial question. The third condition reads as: x>1<4 (since all my entries are nonzero), all values other than the first satisfy the condition, thus the answer. The fourth condition reads as x<1>1 which is not true thus it doesn’t return anything.

1 Like

since x is uneven !

e.g.:

julia> 1&5
1

julia> 1&4
0
1 Like

You can use dump on an expressions to see how the syntax is parsed which can be helpful.

dump(:(x>1&x<4))
Expr
  head: Symbol comparison
  args: Array{Any}((5,))
    1: Symbol x
    2: Symbol >
    3: Expr
      head: Symbol call
      args: Array{Any}((3,))
        1: Symbol &
        2: Int64 1
        3: Symbol x
    4: Symbol <
    5: Int64 4
2 Likes

You can also try a generator for efficiency, and you can iterate over or materialize using collect if needed.

(x for x in A if 1 < x < 4)
1 Like