Inconsistent behavior of getindex method with LinearIndices


#1

Currently we have two getindex methods with LinearIndices here

function getindex(iter::LinearIndices, i::Int)
    @_inline_meta
    @boundscheck checkbounds(iter, i)
    i
end
function getindex(iter::LinearIndices, i::AbstractRange{<:Integer})
    @_inline_meta
    @boundscheck checkbounds(iter, i)
    @inbounds isa(iter, LinearIndices{1}) ? iter.indices[1][i] : (first(iter):last(iter))[i]
end

It’s quite strange that the first one just return i. I suppose that it should return the ith element like the second method. Let’s see the example below:

julia> iter = LinearIndices((-1:1,))
3-element LinearIndices{1,Tuple{UnitRange{Int64}}}:
 1
 2
 3

julia> iter[2:2]
0:0

julia> iter[2]
2

#2
julia> iter[2,:,]
 2

#3

Yeah, I know, this will fallback to AbstractArray's default getindex implementation. My key point here is why LinearIndices here choose to not support negative UnitRange.

Seems CartesianIndices supports it well:

julia> inds = CartesianIndices((-1:1, -1:1))
3×3 CartesianIndices{2,Tuple{UnitRange{Int64},UnitRange{Int64}}}:
 CartesianIndex(-1, -1)  CartesianIndex(-1, 0)  CartesianIndex(-1, 1)
 CartesianIndex(0, -1)   CartesianIndex(0, 0)   CartesianIndex(0, 1) 
 CartesianIndex(1, -1)   CartesianIndex(1, 0)   CartesianIndex(1, 1) 

julia> inds[1]
CartesianIndex(-1, -1)

julia> iter = LinearIndices((-1:1, -1:1))
3×3 LinearIndices{2,Tuple{UnitRange{Int64},UnitRange{Int64}}}:
 1  4  7
 2  5  8
 3  6  9

julia> iter[CartesianIndex(-1,-1)]
ERROR: BoundsError: attempt to access 3×3 LinearIndices{2,Tuple{UnitRange{Int64},UnitRange{Int64}}} at index [-1, -1]
Stacktrace:
 [1] throw_boundserror(::LinearIndices{2,Tuple{UnitRange{Int64},UnitRange{Int64}}}, ::Tuple{Int64,Int64}) at .\abstractarray.jl:484
 [2] checkbounds at .\abstractarray.jl:449 [inlined]
 [3] _getindex at .\abstractarray.jl:927 [inlined]
 [4] getindex(::LinearIndices{2,Tuple{UnitRange{Int64},UnitRange{Int64}}}, ::CartesianIndex{2}) at .\abstractarray.jl:905
 [5] top-level scope at none:0

If the aim of LinearIndices and CartesianIndices is to provide conversion between each other, then I suppose this error should not happen(the last one is supposed to return 1, I guess?).


#4
julia> inds[CartesianIndex(-1, 1)]
ERROR: BoundsError: attempt to access 3×3 
CartesianIndices{2,Tuple{UnitRange{Int64},UnitRange{Int64}}}
 at index [-1, 1]

#5

Thanks!

It’s my fault.