Skip to content

Specialize indexing a CartesianIndices with a CartesianIndex StepRangeLen #57534

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

jishnub
Copy link
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
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
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.

2 participants