mirror of
https://github.com/JuliaLang/julia.git
synced 2026-06-02 01:32:59 +08:00
Progress towards issue #56922 by @LilithHafner. Turns out I didn't find many uses of `Array{T, 1}` or `Array{T, 2}` in `doc` or `base` that were "clearly" in need of being updated to `Vector` or `Matrix`. There are a bunch that can't be changed because they occur before `Vector` or `Matrix` are even defined. There are a couple borderline cases, and I may have overlooked some, but most I looked at felt like "I could change it to Vector or Matrix but I think there is a didactical point in using `Array` here. E.g. in the definition of `struct BitVector <: AbstractArray{Bool, 1}; end` I think the context makes it desirable to leave it at that instead of changing it to `Vector` -- but I admit this is subjective. There was more in `test`, though that's perhaps less important. All in all I think we could close #56922
930 lines
32 KiB
Julia
930 lines
32 KiB
Julia
# This file is a part of Julia. License is MIT: https://julialang.org/license
|
||
|
||
isdefined(Main, :OffsetArrays) || @eval Main include("testhelpers/OffsetArrays.jl")
|
||
using .Main.OffsetArrays
|
||
import .Main.OffsetArrays: IdOffsetRange
|
||
using Random
|
||
using LinearAlgebra
|
||
using Base: IdentityUnitRange
|
||
using Test
|
||
|
||
if !isdefined(@__MODULE__, :T24Linear)
|
||
include("testhelpers/arrayindexingtypes.jl")
|
||
end
|
||
|
||
let
|
||
# Basics
|
||
v0 = rand(4)
|
||
v = OffsetArray(v0, (-3,))
|
||
h = OffsetArray([-1,1,-2,2,0], (-3,))
|
||
@test axes(v) === (OffsetArrays.IdOffsetRange(Base.OneTo(4), -3),)
|
||
@test size(v) == (4,)
|
||
@test size(v, 1) == 4
|
||
@test_throws DimensionMismatch Array(v)
|
||
|
||
A0 = [1 3; 2 4]
|
||
A = OffsetArray(A0, (-1,2)) # IndexLinear
|
||
S = OffsetArray(view(A0, 1:2, 1:2), (-1,2)) # IndexCartesian
|
||
@test axes(A) === axes(S) === (OffsetArrays.IdOffsetRange(Base.OneTo(2), -1), OffsetArrays.IdOffsetRange(Base.OneTo(2), 2))
|
||
@test size(A) == (2,2)
|
||
@test size(A, 1) == 2
|
||
|
||
# Scalar indexing
|
||
@test A[0,3] == A[1] == A[0,3,1] == S[0,3] == S[1] == S[0,3,1] == 1
|
||
@test A[1,3] == A[2] == A[1,3,1] == S[1,3] == S[2] == S[1,3,1] == 2
|
||
@test A[0,4] == A[3] == A[0,4,1] == S[0,4] == S[3] == S[0,4,1] == 3
|
||
@test A[1,4] == A[4] == A[1,4,1] == S[1,4] == S[4] == S[1,4,1] == 4
|
||
@test_throws BoundsError A[1,1]
|
||
@test_throws BoundsError S[1,1]
|
||
@test_throws BoundsError A[0,3,2]
|
||
@test_throws BoundsError S[0,3,2]
|
||
# partial indexing
|
||
S3 = OffsetArray(view(reshape(Vector(1:4*3*1), 4, 3, 1), 1:3, 1:2, :), (-1,-2,1))
|
||
@test S3[1,-1] == 2
|
||
@test S3[1,0] == 6
|
||
@test_throws BoundsError S3[1,1]
|
||
@test_throws BoundsError S3[1,-2]
|
||
S4 = OffsetArray(view(reshape(Vector(1:4*3*2), 4, 3, 2), 1:3, 1:2, :), (-1,-2,1))
|
||
@test S4[1,-1,2] == 2
|
||
@test S4[1,0,2] == 6
|
||
@test_throws BoundsError S4[1,1,2]
|
||
@test_throws BoundsError S4[1,-2,2]
|
||
|
||
|
||
# Vector indexing
|
||
@test A[:, 3] == S[:, 3] == OffsetArray([1,2], (A.offsets[1],))
|
||
@test A[:, 4] == S[:, 4] == OffsetArray([3,4], (A.offsets[1],))
|
||
@test_throws BoundsError A[:, 1]
|
||
@test_throws BoundsError S[:, 1]
|
||
@test A[0, :] == S[0, :] == OffsetArray([1,3], (A.offsets[2],))
|
||
@test A[1, :] == S[1, :] == OffsetArray([2,4], (A.offsets[2],))
|
||
@test_throws BoundsError A[2, :]
|
||
@test_throws BoundsError S[2, :]
|
||
@test A[0:1, 3] == S[0:1, 3] == [1,2]
|
||
@test A[[1,0], 3] == S[[1,0], 3] == [2,1]
|
||
@test A[0, 3:4] == S[0, 3:4] == [1,3]
|
||
@test A[1, [4,3]] == S[1, [4,3]] == [4,2]
|
||
@test A[:, :] == S[:, :] == A
|
||
|
||
A_3_3 = OffsetArray(Matrix{Int}(undef, 3,3), (-2,-1))
|
||
A_3_3[:, :] = reshape(1:9, 3, 3)
|
||
for i = 1:9 @test A_3_3[i] == i end
|
||
A_3_3[-1:1, 0:2] = reshape(1:9, 3, 3)
|
||
for i = 1:9 @test A_3_3[i] == i end
|
||
A_3_3[:, :] = 1:9
|
||
for i = 1:9 @test A_3_3[i] == i end
|
||
A_3_3[-1:1, 0:2] = 1:9
|
||
for i = 1:9 @test A_3_3[i] == i end
|
||
A_3_3[:] = 1:9
|
||
for i = 1:9 @test A_3_3[i] == i end
|
||
A_3_3[1:9] = 1:9
|
||
for i = 1:9 @test A_3_3[i] == i end
|
||
|
||
# CartesianIndexing
|
||
@test A[CartesianIndex((0,3))] == S[CartesianIndex((0,3))] == 1
|
||
@test_throws BoundsError A[CartesianIndex(1,1)]
|
||
@test_throws BoundsError S[CartesianIndex(1,1)]
|
||
@test eachindex(A) == 1:4
|
||
@test eachindex(S) == CartesianIndices(axes(S)) == CartesianIndices(map(Base.IdentityUnitRange, (0:1,3:4)))
|
||
|
||
# LinearIndices
|
||
# issue 27986
|
||
let a1 = [11,12,13], a2 = [1 2; 3 4]
|
||
b1 = OffsetArray(a1, (-3,))
|
||
i1 = LinearIndices(b1)
|
||
@test i1[-2] == -2
|
||
@test_throws BoundsError i1[-3]
|
||
@test_throws BoundsError i1[1]
|
||
@test i1[-2:end] === -2:0
|
||
@test @inferred(i1[-2:0]) === -2:0
|
||
@test_throws BoundsError i1[-3:end]
|
||
@test_throws BoundsError i1[-2:1]
|
||
b2 = OffsetArray(a2, (-3,5))
|
||
i2 = LinearIndices(b2)
|
||
@test i2[3] == 3
|
||
@test_throws BoundsError i2[0]
|
||
@test_throws BoundsError i2[5]
|
||
@test @inferred(i2[2:3]) === 2:3
|
||
@test @inferred(i2[1:2:4]) === 1:2:3
|
||
@test_throws BoundsError i2[1:5]
|
||
@test_throws BoundsError i2[1:2:5]
|
||
end
|
||
|
||
# issue #37274
|
||
let a = 1:3
|
||
oa = OffsetArray(a, 0:2)
|
||
b = @view oa[0]
|
||
@test b[] == b[1] == b[1,1] == 1
|
||
@test_throws BoundsError b[0]
|
||
@test_throws BoundsError b[2]
|
||
end
|
||
|
||
# logical indexing
|
||
@test A[A .> 2] == [3,4]
|
||
@test_throws BoundsError h[trues(2)]
|
||
@test_throws BoundsError h[trues(5)]
|
||
@test h[OffsetArray(trues(5), (-3,))] == parent(h)
|
||
@test h[OffsetArray([true,false,false,true,true], (-3,))] == parent(h)[[1,4,5]]
|
||
@test A[OffsetArray([true false; false true], A.offsets)] == [1,4]
|
||
@test A[OffsetArray([true true; false true], A.offsets)] == [1,3,4]
|
||
@test_throws BoundsError A[[true true; false true]]
|
||
|
||
# begin, end
|
||
a0 = rand(2,3,4,2)
|
||
a = OffsetArray(a0, (-2,-3,4,5))
|
||
@test a[begin,end,end,begin] == a0[begin,end,end,begin] ==
|
||
a0[1,3,4,1] == a0[end-1,begin+2,begin+3,end-1]
|
||
|
||
# view
|
||
S = view(A, :, 3)
|
||
@test S == OffsetArray([1,2], (A.offsets[1],))
|
||
@test S[0] == 1
|
||
@test S[1] == 2
|
||
@test_throws BoundsError S[2]
|
||
@test axes(S) === (Base.IdentityUnitRange(OffsetArrays.IdOffsetRange(Base.OneTo(2), -1)),)
|
||
S = view(A, 0, :)
|
||
@test S == OffsetArray([1,3], (A.offsets[2],))
|
||
@test S[3] == 1
|
||
@test S[4] == 3
|
||
@test_throws BoundsError S[1]
|
||
@test axes(S) === (Base.IdentityUnitRange(OffsetArrays.IdOffsetRange(Base.OneTo(2), 2)),)
|
||
S = view(A, 0:0, 4)
|
||
@test S == [3]
|
||
@test S[1] == 3
|
||
@test_throws BoundsError S[0]
|
||
@test axes(S) === (Base.OneTo(1),)
|
||
S = view(A, 1, 3:4)
|
||
@test S == [2,4]
|
||
@test S[1] == 2
|
||
@test S[2] == 4
|
||
@test_throws BoundsError S[3]
|
||
@test axes(S) === (Base.OneTo(2),)
|
||
S = view(A, :, :)
|
||
@test S == A
|
||
@test S[0,3] == S[1] == 1
|
||
@test S[1,3] == S[2] == 2
|
||
@test S[0,4] == S[3] == 3
|
||
@test S[1,4] == S[4] == 4
|
||
@test_throws BoundsError S[1,1]
|
||
@test axes(S) === Base.IdentityUnitRange.((OffsetArrays.IdOffsetRange(Base.OneTo(2), -1), OffsetArrays.IdOffsetRange(Base.OneTo(2), 2)))
|
||
# https://github.com/JuliaArrays/OffsetArrays.jl/issues/27
|
||
g = OffsetArray(Vector(-2:3), (-3,))
|
||
gv = view(g, -1:2)
|
||
@test axes(gv, 1) === Base.OneTo(4)
|
||
@test collect(gv) == -1:2
|
||
gv = view(g, OffsetArray(-1:2, (-2,)))
|
||
@test axes(gv, 1) === OffsetArrays.IdOffsetRange(Base.OneTo(4), -2)
|
||
@test collect(gv) == -1:2
|
||
gv = view(g, OffsetArray(-1:2, (-1,)))
|
||
@test axes(gv, 1) === OffsetArrays.IdOffsetRange(Base.OneTo(4), -1)
|
||
@test collect(gv) == -1:2
|
||
|
||
# iteration
|
||
for (a,d) in zip(A, A0)
|
||
@test a == d
|
||
end
|
||
|
||
|
||
# show
|
||
io = IOBuffer()
|
||
show(io, v)
|
||
str = String(take!(io))
|
||
show(io, v0)
|
||
@test str == String(take!(io))
|
||
show(io, A)
|
||
str = String(take!(io))
|
||
@test str == "[1 3; 2 4]"
|
||
show(io, S)
|
||
str = String(take!(io))
|
||
@test str == "[1 3; 2 4]"
|
||
show(io, MIME("text/plain"), A)
|
||
strs = split(strip(String(take!(io))), '\n')
|
||
@test strs[2] == " 1 3"
|
||
@test strs[3] == " 2 4"
|
||
v = OffsetArray(rand(3), (-2,))
|
||
show(io, v)
|
||
str = String(take!(io))
|
||
show(io, parent(v))
|
||
@test str == String(take!(io))
|
||
smry = summary(v)
|
||
@test occursin("OffsetArray(::Vector{Float64", smry)
|
||
@test occursin("with indices -1:1", smry)
|
||
function cmp_showf(printfunc, io, A; options = ())
|
||
ioc = IOContext(io, :limit => true, :compact => true, options...)
|
||
printfunc(ioc, A)
|
||
str1 = String(take!(io))
|
||
printfunc(ioc, parent(A))
|
||
str2 = String(take!(io))
|
||
@test str1 == str2
|
||
end
|
||
cmp_showf(Base.print_matrix, io, OffsetArray(rand(5,5), (10,-9))) # rows&cols fit
|
||
cmp_showf(Base.print_matrix, io, OffsetArray(rand(10^3,5), (10,-9))) # columns fit
|
||
cmp_showf(Base.print_matrix, io, OffsetArray(rand(5,10^3), (10,-9))) # rows fit
|
||
cmp_showf(Base.print_matrix, io, OffsetArray(rand(10^3,10^3), (10,-9))) # neither fits
|
||
cmp_showf(Base.print_matrix, io, OffsetArray(reshape(range(-0.212121212121, stop=2/11, length=3*29), 3, 29), (-2, -15)); options=(:displaysize=>(53,210),))
|
||
cmp_showf(show, io, OffsetArray(collect(1:100), (100,))) # issue #31641
|
||
|
||
targets1 = ["0-dimensional OffsetArray(::Array{Float64, 0}) with eltype Float64:\n1.0",
|
||
"1-element OffsetArray(::Vector{Float64}, 2:2) with eltype Float64 with indices 2:2:\n 1.0",
|
||
"1×1 OffsetArray(::Matrix{Float64}, 2:2, 3:3) with eltype Float64 with indices 2:2×3:3:\n 1.0",
|
||
"1×1×1 OffsetArray(::Array{Float64, 3}, 2:2, 3:3, 4:4) with eltype Float64 with indices 2:2×3:3×4:4:\n[:, :, 4] =\n 1.0",
|
||
"1×1×1×1 OffsetArray(::Array{Float64, 4}, 2:2, 3:3, 4:4, 5:5) with eltype Float64 with indices 2:2×3:3×4:4×5:5:\n[:, :, 4, 5] =\n 1.0"]
|
||
targets2 = ["(fill(1.0), fill(1.0))",
|
||
"([1.0], [1.0])",
|
||
"([1.0;;], [1.0;;])",
|
||
"([1.0;;;], [1.0;;;])",
|
||
"([1.0;;;;], [1.0;;;;])"]
|
||
@testset "printing of OffsetArray with n=$n" for n = 0:4
|
||
a = OffsetArray(fill(1.,ntuple(Returns(1),n)), ntuple(identity,n))
|
||
show(IOContext(io, :limit => true), MIME("text/plain"), a)
|
||
@test String(take!(io)) == targets1[n+1]
|
||
show(IOContext(io, :limit => true), MIME("text/plain"), (a,a))
|
||
@test String(take!(io)) == targets2[n+1]
|
||
end
|
||
P = OffsetArray(rand(8,8), (1,1))
|
||
PV = view(P, 2:3, :)
|
||
@test endswith(summary(PV), "with indices Base.OneTo(2)×$(repr(axes(P,2)))")
|
||
|
||
# Similar
|
||
B = similar(A, Float32)
|
||
@test isa(B, OffsetMatrix{Float32})
|
||
@test axes(B) === axes(A)
|
||
B = similar(A, (3,4))
|
||
@test isa(B, Matrix{Int})
|
||
@test size(B) == (3,4)
|
||
@test axes(B) === (Base.OneTo(3), Base.OneTo(4))
|
||
B = similar(A, (-3:3,1:4))
|
||
@test isa(B, OffsetMatrix{Int})
|
||
@test axes(B) === (OffsetArrays.IdOffsetRange(Base.OneTo(7), -4), OffsetArrays.IdOffsetRange(Base.OneTo(4)))
|
||
B = similar(parent(A), (-3:3,1:4))
|
||
@test isa(B, OffsetMatrix{Int})
|
||
@test axes(B) === (OffsetArrays.IdOffsetRange(Base.OneTo(7), -4), OffsetArrays.IdOffsetRange(Base.OneTo(4)))
|
||
|
||
# Indexing with OffsetArray indices
|
||
i1 = OffsetArray([2,1], (-5,))
|
||
i1 = OffsetArray([2,1], -5)
|
||
b = A0[i1, 1]
|
||
@test axes(b) === (OffsetArrays.IdOffsetRange(Base.OneTo(2), -5),)
|
||
@test b[-4] == 2
|
||
@test b[-3] == 1
|
||
b = A0[1,i1]
|
||
@test axes(b) === (OffsetArrays.IdOffsetRange(Base.OneTo(2), -5),)
|
||
@test b[-4] == 3
|
||
@test b[-3] == 1
|
||
v = view(A0, i1, 1)
|
||
@test axes(v) === (OffsetArrays.IdOffsetRange(Base.OneTo(2), -5),)
|
||
v = view(A0, 1:1, i1)
|
||
@test axes(v) === (Base.OneTo(1), OffsetArrays.IdOffsetRange(Base.OneTo(2), -5))
|
||
|
||
# copyto! and fill!
|
||
a = OffsetArray{Int}(undef, (-3:-1,))
|
||
fill!(a, -1)
|
||
copyto!(a, (1,2)) # non-array iterables
|
||
@test a[-3] == 1
|
||
@test a[-2] == 2
|
||
@test a[-1] == -1
|
||
fill!(a, -1)
|
||
copyto!(a, -2, (1,2))
|
||
@test a[-3] == -1
|
||
@test a[-2] == 1
|
||
@test a[-1] == 2
|
||
@test_throws BoundsError copyto!(a, 1, (1,2))
|
||
fill!(a, -1)
|
||
copyto!(a, -2, (1,2,3), 2)
|
||
@test a[-3] == -1
|
||
@test a[-2] == 2
|
||
@test a[-1] == 3
|
||
@test_throws BoundsError copyto!(a, -2, (1,2,3), 1)
|
||
fill!(a, -1)
|
||
copyto!(a, -2, (1,2,3), 1, 2)
|
||
@test a[-3] == -1
|
||
@test a[-2] == 1
|
||
@test a[-1] == 2
|
||
|
||
b = 1:2 # copy between AbstractArrays
|
||
bo = OffsetArray(1:2, (-3,))
|
||
copyto!(a, b) # no BoundsError, see #34049
|
||
@test a[-3] == 1
|
||
@test a[-2] == 2
|
||
@test a[-1] == 2
|
||
fill!(a, -1)
|
||
copyto!(a, bo)
|
||
@test a[-3] == 1
|
||
@test a[-2] == 2
|
||
@test a[-1] == -1
|
||
fill!(a, -1)
|
||
copyto!(a, -2, bo)
|
||
@test a[-3] == -1
|
||
@test a[-2] == 1
|
||
@test a[-1] == 2
|
||
@test_throws BoundsError copyto!(a, -4, bo)
|
||
@test_throws BoundsError copyto!(a, -1, bo)
|
||
fill!(a, -1)
|
||
copyto!(a, -3, b, 2)
|
||
@test a[-3] == 2
|
||
@test a[-2] == a[-1] == -1
|
||
@test_throws BoundsError copyto!(a, -3, b, 1, 4)
|
||
am = OffsetArray{Int}(undef, (1:1, 7:9)) # for testing linear indexing
|
||
fill!(am, -1)
|
||
copyto!(am, b)
|
||
@test am[1] == 1
|
||
@test am[2] == 2
|
||
@test am[3] == -1
|
||
@test am[1,7] == 1
|
||
@test am[1,8] == 2
|
||
@test am[1,9] == -1
|
||
|
||
# map
|
||
dest = similar(am)
|
||
map!(+, dest, am, am)
|
||
@test dest[1,7] == 2
|
||
@test dest[1,8] == 4
|
||
@test dest[1,9] == -2
|
||
|
||
am = map(identity, a)
|
||
@test isa(am, OffsetArray)
|
||
@test am == a
|
||
|
||
# https://github.com/JuliaArrays/OffsetArrays.jl/issues/106
|
||
@test isequal(map(!, OffsetArray([true,missing],2)), OffsetArray([false, missing], 2))
|
||
@test isequal(map(!, OffsetArray([true missing; false true], 2, -1)), OffsetArray([false missing; true false], 2, -1))
|
||
P = view([true missing; false true; true false], 1:2:3, :)
|
||
@test IndexStyle(P) === IndexCartesian()
|
||
@test isequal(map(!, OffsetArray(P, 2, -1)), OffsetArray(map(!, P), 2, -1))
|
||
P = TSlow([true missing; false true])
|
||
@test IndexStyle(P) === IndexCartesian()
|
||
@test isequal(map(!, OffsetArray(P, 2, -1)), OffsetArray(map(!, P), 2, -1))
|
||
|
||
# dropdims
|
||
a0 = rand(1,1,8,8,1)
|
||
a = OffsetArray(a0, (-1,2,3,4,5))
|
||
@test @inferred(dropdims(a, dims=1)) == @inferred(dropdims(a, dims=(1,))) == OffsetArray(reshape(a, (1,8,8,1)), (2,3,4,5))
|
||
@test @inferred(dropdims(a, dims=5)) == @inferred(dropdims(a, dims=(5,))) == OffsetArray(reshape(a, (1,1,8,8)), (-1,2,3,4))
|
||
@test @inferred(dropdims(a, dims=(1,5))) == dropdims(a, dims=(5,1)) == OffsetArray(reshape(a, (1,8,8)), (2,3,4))
|
||
@test @inferred(dropdims(a, dims=(1,2,5))) == dropdims(a, dims=(5,2,1)) == OffsetArray(reshape(a, (8,8)), (3,4))
|
||
@test_throws ArgumentError dropdims(a, dims=0)
|
||
@test_throws ArgumentError dropdims(a, dims=(1,1))
|
||
@test_throws ArgumentError dropdims(a, dims=(1,2,1))
|
||
@test_throws ArgumentError dropdims(a, dims=(1,1,2))
|
||
@test_throws ArgumentError dropdims(a, dims=3)
|
||
@test_throws ArgumentError dropdims(a, dims=4)
|
||
@test_throws ArgumentError dropdims(a, dims=6)
|
||
|
||
# push!
|
||
v = OffsetArray(rand(4), (-3,))
|
||
v2 = copy(v)
|
||
@test push!(v2, 1) === v2
|
||
@test v2[axes(v, 1)] == v
|
||
@test v2[end] == 1
|
||
@test v2[begin] == v[begin] == v[-2]
|
||
v2 = copy(v)
|
||
@test push!(v2, 2, 1) === v2
|
||
@test v2[axes(v, 1)] == v
|
||
@test v2[end-1] == 2
|
||
@test v2[end] == 1
|
||
|
||
# push!(v::AbstractVector, x...)
|
||
v2 = copy(v)
|
||
@test @invoke(push!(v2::AbstractVector, 3)) === v2
|
||
@test v2[axes(v,1)] == v
|
||
@test v2[end] == 3
|
||
@test v2[begin] == v[begin] == v[-2]
|
||
v2 = copy(v)
|
||
@test @invoke(push!(v2::AbstractVector, 5, 6)) == v2
|
||
@test v2[axes(v,1)] == v
|
||
@test v2[end-1] == 5
|
||
@test v2[end] == 6
|
||
|
||
# append! from array
|
||
v2 = copy(v)
|
||
@test append!(v2, [2, 1]) === v2
|
||
@test v2[axes(v, 1)] == v
|
||
@test v2[lastindex(v)+1:end] == [2, 1]
|
||
# append! from HasLength iterator
|
||
v2 = copy(v)
|
||
@test append!(v2, (v for v in [2, 1])) === v2
|
||
@test v2[axes(v, 1)] == v
|
||
@test v2[lastindex(v)+1:end] == [2, 1]
|
||
# append! from SizeUnknown iterator
|
||
v2 = copy(v)
|
||
@test append!(v2, (v for v in [2, 1] if true)) === v2
|
||
@test v2[axes(v, 1)] == v
|
||
@test v2[lastindex(v)+1:end] == [2, 1]
|
||
|
||
# append!(::AbstractVector, ...)
|
||
# append! from array
|
||
v2 = copy(v)
|
||
@test @invoke(append!(v2::AbstractVector, [2, 1]::Any)) === v2
|
||
@test v2[axes(v, 1)] == v
|
||
@test v2[lastindex(v)+1:end] == [2, 1]
|
||
# append! from HasLength iterator
|
||
v2 = copy(v)
|
||
@test @invoke(append!(v2::AbstractVector, (v for v in [2, 1])::Any)) === v2
|
||
@test v2[axes(v, 1)] == v
|
||
@test v2[lastindex(v)+1:end] == [2, 1]
|
||
# append! from SizeUnknown iterator
|
||
v2 = copy(v)
|
||
@test @invoke(append!(v2::AbstractVector, (v for v in [2, 1] if true)::Any)) === v2
|
||
@test v2[axes(v, 1)] == v
|
||
@test v2[lastindex(v)+1:end] == [2, 1]
|
||
|
||
# other functions
|
||
v = OffsetArray(v0, (-3,))
|
||
@test lastindex(v) == 1
|
||
@test v ≈ v
|
||
@test (@inferred axes(v')[1]) === OffsetArrays.IdOffsetRange(Base.OneTo(1))
|
||
@test (@inferred axes(v')[2]) === OffsetArrays.IdOffsetRange(Base.OneTo(4), -3)
|
||
@test parent(v) == collect(v)
|
||
rv = reverse(v)
|
||
@test axes(rv) == axes(v)
|
||
@test rv[1] == v[-2]
|
||
@test rv[0] == v[-1]
|
||
@test rv[-1] == v[0]
|
||
@test rv[-2] == v[1]
|
||
cv = copy(v)
|
||
@test reverse!(cv) == rv
|
||
|
||
@testset "reverse! (issue #45870)" begin
|
||
@testset for n in [4,5]
|
||
offset = typemax(Int)-n
|
||
vo = OffsetArray([1:n;], offset)
|
||
vo2 = OffsetArray([1:n;], offset)
|
||
@test reverse!(vo) == OffsetArray(n:-1:1, offset)
|
||
@test reverse!(vo) == vo2
|
||
@test_throws BoundsError reverse!(vo, firstindex(vo)-1, firstindex(vo))
|
||
@test reverse!(vo, firstindex(vo), firstindex(vo)-1) == vo2
|
||
@test reverse!(vo, firstindex(vo), firstindex(vo)) == vo2
|
||
@test reverse!(vo, lastindex(vo), lastindex(vo)) == vo2
|
||
@test reverse!(vo, lastindex(vo), lastindex(vo)+1) == vo2 # overflow in stop
|
||
@test reverse!(vo, firstindex(vo)+1) == OffsetArray([1;n:-1:2], offset)
|
||
@test reverse!(vo2, firstindex(vo)+1, lastindex(vo)-1) == OffsetArray([1;n-1:-1:2;n], offset)
|
||
end
|
||
end
|
||
|
||
A = OffsetArray(rand(4,4), (-3,5))
|
||
@test lastindex(A) == 16
|
||
@test lastindex(A, 1) == 1
|
||
@test lastindex(A, 2) == 9
|
||
@test A ≈ A
|
||
@test axes(A') === (OffsetArrays.IdOffsetRange(Base.OneTo(4), 5), OffsetArrays.IdOffsetRange(Base.OneTo(4), -3))
|
||
@test parent(copy(A')) == copy(parent(A)')
|
||
@test collect(A) == parent(A)
|
||
@test maximum(A) == maximum(parent(A))
|
||
@test minimum(A) == minimum(parent(A))
|
||
@test extrema(A) == extrema(parent(A))
|
||
@test maximum(A, dims=1) == OffsetArray(maximum(parent(A), dims=1), A.offsets)
|
||
@test maximum(A, dims=2) == OffsetArray(maximum(parent(A), dims=2), A.offsets)
|
||
@test maximum(A, dims=1:2) == OffsetArray(maximum(parent(A), dims=1:2), A.offsets)
|
||
C = similar(A)
|
||
cumsum!(C, A, dims=1)
|
||
@test parent(C) == cumsum(parent(A), dims=1)
|
||
@test parent(cumsum(A, dims=1)) == cumsum(parent(A), dims=1)
|
||
cumsum!(C, A, dims=2)
|
||
@test parent(C) == cumsum(parent(A), dims=2)
|
||
R = similar(A, (1:1, 6:9))
|
||
maximum!(R, A)
|
||
@test parent(R) == maximum(parent(A), dims=1)
|
||
R = similar(A, (-2:1, 1:1))
|
||
maximum!(R, A)
|
||
@test parent(R) == maximum(parent(A), dims=2)
|
||
amin, iamin = findmin(A)
|
||
pmin, ipmin = findmin(parent(A))
|
||
@test amin == pmin
|
||
@test A[iamin] == amin
|
||
@test amin == parent(A)[ipmin]
|
||
amax, iamax = findmax(A)
|
||
pmax, ipmax = findmax(parent(A))
|
||
@test amax == pmax
|
||
@test A[iamax] == amax
|
||
@test amax == parent(A)[ipmax]
|
||
z = OffsetArray([0 0; 2 0; 0 0; 0 0], (-3,-1))
|
||
I = findall(!iszero, z)
|
||
@test I == [CartesianIndex(-1, 0)]
|
||
@test findall(!iszero,h) == [-2:1;]
|
||
@test findall(x->x>0, h) == [-1,1]
|
||
@test findall(x->x<0, h) == [-2,0]
|
||
@test findall(x->x==0, h) == [2]
|
||
@test sum(A_3_3) == 45
|
||
@test sum(x->2x, A_3_3) == 90
|
||
@test sum(A_3_3, dims=1) == OffsetArray([6 15 24], A_3_3.offsets)
|
||
@test sum(A_3_3, dims=2) == OffsetArray(reshape([12,15,18],(3,1)), A_3_3.offsets)
|
||
@test sum(OffsetArray(fill(1,3000), -1000)) == 3000
|
||
|
||
# https://github.com/JuliaArrays/OffsetArrays.jl/issues/92
|
||
A92 = OffsetArray(reshape(1:27, 3, 3, 3), -2, -2, -2)
|
||
B92 = view(A92, :, :, -1:0)
|
||
@test axes(B92) == (-1:1, -1:1, 1:2)
|
||
@test sum(B92, dims=(2,3)) == OffsetArray(reshape([51,57,63], Val(3)), -2, -2, 0)
|
||
B92 = view(A92, :, :, Base.IdentityUnitRange(-1:0))
|
||
@test sum(B92, dims=(2,3)) == OffsetArray(reshape([51,57,63], Val(3)), -2, -2, -2)
|
||
|
||
@test norm(v) ≈ norm(parent(v))
|
||
@test norm(A) ≈ norm(parent(A))
|
||
@test dot(v, v) ≈ dot(v0, v0)
|
||
|
||
# Prior to its removal from Base, cumsum_kbn was used here. To achieve the same level of
|
||
# accuracy in the tests, we need to use BigFloats with enlarged precision.
|
||
@testset "high-precision array reduction" begin
|
||
setprecision(BigFloat, 500) do
|
||
v = OffsetArray(BigFloat[1,1e100,1,-1e100], (-3,)) .* 1000
|
||
v2 = OffsetArray(BigFloat[1,-1e100,1,1e100], ( 5,)) .* 1000
|
||
@test isa(v, OffsetArray)
|
||
cv = OffsetArray(BigFloat[1, 1e100, 1e100,2], (-3,)) .* 1000
|
||
cv2 = OffsetArray(BigFloat[1,-1e100,-1e100,2], ( 5,)) .* 1000
|
||
@test cumsum(v) ≈ cv
|
||
@test cumsum(v2) ≈ cv2
|
||
@test sum(v) ≈ sum(parent(v))
|
||
end
|
||
end
|
||
|
||
amin, amax = extrema(parent(A))
|
||
@test clamp.(A, (amax+amin)/2, amax).parent == clamp.(parent(A), (amax+amin)/2, amax)
|
||
|
||
@test unique(A, dims=1) == OffsetArray(parent(A), 0, first(axes(A, 2)) - 1)
|
||
@test unique(A, dims=2) == OffsetArray(parent(A), first(axes(A, 1)) - 1, 0)
|
||
v = OffsetArray(rand(8), (-2,))
|
||
@test sort(v) == OffsetArray(sort(parent(v)), v.offsets)
|
||
@test sortslices(A, dims=1) == OffsetArray(sortslices(parent(A), dims=1), A.offsets)
|
||
@test sortslices(A, dims=2) == OffsetArray(sortslices(parent(A), dims=2), A.offsets)
|
||
@test sort(A, dims=1) == OffsetArray(sort(parent(A), dims=1), A.offsets)
|
||
@test sort(A, dims=2) == OffsetArray(sort(parent(A), dims=2), A.offsets)
|
||
# Issue #33977
|
||
soa = OffsetArray([2,2,3], -2)
|
||
@test searchsorted(soa, 1) === -1:-2
|
||
@test searchsortedfirst(soa, 1) == -1
|
||
@test searchsortedlast(soa, 1) == -2
|
||
@test first(sort!(soa; alg=QuickSort)) == 2
|
||
@test first(sort!(soa; alg=MergeSort)) == 2
|
||
soa = OffsetArray([2,2,3], typemax(Int)-4)
|
||
@test searchsorted(soa, 1) == typemax(Int)-3:typemax(Int)-4
|
||
@test searchsortedfirst(soa, 2) == typemax(Int) - 3
|
||
@test searchsortedlast(soa, 2) == typemax(Int) - 2
|
||
@test first(sort!(soa; alg=QuickSort)) == 2
|
||
@test first(sort!(soa; alg=MergeSort)) == 2
|
||
|
||
@test mapslices(sort, A, dims=1) == OffsetArray(mapslices(sort, parent(A), dims=1), A.offsets)
|
||
@test mapslices(sort, A, dims=2) == OffsetArray(mapslices(sort, parent(A), dims=2), A.offsets)
|
||
|
||
@test rotl90(A) == OffsetArray(rotl90(parent(A)), A.offsets[[2,1]])
|
||
@test rotr90(A) == OffsetArray(rotr90(parent(A)), A.offsets[[2,1]])
|
||
@test reverse(A, dims=1) == OffsetArray(reverse(parent(A), dims=1), A.offsets)
|
||
@test reverse(A, dims=2) == OffsetArray(reverse(parent(A), dims=2), A.offsets)
|
||
@test reverse(A) == reverse!(reverse(A, dims=1), dims=2)
|
||
|
||
Aodd = OffsetArray(rand(3,5), (-3,5))
|
||
@test reverse(Aodd, dims=1) == OffsetArray(reverse(parent(Aodd), dims=1), Aodd.offsets)
|
||
@test reverse(Aodd, dims=2) == OffsetArray(reverse(parent(Aodd), dims=2), Aodd.offsets)
|
||
@test reverse(Aodd) == reverse!(reverse(Aodd, dims=1), dims=2)
|
||
|
||
@test A .+ 1 == OffsetArray(parent(A) .+ 1, A.offsets)
|
||
@test 2*A == OffsetArray(2*parent(A), A.offsets)
|
||
@test A+A == OffsetArray(parent(A)+parent(A), A.offsets)
|
||
@test A.*A == OffsetArray(parent(A).*parent(A), A.offsets)
|
||
|
||
@test circshift(A, (-1,2)) == OffsetArray(circshift(parent(A), (-1,2)), A.offsets)
|
||
|
||
src = reshape(Vector(1:16), (4,4))
|
||
dest = OffsetArray(Matrix{Int}(undef, 4,4), (-1,1))
|
||
circcopy!(dest, src)
|
||
@test parent(dest) == [8 12 16 4; 5 9 13 1; 6 10 14 2; 7 11 15 3]
|
||
@test dest[1:3,2:4] == src[1:3,2:4]
|
||
|
||
# reshape
|
||
A = OffsetArray(rand(4,4), (-3,5))
|
||
@test vec(A) == reshape(A, :) == reshape(A, 16) == reshape(A, Val(1)) == A[:] == vec(A.parent)
|
||
A = OffsetArray(view(rand(4,4), 1:4, 4:-1:1), (-3,5))
|
||
@test vec(A) == reshape(A, :) == reshape(A, 16) == reshape(A, Val(1)) == A[:] == vec(A.parent)
|
||
# issue #33614
|
||
A = OffsetArray(-1:0, (-2,))
|
||
@test reshape(A, :) === A
|
||
@test axes(similar(typeof(A),axes(A))) == axes(A)
|
||
@test eltype(similar(typeof(A),axes(A))) == eltype(A)
|
||
Arsc = reshape(A, :, 1)
|
||
Arss = reshape(A, 2, 1)
|
||
@test Arsc[1,1] == Arss[1,1] == -1
|
||
@test Arsc[2,1] == Arss[2,1] == 0
|
||
@test_throws BoundsError Arsc[0,1]
|
||
@test_throws BoundsError Arss[0,1]
|
||
A = OffsetArray([-1,0], (-2,))
|
||
Arsc = reshape(A, :, 1)
|
||
Arsc[1,1] = 5
|
||
@test first(A) == 5
|
||
|
||
# broadcast
|
||
a = [1]
|
||
b = OffsetArray(a, (0,))
|
||
@test @inferred(a .+ b) == [2]
|
||
a = OffsetArray([1, -2, 1], (-2,))
|
||
@test a .* a' == OffsetArray([ 1 -2 1;
|
||
-2 4 -2;
|
||
1 -2 1], (-2,-2))
|
||
|
||
end # let
|
||
|
||
# Check that similar throws a MethodError rather than a
|
||
# StackOverflowError if no appropriate method has been defined
|
||
# (#18107)
|
||
module SimilarUR
|
||
using Test
|
||
struct MyURange <: AbstractUnitRange{Int}
|
||
start::Int
|
||
stop::Int
|
||
end
|
||
ur = MyURange(1,3)
|
||
a = Vector{Int}(undef, 2)
|
||
|
||
function catch_exception(f, args...)
|
||
try
|
||
f(args...)
|
||
catch err
|
||
return err
|
||
end
|
||
end
|
||
# type-piracy https://github.com/JuliaArrays/OffsetArrays.jl/issues/87
|
||
@test_broken (catch_exception(similar, a, ur) isa MethodError)
|
||
@test_broken (catch_exception(similar, a, Float64, ur) isa MethodError)
|
||
@test_broken (catch_exception(similar, a, Float64, (ur,)) isa MethodError)
|
||
# @test_throws MethodError similar(a, ur)
|
||
# @test_throws MethodError similar(a, Float64, ur)
|
||
# @test_throws MethodError similar(a, Float64, (ur,))
|
||
@test_throws MethodError similar(a, (2.0,3.0))
|
||
end
|
||
|
||
@testset "Issue 28101" begin
|
||
A = OffsetArray(reshape(16:-1:1, (4, 4)), (-3,5))
|
||
@test maximum(A, dims=1) == OffsetArray(maximum(parent(A), dims=1), A.offsets)
|
||
end
|
||
|
||
@testset "in-place reductions with mismatched dimensionalities" begin
|
||
B = OffsetArray(reshape(1:24, 4, 3, 2), -5, 6, -7)
|
||
for R in (fill(0, -4:-1), fill(0, -4:-1, 7:7), fill(0, -4:-1, 7:7, -6:-6))
|
||
@test @inferred(maximum!(R, B)) == reshape(maximum(B, dims=(2,3)), axes(R)) == reshape(21:24, axes(R))
|
||
@test @allocated(maximum!(R, B)) <= 400
|
||
@test @inferred(minimum!(R, B)) == reshape(minimum(B, dims=(2,3)), axes(R)) == reshape(1:4, axes(R))
|
||
@test @allocated(minimum!(R, B)) <= 400
|
||
end
|
||
for R in (fill(0, -4:-4, 7:9), fill(0, -4:-4, 7:9, -6:-6))
|
||
@test @inferred(maximum!(R, B)) == reshape(maximum(B, dims=(1,3)), axes(R)) == reshape(16:4:24, axes(R))
|
||
@test @allocated(maximum!(R, B)) <= 400
|
||
@test @inferred(minimum!(R, B)) == reshape(minimum(B, dims=(1,3)), axes(R)) == reshape(1:4:9, axes(R))
|
||
@test @allocated(minimum!(R, B)) <= 400
|
||
end
|
||
@test_throws DimensionMismatch maximum!(fill(0, -4:-1, 7:7, -6:-6, 1:1), B)
|
||
@test_throws DimensionMismatch minimum!(fill(0, -4:-1, 7:7, -6:-6, 1:1), B)
|
||
@test_throws DimensionMismatch maximum!(fill(0, -4:-4, 7:9, -6:-6, 1:1), B)
|
||
@test_throws DimensionMismatch minimum!(fill(0, -4:-4, 7:9, -6:-6, 1:1), B)
|
||
@test_throws DimensionMismatch maximum!(fill(0, -4:-4, 7:7, -6:-5, 1:1), B)
|
||
@test_throws DimensionMismatch minimum!(fill(0, -4:-4, 7:7, -6:-5, 1:1), B)
|
||
end
|
||
|
||
@testset "first/last n elements of vector" begin
|
||
v0 = rand(6)
|
||
v = OffsetArray(v0, (-3,))
|
||
@test_throws ArgumentError first(v, -2)
|
||
@test first(v, 2) == v[begin:begin+1]
|
||
@test first(v, 100) == v0
|
||
@test first(v, 100) !== v
|
||
@test first(v, 1) == [v[begin]]
|
||
@test_throws ArgumentError last(v, -2)
|
||
@test last(v, 2) == v[end-1:end]
|
||
@test last(v, 100) == v0
|
||
@test last(v, 100) !== v
|
||
@test last(v, 1) == [v[end]]
|
||
|
||
@testset "overflow (issue #45842)" begin
|
||
a = [2,3,4]
|
||
b = OffsetArray(a, 2:4)
|
||
@test first(a, typemax(Int)) == first(b, typemax(Int))
|
||
b = OffsetArray(a, typemin(Int))
|
||
@test last(a, 100) == last(b, 100)
|
||
end
|
||
end
|
||
|
||
@testset "Resizing OffsetVectors" begin
|
||
local a = OffsetVector(rand(5),-3)
|
||
axes(a,1) == -2:2
|
||
length(a) == 5
|
||
resize!(a,3)
|
||
length(a) == 3
|
||
axes(a,1) == -2:0
|
||
@test_throws ArgumentError resize!(a,-3)
|
||
end
|
||
|
||
@testset "issue #37199: offset range indices" begin
|
||
# https://github.com/JuliaArrays/OffsetArrays.jl/issues/133
|
||
A0 = [1 3; 2 4]
|
||
A = OffsetArray(A0, (-1,2))
|
||
|
||
r = OffsetArrays.IdOffsetRange(1:2, -1)
|
||
v1 = view(A, r, 3)
|
||
@test v1[0] == 1
|
||
@test v1[1] == 2
|
||
@test axes(v1, 1) == axes(r, 1)
|
||
v2 = view(A, UnitRange(r), 3)
|
||
for (indflat, indoffset) in enumerate(r)
|
||
@test v1[indoffset] == v2[indflat]
|
||
end
|
||
|
||
r = OffsetArrays.IdOffsetRange(1:2, 2)
|
||
v1 = view(A, 1, r)
|
||
@test v1[3] == 2
|
||
@test v1[4] == 4
|
||
@test axes(v1, 1) == axes(r, 1)
|
||
v2 = view(A, 1, UnitRange(r))
|
||
for (indflat, indoffset) in enumerate(r)
|
||
@test v1[indoffset] == v2[indflat]
|
||
end
|
||
|
||
a12 = zeros(3:8, 3:4)
|
||
r = OffsetArrays.IdOffsetRange(Base.OneTo(3), 5)
|
||
a12[r, 4] .= 3
|
||
@test all(a12[r, 4] .== 3)
|
||
@test all(a12[UnitRange(r), 4] .== 3)
|
||
|
||
# https://github.com/JuliaArrays/OffsetArrays.jl/issues/100
|
||
S = view(A, axes(A)...)
|
||
@test S == A
|
||
@test S[0,3] == S[1] == 1
|
||
@test S[1,3] == S[2] == 2
|
||
@test S[0,4] == S[3] == 3
|
||
@test S[1,4] == S[4] == 4
|
||
@test_throws BoundsError S[1,1]
|
||
@test axes(S) == OffsetArrays.IdOffsetRange.((0:1, 3:4))
|
||
S = view(A, axes(A, 1), 3)
|
||
@test S == A[:, 3]
|
||
@test S[0] == 1
|
||
@test S[1] == 2
|
||
@test_throws BoundsError S[length(S)]
|
||
@test axes(S) == (OffsetArrays.IdOffsetRange(0:1), )
|
||
S = view(A, 1, axes(A, 2))
|
||
@test S == A[1, :]
|
||
@test S[3] == 2
|
||
@test S[4] == 4
|
||
@test_throws BoundsError S[1]
|
||
@test axes(S) == (OffsetArrays.IdOffsetRange(3:4), )
|
||
|
||
A0 = collect(reshape(1:24, 2, 3, 4))
|
||
A = OffsetArray(A0, (-1,2,1))
|
||
S = view(A, axes(A, 1), 3:4, axes(A, 3))
|
||
@test S == A[:, 3:4, :]
|
||
@test S[0, 1, 2] == A[0, 3, 2]
|
||
@test S[0, 2, 2] == A[0, 4, 2]
|
||
@test S[1, 1, 2] == A[1, 3, 2]
|
||
@test axes(S) == (OffsetArrays.IdOffsetRange(0:1), Base.OneTo(2), OffsetArrays.IdOffsetRange(2:5))
|
||
end
|
||
|
||
@testset "Zero-index indexing" begin
|
||
@test OffsetArray([6], 2:2)[] == 6
|
||
@test OffsetArray(fill(6, 1, 1), 2:2, 3:3)[] == 6
|
||
@test OffsetArray(fill(6))[] == 6
|
||
@test_throws BoundsError OffsetArray([6,7], 2:3)[]
|
||
@test_throws BoundsError OffsetArray([6 7], 2:2, 2:3)[]
|
||
@test_throws BoundsError OffsetArray([], 2:1)[]
|
||
end
|
||
|
||
@testset "IdentityUnitRange indexing" begin
|
||
a = OffsetVector(3:4, 2:3)
|
||
ax = IdentityUnitRange(2:3)
|
||
@test a[ax[2]] == a[ax][2]
|
||
|
||
s = -2:2:4
|
||
r = 5:8
|
||
y = OffsetArray(s, r)
|
||
@test axes(y) == (r,)
|
||
@test step(y) == step(s)
|
||
|
||
a = OffsetVector(3:4, 10:11)
|
||
ax = OffsetArrays.IdOffsetRange(5:6, 5)
|
||
@test axes(a[ax]) == axes(ax)
|
||
for i in axes(ax,1)
|
||
@test a[ax[i]] == a[ax][i]
|
||
end
|
||
|
||
ax = IdentityUnitRange(10:11)
|
||
@test axes(a[ax]) == axes(ax)
|
||
for i in axes(ax,1)
|
||
@test a[ax[i]] == a[ax][i]
|
||
end
|
||
end
|
||
|
||
@testset "show OffsetMatrix" begin
|
||
Y = reshape(1:25, 5, 5)
|
||
X = OffsetArray(Y, -2:2, -4:0)
|
||
|
||
io = IOBuffer()
|
||
show(io, X)
|
||
strX = String(take!(io))
|
||
show(io, Y)
|
||
strY = String(take!(io))
|
||
@test strX == strY
|
||
|
||
io_limit = IOContext(io, :limit => true)
|
||
show(io_limit, X)
|
||
strX = String(take!(io))
|
||
show(io_limit, Y)
|
||
strY = String(take!(io))
|
||
@test strX == strY
|
||
end
|
||
|
||
@testset "vector indexing (issue #39896)" begin
|
||
a = collect(1:10)
|
||
r = Base.IdentityUnitRange(2:3)
|
||
b = a[r]
|
||
@test axes(b) == axes(r)
|
||
for i in r
|
||
@test b[i] == a[r[i]]
|
||
end
|
||
end
|
||
|
||
@testset "proper partition for non-1-indexed vector" begin
|
||
@test Iterators.partition(OffsetArray(1:10,10), 5) |> collect == [1:5,6:10] # OffsetVector
|
||
@test Iterators.partition(OffsetArray(collect(1:10),10), 5) |> collect == [1:5,6:10] # OffsetVector
|
||
@test Iterators.partition(OffsetArray(reshape(1:9,3,3), (3,3)), 5) |> collect == [1:5,6:9] #OffsetMatrix
|
||
@test Iterators.partition(OffsetArray(reshape(collect(1:9),3,3), (3,3)), 5) |> collect == [1:5,6:9] #OffsetMatrix
|
||
@test Iterators.partition(IdOffsetRange(2:7,10), 5) |> collect == [12:16,17:17] # IdOffsetRange
|
||
end
|
||
|
||
@testset "reshape" begin
|
||
a = OffsetArray(4:5, 5:6)
|
||
@test reshape(a, :) === a
|
||
@test reshape(a, (:,)) === a
|
||
end
|
||
|
||
@testset "stack" begin
|
||
nought = OffsetArray([0, 0.1, 0.01], 0:2)
|
||
ten = OffsetArray([1,10,100,1000], 10:13)
|
||
|
||
@test stack(ten) == ten
|
||
@test stack(ten .+ nought') == ten .+ nought'
|
||
@test stack(x^2 for x in ten) == ten.^2
|
||
|
||
@test axes(stack(nought for _ in ten)) == (0:2, 10:13)
|
||
@test axes(stack([nought for _ in ten])) == (0:2, 10:13)
|
||
@test axes(stack(nought for _ in ten; dims=1)) == (10:13, 0:2)
|
||
@test axes(stack((x, x^2) for x in nought)) == (1:2, 0:2)
|
||
@test axes(stack(x -> x[end-1:end], ten for _ in nought, _ in nought)) == (1:2, 0:2, 0:2)
|
||
@test axes(stack([ten[end-1:end] for _ in nought, _ in nought])) == (1:2, 0:2, 0:2)
|
||
end
|
||
|
||
@testset "issue #41630: replace_ref_begin_end!/@view on offset-like arrays" begin
|
||
x = OffsetArray([1 2; 3 4], -10:-9, 9:10) # 2×2 OffsetArray{...} with indices -10:-9×9:10
|
||
|
||
# begin/end with offset indices
|
||
@test (@view x[begin, 9])[] == 1
|
||
@test (@view x[-10, end])[] == 2
|
||
@test (@view x[-9, begin])[] == 3
|
||
@test (@view x[end, 10])[] == 4
|
||
@test (@view x[begin, begin])[] == 1
|
||
@test (@view x[begin, end])[] == 2
|
||
@test (@view x[end, begin])[] == 3
|
||
@test (@view x[end, end])[] == 4
|
||
|
||
# nested usages of begin/end
|
||
y = OffsetArray([-10, -9], (5,))
|
||
@test (@view x[begin, -y[end]])[] == 1
|
||
@test (@view x[y[begin], end])[] == 2
|
||
@test (@view x[end, -y[end]])[] == 3
|
||
@test (@view x[y[end], end])[] == 4
|
||
end
|
||
|
||
@testset "CartesianIndices (issue #40035)" begin
|
||
A = OffsetArray(big(1):big(2), 0);
|
||
B = OffsetArray(1:2, 0);
|
||
# axes of an OffsetArray may be converted to an AbstractUnitRange,
|
||
# but the conversion to an OrdinalRange was not defined.
|
||
# this is fixed in #40038, so the evaluation of its CartesianIndices should work
|
||
@test CartesianIndices(A) == CartesianIndices(B)
|
||
end
|
||
|
||
@testset "overflowing show" begin
|
||
A = OffsetArray(repeat([1], 1), typemax(Int)-1)
|
||
b = IOBuffer(maxsize=10)
|
||
show(b, A)
|
||
@test String(take!(b)) == "[1]"
|
||
show(b, (A, A))
|
||
@test String(take!(b)) == "([1], [1])"
|
||
end
|
||
|
||
@testset "indexing views (#53249)" begin
|
||
v = view([1,2,3,4], :)
|
||
@test v[Base.IdentityUnitRange(2:3)] == OffsetArray(2:3, 2:3)
|
||
end
|
||
|
||
@testset "mapreduce with OffsetRanges" begin
|
||
r = 5:100
|
||
a = OffsetArray(r, 2)
|
||
b = sum(a, dims=1)
|
||
@test b[begin] == sum(r)
|
||
end
|
||
|
||
@testset "reshape" begin
|
||
A0 = [1 3; 2 4]
|
||
A = reshape(A0, 2:3, 4:5)
|
||
@test axes(A) == Base.IdentityUnitRange.((2:3, 4:5))
|
||
|
||
B = reshape(A0, -10:-9, 9:10)
|
||
@test isa(B, OffsetMatrix{Int})
|
||
@test parent(B) == A0
|
||
@test axes(B) == Base.IdentityUnitRange.((-10:-9, 9:10))
|
||
end
|