Keeping Up With The Cartesians - Findall Return Type

I was writing Julia code yesterday and came across a bug in my code – the return from findall(f,A) came back with type Array{CartesianIndex{2},1} instead of what I expected, type Array{Int64,1}. Working in the REPL, I always got return type Array{Int64,1} from findall(f,A). Put the same line of code in a function, and findall(f,A) was returning type Array{CartesianIndex{2},1}.

What I discovered is an easily overlooked difference in the return type for findall(f, A) depending on how Array A was defined.

Consider:

function findcart()
β€œβ€β€œFindall return type: arrays β€œβ€β€

a = Array{Int64}(undef,6)
b = Array{Int64}(undef,(6,1))

a[1:6] = [0, 1, 2, 0, -3, 4]
b[1:6] = [0, 1, 2, 0, -3, 4]

pa = findall(isequal(0),a)
pb = findall(isequal(0),b)

println("a matrix size: ",size(a),"\tType: ",typeof(a))
println("b matrix size: ",size(b),"\tType: ",typeof(b))

println("Type of pa = ",typeof(pa))
println("Type of pb = ",typeof(pb))

end #findcart

Run this function and the output is:

julia> findcart()
a matrix size: (6,) Type: Array{Int64,1}
b matrix size: (6, 1) Type: Array{Int64,2}
Type of pa = Array{Int64,1}
Type of pb = Array{CartesianIndex{2},1}

Functionally, defining an array as (undef,6) or (undef,(6,1)) are functionally equivalent – you can access a[1], a[1,1], b[1], b[1,1].

I presume the internal indexing is different under the hood, however, between the two different ways that array β€œa” and β€œb” were defined, and this is what causes the output of findall(f,A) to be different.

3 Likes

The number of elements in the arrays is the same, but the arrays are really different shape, aren’t they?

1 Like

Yes, this is expected. Matrices have two dimensions and thus their keys have two indices β€” even when they only happen to have one column.

While we’ve made vectors behave like one-column matrices in many circumstances, they indeed live in different spaces and that becomes significant in certain places (like this). To get the linear index into the matrix, you can reshape it to a vector before doing findall (e.g., with vec).

1 Like

Both of these are misunderstandings. They are two different types, one is a Vector, the other a Matrix. Types are important in Julia, and you should expect different return types for different input types.

For the same reason it’s significant whether you create arrays as zeros(n), rand(n), ones(n) etc. or zeros(n, 1), rand(n, 1), ones(n, 1). This is something that many new users are unaware of.

1 Like

Since your question seems to have been answered, the only thing left to do is to commend you on a title done right. :+1: :joy:

8 Likes