Closed wangl-cc closed 2 years ago
Merging #312 (3e324ae) into master (d9b5089) will increase coverage by
0.29%
. The diff coverage is100.00%
.
@@ Coverage Diff @@
## master #312 +/- ##
==========================================
+ Coverage 91.49% 91.79% +0.29%
==========================================
Files 9 9
Lines 1399 1413 +14
==========================================
+ Hits 1280 1297 +17
+ Misses 119 116 -3
Impacted Files | Coverage Δ | |
---|---|---|
src/indexing.jl | 89.09% <100.00%> (+2.19%) |
:arrow_up: |
Continue to review full report at Codecov.
Legend - Click here to learn more
Δ = absolute <relative> (impact)
,ø = not affected
,? = missing data
Powered by Codecov. Last update d9b5089...3e324ae. Read the comment docs.
Reshape to get the right sized output?
Thanks for your suggestion @ChrisRackauckas, but I found that the main reason of the problem is that the additional :
are converted to a zero dimensional CartesianIndices
, and then ignored by Base._getindex
(in below function). The similar problems occurs for LinearIndices
.
But if I defined
to_index(::LinearIndices{0,Tuple{}}, ::Colon) = Slice(static(1):static(1))
to_index(::CartesianIndices{0,Tuple{}}, ::Colon) = Slice(static(1):static(1))
the stride_preserving_index(typeof(inds))
will be True()
, and CartesianIndices(to_axes(A, _ints2range.(inds)))
doesn't return excepted shape. Then I found that ArrayInterface.getindex(::CartesianIndices, I...)
works very different from Base.getindex
even for normal indices:
julia> ArrayInterface.getindex(CartesianIndices((3, 3)), 1, 1, 1)
CartesianIndex(1, 1, 1)
julia> Base.getindex(CartesianIndices((3, 3)), 1, 1, 1)
CartesianIndex(1, 1)
julia> ArrayInterface.getindex(CartesianIndices((3, 3)), 1, :)
1×3 CartesianIndices{2, Tuple{ArrayInterface.OptionallyStaticUnitRange{StaticInt{1}, Int64}, Base.OneTo{Int64}}} with indices 1:1:1×Base.OneTo(3):
CartesianIndex(1, 1) CartesianIndex(1, 2) CartesianIndex(1, 3)
julia> Base.getindex(CartesianIndices((3, 3)), 1, :)
3-element Vector{CartesianIndex{2}}:
CartesianIndex(1, 1)
CartesianIndex(1, 2)
CartesianIndex(1, 3)
I'm not sure if it is designed in purpose or not?
There is a commit 4334830a41a7c61f6488aaa61537e82af458e93d which make ArrayInterface.getindex(::CartesianIndices, I...)
works the same as Base
. But I'm not sure if it can be merged.
A lot of this was designed with the goal to avoid allocating new arrays whenever possible, but there's been a lot of work over the years on improving CartesianIndices
in base (some of which has come as a result of discussions in ArrayInterface). I'd be open to changing things here, especially if it didn't break any of the current tests.
I revert to construct a CartesianIndices
when possible and reshape it to correct shape. But for LinearIndices
it seems impossible if first of indices is not one.
Besides, construct with to_axes(A, inds)
will cause the similar issue to #308, so I remove it.
What we really need is our own Indices
type that we can optimize however we want
@wangl-cc , it looks like all tests are passing and the changes seem reasonable to me. There's certainly more we can do related to this but that may be a lot for a single PR. Let me know if you're comfortable with the state of this PR and I can merge it. I'd of course be happy to review more
I may not have enough time on this PR this week, so merge this PR now is okay for me. If it's possible, I can do more related works on this weekend, maybe a new PR? @Tokazama
Cuurently,
getindex(A, inds...)
withinds
whose length is larger thanndims(A)
will cause a error, but it is allowed forBase.getindex
:The reason is
to_axes
only workslength(inds) == ndims(A)
currently, This PR fixes it with_maybe_first
and_maybe_tail
.However, the behavior for
CartesianIndices
is different, which works currently but ignores additional indsHow can I fix it or ignore it?