-
Notifications
You must be signed in to change notification settings - Fork 42
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
Add constructors for CartesianIndices #142
Conversation
Codecov Report
@@ Coverage Diff @@
## master #142 +/- ##
==========================================
+ Coverage 90.49% 91.39% +0.89%
==========================================
Files 2 2
Lines 221 244 +23
==========================================
+ Hits 200 223 +23
Misses 21 21
Continue to review full report at Codecov.
|
This looks pretty handy at the first sight. However, I wouldn't expect fusions like this work and this seems like an overdesign to me. Do we have similar usage in Base or other Julia packages? It seems that there're other constructors that haven't yet get benefit from this: |
Slicing implements something like this, so perhaps this might serve to wrap the slice with the indices? Eg something like this: julia> a = reshape(1:24, 3, 4, 2)
3×4×2 reshape(::UnitRange{Int64}, 3, 4, 2) with eltype Int64:
[:, :, 1] =
1 4 7 10
2 5 8 11
3 6 9 12
[:, :, 2] =
13 16 19 22
14 17 20 23
15 18 21 24
julia> inds = (:, CartesianIndex(2,1):CartesianIndex(3,2))
(Colon(), CartesianIndex{2}[CartesianIndex(2, 1) CartesianIndex(2, 2); CartesianIndex(3, 1) CartesianIndex(3, 2)])
julia> oa = OffsetArray(a[inds...], inds...)
3×2×2 OffsetArray(::Array{Int64,3}, 1:3, 2:3, 1:2) with eltype Int64 with indices 1:3×2:3×1:2:
[:, :, 1] =
4 7
5 8
6 9
[:, :, 2] =
16 19
17 20
18 21
julia> oa[1,2,1] == a[1,2,1]
true I think it might be convenient to have constructors with any The reason I didn't implement |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is nice work!
@jishnub I think this one is ready? Or do you have any other more commits in?
function stripCartesianIndices(inds::Tuple{CartesianIndices{1},Vararg{Any}}) | ||
I = first(inds) | ||
Ir = convert(Tuple{AbstractUnitRange{Int}}, I) |> first | ||
(Ir, stripCartesianIndices(tail(inds))...) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function stripCartesianIndices(inds::Tuple{CartesianIndices{1},Vararg{Any}}) | |
I = first(inds) | |
Ir = convert(Tuple{AbstractUnitRange{Int}}, I) |> first | |
(Ir, stripCartesianIndices(tail(inds))...) | |
end | |
stripCartesianIndices(inds::Tuple{CartesianIndices{1},Vararg{Any}}) = (first(inds).indices..., stripCartesianIndices(tail(inds))...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to avoid using CartesianIndices(..).indices
, as I'm not entirely sure that it's future-proof. The convert
route was suggested by Tim Holy to get around this, and seems to produce the same lowered code
julia> @code_lowered convert(Tuple{AbstractUnitRange{Int}}, c)
CodeInfo(
1 ─ %1 = Base.getproperty(R, :indices)
└── return %1
)
I can condense these a bit if that helps in legibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh sorry, I missed that part of the conversation. These two are actually equivalent.
Future-proof seems okay to me.
function splitCartesianIndices(c::CartesianIndices) | ||
c1, ct = Base.IteratorsMD.split(c, Val(1)) | ||
(c1, splitCartesianIndices(ct)...) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to know this split
usage.
I tried the following, too. But this one is much slower than your version.
splitCartesianIndices(c::CartesianIndices) = IdOffsetRange.(c.indices)
IdOffsetRange
could perhaps be optimized a bit. Of course not in this PR.
I don't think that there are more commits to this |
Has @timholy given you an invitation to this repo? If so, please merge when you feel it's ready! |
Fixes #71 . With this PR the following are possible:
Not too sure ifCartesianIndices(..).indices
is future-proof.