In Julia you can find the coordinates of elements in a matrix via:
julia> find( x -> x == 2, [ 1 2 3; 2 3 4; 1 0 2] )
3-element Array{Int64,1}:
2
4
9
These values are correct but I would prefer that I would get the (row,col) tuples instead.
(1,2)
(2,1)
(3,3)
What is the easiest way to achieve this in Julia?
I don't believe there is an inbuilt way to do it, but here is a function to do it
function findmat(f, A::AbstractMatrix)
m,n = size(A)
out = (Int,Int)[]
for i in 1:m, j in 1:n
f(A[i,j]) && push!(out,(i,j))
end
out
end
e.g.
julia> findmat(x->x==2, [ 1 2 3; 2 3 4; 1 0 2] )
3-element Array{(Int64,Int64),1}:
(1,2)
(2,1)
(3,3)
If a large number of items satisfy the condition it might be more efficient to do it in two passes, but I doubt it.
In case anyone else finds this you can now use:
ind2sub(a, index)
It returns a tuple of subscripts into array a
corresponding to the linear index index
The closest thing that I can find in the Julia standard library is findn
:
julia> A = [1 2 3; 2 3 4; 1 0 2]
3x3 Array{Int64,2}:
1 2 3
2 3 4
1 0 2
julia> findn(A .== 2)
([2,1,3],[1,2,3])
This gives a tuple of vectors instead of a vector of tuples, though.
Another thing to note is that the match at (2,1)
is reported before the one at (1,2)
. This is because arrays in Julia are stored in column major order, so scanning the array A
in storage order will look at the position (2,1)
before (1,2)
.
if you wish to avoid defining "new" functions, perhaps:
collect(zip(ind2sub((3,3),find( x -> x == 2, [ 1 2 3; 2 3 4; 1 0 2] ))...))
is what you are looking for. the (3,3) is implicit in the size of the matrix. if the matrix was given by a variable it would look more natural with a size(M)