Skip to content

Commit f35032b

Browse files
authored
Preserve axes in permutedims for AbstractVectors (#243)
* preserve axes in permutedims for AbstractVectors * fix stackoverflow in reshape * conditionally pop parent array in reshape * add test for 2D permutedims
1 parent 41823a0 commit f35032b

File tree

3 files changed

+48
-2
lines changed

3 files changed

+48
-2
lines changed

src/OffsetArrays.jl

+6-1
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,8 @@ _similar_axes_or_length(AT, ax::I, ::I) where {I} = similar(AT, map(_indexlength
349349
Base.reshape(A::AbstractArray, inds::OffsetAxis...) = reshape(A, inds)
350350
function Base.reshape(A::AbstractArray, inds::Tuple{OffsetAxis,Vararg{OffsetAxis}})
351351
AR = reshape(A, map(_indexlength, inds))
352-
return OffsetArray(AR, map(_offset, axes(AR), inds))
352+
O = OffsetArray(AR, map(_offset, axes(AR), inds))
353+
return _popreshape(O, axes(AR), _filterreshapeinds(inds))
353354
end
354355

355356
# Reshaping OffsetArrays can "pop" the original OffsetArray wrapper and return
@@ -364,6 +365,10 @@ Base.reshape(A::OffsetVector, ::Colon) = A
364365
Base.reshape(A::OffsetArray, inds::Union{Int,Colon}...) = reshape(parent(A), inds)
365366
Base.reshape(A::OffsetArray, inds::Tuple{Vararg{Union{Int,Colon}}}) = reshape(parent(A), inds)
366367

368+
# permutedims in Base does not preserve axes, and can not be fixed in a non-breaking way
369+
# This is a stopgap solution
370+
Base.permutedims(v::OffsetVector) = reshape(v, (1, axes(v, 1)))
371+
367372
Base.fill(v, inds::NTuple{N, Union{Integer, AbstractUnitRange}}) where {N} =
368373
fill!(similar(Array{typeof(v)}, inds), v)
369374
Base.zeros(::Type{T}, inds::NTuple{N, Union{Integer, AbstractUnitRange}}) where {T, N} =

src/utils.jl

+9-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ _indexoffset(r::AbstractRange) = first(r) - 1
44
_indexoffset(i::Integer) = 0
55
_indexoffset(i::Colon) = 0
66
_indexlength(r::AbstractRange) = length(r)
7-
_indexlength(i::Integer) = i
7+
_indexlength(i::Integer) = Int(i)
88
_indexlength(i::Colon) = Colon()
99

1010
_strip_IdOffsetRange(r::IdOffsetRange) = parent(r)
@@ -102,3 +102,11 @@ end
102102

103103
_of_eltype(::Type{T}, M::AbstractArray{T}) where {T} = M
104104
_of_eltype(T, M::AbstractArray) = map(T, M)
105+
106+
# filter the arguments to reshape to check if there are any ranges
107+
# If not, we may pop the parent array
108+
_filterreshapeinds(t::Tuple{AbstractUnitRange, Vararg{Any}}) = t
109+
_filterreshapeinds(t::Tuple) = _filterreshapeinds(tail(t))
110+
_filterreshapeinds(t::Tuple{}) = t
111+
_popreshape(A::AbstractArray, ax::Tuple{Vararg{Base.OneTo}}, inds::Tuple{}) = no_offset_view(A)
112+
_popreshape(A::AbstractArray, ax, inds) = A

test/runtests.jl

+33
Original file line numberDiff line numberDiff line change
@@ -1767,6 +1767,39 @@ end
17671767
Arsc = reshape(A, :, 1)
17681768
Arsc[1,1] = 5
17691769
@test first(A) == 5
1770+
1771+
@testset "issue #235" begin
1772+
Vec64 = zeros(6)
1773+
ind_a_64 = 3
1774+
ind_a_32 =Int32.(ind_a_64)
1775+
@test reshape(Vec64, ind_a_32, :) == reshape(Vec64, ind_a_64, :)
1776+
end
1777+
1778+
R = reshape(zeros(6), 2, :)
1779+
@test R isa Matrix
1780+
@test axes(R) == (1:2, 1:3)
1781+
R = reshape(zeros(6,1), 2, :)
1782+
@test R isa Matrix
1783+
@test axes(R) == (1:2, 1:3)
1784+
1785+
R = reshape(zeros(6), 1:2, :)
1786+
@test axes(R) == (1:2, 1:3)
1787+
R = reshape(zeros(6,1), 1:2, :)
1788+
@test axes(R) == (1:2, 1:3)
1789+
end
1790+
1791+
@testset "permutedims" begin
1792+
a = OffsetArray(1:2, 2:3)
1793+
@test permutedims(a) == reshape(1:2, 1, 2:3)
1794+
a = OffsetArray([10,11], Base.OneTo(2))
1795+
@test permutedims(a) == reshape(10:11, 1, 1:2)
1796+
a = OffsetArray(SVector{2}(1,2), 3:4)
1797+
@test permutedims(a) == reshape(1:2, 1, 3:4)
1798+
1799+
# check that the 2D case is unaffected
1800+
a = OffsetArray(reshape(1:2, 1, 2), 2:2, 4:5)
1801+
b = permutedims(a)
1802+
@test a[2,:] == b[:,2]
17701803
end
17711804

17721805
@testset "Indexing with OffsetArray axes" begin

0 commit comments

Comments
 (0)