# Getting original array index from its view with reduced dimensions

In this code:

``````a = reshape(collect(1:12), 4, 3)
v = view(a, 2, :)

for i in eachindex(v)
# print corresponding index of array a
end
``````

I would like to get corresponding original indices of array `a`, either linear or Cartesian, i.e.:

``````  2
6
10
``````

or

``````(2, 1)
(2, 2)
(2, 3)
``````

Is it possible?

Yes!

``````julia> parentindices(v)
(2, Base.Slice(Base.OneTo(3)))
``````

The 2 is the first dimension (1-d slice) and the 1:3 is the second dimension.
You can do

``````julia> CartesianIndices(parentindices(v))
1Ă—3 CartesianIndices{2,Tuple{UnitRange{Int64},UnitRange{Int64}}}:
CartesianIndex(2, 1)  CartesianIndex(2, 2)  CartesianIndex(2, 3)
``````

And of course you can convert these to linear indices if you want.

5 Likes

How do I do it in my code example?

``````a = reshape(collect(1:12), 4, 3)
v = view(a, 2, :)

for i in eachindex(v)
println(i, " -> ", #= index of a =#)
end
``````

I need both indexes: contiguous linear index of `v` and any type of index of `a`.

You can `zip` the two together if you want to stick to the exported api

``````for i_view, ci_orig in zip(eachindex(v), CartesianIndices(parentindices(v)))
# ...
end
``````

You can also take a more â€śunder the hoodâ€ť approach, keeping in mind that implementation details of these types arenâ€™t guaranteed to remain the same (probably still a safe bet in this case)

``````for i in eachindex(v)
i_orig = v.offset1 + v.stride1*i
#...
end
``````
2 Likes

@tomerarnon, sorry to revisit this but could not get the expected results.
Would it be possible to produce a MWE?

By using `Iterators.product` and splatting, the results requested by the OP can be obtained:

``````a = reshape(collect(1:12), 4, 3)

v = view(a, 2, :)   # view of 1 row
for i_view in Iterators.product(parentindices(v)...)
println("parent index = \$i_view")
end

# result:
parent index = (2, 1)
parent index = (2, 2)
parent index = (2, 3)
``````

Seems like the behavior of `CartesianIndices` changed at some point.

Julia1.2:

``````julia> a = reshape(collect(1:12), 4, 3);

julia> v = view(a, 2, :);

julia> for (i_view, ci_orig) in zip(eachindex(v), CartesianIndices(parentindices(v)))
@show i_view, ci_orig
end
(i_view, ci_orig) = (1, CartesianIndex(2, 1))
(i_view, ci_orig) = (2, CartesianIndex(2, 2))
(i_view, ci_orig) = (3, CartesianIndex(2, 3))
``````

Julia1.6:

``````julia> a = reshape(collect(1:12), 4, 3);

julia> v = view(a, 2, :);

julia> for (i_view, ci_orig) in zip(eachindex(v), CartesianIndices(parentindices(v)))
@show i_view, ci_orig
end
(i_view, ci_orig) = (1, CartesianIndex(1, 1))
(i_view, ci_orig) = (2, CartesianIndex(2, 1))
(i_view, ci_orig) = (3, CartesianIndex(1, 2))
``````

The second method I gave still works, although ironically it was supposed to be the less stable oneâ€¦

1 Like

Thanks for the feedback, the second method still works indeed (the input example is a bit unfortunate because the index numbers are equal to the matrix values)