From 10024556ee718f4d4198d496bb9d33ebe0b4998f Mon Sep 17 00:00:00 2001 From: jishnub Date: Sat, 29 May 2021 21:15:27 +0400 Subject: [PATCH 1/4] preserve axes in permutedims for AbstractVectors --- src/OffsetArrays.jl | 4 ++++ test/runtests.jl | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/src/OffsetArrays.jl b/src/OffsetArrays.jl index eecb2333..ff8edb9b 100644 --- a/src/OffsetArrays.jl +++ b/src/OffsetArrays.jl @@ -364,6 +364,10 @@ Base.reshape(A::OffsetVector, ::Colon) = A Base.reshape(A::OffsetArray, inds::Union{Int,Colon}...) = reshape(parent(A), inds) Base.reshape(A::OffsetArray, inds::Tuple{Vararg{Union{Int,Colon}}}) = reshape(parent(A), inds) +# permutedims in Base does not preserve axes, and can not be fixed in a non-breaking way +# This is a stopgap solution +Base.permutedims(v::OffsetVector) = reshape(v, (1, axes(v, 1))) + Base.fill(v, inds::NTuple{N, Union{Integer, AbstractUnitRange}}) where {N} = fill!(similar(Array{typeof(v)}, inds), v) Base.zeros(::Type{T}, inds::NTuple{N, Union{Integer, AbstractUnitRange}}) where {T, N} = diff --git a/test/runtests.jl b/test/runtests.jl index 2ee6e854..31c2dfd0 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1769,6 +1769,15 @@ end @test first(A) == 5 end +@testset "permutedims" begin + a = OffsetArray(1:2, 2:3) + @test permutedims(a) == reshape(1:2, 1, 2:3) + a = OffsetArray([10,11], Base.OneTo(2)) + @test permutedims(a) == reshape(10:11, 1, 1:2) + a = OffsetArray(SVector{2}(1,2), 3:4) + @test permutedims(a) == reshape(1:2, 1, 3:4) +end + @testset "Indexing with OffsetArray axes" begin A0 = [1 3; 2 4] From c312eacdd2f2b174986f033e31ca383818996617 Mon Sep 17 00:00:00 2001 From: jishnub Date: Sun, 30 May 2021 10:41:26 +0400 Subject: [PATCH 2/4] fix stackoverflow in reshape --- src/utils.jl | 2 +- test/runtests.jl | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/utils.jl b/src/utils.jl index f2bf3dcc..e894cd67 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -4,7 +4,7 @@ _indexoffset(r::AbstractRange) = first(r) - 1 _indexoffset(i::Integer) = 0 _indexoffset(i::Colon) = 0 _indexlength(r::AbstractRange) = length(r) -_indexlength(i::Integer) = i +_indexlength(i::Integer) = Int(i) _indexlength(i::Colon) = Colon() _strip_IdOffsetRange(r::IdOffsetRange) = parent(r) diff --git a/test/runtests.jl b/test/runtests.jl index 31c2dfd0..07c09f87 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1767,6 +1767,13 @@ end Arsc = reshape(A, :, 1) Arsc[1,1] = 5 @test first(A) == 5 + + @testset "issue #235" begin + Vec64 = zeros(6) + ind_a_64 = 3 + ind_a_32 =Int32.(ind_a_64) + @test reshape(Vec64, ind_a_32, :) == reshape(Vec64, ind_a_64, :) + end end @testset "permutedims" begin From 8409f01b4f1f88b5f50d4c44de0d459b7977cb03 Mon Sep 17 00:00:00 2001 From: jishnub Date: Sun, 30 May 2021 11:01:44 +0400 Subject: [PATCH 3/4] conditionally pop parent array in reshape --- src/OffsetArrays.jl | 3 ++- src/utils.jl | 8 ++++++++ test/runtests.jl | 12 ++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/OffsetArrays.jl b/src/OffsetArrays.jl index ff8edb9b..54b697a4 100644 --- a/src/OffsetArrays.jl +++ b/src/OffsetArrays.jl @@ -349,7 +349,8 @@ _similar_axes_or_length(AT, ax::I, ::I) where {I} = similar(AT, map(_indexlength 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)) + O = OffsetArray(AR, map(_offset, axes(AR), inds)) + return _popreshape(O, axes(AR), _filterreshapeinds(inds)) end # Reshaping OffsetArrays can "pop" the original OffsetArray wrapper and return diff --git a/src/utils.jl b/src/utils.jl index e894cd67..2adc3538 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -102,3 +102,11 @@ end _of_eltype(::Type{T}, M::AbstractArray{T}) where {T} = M _of_eltype(T, M::AbstractArray) = map(T, M) + +# filter the arguments to reshape to check if there are any ranges +# If not, we may pop the parent array +_filterreshapeinds(t::Tuple{AbstractUnitRange, Vararg{Any}}) = t +_filterreshapeinds(t::Tuple) = _filterreshapeinds(tail(t)) +_filterreshapeinds(t::Tuple{}) = t +_popreshape(A::AbstractArray, ax::Tuple{Vararg{Base.OneTo}}, inds::Tuple{}) = no_offset_view(A) +_popreshape(A::AbstractArray, ax, inds) = A diff --git a/test/runtests.jl b/test/runtests.jl index 07c09f87..ffcf3663 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1774,6 +1774,18 @@ end ind_a_32 =Int32.(ind_a_64) @test reshape(Vec64, ind_a_32, :) == reshape(Vec64, ind_a_64, :) end + + R = reshape(zeros(6), 2, :) + @test R isa Matrix + @test axes(R) == (1:2, 1:3) + R = reshape(zeros(6,1), 2, :) + @test R isa Matrix + @test axes(R) == (1:2, 1:3) + + R = reshape(zeros(6), 1:2, :) + @test axes(R) == (1:2, 1:3) + R = reshape(zeros(6,1), 1:2, :) + @test axes(R) == (1:2, 1:3) end @testset "permutedims" begin From 986fc0a4a0ba888671b622d0ff2509b4f8dbf2b1 Mon Sep 17 00:00:00 2001 From: jishnub Date: Sun, 30 May 2021 11:36:22 +0400 Subject: [PATCH 4/4] add test for 2D permutedims --- test/runtests.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index ffcf3663..d66dadc7 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1795,6 +1795,11 @@ end @test permutedims(a) == reshape(10:11, 1, 1:2) a = OffsetArray(SVector{2}(1,2), 3:4) @test permutedims(a) == reshape(1:2, 1, 3:4) + + # check that the 2D case is unaffected + a = OffsetArray(reshape(1:2, 1, 2), 2:2, 4:5) + b = permutedims(a) + @test a[2,:] == b[:,2] end @testset "Indexing with OffsetArray axes" begin