CartesianIndex() - how to? - general questions

Is there a convenient way to:

  1. Convert CaresianIndex into Vector{<:Integer}
  2. Convert CartesianIndex{4} into CartesianIndex{3} by removing last coordinate?
  3. get k first values of Cartesian Index ( CI[1:4] → returns CartesianIndex{4} )

I know I can transform CI into tuple and work from there, but I wonder if there is some simpler way?

ind = CartesianIndices(zeros(2,2,2,2))
2×2×2×2 CartesianIndices{4,NTuple{4,Base.OneTo{Int64}}}:
[:, :, 1, 1] =
 CartesianIndex(1, 1, 1, 1)  CartesianIndex(1, 2, 1, 1)
 CartesianIndex(2, 1, 1, 1)  CartesianIndex(2, 2, 1, 1)
[:, :, 2, 1] =
 CartesianIndex(1, 1, 2, 1)  CartesianIndex(1, 2, 2, 1)
 CartesianIndex(2, 1, 2, 1)  CartesianIndex(2, 2, 2, 1)
[:, :, 1, 2] =
 CartesianIndex(1, 1, 1, 2)  CartesianIndex(1, 2, 1, 2)
 CartesianIndex(2, 1, 1, 2)  CartesianIndex(2, 2, 1, 2)
[:, :, 2, 2] =
 CartesianIndex(1, 1, 2, 2)  CartesianIndex(1, 2, 2, 2)
 CartesianIndex(2, 1, 2, 2)  CartesianIndex(2, 2, 2, 2)
julia> Tuple.(ind)
2×2×2×2 Array{NTuple{4,Int64},4}:
[:, :, 1, 1] =
 (1, 1, 1, 1)  (1, 2, 1, 1)
 (2, 1, 1, 1)  (2, 2, 1, 1)
[:, :, 2, 1] =
 (1, 1, 2, 1)  (1, 2, 2, 1)
 (2, 1, 2, 1)  (2, 2, 2, 1)
[:, :, 1, 2] =
 (1, 1, 1, 2)  (1, 2, 1, 2)
 (2, 1, 1, 2)  (2, 2, 1, 2)
[:, :, 2, 2] =
 (1, 1, 2, 2)  (1, 2, 2, 2)
 (2, 1, 2, 2)  (2, 2, 2, 2)
collect.(Tuple.(ind))
2×2×2×2 Array{Array{Int64,1},4}:
[:, :, 1, 1] =
 [1, 1, 1, 1]  [1, 2, 1, 1]
 [2, 1, 1, 1]  [2, 2, 1, 1]
[:, :, 2, 1] =
 [1, 1, 2, 1]  [1, 2, 2, 1]
 [2, 1, 2, 1]  [2, 2, 2, 1]
[:, :, 1, 2] =
 [1, 1, 1, 2]  [1, 2, 1, 2]
 [2, 1, 1, 2]  [2, 2, 1, 2]
[:, :, 2, 2] =
 [1, 1, 2, 2]  [1, 2, 2, 2]
 [2, 1, 2, 2]  [2, 2, 2, 2]
Tuple.(ind)[:]
16-element Array{NTuple{4,Int64},1}:
 (1, 1, 1, 1)
 (2, 1, 1, 1)
 (1, 2, 1, 1)
 (2, 2, 1, 1)
 (1, 1, 2, 1)
 (2, 1, 2, 1)
 (1, 2, 2, 1)
 (2, 2, 2, 1)
 (1, 1, 1, 2)
 (2, 1, 1, 2)
 (1, 2, 1, 2)
 (2, 2, 1, 2)
 (1, 1, 2, 2)
 (2, 1, 2, 2)
 (1, 2, 2, 2)
 (2, 2, 2, 2)
collect.(Tuple.(ind))[:]
16-element Array{Array{Int64,1},1}:
 [1, 1, 1, 1]
 [2, 1, 1, 1]
 [1, 2, 1, 1]
 [2, 2, 1, 1]
 [1, 1, 2, 1]
 [2, 1, 2, 1]
 [1, 2, 2, 1]
 [2, 2, 2, 1]
 [1, 1, 1, 2]
 [2, 1, 1, 2]
 [1, 2, 1, 2]
 [2, 2, 1, 2]
 [1, 1, 2, 2]
 [2, 1, 2, 2]
 [1, 2, 2, 2]
 [2, 2, 2, 2]
cat(collect.(Tuple.(ind))...,dims=2)
4×16 Array{Int64,2}:
 1  2  1  2  1  2  1  2  1  2  1  2  1  2  1  2
 1  1  2  2  1  1  2  2  1  1  2  2  1  1  2  2
 1  1  1  1  2  2  2  2  1  1  1  1  2  2  2  2
 1  1  1  1  1  1  1  1  2  2  2  2  2  2  2  2
(ci->ntuple(i->ci[i],3)).(ind)
2×2×2×2 Array{Tuple{Int64,Int64,Int64},4}:
[:, :, 1, 1] =
 (1, 1, 1)  (1, 2, 1)
 (2, 1, 1)  (2, 2, 1)
[:, :, 2, 1] =
 (1, 1, 2)  (1, 2, 2)
 (2, 1, 2)  (2, 2, 2)
[:, :, 1, 2] =
 (1, 1, 1)  (1, 2, 1)
 (2, 1, 1)  (2, 2, 1)
[:, :, 2, 2] =
 (1, 1, 2)  (1, 2, 2)
 (2, 1, 2)  (2, 2, 2)
 (ci->CartesianIndex(ntuple(i->ci[i],3))).(ind)
2×2×2×2 Array{CartesianIndex{3},4}:
[:, :, 1, 1] =
 CartesianIndex(1, 1, 1)  CartesianIndex(1, 2, 1)
 CartesianIndex(2, 1, 1)  CartesianIndex(2, 2, 1)
[:, :, 2, 1] =
 CartesianIndex(1, 1, 2)  CartesianIndex(1, 2, 2)
 CartesianIndex(2, 1, 2)  CartesianIndex(2, 2, 2)
[:, :, 1, 2] =
 CartesianIndex(1, 1, 1)  CartesianIndex(1, 2, 1)
 CartesianIndex(2, 1, 1)  CartesianIndex(2, 2, 1)
[:, :, 2, 2] =
 CartesianIndex(1, 1, 2)  CartesianIndex(1, 2, 2)
 CartesianIndex(2, 1, 2)  CartesianIndex(2, 2, 2)

You could also use Base.front instead of ntuple(i->ci[i], 3) here.

1 Like