Skip to content

Not wrapping CartesianIndices incorrectly processed by to_indices #46

@sethaxen

Description

@sethaxen

Indexing a matrix with Not(::CartesianIndices) results in Not only being applied to the row selector, not the column selector:

julia> x = reshape(1:12, (4, 3))
4×3 reshape(::UnitRange{Int64}, 4, 3) with eltype Int64:
 1  5   9
 2  6  10
 3  7  11
 4  8  12

julia> inds = CartesianIndices(x)[2:3, 1:2]
CartesianIndices((2:3, 1:2))

julia> x[inds]
2×2 Matrix{Int64}:
 2  6
 3  7

julia> x[Not(inds)]  # expected setdiff(x, x[inds])
2×2 Matrix{Int64}:
 1  5
 4  8

julia> x[Not(vec(inds))] == setdiff(x, x[inds])  # fine if we reshape to a vector
true

julia> x[Not(Matrix(inds))] == setdiff(x, x[inds])  # fine if we convert to a Matrix
true

julia> lin_inds = LinearIndices(x)[2:3, 1:2]
2×2 Matrix{Int64}:
 2  6
 3  7

julia> x[Not(lin_inds)] == setdiff(x, x[inds])  # fine if we convert to linear indices
true

This happens because to_indices only applies the Not to the first selector being returned:

julia> Base.to_indices(x, (inds,))
(2:3, 1:2)

julia> Base.to_indices(x, (Not(inds),))  # Not only applied to row selection
(Not(2:3), 1:2)

julia> Base.to_indices(x, (vec(inds),))  # calling vec on the indices makes to_indices a no-op
(CartesianIndex{2}[CartesianIndex(2, 1), CartesianIndex(3, 1), CartesianIndex(2, 2), CartesianIndex(3, 2)],)

julia> Base.to_indices(x, (Matrix(inds),))  # same for converting to matrix
(CartesianIndex{2}[CartesianIndex(2, 1) CartesianIndex(2, 2); CartesianIndex(3, 1) CartesianIndex(3, 2)],)

AFAICT this is because these lines assumesthat Not's skipped indices all are resolved by to_indices to the first entry of the resulting tuple, but for CartesIndices this is (at least somtimes?) false.

new_indices = to_indices(A, inds, (I[1].skip, tail(I)...))
skips = uniquesort(new_indices[1])
picks = spanned_indices(inds, skips)[1]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions