diff --git a/README.md b/README.md index 3264bbfa..7cb65806 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,12 @@ vA = VectorOfArray(a) vB = VectorOfArray(b) vA .* vB # Now all standard array stuff works! + +# you can also create it directly with a vector-like syntax: +c = VA[[1, 2, 3], [4, 5, 6], [7, 8, 9]] +d = VA[[1, 2, 3], [4, 5, 6], [7, 8, 9]] + +c .* d ``` ### ArrayPartition @@ -44,15 +50,15 @@ pB = ArrayPartition(b) pA .* pB # Now all standard array stuff works! -# or do: +# or using the vector syntax: x0 = rand(3, 3) v0 = rand(3, 3) a0 = rand(3, 3) -u0 = ArrayPartition(x0, v0, a0) -u0.x[1] == x0 # true +u0 = AP[x0, v0, a0] +u0.x[1] === x0 # true u0 .+= 1 -u0.x[2] == v0 # still true +u0.x[2] === v0 # still true # do some calculations creating a new partitioned array unew = u0 * 10 diff --git a/src/RecursiveArrayTools.jl b/src/RecursiveArrayTools.jl index 20a030f2..f6f813fc 100644 --- a/src/RecursiveArrayTools.jl +++ b/src/RecursiveArrayTools.jl @@ -133,14 +133,14 @@ module RecursiveArrayTools Base.convert(T::Type{<:GPUArraysCore.AnyGPUArray}, VA::AbstractVectorOfArray) = stack(VA.u) (T::Type{<:GPUArraysCore.AnyGPUArray})(VA::AbstractVectorOfArray) = T(Array(VA)) - export VectorOfArray, DiffEqArray, AbstractVectorOfArray, AbstractDiffEqArray, + export VectorOfArray, VA, DiffEqArray, AbstractVectorOfArray, AbstractDiffEqArray, AllObserved, vecarr_to_vectors, tuples export recursivecopy, recursivecopy!, recursivefill!, vecvecapply, copyat_or_push!, vecvec_to_mat, recursive_one, recursive_mean, recursive_bottom_eltype, recursive_unitless_bottom_eltype, recursive_unitless_eltype - export ArrayPartition, NamedArrayPartition + export ArrayPartition, AP, NamedArrayPartition include("precompilation.jl") diff --git a/src/array_partition.jl b/src/array_partition.jl index bb4057f8..8e2a97be 100644 --- a/src/array_partition.jl +++ b/src/array_partition.jl @@ -722,3 +722,28 @@ end function Adapt.adapt_structure(to, ap::ArrayPartition) return ArrayPartition(map(x -> Adapt.adapt(to, x), ap.x)...) end + +""" +```julia +AP[ matrices, ] +``` + +Create an `ArrayPartition` using vector syntax. Equivalent to `ArrayPartition(matrices)`, but looks nicer with nesting. + +# Examples: + +Simple examples: +```julia +ArrayPartition([1,2,3], [1 2;3 4]) == AP[[1,2,3], [1 2;3 4]] # true +AP[1u"m/s^2", 1u"m/s", 1u"m"] +``` + +With an ODEProblem: +```julia +func(u, p, t) = AP[5u.x[1], u.x[2]./2] +ODEProblem(func, AP[ [1.,2.,3.], [1. 2.;3. 4.] ], (0, 1)) |> solve +``` + +""" +struct AP end +Base.getindex(::Type{AP}, xs...) = ArrayPartition(xs...) diff --git a/src/vector_of_array.jl b/src/vector_of_array.jl index f9f82070..8e416675 100644 --- a/src/vector_of_array.jl +++ b/src/vector_of_array.jl @@ -1655,3 +1655,31 @@ end end unpack_args_voa(i, args::Tuple{Any}) = (unpack_voa(args[1], i),) unpack_args_voa(::Any, args::Tuple{}) = () + +""" +```julia +VA[ matrices, ] +``` + +Create an `VectorOfArray` using vector syntax. Equivalent to `VectorOfArray([matrices])`, but looks nicer with nesting. + +# Simple example: +```julia +VectorOfArray([[1,2,3], [1 2;3 4]]) == VA[[1,2,3], [1 2;3 4]] # true +``` + +# All the layers: +```julia +nested = VA[ + fill(1, 2, 3), + VA[ + VA[8, [1, 2, 3], [1 2;3 4], VA[1, 2, 3]], + fill(2, 3, 4), + VA[3ones(3), zeros(3)], + ], +] +``` + +""" +struct VA end +Base.getindex(::Type{VA}, xs...) = VectorOfArray(collect(xs)) diff --git a/test/basic_indexing.jl b/test/basic_indexing.jl index df6b3914..4ead8ee8 100644 --- a/test/basic_indexing.jl +++ b/test/basic_indexing.jl @@ -6,6 +6,9 @@ testa = cat(recs..., dims = 2) testva = VectorOfArray(recs) @test maximum(testva) == maximum(maximum.(recs)) +testva = VA[[1, 2, 3], [4, 5, 6], [7, 8, 9]] +@test maximum(testva) == maximum(maximum.(recs)) + # broadcast with array X = rand(3, 3) mulX = sqrt.(abs.(testva .* X)) @@ -161,7 +164,7 @@ diffeq = DiffEqArray(recs, t) @test diffeq[:, (end - 1):end].t == t[(length(t) - 1):length(t)] # Test views of heterogeneous arrays (issue #453) -f = VectorOfArray([[1.0], [2.0, 3.0]]) +f = VA[[1.0], [2.0, 3.0]] @test length(view(f, :, 1)) == 1 @test length(view(f, :, 2)) == 2 @test view(f, :, 1) == [1.0] @@ -169,7 +172,7 @@ f = VectorOfArray([[1.0], [2.0, 3.0]]) @test collect(view(f, :, 1)) == f[:, 1] @test collect(view(f, :, 2)) == f[:, 2] -f2 = VectorOfArray([[1.0, 2.0], [3.0]]) +f2 = VA[[1.0, 2.0], [3.0]] @test length(view(f2, :, 1)) == 2 @test length(view(f2, :, 2)) == 1 @test view(f2, :, 1) == [1.0, 2.0] @@ -178,7 +181,7 @@ f2 = VectorOfArray([[1.0, 2.0], [3.0]]) @test collect(view(f2, :, 2)) == f2[:, 2] # Test `end` with ragged arrays -ragged = VectorOfArray([[1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0, 9.0]]) +ragged = VA[[1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0, 9.0]] @test ragged[end, 1] == 2.0 @test ragged[end, 2] == 5.0 @test ragged[end, 3] == 9.0 @@ -192,7 +195,7 @@ ragged = VectorOfArray([[1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0, 9.0]]) @test ragged[:, 2:end] == VectorOfArray(ragged.u[2:end]) @test ragged[:, (end - 1):end] == VectorOfArray(ragged.u[(end - 1):end]) -ragged2 = VectorOfArray([[1.0, 2.0, 3.0, 4.0], [5.0, 6.0], [7.0, 8.0, 9.0]]) +ragged2 = VA[[1.0, 2.0, 3.0, 4.0], [5.0, 6.0], [7.0, 8.0, 9.0]] @test ragged2[end, 1] == 4.0 @test ragged2[end, 2] == 6.0 @test ragged2[end, 3] == 9.0 @@ -228,7 +231,7 @@ ragged_range_idx = 1:lastindex(ragged, 1) @test identity.(ragged_range_idx) === ragged_range_idx # Broadcasting of heterogeneous arrays (issue #454) -u = VectorOfArray([[1.0], [2.0, 3.0]]) +u = VA[[1.0], [2.0, 3.0]] @test length(view(u, :, 1)) == 1 @test length(view(u, :, 2)) == 2 # broadcast assignment into selected column (last index Int) @@ -293,7 +296,7 @@ u[1:2, 1, [1, 3], 2] .= [1.0 3.0; 2.0 4.0] @test u[end, 1, end] == u.u[end][end, 1, end] # Test that views can be modified -f3 = VectorOfArray([[1.0, 2.0], [3.0, 4.0, 5.0]]) +f3 = VA[[1.0, 2.0], [3.0, 4.0, 5.0]] v = view(f3, :, 2) @test length(v) == 3 v[1] = 10.0 @@ -384,7 +387,7 @@ mulX .= sqrt.(abs.(testva .* testvb)) @test mulX == ref # https://github.com/SciML/RecursiveArrayTools.jl/issues/49 -a = ArrayPartition(1:5, 1:6) +a = AP[1:5, 1:6] a[1:8] a[[1, 3, 8]] diff --git a/test/downstream/downstream_events.jl b/test/downstream/downstream_events.jl index 0bdfdfb8..230dcbb0 100644 --- a/test/downstream/downstream_events.jl +++ b/test/downstream/downstream_events.jl @@ -1,9 +1,9 @@ using OrdinaryDiffEq, StaticArrays, RecursiveArrayTools -u0 = ArrayPartition(SVector{1}(50.0), SVector{1}(0.0)) +u0 = AP[SVector{1}(50.0), SVector{1}(0.0)] tspan = (0.0, 15.0) function f(u, p, t) - return ArrayPartition(SVector{1}(u[2]), SVector{1}(-9.81)) + return AP[SVector{1}(u[2]), SVector{1}(-9.81)] end prob = ODEProblem(f, u0, tspan) @@ -13,7 +13,7 @@ function condition(u, t, integrator) # Event when event_f(u,t,k) == 0 end affect! = nothingf = affect_neg! = function (integrator) - return integrator.u = ArrayPartition(SVector{1}(integrator.u[1]), SVector{1}(-integrator.u[2])) + return integrator.u = AP[SVector{1}(integrator.u[1]), SVector{1}(-integrator.u[2])] end callback = ContinuousCallback(condition, affect!, affect_neg!, interp_points = 100) diff --git a/test/downstream/odesolve.jl b/test/downstream/odesolve.jl index 6e74197b..2ca163ab 100644 --- a/test/downstream/odesolve.jl +++ b/test/downstream/odesolve.jl @@ -4,7 +4,7 @@ function lorenz(du, u, p, t) du[2] = u[1] * (28.0 - u[3]) - u[2] return du[3] = u[1] * u[2] - (8 / 3) * u[3] end -u0 = ArrayPartition([1.0, 0.0], [0.0]) +u0 = AP[[1.0, 0.0], [0.0]] @test ArrayInterface.zeromatrix(u0) isa Matrix tspan = (0.0, 100.0) prob = ODEProblem(lorenz, u0, tspan) @@ -25,8 +25,8 @@ function mymodel(F, vars) return end # To show that the function works -F = ArrayPartition([0.0 0.0; 0.0 0.0], [0.0 0.0; 0.0 0.0]) -u0 = ArrayPartition([0.1 1.2; 0.1 1.2], [0.1 1.2; 0.1 1.2]) +F = AP[[0.0 0.0; 0.0 0.0], [0.0 0.0; 0.0 0.0]] +u0 = AP[[0.1 1.2; 0.1 1.2], [0.1 1.2; 0.1 1.2]] result = mymodel(F, u0) nlsolve(mymodel, u0) @@ -34,8 +34,8 @@ nlsolve(mymodel, u0) function dyn(u, p, t) return ArrayPartition( - ArrayPartition(zeros(1), [0.0]), - ArrayPartition(zeros(1), [0.0]) + AP[zeros(1), [0.0]], + AP[zeros(1), [0.0]] ) end @@ -43,8 +43,8 @@ end ODEProblem( dyn, ArrayPartition( - ArrayPartition(zeros(1), [-1.0]), - ArrayPartition(zeros(1), [0.75]) + AP[zeros(1), [-1.0]], + AP[zeros(1), [0.75]] ), (0.0, 1.0) ), @@ -55,8 +55,8 @@ end ODEProblem( dyn, ArrayPartition( - ArrayPartition(zeros(1), [-1.0]), - ArrayPartition(zeros(1), [0.75]) + AP[zeros(1), [-1.0]], + AP[zeros(1), [0.75]] ), (0.0, 1.0) ), diff --git a/test/interface_tests.jl b/test/interface_tests.jl index cd255094..77b75b4e 100644 --- a/test/interface_tests.jl +++ b/test/interface_tests.jl @@ -3,7 +3,7 @@ using FastBroadcast using SymbolicIndexingInterface: SymbolCache t = 1:3 -testva = VectorOfArray([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) +testva = VA[[1, 2, 3], [4, 5, 6], [7, 8, 9]] testda = DiffEqArray([[1, 2, 3], [4, 5, 6], [7, 8, 9]], t) for (i, elem) in enumerate(testva) @@ -64,7 +64,7 @@ push!(testda, [-1, -2, -3, -4]) # Type inference @inferred sum(testva) -@inferred sum(VectorOfArray([VectorOfArray([zeros(4, 4)])])) +@inferred sum(VA[VA[zeros(4, 4)]]) @inferred mapreduce(string, *, testva) # Type stability for `end` indexing (issue #525) testva_end = VectorOfArray(fill(fill(2.0, 2), 10)) @@ -79,7 +79,7 @@ last_row = lastindex(testva_end, 1) @test testva_end[last_row, 1] == 2.0 # mapreduce -testva = VectorOfArray([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) +testva = VA[[1, 2, 3], [4, 5, 6], [7, 8, 9]] @test mapreduce(x -> string(x) * "q", *, testva) == "1q2q3q4q5q6q7q8q9q" testvb = VectorOfArray([rand(1:10, 3, 3, 3) for _ in 1:4]) @@ -128,7 +128,7 @@ end @test stack(testva) == [1 4 7; 2 5 8; 3 6 9] @test stack(testva; dims = 1) == [1 2 3; 4 5 6; 7 8 9] -testva = VectorOfArray([VectorOfArray([ones(2, 2), 2ones(2, 2)]), 3ones(2, 2, 2)]) +testva = VA[VA[ones(2, 2), 2ones(2, 2)], 3ones(2, 2, 2)] @test stack(testva) == [1.0 1.0; 1.0 1.0;;; 2.0 2.0; 2.0 2.0;;;; 3.0 3.0; 3.0 3.0;;; 3.0 3.0; 3.0 3.0] @@ -180,29 +180,22 @@ testva = VectorOfArray([i * ones(3, 2) for i in 1:4]) arr = rand(3, 2, 4) copyto!(testva, arr) @test Array(testva) == arr -testva = VectorOfArray( - [ - ones(3, 2, 2), - VectorOfArray( - [ - 2ones(3, 2), - VectorOfArray([3ones(3), 4ones(3)]), - ] - ), - DiffEqArray( - [ - 5ones(3, 2), - VectorOfArray( - [ - 6ones(3), - 7ones(3), - ] - ), - ], [0.1, 0.2], - [100.0, 200.0], SymbolCache([:x, :y], [:a, :b], :t) - ), - ] -) +testva = VA[ + ones(3, 2, 2), + VA[ + 2ones(3, 2), + VA[3ones(3), 4ones(3)], + ], + DiffEqArray( + [ + 5ones(3, 2), + VA[6ones(3), 7ones(3)], + ], + [0.1, 0.2], + [100.0, 200.0], + SymbolCache([:x, :y], [:a, :b], :t) + ), +] arr = rand(3, 2, 2, 3) copyto!(testva, arr) @test Array(testva) == arr @@ -244,16 +237,16 @@ resize!(u, 3) @test pointer(u) === pointer(u.u) # Ensure broadcast (including assignment) works with StaticArrays -x = VectorOfArray([fill(2, SVector{2, Float64}), ones(SVector{2, Float64})]) -y = VectorOfArray([fill(2, SVector{2, Float64}), ones(SVector{2, Float64})]) -z = VectorOfArray([zeros(SVector{2, Float64}), zeros(SVector{2, Float64})]) +x = VA[fill(2, SVector{2, Float64}), ones(SVector{2, Float64})] +y = VA[fill(2, SVector{2, Float64}), ones(SVector{2, Float64})] +z = VA[zeros(SVector{2, Float64}), zeros(SVector{2, Float64})] z .= x .+ y -@test z == VectorOfArray([fill(4, SVector{2, Float64}), fill(2, SVector{2, Float64})]) +@test z == VA[fill(4, SVector{2, Float64}), fill(2, SVector{2, Float64})] -u1 = VectorOfArray([fill(2, SVector{2, Float64}), ones(SVector{2, Float64})]) -u2 = VectorOfArray([fill(4, SVector{2, Float64}), 2 .* ones(SVector{2, Float64})]) -u3 = VectorOfArray([fill(4, SVector{2, Float64}), 2 .* ones(SVector{2, Float64})]) +u1 = VA[fill(2, SVector{2, Float64}), ones(SVector{2, Float64})] +u2 = VA[fill(4, SVector{2, Float64}), 2 .* ones(SVector{2, Float64})] +u3 = VA[fill(4, SVector{2, Float64}), 2 .* ones(SVector{2, Float64})] function f(u1, u2, u3) return u3 .= u1 .+ u2 @@ -265,9 +258,9 @@ yy = [2.0 1.0; 2.0 1.0] zz = x .+ yy @test zz == [4.0 2.0; 4.0 2.0] -z = VectorOfArray([zeros(SVector{2, Float64}), zeros(SVector{2, Float64})]) +z = VA[zeros(SVector{2, Float64}), zeros(SVector{2, Float64})] z .= zz -@test z == VectorOfArray([fill(4, SVector{2, Float64}), fill(2, SVector{2, Float64})]) +@test z == VA[fill(4, SVector{2, Float64}), fill(2, SVector{2, Float64})] function f!(z, zz) return z .= zz @@ -276,7 +269,7 @@ f!(z, zz) @test (@allocated f!(z, zz)) == 0 z .= 0.1 -@test z == VectorOfArray([fill(0.1, SVector{2, Float64}), fill(0.1, SVector{2, Float64})]) +@test z == VA[fill(0.1, SVector{2, Float64}), fill(0.1, SVector{2, Float64})] function f2!(z) return z .= 0.1 @@ -288,7 +281,7 @@ function f3!(z, zz) return @.. broadcast = false z = zz end f3!(z, zz) -@test z == VectorOfArray([fill(4, SVector{2, Float64}), fill(2, SVector{2, Float64})]) +@test z == VA[fill(4, SVector{2, Float64}), fill(2, SVector{2, Float64})] @test (@allocated f3!(z, zz)) == 0 struct ImmutableVectorOfArray{T, N, A} <: AbstractVectorOfArray{T, N, A} @@ -329,7 +322,7 @@ end using SparseArrays # Test that issparse returns false for VectorOfArray - testva = VectorOfArray([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) + testva = VA[[1, 2, 3], [4, 5, 6], [7, 8, 9]] @test issparse(testva) == false # Test that issparse returns false for DiffEqArray @@ -342,6 +335,6 @@ end @test issparse(testview) == false # Test with nested VectorOfArray - nested_voa = VectorOfArray([testva, testva]) + nested_voa = VA[testva, testva] @test issparse(nested_voa) == false end diff --git a/test/linalg.jl b/test/linalg.jl index 33a8c4ec..78d49581 100644 --- a/test/linalg.jl +++ b/test/linalg.jl @@ -56,4 +56,4 @@ mat = Array(va) @test all(va'[i] == mat'[i] for i in eachindex(mat')) @test Array(va') == mat' -@test !ArrayInterface.issingular(VectorOfArray([rand(2), rand(2)])) +@test !ArrayInterface.issingular(VA[rand(2), rand(2)]) diff --git a/test/partitions_and_static_arrays.jl b/test/partitions_and_static_arrays.jl index 7eac8809..8f5ac3e5 100644 --- a/test/partitions_and_static_arrays.jl +++ b/test/partitions_and_static_arrays.jl @@ -1,11 +1,10 @@ using Test, RecursiveArrayTools, StaticArrays -p = ArrayPartition( - ( - zeros(Float32, 2), zeros(SMatrix{2, 2, Int64}, 2), - zeros(SVector{3, Float64}, 2), - ) -) +p = AP[ + zeros(Float32, 2), + zeros(SMatrix{2, 2, Int64}, 2), + zeros(SVector{3, Float64}, 2), +] @test eltype(p) == Float64 @test recursive_bottom_eltype(p) == Float64 @test recursive_unitless_eltype(p) == Float64 @@ -14,5 +13,5 @@ p = ArrayPartition( p2 = similar(p) @test typeof(p2) == typeof(p) -p3 = ArrayPartition(SA[1.0, 2.0], MMatrix{2, 2}([3.0 4.0; 3.0 5.0])) +p3 = AP[SA[1.0, 2.0], MMatrix{2, 2}([3.0 4.0; 3.0 5.0])] @test (@inferred length(typeof(p3))) == 6 diff --git a/test/partitions_test.jl b/test/partitions_test.jl index 0cc1226a..0d708f5f 100644 --- a/test/partitions_test.jl +++ b/test/partitions_test.jl @@ -2,6 +2,8 @@ using RecursiveArrayTools, Test, Statistics, ArrayInterface, Adapt @test length(ArrayPartition()) == 0 @test isempty(ArrayPartition()) +@test length(AP[]) == 0 +@test isempty(AP[]) # Test undef initializer for single-partition ArrayPartition p_undef = ArrayPartition{Float64, Tuple{Vector{Float64}}}(undef, 10) @@ -17,6 +19,10 @@ p = ArrayPartition(A) @inferred p[1] @test (p.x[1][1], p.x[2][1]) == (p[1], p[6]) +q = AP[rand(5), rand(5)] +@inferred q[1] +@test (q.x[1][1], q.x[2][1]) == (q[1], q[6]) + p = ArrayPartition(A, Val{true}) @test !(p.x[1] === A[1]) @@ -24,6 +30,10 @@ p2 = similar(p) p2[1] = 1 @test p2.x[1] != p.x[1] +q2 = similar(q) +q2[1] = 1 +@test q2.x[1] != q.x[1] + C = rand(10) p3 = similar(p, axes(p)) @test length(p3.x[1]) == length(p3.x[2]) == 5 @@ -55,7 +65,7 @@ y = p .* p' @test y[1:5, 6:10] == p.x[1] .* p.x[2]' @test y[6:10, 1:5] == p.x[2] .* p.x[1]' -a = ArrayPartition([1], [2]) +a = AP[[1], [2]] a .= [10, 20] b = rand(10) @@ -75,8 +85,8 @@ resize!(p, (6, 7)) ## inference tests -x = ArrayPartition([1, 2], [3.0, 4.0]) -y = ArrayPartition(ArrayPartition([1], [2.0]), ArrayPartition([3], [4.0])) +x = AP[[1, 2], [3.0, 4.0]] +y = ArrayPartition(AP[[1], [2.0]], AP[[3], [4.0]]) @test x[:, 1] == (1, 3.0) # similar partitions @@ -142,7 +152,7 @@ y = ArrayPartition(ArrayPartition([1], [2.0]), ArrayPartition([3], [4.0])) @inferred recursive_one(x) @inferred recursive_bottom_eltype(x) -src_voa = VectorOfArray([[1.0, 2.0], [3.0, 4.0]]) +src_voa = VA[[1.0, 2.0], [3.0, 4.0]] src_ap = ArrayPartition(src_voa) copied_ap = recursivecopy(src_ap) @@ -151,7 +161,7 @@ copied_ap = recursivecopy(src_ap) @test copied_ap.x[1].u[1] !== src_ap.x[1].u[1] @test copied_ap.x[1].u[2] !== src_ap.x[1].u[2] -dest_voa = VectorOfArray([zeros(2), zeros(2)]) +dest_voa = VA[zeros(2), zeros(2)] dest_ap = ArrayPartition(dest_voa) recursivecopy!(dest_ap, src_ap) @test dest_ap.x[1].u[1] == src_ap.x[1].u[1] @@ -161,30 +171,30 @@ recursivecopy!(dest_ap, src_ap) # mapreduce @inferred Union{Int, Float64} sum(x) -@inferred sum(ArrayPartition(ArrayPartition(zeros(4, 4)))) -@inferred sum(ArrayPartition(ArrayPartition(zeros(4)))) -@inferred sum(ArrayPartition(zeros(4, 4))) +@inferred sum(AP[AP[zeros(4, 4)]]) +@inferred sum(AP[AP[zeros(4)]]) +@inferred sum(AP[zeros(4, 4)]) @inferred mapreduce(string, *, x) @test mapreduce(i -> string(i) * "q", *, x) == "1q2q3.0q4.0q" # any -@test !any(isnan, ArrayPartition([1, 2], [3.0, 4.0])) -@test !any(isnan, ArrayPartition([3.0, 4.0])) -@test any(isnan, ArrayPartition([NaN], [3.0, 4.0])) -@test any(isnan, ArrayPartition([NaN])) -@test any(isnan, ArrayPartition(ArrayPartition([NaN]))) -@test any(isnan, ArrayPartition([2], [NaN])) -@test any(isnan, ArrayPartition([2], ArrayPartition([NaN]))) +@test !any(isnan, AP[[1, 2], [3.0, 4.0]]) +@test !any(isnan, AP[[3.0, 4.0]]) +@test any(isnan, AP[[NaN], [3.0, 4.0]]) +@test any(isnan, AP[[NaN]]) +@test any(isnan, AP[AP[[NaN]]]) +@test any(isnan, AP[[2], [NaN]]) +@test any(isnan, AP[[2], AP[[NaN]]]) # all -@test !all(isnan, ArrayPartition([1, 2], [3.0, 4.0])) -@test !all(isnan, ArrayPartition([3.0, 4.0])) -@test !all(isnan, ArrayPartition([NaN], [3.0, 4.0])) -@test all(isnan, ArrayPartition([NaN])) -@test all(isnan, ArrayPartition(ArrayPartition([NaN]))) -@test !all(isnan, ArrayPartition([2], [NaN])) -@test all(isnan, ArrayPartition([NaN], [NaN])) -@test all(isnan, ArrayPartition([NaN], ArrayPartition([NaN]))) +@test !all(isnan, AP[[1, 2], [3.0, 4.0]]) +@test !all(isnan, AP[[3.0, 4.0]]) +@test !all(isnan, AP[[NaN], [3.0, 4.0]]) +@test all(isnan, AP[[NaN]]) +@test all(isnan, AP[AP[[NaN]]]) +@test !all(isnan, AP[[2], [NaN]]) +@test all(isnan, AP[[NaN], [NaN]]) +@test all(isnan, AP[[NaN], AP[[NaN]]]) # broadcasting _scalar_op(y) = y + 1 @@ -194,10 +204,10 @@ _broadcast_wrapper(y) = _scalar_op.(y) @inferred _broadcast_wrapper(x) # Testing map -@test map(x -> x^2, x) == ArrayPartition(x.x[1] .^ 2, x.x[2] .^ 2) +@test map(x -> x^2, x) == AP[x.x[1] .^ 2, x.x[2] .^ 2] # Testing filter -@test filter(x -> iseven(round(Int, x)), x) == ArrayPartition([2], [4.0]) +@test filter(x -> iseven(round(Int, x)), x) == AP[[2], [4.0]] #### testing copyto! S = [ @@ -207,8 +217,8 @@ S = [ ] for sizes in S - local x = ArrayPartition(randn.(sizes[1])) - local y = ArrayPartition(zeros.(sizes[2])) + local x = AP[randn.(sizes[1])] + local y = AP[zeros.(sizes[2])] y_array = zeros(length(x)) copyto!(y, x) #testing Base.copyto!(dest::ArrayPartition,A::ArrayPartition) copyto!(y_array, x) #testing Base.copyto!(dest::Array,A::ArrayPartition) @@ -217,7 +227,7 @@ for sizes in S end # Non-allocating broadcast -xce0 = ArrayPartition(zeros(2), [0.0]) +xce0 = AP[zeros(2), [0.0]] xcde0 = copy(xce0) function foo(y, x) y .= y .+ x @@ -264,7 +274,7 @@ find_mt(::Tuple{}) = nothing find_mt(a::MyType, rest) = a find_mt(::Any, rest) = find_mt(rest) -ap = ArrayPartition(MyType(ones(10)), collect(1:2)) +ap = AP[MyType(ones(10)), collect(1:2)] up = ap .+ 1 @test typeof(ap) == typeof(up) @@ -272,14 +282,14 @@ up = 2 .* ap .+ 1 @test typeof(ap) == typeof(up) # Test that `zeros()` does not get screwed up -ap = ArrayPartition(zeros(), [1.0]) +ap = AP[zeros(), [1.0]] up = ap .+ 1 @test typeof(ap) == typeof(up) up = 2 .* ap .+ 1 @test typeof(ap) == typeof(up) -@testset "ArrayInterface.ismutable(ArrayPartition($a, $b)) == $r" for (a, b, r) in ( +@testset "ArrayInterface.ismutable(AP[$a, $b]) == $r" for (a, b, r) in ( ( 1, 2, @@ -302,12 +312,12 @@ up = 2 .* ap .+ 1 true, ), ) - @test ArrayInterface.ismutable(ArrayPartition(a, b)) == r + @test ArrayInterface.ismutable(AP[a, b]) == r end # Test unary minus -x = ArrayPartition(ArrayPartition([1, 2]), [3, 4]) +x = AP[AP[[1, 2]], [3, 4]] @test -x == 0 - x @test typeof(x) === typeof(-x) @@ -315,12 +325,12 @@ x = ArrayPartition(ArrayPartition([1, 2]), [3, 4]) begin b = [1, 2, 3] c = [1 2; 3 4] - d = ArrayPartition(view(b, :), c) + d = AP[view(b, :), c] new_type = ArrayPartition{Float64, Tuple{Vector{Float64}, Matrix{Float64}}} @test (@inferred convert(new_type, d)) isa new_type @test convert(new_type, d) == d - @test_throws MethodError convert(new_type, ArrayPartition(view(b, :), c, c)) + @test_throws MethodError convert(new_type, AP[view(b, :), c, c]) end @testset "Copy and zero with type changing array" begin @@ -336,31 +346,31 @@ end ) Base.zero(::TypeChangingArray{T, N}) where {T, N} = zeros(T, ntuple(_ -> 0, N)) - a = ArrayPartition(TypeChangingArray{Int, 2}(), TypeChangingArray{Float32, 2}()) - @test copy(a) == ArrayPartition(zeros(Int, 0, 0), zeros(Float32, 0, 0)) - @test zero(a) == ArrayPartition(zeros(Int, 0, 0), zeros(Float32, 0, 0)) + a = AP[TypeChangingArray{Int, 2}(), TypeChangingArray{Float32, 2}()] + @test copy(a) == AP[zeros(Int, 0, 0), zeros(Float32, 0, 0)] + @test zero(a) == AP[zeros(Int, 0, 0), zeros(Float32, 0, 0)] end -@test !iszero(ArrayPartition([2], [3, 4])) +@test !iszero(AP[[2], [3, 4]]) @testset "Cartesian indexing" begin - @test ArrayPartition([1, 2], [3])[1:3, 1] == [1, 2, 3] + @test AP[[1, 2], [3]][1:3, 1] == [1, 2, 3] end @testset "Scalar copyto!" begin u = [2.0, 1.0] - copyto!(u, ArrayPartition(1.0, -1.2)) + copyto!(u, AP[1.0, -1.2]) @test u == [1.0, -1.2] end # Test adapt on ArrayPartition from Float64 to Float32 arrays a = Float64.([1.0, 2.0, 3.0, 4.0]) b = Float64.([1.0, 2.0, 3.0, 4.0]) -part_a_64 = ArrayPartition(a, b) +part_a_64 = AP[a, b] part_a = adapt(Array{Float32}, part_a_64) c = Float32.([1.0, 2.0, 3.0, 4.0]) d = Float32.([1.0, 2.0, 3.0, 4.0]) -part_b = ArrayPartition(c, d) +part_b = AP[c, d] @test part_a == part_b # Test equality of partitions @@ -374,4 +384,4 @@ end # ArrayPartition `all` with a functor struct TestIsnanFunctor end (::TestIsnanFunctor)(x) = isnan(x) -@test all(TestIsnanFunctor(), ArrayPartition([NaN], [NaN])) +@test all(TestIsnanFunctor(), AP[[NaN], [NaN]]) diff --git a/test/utils_test.jl b/test/utils_test.jl index be263ff1..15807ea1 100644 --- a/test/utils_test.jl +++ b/test/utils_test.jl @@ -35,7 +35,7 @@ AofSA = [@SVector [2.0, 3.0] for i in 1:5] AofuSA = [@SVector [2.0u"kg", 3.0u"kg"] for i in 1:5] @test recursive_unitless_eltype(AofuSA) == SVector{2, Float64} -A = [ArrayPartition(ones(1), ones(1))] +A = [AP[ones(1), ones(1)]] function test_recursive_bottom_eltype() function test_value(val::Any, expected_type::Type) @@ -124,16 +124,16 @@ recursivefill!(x, true) end @testset "VectorOfArray recursivecopy!" begin - u1 = VectorOfArray([fill(2, MVector{2, Float64}), ones(MVector{2, Float64})]) - u2 = VectorOfArray([fill(4, MVector{2, Float64}), 2 .* ones(MVector{2, Float64})]) + u1 = VA[fill(2, MVector{2, Float64}), ones(MVector{2, Float64})] + u2 = VA[fill(4, MVector{2, Float64}), 2 .* ones(MVector{2, Float64})] recursivecopy!(u1, u2) @test u1.u[1] == [4.0, 4.0] @test u1.u[2] == [2.0, 2.0] @test u1.u[1] isa MVector @test u1.u[2] isa MVector - u1 = VectorOfArray([fill(2, SVector{2, Float64}), ones(SVector{2, Float64})]) - u2 = VectorOfArray([fill(4, SVector{2, Float64}), 2 .* ones(SVector{2, Float64})]) + u1 = VA[fill(2, SVector{2, Float64}), ones(SVector{2, Float64})] + u2 = VA[fill(4, SVector{2, Float64}), 2 .* ones(SVector{2, Float64})] recursivecopy!(u1, u2) @test u1.u[1] == [4.0, 4.0] @test u1.u[2] == [2.0, 2.0] @@ -142,7 +142,7 @@ end # mixed/nested partition types create a Union eltype for `u`. # recursivecopy! must not fall back to a shallow copy in this case. - a = VectorOfArray([ones(2), VectorOfArray([1.0, 1.0])]) + a = VA[ones(2), VA[1.0, 1.0]] b = recursivecopy(a) recursivecopy!(b, a) @test !(b.u[1] === a.u[1]) @@ -152,7 +152,7 @@ end end @testset "VectorOfArray similar with nested scalar leaves" begin - a = VectorOfArray([ones(2), VectorOfArray([1.0, 1.0])]) + a = VA[ones(2), VA[1.0, 1.0]] b = similar(a, Float64) @test b isa typeof(a) @test b.u[1] isa Vector{Float64} @@ -162,7 +162,7 @@ end end @testset "recursivefill! with nested union partitions" begin - a = VectorOfArray([ones(2), VectorOfArray([1.0, 1.0])]) + a = VA[ones(2), VA[1.0, 1.0]] recursivefill!(a, true) @test a.u[1] == ones(2) @test a.u[2].u == ones(2) @@ -171,26 +171,26 @@ end # Test recursivefill! with immutable StaticArrays (issue #461) @testset "recursivefill! with immutable StaticArrays (issue #461)" begin # Test with only immutable SVectors - x = VectorOfArray([SVector{2}(ones(2)), SVector{2}(ones(2))]) + x = VA[SVector{2}(ones(2)), SVector{2}(ones(2))] recursivefill!(x, 0.0) @test all(x.u[i] == SVector{2}(zeros(2)) for i in 1:2) @test all(x.u[i] isa SVector for i in 1:2) # Test with mixed immutable and mutable StaticArrays - x = VectorOfArray([SVector{2}(ones(2)), MVector{2}(ones(2))]) + x = VA[SVector{2}(ones(2)), MVector{2}(ones(2))] recursivefill!(x, 0.0) @test all(x.u[i] == [0.0, 0.0] for i in 1:2) @test x.u[1] isa SVector @test x.u[2] isa MVector # Test fill! on VectorOfArray with immutable SVectors - x = VectorOfArray([SVector{2}(ones(2)), SVector{2}(ones(2))]) + x = VA[SVector{2}(ones(2)), SVector{2}(ones(2))] fill!(x, 0.0) @test all(x.u[i] == SVector{2}(zeros(2)) for i in 1:2) @test all(x.u[i] isa SVector for i in 1:2) # Test fill! on VectorOfArray with mixed types - x = VectorOfArray([SVector{2}(ones(2)), MVector{2}(ones(2))]) + x = VA[SVector{2}(ones(2)), MVector{2}(ones(2))] fill!(x, 0.0) @test all(x.u[i] == [0.0, 0.0] for i in 1:2) @test x.u[1] isa SVector