-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Inconsistency in interpreting a range of CartesianIndexes as a CartesianIndices #41959
Comments
I think this is intended - a single step is taken as a step in any of the given cartesian directions, resulting in the product of the involved possibilities. What version are you on?
|
This inconsistency is due to the fact that you're trying to project the N-dimensional space into 1-dimensional space and thus lose the step information. If you stick to the N-dimensional range concept, which might be a little bit weird at first sight, it's consistent: # N-dimensional range
C = range(CartesianIndex(1, 1), step=CartesianIndex(2, 2), stop=CartesianIndex(10, 10))
R = CartesianIndices(C)
all(R .- one(eltype(R))) do i
C[first(R)] + CartesianIndex(i.I .* step(C).I) == C[first(R)+i]
end # true
# 1-dimensional range
C = range(1, step=2, stop=10)
R = LinearIndices(C)
all(R .- one(eltype(R))) do i
C[first(R)] + i * step(C) == C[first(R)+i]
end # true |
Ah I'm sorry, I seem to have added the missing Base.CartesianIndex{N}(c::CartesianIndex{N}) where {N} = c With this added, julia> StepRangeLen(a, a, 2)
CartesianIndex(1, 1):CartesianIndex(1, 1):CartesianIndex(2, 2) |
Yes this does indeed make sense as an N-dimensional iterator, however perhaps there should be a different name given to this? For example, this results in julia> g(a, I = eachindex(a)) = a[first(I):last(I)]
g (generic function with 2 methods)
julia> g(a[1:end, 1:end])
4-element Vector{Int64}:
1
3
2
4
julia> g(@view a[1:end, 1:end])
2×2 Matrix{Int64}:
1 2
3 4
Ideally views should not lead to different behavior from slices. |
This is another issue, though: julia> IndexStyle(a[1:end, 1:end])
IndexLinear()
julia> IndexStyle(@view a[1:end, 1:end])
IndexCartesian() When clarification is needed, I would try to avoid using I agree that having a different symbol to |
Indeed the Also, isn't |
If you really have to filter out certain indices based on the index alone, you have to choose whether to filter based on cartesian or linear indices. If you want to be on the save side and know you have an array-like, The index style for views may be specialized based on what indices are passed in - the information is already part of the type of the view, so I think this could be a good addition. It currently falls back to a generic |
I've created a discourse post to continue the discussion. My view now is that the current behavior of the range julia> h(a, I = eachindex(a)) = a[first(I):2step(I):last(I)]
h (generic function with 2 methods)
julia> h(a[1:end, 1:end])
2-element Vector{Int64}:
1
2
julia> h(@view a[1:end, 1:end])
1×1 Matrix{Int64}:
1 where slices and views behave very differently. This should really be treated as a bug. Perhaps we may continue further discussion on discourse to avoid cluttering this issue? |
My whole point here is that if you choose to look from a 1D perspective, then you're losing step information and you get unwanted things. When you really need to differentiate between an N-dimensional array and a linear array, use The
julia> one(CartesianIndex{2})
┌ Warning: `one(I::Type{CartesianIndex{N}}) where N` is deprecated, use `oneunit(I)` instead.
│ caller = top-level scope at REPL[1]:1
└ @ Core REPL[1]:1
CartesianIndex(1, 1) |
You're right, the linear range of I'll close this issue for the time being and reopen if I can think of a better approach. |
I'm not sure if this is the intended behavior, but the
a:b:c
method involvingCartesianIndex
es that results in aCartesianIndices
seems inconsistent with conventional usage of range. This is becauseCartesianIndices
behaves as aproduct
of ranges. To illustrate the behavior:While
a:b:c
is a convenient constructor forCartesianIndices
, it is inconsistent with the idea of ranges. Should this simply return aStepRangeLen
instead? What's worse is that the display of such aStepRangeLen
is corrupted by this methodThe text was updated successfully, but these errors were encountered: