-
Notifications
You must be signed in to change notification settings - Fork 40
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
properly handle colon in offset reshape #228
base: master
Are you sure you want to change the base?
Conversation
Codecov Report
@@ Coverage Diff @@
## master #228 +/- ##
==========================================
- Coverage 94.40% 94.26% -0.15%
==========================================
Files 5 5
Lines 322 349 +27
==========================================
+ Hits 304 329 +25
- Misses 18 20 +2
Continue to review full report at Codecov.
|
include("axes.jl") | ||
include("utils.jl") | ||
include("origin.jl") | ||
|
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 to let utils.jl
know the OffsetAxisKnownLength
and OffsetAxis
.
For better compatibility to old and future Julia versions
Since this changes the axes of the reshaped array, this should perhaps be treated as a breaking change? |
Since we never successfully supported |
This works currently on master: julia> A = zeros(1:2, 3:4)
2×2 OffsetArray(::Matrix{Float64}, 1:2, 3:4) with eltype Float64 with indices 1:2×3:4:
0.0 0.0
0.0 0.0
julia> reshape(A, 2:3, :)
2×2 OffsetArray(::Matrix{Float64}, 2:3, 1:2) with eltype Float64 with indices 2:3×1:2:
0.0 0.0
0.0 0.0 After this PR: julia> reshape(A, 2:3, :)
2×2 OffsetArray(::Matrix{Float64}, 2:3, 3:4) with eltype Float64 with indices 2:3×3:4:
0.0 0.0
0.0 0.0 |
@@ -280,13 +280,15 @@ end | |||
Base.reshape(A::AbstractArray, inds::OffsetAxis...) = reshape(A, inds) | |||
function Base.reshape(A::AbstractArray, inds::Tuple{OffsetAxis,Vararg{OffsetAxis}}) | |||
AR = reshape(A, map(_indexlength, inds)) | |||
return OffsetArray(AR, map(_offset, axes(AR), inds)) | |||
return OffsetArray(AR, _offset_reshape_uncolon(A, 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.
This is equivalent to
return OffsetArray(AR, map(_offset, axes(AR), _offset_reshape_uncolon(A, inds)))
By removing the map
part, it calls another constructor.
OffsetArrays.jl/src/OffsetArrays.jl
Lines 210 to 219 in b74ae55
# convert ranges to offsets | |
@eval @inline function $FT(A::AbstractArray, inds::Tuple{AbstractUnitRange,Vararg{AbstractUnitRange}}) | |
_checkindices(A, inds, "indices") | |
# Performance gain by wrapping the error in a function: see https://github.com/JuliaLang/julia/issues/37558 | |
throw_dimerr(lA, lI) = throw(DimensionMismatch("supplied axes do not agree with the size of the array (got size $lA for the array and $lI for the indices")) | |
lA = size(A) | |
lI = map(length, inds) | |
lA == lI || throw_dimerr(lA, lI) | |
$FT(A, map(_offset, axes(A), inds)) | |
end |
Perhaps some of the other methods need to be altered too to get this to be consistent: julia> reshape(OffsetArray(3:4, 2), :) # preserves offset
3:4 with indices 3:4
julia> reshape(OffsetArray(3:4, 2), :, 1) # does not preserve offset
2×1 reshape(::UnitRange{Int64}, 2, 1) with eltype Int64:
3
4 |
As a placeholder for a slice,
Colon
at the k-th position also preserves the offset of theaxes(A, k)
. The default offset fork>=ndims(A)
is assumed to be 0.The implementation is based on https://github.com/JuliaLang/julia/blob/d29126a43ee289fc5ab8fcb3dc0e03f514605950/base/reshapedarray.jl#L119-L137
closes #220
cc: @jishnub