How to reindex a linear array for cartesian usage?

question
indexing

#1

Hello,

I’d like to use a Package and the underlying arrays are 2-D. I’m hoping make a new type that uses these 2-D based types, but I’d like the usage of my types to be N-dimensional.

I think I can do this with sub2ind and ind2sub, but it seems like there might be a better way with Base.reindex or possibly view.

As an example, if I have
A = randn(50,24)

But I want a new SubArray (or something) called B, that represents the 2nd dimension of A to represent 3 dimensions of size (2,3,4). Such that
B[2, 2, 2, 2] == A[2, 10]

The above example corresponds with:

julia> sub2ind((2,3,4), 2, 2, 2)
10

Should I just define sub2ind / ind2sub on my type or is there a cleaner way to do this?


#2

I think

B = reshape(view(A, :, :), :, 2, 3, 4)

is what you want. Note that this returns a ReshapedArray, which is a view into A, so modifying B[2, 2, 2, 2] also modifies A[2, 10].

See also https://github.com/JuliaLang/julia/issues/24237.


#3

I will give this a try. This sounds promising - thank you!

Update: This definitely works for single elements in the array, although it doesn’t seem to work for slicing/ranges and I’d really like to support slicing with the cartesian coordinates.

Update2: I seem to have mis-spoke.

julia> A = randn(50,24);

julia> B = reshape(view(A, :, :), :, (2,3,4)...);

julia> getindex(B, 2, 2, 2, 2)
0.06798698740819463

julia> A = randn(50,24);

julia> B = reshape(view(A, :, :), :, (2,3,4)...);

julia> getindex(A, 2, 10)
0.8184511930501794

julia> getindex(B, 2, 2, 2, 2)
0.8184511930501794

julia> getindex(B, 2, 2, 2, 2:4)
3-element Array{Float64,1}:
  0.818451
  0.259312
 -0.196341

julia> B[2,2,2,2:4]
3-element Array{Float64,1}:
  0.818451
  0.259312
 -0.196341