Skip to content

Permit the construction of a 1D StepRangeLen of CartesianIndexes #50457

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

Merged

Conversation

jishnub
Copy link
Member

@jishnub jishnub commented Jul 7, 2023

This PR adds a CartesianIndex constructor with ndims-matching CartesianIndex argument.

This allows constructing the following range:

julia> r = StepRangeLen(CartesianIndex(2,3), CartesianIndex(1,1), 10)
CartesianIndex(2, 3):CartesianIndex(1, 1):CartesianIndex(11, 12)

julia> collect(r)
10-element Vector{CartesianIndex{2}}:
 CartesianIndex(2, 3)
 CartesianIndex(3, 4)
 CartesianIndex(4, 5)
 CartesianIndex(5, 6)
 CartesianIndex(6, 7)
 CartesianIndex(7, 8)
 CartesianIndex(8, 9)
 CartesianIndex(9, 10)
 CartesianIndex(10, 11)
 CartesianIndex(11, 12)

@Seelengrab
Copy link
Contributor

The wider discussion around how CartesianIndex is expected to behave in discussions like #43336 is likely related - not quite sure if this PR and the points discussed in that (and other issues linked within) are in conflict or not though.

@jishnub
Copy link
Member Author

jishnub commented Jul 7, 2023

There is certainly some scope for ambiguity here, as the following will behave differently:

julia> range(CartesianIndex(1,1), step=CartesianIndex(1,1), stop=CartesianIndex(2,2))
CartesianIndices((1:1:2, 1:1:2))

julia> range(CartesianIndex(1,1), step=CartesianIndex(1,1), length=2)
CartesianIndex(1, 1):CartesianIndex(1, 1):CartesianIndex(2, 2)

However, a 1D range of CartesianIndexes is a vital cog in indexing into banded matrices, and the StepRangeLen constructor appears to be consistent here. Perhaps we may disallow using range in this case until a decision is reached?

@Seelengrab
Copy link
Contributor

Seelengrab commented Jul 7, 2023

Yes that's a very good point - we'll likely have to decide one way or another at some point what we want the semantics to be. The core issue is in which direction that length ("how many steps to take") should be, i.e. whether a CartesianIndex is vector-like or not. The same issue is unfortunately also present if we take StepRangeLen in isolation..

@jishnub
Copy link
Member Author

jishnub commented Jul 8, 2023

Looking at the history of the colon constructor for CartesianIndices, it seems like this was added as a syntactic sugar, and not with the properties of CartesianIndexes in mind. Given that CartesianIndexes obey all the axioms of a vector space, it'll be odd to not allow them to behave like vectors.

It seems like I had attempted a similar change in #41960, where the suggestion was the same: that StepRangeLen makes sense, but range is inconsistent and may be disallowed beyond the current behavior.

@Seelengrab
Copy link
Contributor

Yes, there have been a few attempts :) Calling StepRangeLen directly makes most sense, because that at least removes the ambiguity on which axis the steps go, but it unfortunately doesn't remove the ambiguity whether the resulting object should open up the cartesian product/hypercube of the resulting extent, or just the axis connecting the endpoints.

@jishnub
Copy link
Member Author

jishnub commented Jul 12, 2023

I think that since StepRangeLen <: AbstractRange <: AbstractVector, the constructor should only return an object of that type (i.e. an AbstractVector), and not an n-D CartesianIndices hypercube. The ambiguity in the meaning of range will probably persist, which is why it makes sense to disallow the start-step-length range method for CartesianIndexes (as in this PR).

@jishnub jishnub changed the title CartesianIndex constructor with ndims-matching CartesianIndex argument Permit the construction of a 1D StepRangeLen of CartesianIndexes Jul 12, 2023
@jishnub jishnub added triage This should be discussed on a triage call ranges Everything AbstractRange labels Jul 16, 2023
@JeffBezanson
Copy link
Member

Triage says 👍 on adding the constructor method, but we don't think adding the error method fixes the real problem. The real problem is the printing of the StepRangeLen object using colons, when that colon syntax gives a different result. The printing needs to be fixed. Some also object to this overloading of :, but that ship has sailed. Anyway we should try to fix the printing instead.

@jishnub jishnub force-pushed the jishnub/CartesianIndexStepRangeLen branch from 9f3740b to 273d2cb Compare September 2, 2023 11:48
@jishnub
Copy link
Member Author

jishnub commented Sep 2, 2023

I've specialized show to display the StepRangeLen constructor:

julia> StepRangeLen(CartesianIndex(1, 2), CartesianIndex(3, 4), 2)
StepRangeLen(CartesianIndex(1, 2), CartesianIndex(3, 4), 2)

This should fix #50784

@jishnub jishnub removed the triage This should be discussed on a triage call label Sep 7, 2023
@jishnub
Copy link
Member Author

jishnub commented Sep 7, 2023

Gentle bump

@jishnub
Copy link
Member Author

jishnub commented Sep 14, 2023

Gentle bump @JeffBezanson

@jishnub
Copy link
Member Author

jishnub commented Sep 29, 2023

Gentle bump

@jishnub jishnub requested a review from vtjnash September 29, 2023 09:02
@jishnub
Copy link
Member Author

jishnub commented Oct 9, 2023

Gentle bump

@Seelengrab Seelengrab added the triage This should be discussed on a triage call label Oct 16, 2023
@jishnub
Copy link
Member Author

jishnub commented Nov 3, 2023

Gentle bump, is there anything that remains to be done here?

@Seelengrab
Copy link
Contributor

I think it's good now, I added the triage label since I wasn't sure that triage approves too. I'll bring it up next session if I have time to join.

@LilithHafner
Copy link
Member

Triage already approved this.

@LilithHafner LilithHafner merged commit 560ede5 into JuliaLang:master Nov 8, 2023
@LilithHafner LilithHafner removed the triage This should be discussed on a triage call label Nov 8, 2023
@jishnub
Copy link
Member Author

jishnub commented Nov 8, 2023

Thanks everyone!

@LilithHafner
Copy link
Member

Thank you for bearing with us.

jishnub added a commit that referenced this pull request Nov 19, 2023
)

With #50457 now merged, an `AbstractRange` of `CartesianIndex`es should
use `CartesianIndexing` in constructing a `SubArray`. I've limited the
method to integer ranges, as this is the case where we know for sure
that the indexing may be linear.

Fixes
```julia
julia> view(1:2, StepRangeLen(CartesianIndex(1), CartesianIndex(1), 0))
0-element view(::UnitRange{Int64}, StepRangeLen(CartesianIndex(1,), CartesianIndex(1,), 0)) with eltype Int64
```

---------

Co-authored-by: N5N3 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ranges Everything AbstractRange
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants