Skip to content

Specialize indexing a CartesianIndices with a CartesianIndex StepRangeLen#57534

Open
jishnub wants to merge 3 commits intomasterfrom
jishnub/cartesianindices_range_indexing
Open

Specialize indexing a CartesianIndices with a CartesianIndex StepRangeLen#57534
jishnub wants to merge 3 commits intomasterfrom
jishnub/cartesianindices_range_indexing

Conversation

@jishnub
Copy link
Copy Markdown
Member

@jishnub jishnub commented Feb 26, 2025

Since a CartesianIndices may be seen as an nD range, indexing it with a range in a specific direction would return a range. This is the nD equivalent of indexing a 1D range with another range, which returns a range as the result.
For example,

julia> C = CartesianIndices((3, 3))
CartesianIndices((3, 3))

julia> collect(C)
3×3 Matrix{CartesianIndex{2}}:
 CartesianIndex(1, 1)  CartesianIndex(1, 2)  CartesianIndex(1, 3)
 CartesianIndex(2, 1)  CartesianIndex(2, 2)  CartesianIndex(2, 3)
 CartesianIndex(3, 1)  CartesianIndex(3, 2)  CartesianIndex(3, 3)

julia> using LinearAlgebra

julia> r = diagind(C, IndexCartesian())
StepRangeLen(CartesianIndex(1, 1), CartesianIndex(1, 1), 3)

julia> C[r] # returns a materialized range
3-element Vector{CartesianIndex{2}}:
 CartesianIndex(1, 1)
 CartesianIndex(2, 2)
 CartesianIndex(3, 3)

After this PR,

julia> C[r] # returns the range without materializing it
StepRangeLen(CartesianIndex(1, 1), CartesianIndex(1, 1), 3)

julia> C[r] |> collect
3-element Vector{CartesianIndex{2}}:
 CartesianIndex(1, 1)
 CartesianIndex(2, 2)
 CartesianIndex(3, 3)

Such operations might find utility in sparse matrix constructions, when one needs a range of indices to populate. See e.g., JuliaSparse/SparseArrays.jl#600

@jishnub jishnub added arrays [a, r, r, a, y, s] ranges Everything AbstractRange labels Feb 26, 2025
@jishnub jishnub force-pushed the jishnub/cartesianindices_range_indexing branch from a81a7cc to 6319f2b Compare June 16, 2025 18:11
@mbauman
Copy link
Copy Markdown
Member

mbauman commented Jun 16, 2025

Are there any offset array packages that support an offset range of CartesianIndex? I'm not sure if we can generically support such a thing, but I think the answer should be similarly offset. The axes of the result should be the axes of the indices. For example:

julia> CartesianIndices((4,1))[CartesianIndex.(Base.IdentityUnitRange(3:4))]
2-element OffsetArray(::Vector{CartesianIndex{2}}, 3:4) with eltype CartesianIndex{2} with indices 3:4:
 CartesianIndex(3, 1)
 CartesianIndex(4, 1)

Maybe add a require_one_based_indexing here?

@jishnub
Copy link
Copy Markdown
Member Author

jishnub commented Jun 17, 2025

Indeed, indexing with ranges doesn't work very well with offset indexing, as we don't use similar to construct the result. Perhaps we require something like #41284 to make this consistent. For now, disallowing offset ranges is the pragmatic approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arrays [a, r, r, a, y, s] ranges Everything AbstractRange

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants