diff --git a/.JuliaFormatter.toml b/.JuliaFormatter.toml deleted file mode 100644 index 959ad88a..00000000 --- a/.JuliaFormatter.toml +++ /dev/null @@ -1,3 +0,0 @@ -style = "sciml" -format_markdown = true -format_docstrings = true \ No newline at end of file diff --git a/.github/workflows/FormatCheck.yml b/.github/workflows/FormatCheck.yml index c240796c..6762c6f3 100644 --- a/.github/workflows/FormatCheck.yml +++ b/.github/workflows/FormatCheck.yml @@ -1,13 +1,19 @@ -name: "Format Check" +name: format-check on: push: branches: - 'master' + - 'main' + - 'release-' tags: '*' pull_request: jobs: - format-check: - name: "Format Check" - uses: "SciML/.github/.github/workflows/format-check.yml@v1" + runic: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: fredrikekre/runic-action@v1 + with: + version: '1' diff --git a/docs/make.jl b/docs/make.jl index 221c6057..2093aa0c 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -5,14 +5,20 @@ cp("./docs/Project.toml", "./docs/src/assets/Project.toml", force = true) include("pages.jl") -makedocs(sitename = "RecursiveArrayTools.jl", +makedocs( + sitename = "RecursiveArrayTools.jl", authors = "Chris Rackauckas", modules = [RecursiveArrayTools], clean = true, doctest = false, linkcheck = true, warnonly = [:missing_docs], - format = Documenter.HTML(assets = ["assets/favicon.ico"], - canonical = "https://docs.sciml.ai/RecursiveArrayTools/stable/"), - pages = pages) + format = Documenter.HTML( + assets = ["assets/favicon.ico"], + canonical = "https://docs.sciml.ai/RecursiveArrayTools/stable/" + ), + pages = pages +) -deploydocs(repo = "github.com/SciML/RecursiveArrayTools.jl.git"; - push_preview = true) +deploydocs( + repo = "github.com/SciML/RecursiveArrayTools.jl.git"; + push_preview = true +) diff --git a/docs/pages.jl b/docs/pages.jl index 16338f15..b049a133 100644 --- a/docs/pages.jl +++ b/docs/pages.jl @@ -4,5 +4,5 @@ pages = [ "Home" => "index.md", "AbstractVectorOfArrayInterface.md", "array_types.md", - "recursive_array_functions.md" + "recursive_array_functions.md", ] diff --git a/ext/RecursiveArrayToolsFastBroadcastExt.jl b/ext/RecursiveArrayToolsFastBroadcastExt.jl index a2f840c8..473657a6 100644 --- a/ext/RecursiveArrayToolsFastBroadcastExt.jl +++ b/ext/RecursiveArrayToolsFastBroadcastExt.jl @@ -5,16 +5,20 @@ using FastBroadcast using StaticArraysCore const AbstractVectorOfSArray = AbstractVectorOfArray{ - T, N, <:AbstractVector{<:StaticArraysCore.SArray}} where {T, N} + T, N, <:AbstractVector{<:StaticArraysCore.SArray}, +} where {T, N} @inline function FastBroadcast.fast_materialize!( ::FastBroadcast.Static.False, ::DB, dst::AbstractVectorOfSArray, - bc::Broadcast.Broadcasted{S}) where {S, DB} + bc::Broadcast.Broadcasted{S} + ) where {S, DB} if FastBroadcast.use_fast_broadcast(S) for i in 1:length(dst.u) unpacked = RecursiveArrayTools.unpack_voa(bc, i) - dst.u[i] = StaticArraysCore.similar_type(dst.u[i])(unpacked[j] - for j in eachindex(unpacked)) + dst.u[i] = StaticArraysCore.similar_type(dst.u[i])( + unpacked[j] + for j in eachindex(unpacked) + ) end else Broadcast.materialize!(dst, bc) diff --git a/ext/RecursiveArrayToolsForwardDiffExt.jl b/ext/RecursiveArrayToolsForwardDiffExt.jl index f6089f64..0a829673 100644 --- a/ext/RecursiveArrayToolsForwardDiffExt.jl +++ b/ext/RecursiveArrayToolsForwardDiffExt.jl @@ -4,7 +4,7 @@ using RecursiveArrayTools using ForwardDiff function ForwardDiff.extract_derivative(::Type{T}, y::AbstractVectorOfArray) where {T} - ForwardDiff.extract_derivative.(T, y) + return ForwardDiff.extract_derivative.(T, y) end end diff --git a/ext/RecursiveArrayToolsMeasurementsExt.jl b/ext/RecursiveArrayToolsMeasurementsExt.jl index ffd0202c..f9b9b508 100644 --- a/ext/RecursiveArrayToolsMeasurementsExt.jl +++ b/ext/RecursiveArrayToolsMeasurementsExt.jl @@ -3,14 +3,16 @@ module RecursiveArrayToolsMeasurementsExt import RecursiveArrayTools import Measurements -function RecursiveArrayTools.recursive_unitless_bottom_eltype(a::Type{ - <:Measurements.Measurement, -}) - typeof(oneunit(a)) +function RecursiveArrayTools.recursive_unitless_bottom_eltype( + a::Type{ + <:Measurements.Measurement, + } + ) + return typeof(oneunit(a)) end function RecursiveArrayTools.recursive_unitless_eltype(a::Type{<:Measurements.Measurement}) - typeof(oneunit(a)) + return typeof(oneunit(a)) end end diff --git a/ext/RecursiveArrayToolsMonteCarloMeasurementsExt.jl b/ext/RecursiveArrayToolsMonteCarloMeasurementsExt.jl index 30a823d7..fcc1d559 100644 --- a/ext/RecursiveArrayToolsMonteCarloMeasurementsExt.jl +++ b/ext/RecursiveArrayToolsMonteCarloMeasurementsExt.jl @@ -3,16 +3,20 @@ module RecursiveArrayToolsMonteCarloMeasurementsExt import RecursiveArrayTools import MonteCarloMeasurements -function RecursiveArrayTools.recursive_unitless_bottom_eltype(a::Type{ - <:MonteCarloMeasurements.Particles, -}) - typeof(one(a)) +function RecursiveArrayTools.recursive_unitless_bottom_eltype( + a::Type{ + <:MonteCarloMeasurements.Particles, + } + ) + return typeof(one(a)) end -function RecursiveArrayTools.recursive_unitless_eltype(a::Type{ - <:MonteCarloMeasurements.Particles, -}) - typeof(one(a)) +function RecursiveArrayTools.recursive_unitless_eltype( + a::Type{ + <:MonteCarloMeasurements.Particles, + } + ) + return typeof(one(a)) end end diff --git a/ext/RecursiveArrayToolsReverseDiffExt.jl b/ext/RecursiveArrayToolsReverseDiffExt.jl index c82d1c79..ffb28eaa 100644 --- a/ext/RecursiveArrayToolsReverseDiffExt.jl +++ b/ext/RecursiveArrayToolsReverseDiffExt.jl @@ -13,6 +13,7 @@ function trackedarraycopyto!(dest, src) dest.u[i] = slice end end + return end @adjoint function Array(VA::AbstractVectorOfArray{<:ReverseDiff.TrackedReal}) @@ -25,7 +26,8 @@ end end @adjoint function Base.view( - A::AbstractVectorOfArray{<:ReverseDiff.TrackedReal, N}, I::Colon...) where {N} + A::AbstractVectorOfArray{<:ReverseDiff.TrackedReal, N}, I::Colon... + ) where {N} view_adjoint = let A = A, I = I function (y) A = recursivecopy(A) diff --git a/ext/RecursiveArrayToolsSparseArraysExt.jl b/ext/RecursiveArrayToolsSparseArraysExt.jl index a8ed047d..bb5d2cbc 100644 --- a/ext/RecursiveArrayToolsSparseArraysExt.jl +++ b/ext/RecursiveArrayToolsSparseArraysExt.jl @@ -4,7 +4,8 @@ import SparseArrays import RecursiveArrayTools function Base.copyto!( - dest::SparseArrays.AbstractCompressedVector, A::RecursiveArrayTools.ArrayPartition) + dest::SparseArrays.AbstractCompressedVector, A::RecursiveArrayTools.ArrayPartition + ) @assert length(dest) == length(A) cur = 1 @inbounds for i in 1:length(A.x) @@ -15,7 +16,7 @@ function Base.copyto!( end cur += length(A.x[i]) end - dest + return dest end # Fix for issue #486: Define issparse for AbstractVectorOfArray diff --git a/ext/RecursiveArrayToolsStatisticsExt.jl b/ext/RecursiveArrayToolsStatisticsExt.jl index abdfb73e..4adf9612 100644 --- a/ext/RecursiveArrayToolsStatisticsExt.jl +++ b/ext/RecursiveArrayToolsStatisticsExt.jl @@ -5,11 +5,11 @@ using Statistics @inline Statistics.mean(VA::AbstractVectorOfArray; kwargs...) = mean(Array(VA); kwargs...) @inline function Statistics.median(VA::AbstractVectorOfArray; kwargs...) - median(Array(VA); kwargs...) + return median(Array(VA); kwargs...) end @inline Statistics.std(VA::AbstractVectorOfArray; kwargs...) = std(Array(VA); kwargs...) @inline Statistics.var(VA::AbstractVectorOfArray; kwargs...) = var(Array(VA); kwargs...) @inline Statistics.cov(VA::AbstractVectorOfArray; kwargs...) = cov(Array(VA); kwargs...) @inline Statistics.cor(VA::AbstractVectorOfArray; kwargs...) = cor(Array(VA); kwargs...) -end \ No newline at end of file +end diff --git a/ext/RecursiveArrayToolsStructArraysExt.jl b/ext/RecursiveArrayToolsStructArraysExt.jl index a77ca20a..866f0e22 100644 --- a/ext/RecursiveArrayToolsStructArraysExt.jl +++ b/ext/RecursiveArrayToolsStructArraysExt.jl @@ -4,34 +4,38 @@ import RecursiveArrayTools, StructArrays RecursiveArrayTools.rewrap(::StructArrays.StructArray, u) = StructArrays.StructArray(u) using RecursiveArrayTools: VectorOfArray, VectorOfArrayStyle, ArrayInterface, unpack_voa, - narrays, StaticArraysCore + narrays, StaticArraysCore using StructArrays: StructArray const VectorOfStructArray{T, N} = VectorOfArray{T, N, <:StructArray} -# Since `StructArray` lazily materializes struct entries, the general `setindex!(x, val, I)` -# operation `VA.u[I[end]][Base.front(I)...]` will only update a lazily materialized struct -# entry of `u`, but will not actually mutate `x::StructArray`. See the StructArray documentation +# Since `StructArray` lazily materializes struct entries, the general `setindex!(x, val, I)` +# operation `VA.u[I[end]][Base.front(I)...]` will only update a lazily materialized struct +# entry of `u`, but will not actually mutate `x::StructArray`. See the StructArray documentation # for more details: # -# https://juliaarrays.github.io/StructArrays.jl/stable/counterintuitive/#Modifying-a-field-of-a-struct-element -# -# To avoid this, we can materialize a struct entry, modify it, and then use `setindex!` +# https://juliaarrays.github.io/StructArrays.jl/stable/counterintuitive/#Modifying-a-field-of-a-struct-element +# +# To avoid this, we can materialize a struct entry, modify it, and then use `setindex!` # with the modified struct entry. -# -function Base.setindex!(VA::VectorOfStructArray{T, N}, v, - I::Int...) where {T, N} +# +function Base.setindex!( + VA::VectorOfStructArray{T, N}, v, + I::Int... + ) where {T, N} u_I = VA.u[I[end]] u_I[Base.front(I)...] = v return VA.u[I[end]] = u_I end for (type, N_expr) in [ - (Broadcast.Broadcasted{<:VectorOfArrayStyle}, :(narrays(bc))), - (Broadcast.Broadcasted{<:Broadcast.DefaultArrayStyle}, :(length(dest.u))) -] - @eval @inline function Base.copyto!(dest::VectorOfStructArray, - bc::$type) + (Broadcast.Broadcasted{<:VectorOfArrayStyle}, :(narrays(bc))), + (Broadcast.Broadcasted{<:Broadcast.DefaultArrayStyle}, :(length(dest.u))), + ] + @eval @inline function Base.copyto!( + dest::VectorOfStructArray, + bc::$type + ) bc = Broadcast.flatten(bc) N = $N_expr @inbounds for i in 1:N @@ -55,7 +59,7 @@ for (type, N_expr) in [ end dest[:, i] = dest_i end - dest + return dest end end diff --git a/ext/RecursiveArrayToolsTablesExt.jl b/ext/RecursiveArrayToolsTablesExt.jl index 3b1e63c4..e95ae6b7 100644 --- a/ext/RecursiveArrayToolsTablesExt.jl +++ b/ext/RecursiveArrayToolsTablesExt.jl @@ -13,15 +13,17 @@ function Tables.rows(A::AbstractDiffEqArray) N = length(A.u[1]) names = [ :timestamp, - (isempty(variable_symbols(A)) ? - (Symbol("value", i) for i in 1:N) : - Symbol.(variable_symbols(A)))... + ( + isempty(variable_symbols(A)) ? + (Symbol("value", i) for i in 1:N) : + Symbol.(variable_symbols(A)) + )..., ] types = Type[eltype(A.t), (eltype(A.u[1]) for _ in 1:N)...] else names = [ :timestamp, - (isempty(variable_symbols(A)) ? :value : Symbol(variable_symbols(A)[1])) + (isempty(variable_symbols(A)) ? :value : Symbol(variable_symbols(A)[1])), ] types = Type[eltype(A.t), VT] end @@ -41,16 +43,20 @@ struct AbstractDiffEqArrayRows{T, U} u::U end function AbstractDiffEqArrayRows(names, types, t, u) - AbstractDiffEqArrayRows(Symbol.(names), types, - Dict(Symbol(nm) => i for (i, nm) in enumerate(names)), t, u) + return AbstractDiffEqArrayRows( + Symbol.(names), types, + Dict(Symbol(nm) => i for (i, nm) in enumerate(names)), t, u + ) end Base.length(x::AbstractDiffEqArrayRows) = length(x.u) function Base.eltype(::Type{AbstractDiffEqArrayRows{T, U}}) where {T, U} - AbstractDiffEqArrayRow{eltype(T), eltype(U)} + return AbstractDiffEqArrayRow{eltype(T), eltype(U)} end -function Base.iterate(x::AbstractDiffEqArrayRows, - (t_state, u_state) = (iterate(x.t), iterate(x.u))) +function Base.iterate( + x::AbstractDiffEqArrayRows, + (t_state, u_state) = (iterate(x.t), iterate(x.u)) + ) t_state === nothing && return nothing u_state === nothing && return nothing t, _t_state = t_state @@ -74,17 +80,17 @@ end Tables.columnnames(x::AbstractDiffEqArrayRow) = getfield(x, :names) function Tables.getcolumn(x::AbstractDiffEqArrayRow, i::Int) - i == 1 ? getfield(x, :t) : getfield(x, :u)[i - 1] + return i == 1 ? getfield(x, :t) : getfield(x, :u)[i - 1] end function Tables.getcolumn(x::AbstractDiffEqArrayRow, nm::Symbol) - nm === :timestamp ? getfield(x, :t) : getfield(x, :u)[getfield(x, :lookup)[nm] - 1] + return nm === :timestamp ? getfield(x, :t) : getfield(x, :u)[getfield(x, :lookup)[nm] - 1] end # Iterator interface for QueryVerse # (see also https://tables.juliadata.org/stable/#Tables.datavaluerows) IteratorInterfaceExtensions.isiterable(::AbstractDiffEqArray) = true function IteratorInterfaceExtensions.getiterator(A::AbstractDiffEqArray) - Tables.datavaluerows(Tables.rows(A)) + return Tables.datavaluerows(Tables.rows(A)) end end diff --git a/ext/RecursiveArrayToolsTrackerExt.jl b/ext/RecursiveArrayToolsTrackerExt.jl index bd9bbb8b..28067c8e 100644 --- a/ext/RecursiveArrayToolsTrackerExt.jl +++ b/ext/RecursiveArrayToolsTrackerExt.jl @@ -3,14 +3,17 @@ module RecursiveArrayToolsTrackerExt import RecursiveArrayTools import Tracker -function RecursiveArrayTools.recursivecopy!(b::AbstractArray{T, N}, - a::AbstractArray{T2, N}) where { +function RecursiveArrayTools.recursivecopy!( + b::AbstractArray{T, N}, + a::AbstractArray{T2, N} + ) where { T <: Tracker.TrackedArray, T2 <: Tracker.TrackedArray, - N} - @inbounds for i in eachindex(a) + N, + } + return @inbounds for i in eachindex(a) b[i] = copy(a[i]) end end diff --git a/ext/RecursiveArrayToolsZygoteExt.jl b/ext/RecursiveArrayToolsZygoteExt.jl index b8ec612e..94aa30d2 100644 --- a/ext/RecursiveArrayToolsZygoteExt.jl +++ b/ext/RecursiveArrayToolsZygoteExt.jl @@ -10,15 +10,20 @@ using Zygote: FillArrays, ChainRulesCore, literal_getproperty, @adjoint function ChainRulesCore.rrule( T::Type{<:RecursiveArrayTools.GPUArraysCore.AbstractGPUArray}, - xs::AbstractVectorOfArray) - T(xs), ȳ -> (ChainRulesCore.NoTangent(), ȳ) + xs::AbstractVectorOfArray + ) + return T(xs), ȳ -> (ChainRulesCore.NoTangent(), ȳ) end -@adjoint function getindex(VA::AbstractVectorOfArray, - i::Union{BitArray, AbstractArray{Bool}}) +@adjoint function getindex( + VA::AbstractVectorOfArray, + i::Union{BitArray, AbstractArray{Bool}} + ) function AbstractVectorOfArray_getindex_adjoint(Δ) - Δ′ = [(i[j] ? Δ[j] : FillArrays.Fill(zero(eltype(x)), size(x))) - for (x, j) in zip(VA.u, 1:length(VA))] + Δ′ = [ + (i[j] ? Δ[j] : FillArrays.Fill(zero(eltype(x)), size(x))) + for (x, j) in zip(VA.u, 1:length(VA)) + ] (VectorOfArray(Δ′), nothing) end VA[:, i], AbstractVectorOfArray_getindex_adjoint @@ -27,8 +32,10 @@ end @adjoint function getindex(VA::AbstractVectorOfArray, i::AbstractArray{Int}) function AbstractVectorOfArray_getindex_adjoint(Δ) iter = 0 - Δ′ = [(j ∈ i ? Δ[iter += 1] : FillArrays.Fill(zero(eltype(x)), size(x))) - for (x, j) in zip(VA.u, 1:length(VA))] + Δ′ = [ + (j ∈ i ? Δ[iter += 1] : FillArrays.Fill(zero(eltype(x)), size(x))) + for (x, j) in zip(VA.u, 1:length(VA)) + ] (VectorOfArray(Δ′), nothing) end VA[:, i], AbstractVectorOfArray_getindex_adjoint @@ -41,9 +48,13 @@ end VA.u[i], AbstractVectorOfArray_getindex_adjoint end -@adjoint function getindex(VA::AbstractVectorOfArray, i::Int, - j::Union{Int, AbstractArray{Int}, CartesianIndex, - Colon, BitArray, AbstractArray{Bool}}...) +@adjoint function getindex( + VA::AbstractVectorOfArray, i::Int, + j::Union{ + Int, AbstractArray{Int}, CartesianIndex, + Colon, BitArray, AbstractArray{Bool}, + }... + ) function AbstractVectorOfArray_getindex_adjoint(Δ) Δ′ = VectorOfArray([zero(x) for (x, j) in zip(VA.u, 1:length(VA))]) if isempty(j) @@ -56,17 +67,19 @@ end VA[i, j...], AbstractVectorOfArray_getindex_adjoint end -@adjoint function ArrayPartition(x::S, - ::Type{Val{copy_x}} = Val{false}) where { +@adjoint function ArrayPartition( + x::S, + ::Type{Val{copy_x}} = Val{false} + ) where { S <: Tuple, - copy_x -} + copy_x, + } function ArrayPartition_adjoint(_y) y = Array(_y) starts = vcat(0, cumsum(reduce(vcat, length.(x)))) ntuple(i -> reshape(y[(starts[i] + 1):starts[i + 1]], size(x[i])), length(x)), - nothing + nothing end ArrayPartition(x, Val{copy_x}), ArrayPartition_adjoint @@ -74,29 +87,39 @@ end @adjoint function VectorOfArray(u) VectorOfArray(u), - y -> begin - y isa Ref && (y = VectorOfArray(y[].u)) - (VectorOfArray([y[ntuple(x -> Colon(), ndims(y) - 1)..., i] - for i in 1:size(y)[end]]),) - end + y -> begin + y isa Ref && (y = VectorOfArray(y[].u)) + ( + VectorOfArray( + [ + y[ntuple(x -> Colon(), ndims(y) - 1)..., i] + for i in 1:size(y)[end] + ] + ), + ) + end end @adjoint function Base.copy(u::VectorOfArray) copy(u), - tuple ∘ copy + tuple ∘ copy end @adjoint function DiffEqArray(u, t) DiffEqArray(u, t), - y -> begin - y isa Ref && (y = VectorOfArray(y[].u)) - ( - DiffEqArray( - [y[ntuple(x -> Colon(), ndims(y) - 1)..., i] - for i in 1:size(y)[end]], - t), - nothing) - end + y -> begin + y isa Ref && (y = VectorOfArray(y[].u)) + ( + DiffEqArray( + [ + y[ntuple(x -> Colon(), ndims(y) - 1)..., i] + for i in 1:size(y)[end] + ], + t + ), + nothing, + ) + end end Zygote.@adjoint function Zygote.literal_getproperty(A::RecursiveArrayTools.AbstractVectorOfArray, ::Val{:u}) @@ -112,7 +135,7 @@ function vofa_u_adjoint(d, A::RecursiveArrayTools.AbstractVectorOfArray) isnothing(d_i) && return zero(A.u[idx]) d_i end - VectorOfArray(m) + return VectorOfArray(m) end function vofa_u_adjoint(d, A::RecursiveArrayTools.AbstractDiffEqArray) @@ -120,7 +143,7 @@ function vofa_u_adjoint(d, A::RecursiveArrayTools.AbstractDiffEqArray) isnothing(d_i) && return zero(A.u[idx]) d_i end - DiffEqArray(m, A.t) + return DiffEqArray(m, A.t) end @adjoint function literal_getproperty(A::ArrayPartition, ::Val{:x}) @@ -165,68 +188,90 @@ end view(A, I...), view_adjoint end -@adjoint function Broadcast.broadcasted(::typeof(+), x::AbstractVectorOfArray, - y::Union{Zygote.Numeric, AbstractVectorOfArray}) +@adjoint function Broadcast.broadcasted( + ::typeof(+), x::AbstractVectorOfArray, + y::Union{Zygote.Numeric, AbstractVectorOfArray} + ) broadcast(+, x, y), ȳ -> (nothing, map(x -> Zygote.unbroadcast(x, ȳ), (x, y))...) end @adjoint function Broadcast.broadcasted( - ::typeof(+), x::Zygote.Numeric, y::AbstractVectorOfArray) + ::typeof(+), x::Zygote.Numeric, y::AbstractVectorOfArray + ) broadcast(+, x, y), ȳ -> (nothing, map(x -> Zygote.unbroadcast(x, ȳ), (x, y))...) end _minus(Δ) = .-Δ _minus(::Nothing) = nothing -@adjoint function Broadcast.broadcasted(::typeof(-), x::AbstractVectorOfArray, - y::Union{AbstractVectorOfArray, Zygote.Numeric}) +@adjoint function Broadcast.broadcasted( + ::typeof(-), x::AbstractVectorOfArray, + y::Union{AbstractVectorOfArray, Zygote.Numeric} + ) x .- y, Δ -> (nothing, Zygote.unbroadcast(x, Δ), _minus(Zygote.unbroadcast(y, Δ))) end -@adjoint function Broadcast.broadcasted(::typeof(*), x::AbstractVectorOfArray, - y::Union{AbstractVectorOfArray, Zygote.Numeric}) +@adjoint function Broadcast.broadcasted( + ::typeof(*), x::AbstractVectorOfArray, + y::Union{AbstractVectorOfArray, Zygote.Numeric} + ) ( x .* y, - Δ -> (nothing, Zygote.unbroadcast(x, Δ .* conj.(y)), - Zygote.unbroadcast(y, Δ .* conj.(x))) + Δ -> ( + nothing, Zygote.unbroadcast(x, Δ .* conj.(y)), + Zygote.unbroadcast(y, Δ .* conj.(x)), + ), ) end -@adjoint function Broadcast.broadcasted(::typeof(/), x::AbstractVectorOfArray, - y::Union{AbstractVectorOfArray, Zygote.Numeric}) +@adjoint function Broadcast.broadcasted( + ::typeof(/), x::AbstractVectorOfArray, + y::Union{AbstractVectorOfArray, Zygote.Numeric} + ) res = x ./ y res, - Δ -> (nothing, Zygote.unbroadcast(x, Δ ./ conj.(y)), - Zygote.unbroadcast(y, .-Δ .* conj.(res ./ y))) + Δ -> ( + nothing, Zygote.unbroadcast(x, Δ ./ conj.(y)), + Zygote.unbroadcast(y, .-Δ .* conj.(res ./ y)), + ) end @adjoint function Broadcast.broadcasted( - ::typeof(-), x::Zygote.Numeric, y::AbstractVectorOfArray) + ::typeof(-), x::Zygote.Numeric, y::AbstractVectorOfArray + ) x .- y, Δ -> (nothing, Zygote.unbroadcast(x, Δ), _minus(Zygote.unbroadcast(y, Δ))) end @adjoint function Broadcast.broadcasted( - ::typeof(*), x::Zygote.Numeric, y::AbstractVectorOfArray) + ::typeof(*), x::Zygote.Numeric, y::AbstractVectorOfArray + ) ( x .* y, - Δ -> (nothing, Zygote.unbroadcast(x, Δ .* conj.(y)), - Zygote.unbroadcast(y, Δ .* conj.(x))) + Δ -> ( + nothing, Zygote.unbroadcast(x, Δ .* conj.(y)), + Zygote.unbroadcast(y, Δ .* conj.(x)), + ), ) end @adjoint function Broadcast.broadcasted( - ::typeof(/), x::Zygote.Numeric, y::AbstractVectorOfArray) + ::typeof(/), x::Zygote.Numeric, y::AbstractVectorOfArray + ) res = x ./ y res, - Δ -> (nothing, Zygote.unbroadcast(x, Δ ./ conj.(y)), - Zygote.unbroadcast(y, .-Δ .* conj.(res ./ y))) + Δ -> ( + nothing, Zygote.unbroadcast(x, Δ ./ conj.(y)), + Zygote.unbroadcast(y, .-Δ .* conj.(res ./ y)), + ) end @adjoint function Broadcast.broadcasted(::typeof(-), x::AbstractVectorOfArray) .-x, Δ -> (nothing, _minus(Δ)) end -@adjoint function Broadcast.broadcasted(::typeof(Base.literal_pow), ::typeof(^), - x::AbstractVectorOfArray, exp::Val{p}) where {p} +@adjoint function Broadcast.broadcasted( + ::typeof(Base.literal_pow), ::typeof(^), + x::AbstractVectorOfArray, exp::Val{p} + ) where {p} y = Base.literal_pow.(^, x, exp) y, ȳ -> (nothing, nothing, ȳ .* p .* conj.(x .^ (p - 1)), nothing) end @adjoint Broadcast.broadcasted(::typeof(identity), x::AbstractVectorOfArray) = x, -Δ -> (nothing, Δ) + Δ -> (nothing, Δ) @adjoint function Broadcast.broadcasted(::typeof(tanh), x::AbstractVectorOfArray) y = tanh.(x) @@ -234,42 +279,50 @@ end end @adjoint Broadcast.broadcasted(::typeof(conj), x::AbstractVectorOfArray) = conj.(x), -z̄ -> (nothing, conj.(z̄)) + z̄ -> (nothing, conj.(z̄)) @adjoint Broadcast.broadcasted(::typeof(real), x::AbstractVectorOfArray) = real.(x), -z̄ -> (nothing, real.(z̄)) + z̄ -> (nothing, real.(z̄)) @adjoint Broadcast.broadcasted( - ::typeof(imag), x::AbstractVectorOfArray) = imag.(x), -z̄ -> (nothing, im .* real.(z̄)) + ::typeof(imag), x::AbstractVectorOfArray +) = imag.(x), + z̄ -> (nothing, im .* real.(z̄)) -@adjoint Broadcast.broadcasted(::typeof(abs2), - x::AbstractVectorOfArray) = abs2.(x), -z̄ -> (nothing, 2 .* real.(z̄) .* x) +@adjoint Broadcast.broadcasted( + ::typeof(abs2), + x::AbstractVectorOfArray +) = abs2.(x), + z̄ -> (nothing, 2 .* real.(z̄) .* x) @adjoint function Broadcast.broadcasted( - ::typeof(+), a::AbstractVectorOfArray{<:Number}, b::Bool) + ::typeof(+), a::AbstractVectorOfArray{<:Number}, b::Bool + ) y = b === false ? a : a .+ b y, Δ -> (nothing, Δ, nothing) end @adjoint function Broadcast.broadcasted( - ::typeof(+), b::Bool, a::AbstractVectorOfArray{<:Number}) + ::typeof(+), b::Bool, a::AbstractVectorOfArray{<:Number} + ) y = b === false ? a : b .+ a y, Δ -> (nothing, nothing, Δ) end @adjoint function Broadcast.broadcasted( - ::typeof(-), a::AbstractVectorOfArray{<:Number}, b::Bool) + ::typeof(-), a::AbstractVectorOfArray{<:Number}, b::Bool + ) y = b === false ? a : a .- b y, Δ -> (nothing, Δ, nothing) end @adjoint function Broadcast.broadcasted( - ::typeof(-), b::Bool, a::AbstractVectorOfArray{<:Number}) + ::typeof(-), b::Bool, a::AbstractVectorOfArray{<:Number} + ) b .- a, Δ -> (nothing, nothing, .-Δ) end @adjoint function Broadcast.broadcasted( - ::typeof(*), a::AbstractVectorOfArray{<:Number}, b::Bool) + ::typeof(*), a::AbstractVectorOfArray{<:Number}, b::Bool + ) if b === false zero(a), Δ -> (nothing, zero(Δ), nothing) else @@ -277,7 +330,8 @@ end end end @adjoint function Broadcast.broadcasted( - ::typeof(*), b::Bool, a::AbstractVectorOfArray{<:Number}) + ::typeof(*), b::Bool, a::AbstractVectorOfArray{<:Number} + ) if b === false zero(a), Δ -> (nothing, nothing, zero(Δ)) else @@ -285,14 +339,18 @@ end end end -@adjoint Broadcast.broadcasted(::Type{T}, - x::AbstractVectorOfArray) where {T <: - Number} = T.(x), -ȳ -> (nothing, Zygote._project(x, ȳ)) +@adjoint Broadcast.broadcasted( + ::Type{T}, + x::AbstractVectorOfArray +) where { + T <: + Number, +} = T.(x), + ȳ -> (nothing, Zygote._project(x, ȳ)) function Zygote.unbroadcast(x::AbstractVectorOfArray, x̄) N = ndims(x̄) - if length(x) == length(x̄) + return if length(x) == length(x̄) Zygote._project(x, x̄) # ProjectTo handles reshape, offsets, structured matrices, row vectors else dims = ntuple(d -> size(x, d) == 1 ? d : ndims(x̄) + 1, ndims(x̄)) @@ -302,15 +360,22 @@ end @adjoint Broadcast.broadcasted( ::Broadcast.AbstractArrayStyle, f::F, a::AbstractVectorOfArray, - b) where {F} = _broadcast_generic( - __context__, f, a, b) -@adjoint Broadcast.broadcasted(::Broadcast.AbstractArrayStyle, f::F, a, - b::AbstractVectorOfArray) where {F} = _broadcast_generic( - __context__, f, a, b) + b +) where {F} = _broadcast_generic( + __context__, f, a, b +) +@adjoint Broadcast.broadcasted( + ::Broadcast.AbstractArrayStyle, f::F, a, + b::AbstractVectorOfArray +) where {F} = _broadcast_generic( + __context__, f, a, b +) @adjoint Broadcast.broadcasted( ::Broadcast.AbstractArrayStyle, f::F, a::AbstractVectorOfArray, - b::AbstractVectorOfArray) where {F} = _broadcast_generic( - __context__, f, a, b) + b::AbstractVectorOfArray +) where {F} = _broadcast_generic( + __context__, f, a, b +) @inline function _broadcast_generic(__context__, f::F, args...) where {F} T = Broadcast.combine_eltypes(f, args) @@ -318,7 +383,7 @@ end if T == Bool return (f.(args...), _ -> nothing) elseif T <: Union{Real, Complex} && isconcretetype(T) && Zygote._dual_purefun(F) && - all(Zygote._dual_safearg, args) && !Zygote.isderiving() + all(Zygote._dual_safearg, args) && !Zygote.isderiving() return Zygote.broadcast_forward(f, args...) end len = Zygote.inclen(args) @@ -330,8 +395,10 @@ end dxs_zip = map(((_, pb), ȳ₁) -> pb(ȳ₁), y∂b, ȳ) getters = ntuple(i -> Zygote.StaticGetter{i}(), len) dxs = map(g -> Zygote.collapse_nothings(map(g, dxs_zip)), getters) - (nothing, Zygote.accum_sum(dxs[1]), - map(Zygote.unbroadcast, args, Base.tail(dxs))...) + return ( + nothing, Zygote.accum_sum(dxs[1]), + map(Zygote.unbroadcast, args, Base.tail(dxs))..., + ) end return y, ∇broadcasted end diff --git a/src/RecursiveArrayTools.jl b/src/RecursiveArrayTools.jl index d366e6a3..20a030f2 100644 --- a/src/RecursiveArrayTools.jl +++ b/src/RecursiveArrayTools.jl @@ -4,144 +4,144 @@ $(DocStringExtensions.README) """ module RecursiveArrayTools -using DocStringExtensions -using RecipesBase, StaticArraysCore, - ArrayInterface, LinearAlgebra -using SymbolicIndexingInterface + using DocStringExtensions + using RecipesBase, StaticArraysCore, + ArrayInterface, LinearAlgebra + using SymbolicIndexingInterface -import Adapt + import Adapt -""" - AbstractVectorOfArray{T, N, A} + """ + AbstractVectorOfArray{T, N, A} -An AbstractVectorOfArray is an object which represents arrays of arrays, -and arbitrary recursive nesting of arrays, as a single array-like object. -Thus a canonical example of an AbstractVectorOfArray is something of the -form `VectorOfArray([[1,2],[3,4]])`, which "acts" like the matrix `[1 3; 2 4]` -where the data is stored and accessed in a column-ordered fashion (as is typical -in Julia), but the actual matrix is never constructed and instead lazily represented -through the type. + An AbstractVectorOfArray is an object which represents arrays of arrays, + and arbitrary recursive nesting of arrays, as a single array-like object. + Thus a canonical example of an AbstractVectorOfArray is something of the + form `VectorOfArray([[1,2],[3,4]])`, which "acts" like the matrix `[1 3; 2 4]` + where the data is stored and accessed in a column-ordered fashion (as is typical + in Julia), but the actual matrix is never constructed and instead lazily represented + through the type. -An AbstractVectorOfArray subtype should match the following behaviors. + An AbstractVectorOfArray subtype should match the following behaviors. -!!! note + !!! note - In 2023 the linear indexing `A[i]` was deprecated. It previously had the behavior that `A[i] = A.u[i]`. However, this is incompatible with standard `AbstractArray` interfaces, Since if `A = VectorOfArray([[1,2],[3,4]])` and `A` is supposed to act like `[1 3; 2 4]`, then there is a difference `A[1] = [1,2]` for the VectorOfArray while `A[1] = 1` for the matrix. This causes many issues if `AbstractVectorOfArray <: AbstractArray`. Thus we plan in 2026 to complete the deprecation and thus have a breaking update where `A[i]` matches the linear indexing of an`AbstractArray`, and then making `AbstractVectorOfArray <: AbstractArray`. Until then, `AbstractVectorOfArray` due to - this interface break but manually implements an `AbstractArray`-like interface for - future compatibility. + In 2023 the linear indexing `A[i]` was deprecated. It previously had the behavior that `A[i] = A.u[i]`. However, this is incompatible with standard `AbstractArray` interfaces, Since if `A = VectorOfArray([[1,2],[3,4]])` and `A` is supposed to act like `[1 3; 2 4]`, then there is a difference `A[1] = [1,2]` for the VectorOfArray while `A[1] = 1` for the matrix. This causes many issues if `AbstractVectorOfArray <: AbstractArray`. Thus we plan in 2026 to complete the deprecation and thus have a breaking update where `A[i]` matches the linear indexing of an`AbstractArray`, and then making `AbstractVectorOfArray <: AbstractArray`. Until then, `AbstractVectorOfArray` due to + this interface break but manually implements an `AbstractArray`-like interface for + future compatibility. -## Fields + ## Fields -An AbstractVectorOfArray has the following fields: + An AbstractVectorOfArray has the following fields: - - `u` which holds the Vector of values at each timestep + - `u` which holds the Vector of values at each timestep -## Array Interface + ## Array Interface -The general operations are as follows. Use + The general operations are as follows. Use -```julia -A.u[j] -``` + ```julia + A.u[j] + ``` -to access the `j`th array. For multidimensional systems, this -will address first by component and lastly by time, and thus + to access the `j`th array. For multidimensional systems, this + will address first by component and lastly by time, and thus -```julia -A[i, j] -``` + ```julia + A[i, j] + ``` -will be the `i`th component at array `j`. Hence, `A[j][i] == A[i, j]`. This is done -because Julia is column-major, so the leading dimension should be contiguous in memory. -If the independent variables had shape (for example, was a matrix), then `i` is the -linear index. We can also access solutions with shape: + will be the `i`th component at array `j`. Hence, `A[j][i] == A[i, j]`. This is done + because Julia is column-major, so the leading dimension should be contiguous in memory. + If the independent variables had shape (for example, was a matrix), then `i` is the + linear index. We can also access solutions with shape: -```julia -A[i, k, j] -``` + ```julia + A[i, k, j] + ``` -gives the `[i,k]` component of the system at array `j`. The colon operator is -supported, meaning that + gives the `[i,k]` component of the system at array `j`. The colon operator is + supported, meaning that -```julia -A[i, :] -``` + ```julia + A[i, :] + ``` -gives the timeseries for the `i`th component. + gives the timeseries for the `i`th component. -## Using the AbstractArray Interface + ## Using the AbstractArray Interface -The `AbstractArray` interface can be directly used. For example, for a vector -system of variables `A[i,j]` is a matrix with rows being the variables and -columns being the timepoints. Operations like `A'` will -transpose the solution type. Functionality written for `AbstractArray`s can -directly use this. For example, the Base `cov` function computes correlations -amongst columns, and thus: + The `AbstractArray` interface can be directly used. For example, for a vector + system of variables `A[i,j]` is a matrix with rows being the variables and + columns being the timepoints. Operations like `A'` will + transpose the solution type. Functionality written for `AbstractArray`s can + directly use this. For example, the Base `cov` function computes correlations + amongst columns, and thus: -```julia -cov(A) -``` + ```julia + cov(A) + ``` -computes the correlation of the system state in time, whereas + computes the correlation of the system state in time, whereas -```julia -cov(A, 2) -``` + ```julia + cov(A, 2) + ``` -computes the correlation between the variables. Similarly, `mean(A,2)` is the -mean of the variable in time, and `var(A,2)` is the variance. Other statistical -functions and packages which work on `AbstractArray` types will work on the -solution type. + computes the correlation between the variables. Similarly, `mean(A,2)` is the + mean of the variable in time, and `var(A,2)` is the variance. Other statistical + functions and packages which work on `AbstractArray` types will work on the + solution type. -## Conversions + ## Conversions -At anytime, a true `Array` can be created using `Array(A)`, or more generally `stack(A)` -to make the array type match the internal array type (for example, if `A` is an array -of GPU arrays, `stack(A)` will be a GPU array). -""" -abstract type AbstractVectorOfArray{T, N, A} end + At anytime, a true `Array` can be created using `Array(A)`, or more generally `stack(A)` + to make the array type match the internal array type (for example, if `A` is an array + of GPU arrays, `stack(A)` will be a GPU array). + """ + abstract type AbstractVectorOfArray{T, N, A} end -""" - AbstractDiffEqArray{T, N, A} <: AbstractVectorOfArray{T, N, A} + """ + AbstractDiffEqArray{T, N, A} <: AbstractVectorOfArray{T, N, A} -An AbstractVectorOfArray object which has extra information of a time array `A.t` -in order to specify a time series. A canonical AbstractDiffEqArray is for example -the pairing `DiffEqArray([[1,2],[3,4]],[1.0,2.0])` which means that at time 1.0 -the values were `[1,2]` and at time 2.0 the values were `[3,4]`. + An AbstractVectorOfArray object which has extra information of a time array `A.t` + in order to specify a time series. A canonical AbstractDiffEqArray is for example + the pairing `DiffEqArray([[1,2],[3,4]],[1.0,2.0])` which means that at time 1.0 + the values were `[1,2]` and at time 2.0 the values were `[3,4]`. -An AbstractDiffEqArray has all of the same behaviors as an AbstractVectorOfArray with the -additional properties: + An AbstractDiffEqArray has all of the same behaviors as an AbstractVectorOfArray with the + additional properties: -## Fields + ## Fields -An AbstractDiffEqArray adds the following fields: + An AbstractDiffEqArray adds the following fields: - - `t` which holds the times of each timestep. -""" -abstract type AbstractDiffEqArray{T, N, A} <: AbstractVectorOfArray{T, N, A} end + - `t` which holds the times of each timestep. + """ + abstract type AbstractDiffEqArray{T, N, A} <: AbstractVectorOfArray{T, N, A} end -include("utils.jl") -include("vector_of_array.jl") -include("array_partition.jl") -include("named_array_partition.jl") + include("utils.jl") + include("vector_of_array.jl") + include("array_partition.jl") + include("named_array_partition.jl") -function Base.show(io::IO, x::Union{ArrayPartition, AbstractVectorOfArray}) - invoke(show, Tuple{typeof(io), Any}, io, x) -end + function Base.show(io::IO, x::Union{ArrayPartition, AbstractVectorOfArray}) + return invoke(show, Tuple{typeof(io), Any}, io, x) + end -import GPUArraysCore -Base.convert(T::Type{<:GPUArraysCore.AnyGPUArray}, VA::AbstractVectorOfArray) = stack(VA.u) -(T::Type{<:GPUArraysCore.AnyGPUArray})(VA::AbstractVectorOfArray) = T(Array(VA)) + import GPUArraysCore + 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, - AllObserved, vecarr_to_vectors, tuples + export VectorOfArray, 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 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, NamedArrayPartition -include("precompilation.jl") + include("precompilation.jl") end # module diff --git a/src/array_partition.jl b/src/array_partition.jl index 7eac2028..8f9ce1f1 100644 --- a/src/array_partition.jl +++ b/src/array_partition.jl @@ -65,7 +65,7 @@ end # similar array partition of common type @inline function Base.similar(A::ArrayPartition, ::Type{T}) where {T} N = npartitions(A) - ArrayPartition(i -> similar(A.x[i], T), N) + return ArrayPartition(i -> similar(A.x[i], T), N) end # return ArrayPartition when possible, otherwise next best thing of the correct size @@ -85,9 +85,9 @@ function Base.similar(A::ArrayPartition, ::Type{T}, ::Type{S}, R::DataType...) w types = (T, S, R...) # new types @inline function f(i) - similar(A.x[i], types[i]) + return similar(A.x[i], types[i]) end - ArrayPartition(f, N) + return ArrayPartition(f, N) end Base.copy(A::ArrayPartition) = ArrayPartition(map(copy, A.x)) @@ -100,15 +100,19 @@ Base.zero(A::ArrayPartition, dims::NTuple{N, Int}) where {N} = zero(A) ## Array Base.Array(A::ArrayPartition) = reduce(vcat, Array.(A.x)) -function Base.Array(VA::AbstractVectorOfArray{ - T, - N, - A -}) where {T, N, +function Base.Array( + VA::AbstractVectorOfArray{ + T, + N, + A, + } + ) where { + T, N, A <: AbstractVector{ <:ArrayPartition, - }} - reduce(hcat, Array.(VA.u)) + }, + } + return reduce(hcat, Array.(VA.u)) end ## ones @@ -120,15 +124,16 @@ function Base.ones(A::ArrayPartition) for i in 1:N fill!(out.x[i], oneunit(eltype(out.x[i]))) end - out + return out end # ignore dims since array partitions are vectors Base.ones(A::ArrayPartition, dims::NTuple{N, Int}) where {N} = ones(A) # mutable iff all components of ArrayPartition are mutable -@generated function ArrayInterface.ismutable(::Type{<:ArrayPartition{T, S}}) where {T, S -} +@generated function ArrayInterface.ismutable(::Type{<:ArrayPartition{T, S}}) where { + T, S, + } res = all(ArrayInterface.ismutable, S.parameters) return :($res) end @@ -136,7 +141,7 @@ end ## resize! function Base.resize!(A::ArrayPartition, sizes::Tuple) resize!.(A.x, sizes) - A + return A end ## vector space operations @@ -144,15 +149,15 @@ end for op in (:+, :-) @eval begin function Base.$op(A::ArrayPartition, B::ArrayPartition) - ArrayPartition(map((x, y) -> Base.broadcast($op, x, y), A.x, B.x)) + return ArrayPartition(map((x, y) -> Base.broadcast($op, x, y), A.x, B.x)) end function Base.$op(A::ArrayPartition, B::Number) - ArrayPartition(map(y -> Base.broadcast($op, y, B), A.x)) + return ArrayPartition(map(y -> Base.broadcast($op, y, B), A.x)) end function Base.$op(A::Number, B::ArrayPartition) - ArrayPartition(map(y -> Base.broadcast($op, A, y), B.x)) + return ArrayPartition(map(y -> Base.broadcast($op, A, y), B.x)) end end end @@ -163,16 +168,16 @@ end for op in (:*, :/) @eval function Base.$op(A::ArrayPartition, B::Number) - ArrayPartition(map(y -> Base.broadcast($op, y, B), A.x)) + return ArrayPartition(map(y -> Base.broadcast($op, y, B), A.x)) end end function Base.:*(A::Number, B::ArrayPartition) - ArrayPartition(map(y -> A .* y, B.x)) + return ArrayPartition(map(y -> A .* y, B.x)) end function Base.:\(A::Number, B::ArrayPartition) - B / A + return B / A end Base.:(==)(A::ArrayPartition, B::ArrayPartition) = A.x == B.x @@ -207,9 +212,11 @@ end return :(op(init, $expr)) end end -@inline function Base.mapreduce(f, op, A::ArrayPartition; - init = Base._InitialValue(), kwargs...) - if init isa Base._InitialValue +@inline function Base.mapreduce( + f, op, A::ArrayPartition; + init = Base._InitialValue(), kwargs... + ) + return if init isa Base._InitialValue _mapreduce_impl(f, op, A) else _mapreduce_impl_init(f, op, A, init) @@ -235,7 +242,7 @@ for type in [AbstractArray, PermutedDimsArray] end cur += length(A.x[i]) end - dest + return dest end end @@ -253,18 +260,18 @@ function Base.copyto!(A::ArrayPartition, src::ArrayPartition) end end end - A + return A end function Base.fill!(A::ArrayPartition, x) unrolled_foreach!(A.x) do x_ fill!(x_, x) end - A + return A end function recursivefill!(b::ArrayPartition, a::T2) where {T2 <: Union{Number, Bool}} - unrolled_foreach!(b.x) do x + return unrolled_foreach!(b.x) do x fill!(x, a) end end @@ -304,7 +311,7 @@ Base.getindex(A::ArrayPartition{T, S}, ::Colon) where {T, S} = T[a for a in Chai Base.@propagate_inbounds function Base.setindex!(A::ArrayPartition, v, i::Int) @boundscheck checkbounds(A, i) - @inbounds for j in 1:length(A.x) + return @inbounds for j in 1:length(A.x) i -= length(A.x[j]) if i <= 0 A.x[j][length(A.x[j]) + i] = v @@ -314,8 +321,10 @@ Base.@propagate_inbounds function Base.setindex!(A::ArrayPartition, v, i::Int) end # workaround for https://github.com/SciML/RecursiveArrayTools.jl/issues/49 -function Base._unsafe_getindex(::IndexStyle, A::ArrayPartition, - I::Vararg{Union{Real, AbstractArray}, N}) where {N} +function Base._unsafe_getindex( + ::IndexStyle, A::ArrayPartition, + I::Vararg{Union{Real, AbstractArray}, N} + ) where {N} # This is specifically not inlined to prevent excessive allocations in type unstable code shape = Base.index_shape(I...) dest = similar(A.x[1], shape) @@ -323,10 +332,12 @@ function Base._unsafe_getindex(::IndexStyle, A::ArrayPartition, return dest end -function Base._maybe_reshape(::IndexCartesian, +function Base._maybe_reshape( + ::IndexCartesian, A::ArrayPartition, - I::Vararg{Union{Real, AbstractArray}, N}) where {N} - Vector(A) + I::Vararg{Union{Real, AbstractArray}, N} + ) where {N} + return Vector(A) end ## recursive methods @@ -335,16 +346,22 @@ function recursivecopy!(A::ArrayPartition, B::ArrayPartition) for (a, b) in zip(A.x, B.x) recursivecopy!(a, b) end + return end recursivecopy(A::ArrayPartition) = ArrayPartition(copy.(A.x)) -function recursivecopy(A::ArrayPartition{ - T, S}) where {T, S <: Tuple{Vararg{AbstractVectorOfArray}}} +function recursivecopy( + A::ArrayPartition{ + T, S, + } + ) where {T, S <: Tuple{Vararg{AbstractVectorOfArray}}} return ArrayPartition(map(recursivecopy, A.x)) end -function recursivecopy!(A::ArrayPartition{T, S}, - B::ArrayPartition{T, S}) where {T, S <: Tuple{Vararg{AbstractVectorOfArray}}} +function recursivecopy!( + A::ArrayPartition{T, S}, + B::ArrayPartition{T, S} + ) where {T, S <: Tuple{Vararg{AbstractVectorOfArray}}} for i in eachindex(A.x, B.x) recursivecopy!(A.x[i], B.x[i]) end @@ -386,56 +403,70 @@ Base.show(io::IO, m::MIME"text/plain", A::ArrayPartition) = show(io, m, A.x) ## broadcasting struct ArrayPartitionStyle{Style <: Broadcast.BroadcastStyle} <: - Broadcast.AbstractArrayStyle{Any} end + Broadcast.AbstractArrayStyle{Any} end ArrayPartitionStyle(::S) where {S} = ArrayPartitionStyle{S}() ArrayPartitionStyle(::S, ::Val{N}) where {S, N} = ArrayPartitionStyle(S(Val(N))) function ArrayPartitionStyle(::Val{N}) where {N} - ArrayPartitionStyle{Broadcast.DefaultArrayStyle{N}}() + return ArrayPartitionStyle{Broadcast.DefaultArrayStyle{N}}() end # promotion rules -@inline function Broadcast.BroadcastStyle(::ArrayPartitionStyle{AStyle}, - ::ArrayPartitionStyle{BStyle}) where {AStyle, - BStyle} - ArrayPartitionStyle(Broadcast.BroadcastStyle(AStyle(), BStyle())) -end -function Broadcast.BroadcastStyle(::ArrayPartitionStyle{Style}, - ::Broadcast.DefaultArrayStyle{0}) where { +@inline function Broadcast.BroadcastStyle( + ::ArrayPartitionStyle{AStyle}, + ::ArrayPartitionStyle{BStyle} + ) where { + AStyle, + BStyle, + } + return ArrayPartitionStyle(Broadcast.BroadcastStyle(AStyle(), BStyle())) +end +function Broadcast.BroadcastStyle( + ::ArrayPartitionStyle{Style}, + ::Broadcast.DefaultArrayStyle{0} + ) where { Style <: Broadcast.BroadcastStyle, -} - ArrayPartitionStyle{Style}() + } + return ArrayPartitionStyle{Style}() end -function Broadcast.BroadcastStyle(::ArrayPartitionStyle, - ::Broadcast.DefaultArrayStyle{N}) where {N} - Broadcast.DefaultArrayStyle{N}() +function Broadcast.BroadcastStyle( + ::ArrayPartitionStyle, + ::Broadcast.DefaultArrayStyle{N} + ) where {N} + return Broadcast.DefaultArrayStyle{N}() end combine_styles(::Type{Tuple{}}) = Broadcast.DefaultArrayStyle{0}() function combine_styles(::Type{T}) where {T} - Broadcast.result_style(Broadcast.BroadcastStyle(T.parameters[1]), - combine_styles(Tuple{Base.tail((T.parameters...,))...})) + return Broadcast.result_style( + Broadcast.BroadcastStyle(T.parameters[1]), + combine_styles(Tuple{Base.tail((T.parameters...,))...}) + ) end function Broadcast.BroadcastStyle(::Type{ArrayPartition{T, S}}) where {T, S} Style = combine_styles(S) - ArrayPartitionStyle(Style) + return ArrayPartitionStyle(Style) end -@inline function Base.copy(bc::Broadcast.Broadcasted{ - ArrayPartitionStyle{Style}, -}) where { +@inline function Base.copy( + bc::Broadcast.Broadcasted{ + ArrayPartitionStyle{Style}, + } + ) where { Style, -} + } N = npartitions(bc) @inline function f(i) - copy(unpack(bc, i)) + return copy(unpack(bc, i)) end - ArrayPartition(f, N) + return ArrayPartition(f, N) end -@inline function Base.copyto!(dest::ArrayPartition, - bc::Broadcast.Broadcasted{ArrayPartitionStyle{Style}}) where {Style} +@inline function Base.copyto!( + dest::ArrayPartition, + bc::Broadcast.Broadcasted{ArrayPartitionStyle{Style}} + ) where {Style} N = npartitions(dest, bc) # If dest is all the same underlying array type, use for-loop if all(x isa typeof(first(dest.x)) for x in dest.x) @@ -445,11 +476,11 @@ end else # Fall back to original implementation for complex broadcasts @inline function f(i) - copyto!(dest.x[i], unpack(bc, i)) + return copyto!(dest.x[i], unpack(bc, i)) end ntuple(f, Val(N)) end - dest + return dest end ## broadcasting utils @@ -466,63 +497,77 @@ npartitions(bc::Broadcast.Broadcasted) = _npartitions(bc.args) npartitions(A, Bs...) = common_number(npartitions(A), _npartitions(Bs)) @inline function _npartitions(args::Tuple) - common_number(npartitions(args[1]), _npartitions(Base.tail(args))) + return common_number(npartitions(args[1]), _npartitions(Base.tail(args))) end _npartitions(args::Tuple{Any}) = npartitions(args[1]) _npartitions(args::Tuple{}) = 0 # drop axes because it is easier to recompute @inline function unpack(bc::Broadcast.Broadcasted{Style}, i) where {Style} - Broadcast.Broadcasted(bc.f, unpack_args(i, bc.args)) -end -@inline function unpack(bc::Broadcast.Broadcasted{ArrayPartitionStyle{Style}}, - i) where {Style} - Broadcast.Broadcasted(bc.f, unpack_args(i, bc.args)) -end -@inline function unpack(bc::Broadcast.Broadcasted{Style}, - i) where {Style <: Broadcast.DefaultArrayStyle} - Broadcast.Broadcasted{Style}(bc.f, unpack_args(i, bc.args)) -end -@inline function unpack(bc::Broadcast.Broadcasted{ArrayPartitionStyle{Style}}, - i) where {Style <: Broadcast.DefaultArrayStyle} - Broadcast.Broadcasted{Style}(bc.f, unpack_args(i, bc.args)) + return Broadcast.Broadcasted(bc.f, unpack_args(i, bc.args)) +end +@inline function unpack( + bc::Broadcast.Broadcasted{ArrayPartitionStyle{Style}}, + i + ) where {Style} + return Broadcast.Broadcasted(bc.f, unpack_args(i, bc.args)) +end +@inline function unpack( + bc::Broadcast.Broadcasted{Style}, + i + ) where {Style <: Broadcast.DefaultArrayStyle} + return Broadcast.Broadcasted{Style}(bc.f, unpack_args(i, bc.args)) +end +@inline function unpack( + bc::Broadcast.Broadcasted{ArrayPartitionStyle{Style}}, + i + ) where {Style <: Broadcast.DefaultArrayStyle} + return Broadcast.Broadcasted{Style}(bc.f, unpack_args(i, bc.args)) end @inline unpack(x, ::Any) = x @inline unpack(x::ArrayPartition, i) = x.x[i] @inline function unpack_args(i, args::Tuple) - (unpack(args[1], i), unpack_args(i, Base.tail(args))...) + return (unpack(args[1], i), unpack_args(i, Base.tail(args))...) end unpack_args(i, args::Tuple{Any}) = (unpack(args[1], i),) unpack_args(::Any, args::Tuple{}) = () ## utils function common_number(a, b) - a == 0 ? b : - (b == 0 ? a : - (a == b ? a : - throw(DimensionMismatch("number of partitions must be equal")))) + return a == 0 ? b : + ( + b == 0 ? a : + ( + a == b ? a : + throw(DimensionMismatch("number of partitions must be equal")) + ) + ) end ## Linear Algebra function ArrayInterface.zeromatrix(A::ArrayPartition) x = reduce(vcat, vec.(A.x)) - x .* x' .* false + return x .* x' .* false end function __get_subtypes_in_module( - mod, supertype; include_supertype = true, all = false, except = []) + mod, supertype; include_supertype = true, all = false, except = [] + ) return filter([getproperty(mod, name) for name in names(mod; all) if !in(name, except)]) do value return value != Union{} && value isa Type && (value <: supertype) && - (include_supertype || value != supertype) && !in(value, except) + (include_supertype || value != supertype) && !in(value, except) end end for factorization in vcat( - __get_subtypes_in_module(LinearAlgebra, Factorization; include_supertype = false, - all = true, except = [:LU, :LAPACKFactorizations]), - LDLt{T, <:SymTridiagonal{T, V} where {V <: AbstractVector{T}}} where {T}) + __get_subtypes_in_module( + LinearAlgebra, Factorization; include_supertype = false, + all = true, except = [:LU, :LAPACKFactorizations] + ), + LDLt{T, <:SymTridiagonal{T, V} where {V <: AbstractVector{T}}} where {T} + ) @eval function LinearAlgebra.ldiv!(A::T, b::ArrayPartition) where {T <: $factorization} (x = ldiv!(A, Array(b)); copyto!(b, x)) end @@ -530,17 +575,20 @@ end function LinearAlgebra.ldiv!( A::LinearAlgebra.QRPivoted{T, <:StridedMatrix{T}, <:AbstractVector{T}}, - b::ArrayPartition{T}) where {T <: Union{Float32, Float64, ComplexF64, ComplexF32}} + b::ArrayPartition{T} + ) where {T <: Union{Float32, Float64, ComplexF64, ComplexF32}} x = ldiv!(A, Array(b)) - copyto!(b, x) + return copyto!(b, x) end -function LinearAlgebra.ldiv!(A::LinearAlgebra.QRCompactWY{T, M, C}, - b::ArrayPartition) where { +function LinearAlgebra.ldiv!( + A::LinearAlgebra.QRCompactWY{T, M, C}, + b::ArrayPartition + ) where { T <: Union{Float32, Float64, ComplexF64, ComplexF32}, M <: AbstractMatrix{T}, - C <: AbstractMatrix{T} -} + C <: AbstractMatrix{T}, + } (x = ldiv!(A, Array(b)); copyto!(b, x)) end @@ -566,8 +614,10 @@ end # [ 0 U22 U23] \ [ b2 ] # [ 0 0 U33] [ b3 ] for basetype in [UnitUpperTriangular, UpperTriangular, UnitLowerTriangular, LowerTriangular] - for type in [basetype, basetype{T, <:Adjoint{T}} where {T}, - basetype{T, <:Transpose{T}} where {T}] + for type in [ + basetype, basetype{T, <:Adjoint{T}} where {T}, + basetype{T, <:Transpose{T}} where {T}, + ] j_iter, i_iter = if basetype <: UnitUpperTriangular || basetype <: UpperTriangular (:(n:-1:1), :((j - 1):-1:1)) else @@ -632,20 +682,33 @@ function LinearAlgebra.mul!(C::ArrayPartition, A::ArrayPartition, B::ArrayPartit return C end -function Base.convert(::Type{ArrayPartition{T, S}}, - A::ArrayPartition{<:Any, <:NTuple{N, Any}}) where {N, T, +function Base.convert( + ::Type{ArrayPartition{T, S}}, + A::ArrayPartition{<:Any, <:NTuple{N, Any}} + ) where { + N, T, S <: - NTuple{N, Any}} - return ArrayPartition{T, S}(ntuple((@inline i -> convert(S.parameters[i], A.x[i])), - Val(N))) -end - -@generated function Base.length(::Type{ - <:ArrayPartition{F, T}, -}) where {F, N, - T <: NTuple{N, - StaticArraysCore.StaticArray - }} + NTuple{N, Any}, + } + return ArrayPartition{T, S}( + ntuple( + (@inline i -> convert(S.parameters[i], A.x[i])), + Val(N) + ) + ) +end + +@generated function Base.length( + ::Type{ + <:ArrayPartition{F, T}, + } + ) where { + F, N, + T <: NTuple{ + N, + StaticArraysCore.StaticArray, + }, + } sum_expr = Expr(:call, :+) for param in T.parameters push!(sum_expr.args, :(length($param))) @@ -654,5 +717,5 @@ end end function Adapt.adapt_structure(to, ap::ArrayPartition) - ArrayPartition(map(x -> Adapt.adapt(to, x), ap.x)...) + return ArrayPartition(map(x -> Adapt.adapt(to, x), ap.x)...) end diff --git a/src/named_array_partition.jl b/src/named_array_partition.jl index 3e8abf4e..d80fe090 100644 --- a/src/named_array_partition.jl +++ b/src/named_array_partition.jl @@ -12,8 +12,10 @@ struct NamedArrayPartition{T, A <: ArrayPartition{T}, NT <: NamedTuple} <: Abstr end NamedArrayPartition(; kwargs...) = NamedArrayPartition(NamedTuple(kwargs)) function NamedArrayPartition(x::NamedTuple) - names_to_indices = NamedTuple(Pair(symbol, index) - for (index, symbol) in enumerate(keys(x))) + names_to_indices = NamedTuple( + Pair(symbol, index) + for (index, symbol) in enumerate(keys(x)) + ) # enforce homogeneity of eltypes @assert all(eltype.(values(x)) .== eltype(first(x))) @@ -27,58 +29,65 @@ end ArrayPartition(x::NamedArrayPartition) = getfield(x, :array_partition) function Base.similar(A::NamedArrayPartition) - NamedArrayPartition( - similar(getfield(A, :array_partition)), getfield(A, :names_to_indices)) + return NamedArrayPartition( + similar(getfield(A, :array_partition)), getfield(A, :names_to_indices) + ) end # return ArrayPartition when possible, otherwise next best thing of the correct size function Base.similar(A::NamedArrayPartition, dims::NTuple{N, Int}) where {N} - NamedArrayPartition( - similar(getfield(A, :array_partition), dims), getfield(A, :names_to_indices)) + return NamedArrayPartition( + similar(getfield(A, :array_partition), dims), getfield(A, :names_to_indices) + ) end # similar array partition of common type @inline function Base.similar(A::NamedArrayPartition, ::Type{T}) where {T} - NamedArrayPartition( - similar(getfield(A, :array_partition), T), getfield(A, :names_to_indices)) + return NamedArrayPartition( + similar(getfield(A, :array_partition), T), getfield(A, :names_to_indices) + ) end # return ArrayPartition when possible, otherwise next best thing of the correct size function Base.similar(A::NamedArrayPartition, ::Type{T}, dims::NTuple{N, Int}) where {T, N} - NamedArrayPartition( - similar(getfield(A, :array_partition), T, dims), getfield(A, :names_to_indices)) + return NamedArrayPartition( + similar(getfield(A, :array_partition), T, dims), getfield(A, :names_to_indices) + ) end # similar array partition with different types function Base.similar( - A::NamedArrayPartition, ::Type{T}, ::Type{S}, R::DataType...) where {T, S} - NamedArrayPartition( - similar(getfield(A, :array_partition), T, S, R...), getfield(A, :names_to_indices)) + A::NamedArrayPartition, ::Type{T}, ::Type{S}, R::DataType... + ) where {T, S} + return NamedArrayPartition( + similar(getfield(A, :array_partition), T, S, R...), getfield(A, :names_to_indices) + ) end Base.Array(x::NamedArrayPartition) = Array(ArrayPartition(x)) function Base.zero(x::NamedArrayPartition{T, S, TN}) where {T, S, TN} - NamedArrayPartition{T, S, TN}(zero(ArrayPartition(x)), getfield(x, :names_to_indices)) + return NamedArrayPartition{T, S, TN}(zero(ArrayPartition(x)), getfield(x, :names_to_indices)) end Base.zero(A::NamedArrayPartition, dims::NTuple{N, Int}) where {N} = zero(A) # ignore dims since named array partitions are vectors Base.propertynames(x::NamedArrayPartition) = propertynames(getfield(x, :names_to_indices)) function Base.getproperty(x::NamedArrayPartition, s::Symbol) - getindex(ArrayPartition(x).x, getproperty(getfield(x, :names_to_indices), s)) + return getindex(ArrayPartition(x).x, getproperty(getfield(x, :names_to_indices), s)) end # this enables x.s = some_array. @inline function Base.setproperty!(x::NamedArrayPartition, s::Symbol, v) index = getproperty(getfield(x, :names_to_indices), s) - ArrayPartition(x).x[index] .= v + return ArrayPartition(x).x[index] .= v end # print out NamedArrayPartition as a NamedTuple Base.summary(x::NamedArrayPartition) = string(typeof(x), " with arrays:") function Base.show(io::IO, m::MIME"text/plain", x::NamedArrayPartition) - show( - io, m, NamedTuple(Pair.(keys(getfield(x, :names_to_indices)), ArrayPartition(x).x))) + return show( + io, m, NamedTuple(Pair.(keys(getfield(x, :names_to_indices)), ArrayPartition(x).x)) + ) end Base.size(x::NamedArrayPartition) = size(ArrayPartition(x)) @@ -87,61 +96,74 @@ Base.getindex(x::NamedArrayPartition, args...) = getindex(ArrayPartition(x), arg Base.setindex!(x::NamedArrayPartition, args...) = setindex!(ArrayPartition(x), args...) function Base.map(f, x::NamedArrayPartition) - NamedArrayPartition(map(f, ArrayPartition(x)), getfield(x, :names_to_indices)) + return NamedArrayPartition(map(f, ArrayPartition(x)), getfield(x, :names_to_indices)) end Base.mapreduce(f, op, x::NamedArrayPartition) = mapreduce(f, op, ArrayPartition(x)) # Base.filter(f, x::NamedArrayPartition) = filter(f, ArrayPartition(x)) function Base.similar(x::NamedArrayPartition{T, S, NT}) where {T, S, NT} - NamedArrayPartition{T, S, NT}( - similar(ArrayPartition(x)), getfield(x, :names_to_indices)) + return NamedArrayPartition{T, S, NT}( + similar(ArrayPartition(x)), getfield(x, :names_to_indices) + ) end # broadcasting function Base.BroadcastStyle(::Type{<:NamedArrayPartition}) - Broadcast.ArrayStyle{NamedArrayPartition}() + return Broadcast.ArrayStyle{NamedArrayPartition}() end -function Base.similar(bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{NamedArrayPartition}}, - ::Type{ElType}) where {ElType} +function Base.similar( + bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{NamedArrayPartition}}, + ::Type{ElType} + ) where {ElType} x = find_NamedArrayPartition(bc) return NamedArrayPartition(similar(ArrayPartition(x)), getfield(x, :names_to_indices)) end # when broadcasting with ArrayPartition + another array type, the output is the other array tupe function Base.BroadcastStyle( - ::Broadcast.ArrayStyle{NamedArrayPartition}, ::Broadcast.DefaultArrayStyle{1}) - Broadcast.DefaultArrayStyle{1}() + ::Broadcast.ArrayStyle{NamedArrayPartition}, ::Broadcast.DefaultArrayStyle{1} + ) + return Broadcast.DefaultArrayStyle{1}() end # hook into ArrayPartition broadcasting routines @inline RecursiveArrayTools.npartitions(x::NamedArrayPartition) = npartitions(ArrayPartition(x)) @inline RecursiveArrayTools.unpack( bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{NamedArrayPartition}}, - i) = Broadcast.Broadcasted( - bc.f, RecursiveArrayTools.unpack_args(i, bc.args)) + i +) = Broadcast.Broadcasted( + bc.f, RecursiveArrayTools.unpack_args(i, bc.args) +) @inline RecursiveArrayTools.unpack(x::NamedArrayPartition, i) = unpack(ArrayPartition(x), i) function Base.copy(A::NamedArrayPartition{T, S, NT}) where {T, S, NT} - NamedArrayPartition{T, S, NT}(copy(ArrayPartition(A)), getfield(A, :names_to_indices)) + return NamedArrayPartition{T, S, NT}(copy(ArrayPartition(A)), getfield(A, :names_to_indices)) end -@inline NamedArrayPartition(f::F, +@inline NamedArrayPartition( + f::F, N, - names_to_indices) where {F <: - Function} = NamedArrayPartition( - ArrayPartition(ntuple(f, Val(N))), names_to_indices) + names_to_indices +) where { + F <: + Function, +} = NamedArrayPartition( + ArrayPartition(ntuple(f, Val(N))), names_to_indices +) @inline function Base.copy(bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{NamedArrayPartition}}) N = npartitions(bc) @inline function f(i) - copy(unpack(bc, i)) + return copy(unpack(bc, i)) end x = find_NamedArrayPartition(bc) - NamedArrayPartition(f, N, getfield(x, :names_to_indices)) + return NamedArrayPartition(f, N, getfield(x, :names_to_indices)) end -@inline function Base.copyto!(dest::NamedArrayPartition, - bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{NamedArrayPartition}}) +@inline function Base.copyto!( + dest::NamedArrayPartition, + bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{NamedArrayPartition}} + ) N = npartitions(dest, bc) @inbounds for i in 1:N copyto!(getfield(dest, :array_partition).x[i], unpack(bc, i)) @@ -153,13 +175,13 @@ end function ArrayInterface.zeromatrix(A::NamedArrayPartition) B = ArrayPartition(A) x = reduce(vcat, vec.(B.x)) - x .* x' .* false + return x .* x' .* false end # `x = find_NamedArrayPartition(x)` returns the first `NamedArrayPartition` among broadcast arguments. find_NamedArrayPartition(bc::Base.Broadcast.Broadcasted) = find_NamedArrayPartition(bc.args) function find_NamedArrayPartition(args::Tuple) - find_NamedArrayPartition(find_NamedArrayPartition(args[1]), Base.tail(args)) + return find_NamedArrayPartition(find_NamedArrayPartition(args[1]), Base.tail(args)) end find_NamedArrayPartition(x) = x find_NamedArrayPartition(::Tuple{}) = nothing diff --git a/src/utils.jl b/src/utils.jl index 61fbafe4..68916f91 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -10,18 +10,22 @@ A recursive `copy` function. Acts like a `deepcopy` on arrays of arrays, but like `copy` on arrays of scalars. """ function recursivecopy(a) - deepcopy(a) + return deepcopy(a) end -function recursivecopy(a::Union{StaticArraysCore.SVector, StaticArraysCore.SMatrix, - StaticArraysCore.SArray, Number}) - copy(a) +function recursivecopy( + a::Union{ + StaticArraysCore.SVector, StaticArraysCore.SMatrix, + StaticArraysCore.SArray, Number, + } + ) + return copy(a) end function recursivecopy(a::AbstractArray{T, N}) where {T <: Number, N} - copy(a) + return copy(a) end function recursivecopy(a::AbstractArray{T, N}) where {T <: AbstractArray, N} - if ArrayInterface.ismutable(a) + return if ArrayInterface.ismutable(a) b = similar(a) map!(recursivecopy, b, a) else @@ -45,29 +49,41 @@ like `copy!` on arrays of scalars. """ function recursivecopy! end -function recursivecopy!(b::AbstractArray{T, N}, - a::AbstractArray{T2, N}) where {T <: StaticArraysCore.StaticArray, +function recursivecopy!( + b::AbstractArray{T, N}, + a::AbstractArray{T2, N} + ) where { + T <: StaticArraysCore.StaticArray, T2 <: StaticArraysCore.StaticArray, - N} - @inbounds for i in eachindex(a) + N, + } + return @inbounds for i in eachindex(a) # TODO: Check for `setindex!`` and use `copy!(b[i],a[i])` or `b[i] = a[i]`, see #19 b[i] = copy(a[i]) end end -function recursivecopy!(b::AbstractArray{T, N}, - a::AbstractArray{T2, N}) where {T <: Enum, T2 <: Enum, N} - copyto!(b, a) +function recursivecopy!( + b::AbstractArray{T, N}, + a::AbstractArray{T2, N} + ) where {T <: Enum, T2 <: Enum, N} + return copyto!(b, a) end -function recursivecopy!(b::AbstractArray{T, N}, - a::AbstractArray{T2, N}) where {T <: Number, T2 <: Number, N} - copyto!(b, a) +function recursivecopy!( + b::AbstractArray{T, N}, + a::AbstractArray{T2, N} + ) where {T <: Number, T2 <: Number, N} + return copyto!(b, a) end -function recursivecopy!(b::AbstractArray{T, N}, - a::AbstractArray{T2, N}) where {T <: Union{AbstractArray, AbstractVectorOfArray}, - T2 <: Union{AbstractArray, AbstractVectorOfArray}, N} +function recursivecopy!( + b::AbstractArray{T, N}, + a::AbstractArray{T2, N} + ) where { + T <: Union{AbstractArray, AbstractVectorOfArray}, + T2 <: Union{AbstractArray, AbstractVectorOfArray}, N, + } if ArrayInterface.ismutable(T) @inbounds for i in eachindex(b, a) recursivecopy!(b[i], a[i]) @@ -98,36 +114,52 @@ A recursive `fill!` function. """ function recursivefill! end -function recursivefill!(b::AbstractArray{T, N}, - a::T2) where {T <: StaticArraysCore.StaticArray, - T2 <: StaticArraysCore.StaticArray, N} - @inbounds for i in eachindex(b) +function recursivefill!( + b::AbstractArray{T, N}, + a::T2 + ) where { + T <: StaticArraysCore.StaticArray, + T2 <: StaticArraysCore.StaticArray, N, + } + return @inbounds for i in eachindex(b) b[i] = copy(a) end end -function recursivefill!(bs::AbstractVectorOfArray{T, N}, - a::T2) where {T <: StaticArraysCore.StaticArray, - T2 <: StaticArraysCore.StaticArray, N} - @inbounds for b in bs, i in eachindex(b) +function recursivefill!( + bs::AbstractVectorOfArray{T, N}, + a::T2 + ) where { + T <: StaticArraysCore.StaticArray, + T2 <: StaticArraysCore.StaticArray, N, + } + return @inbounds for b in bs, i in eachindex(b) b[i] = copy(a) end end -function recursivefill!(b::AbstractArray{T, N}, - a::T2) where {T <: StaticArraysCore.SArray, - T2 <: Union{Number, Bool}, N} - @inbounds for i in eachindex(b) +function recursivefill!( + b::AbstractArray{T, N}, + a::T2 + ) where { + T <: StaticArraysCore.SArray, + T2 <: Union{Number, Bool}, N, + } + return @inbounds for i in eachindex(b) # Preserve static array shape while replacing all entries with the scalar b[i] = map(_ -> a, b[i]) end end -function recursivefill!(bs::AbstractVectorOfArray{T, N}, - a::T2) where {T <: StaticArraysCore.SArray, - T2 <: Union{Number, Bool}, N} - @inbounds for b in bs, i in eachindex(b) +function recursivefill!( + bs::AbstractVectorOfArray{T, N}, + a::T2 + ) where { + T <: StaticArraysCore.SArray, + T2 <: Union{Number, Bool}, N, + } + return @inbounds for b in bs, i in eachindex(b) # Preserve static array shape while replacing all entries with the scalar b[i] = map(_ -> a, b[i]) @@ -136,19 +168,23 @@ end for type in [AbstractArray, AbstractVectorOfArray] @eval function recursivefill!(b::$type{T, N}, a::T2) where {T <: Enum, T2 <: Enum, N} - fill!(b, a) + return fill!(b, a) end - @eval function recursivefill!(b::$type{T, N}, - a::T2) where {T <: Union{Number, Bool}, T2 <: Union{Number, Bool}, N - } - fill!(b, a) + @eval function recursivefill!( + b::$type{T, N}, + a::T2 + ) where { + T <: Union{Number, Bool}, T2 <: Union{Number, Bool}, N, + } + return fill!(b, a) end for type2 in [Any, StaticArraysCore.StaticArray] @eval function recursivefill!( - b::$type{T, N}, a::$type2) where {T <: StaticArraysCore.MArray, N} - @inbounds for i in eachindex(b) + b::$type{T, N}, a::$type2 + ) where {T <: StaticArraysCore.MArray, N} + return @inbounds for i in eachindex(b) if isassigned(b, i) recursivefill!(b[i], a) else @@ -173,7 +209,7 @@ function vecvec_to_mat(vecvec) for i in 1:length(vecvec) mat[i, :] = vecvec[i] end - mat + return mat end """ @@ -190,17 +226,17 @@ function vecvecapply(f, v::AbstractArray{<:AbstractArray}) push!(sol, v[i][j]) end end - f(sol) + return f(sol) end vecvecapply(f, v::AbstractVectorOfArray) = vecvecapply(f, v.u) function vecvecapply(f, v::Array{T}) where {T <: Number} - f(v) + return f(v) end function vecvecapply(f, v::T) where {T <: Number} - f(v) + return f(v) end """ @@ -231,12 +267,14 @@ function copyat_or_push!(a::AbstractVector{T}, i::Int, x, perform_copy = true) w push!(a, x) end end - nothing + return nothing end -function copyat_or_push!(a::AbstractVector{T}, i::Int, x, - nc::Type{Val{perform_copy}}) where {T, perform_copy} - copyat_or_push!(a, i, x, perform_copy) +function copyat_or_push!( + a::AbstractVector{T}, i::Int, x, + nc::Type{Val{perform_copy}} + ) where {T, perform_copy} + return copyat_or_push!(a, i, x, perform_copy) end """ @@ -262,13 +300,13 @@ ones has a `Array{Array{Float64,N},N}`, this will return `Float64`. recursive_unitless_bottom_eltype(a) = recursive_unitless_bottom_eltype(typeof(a)) recursive_unitless_bottom_eltype(a::Type{Any}) = Any function recursive_unitless_bottom_eltype(a::Type{T}) where {T} - recursive_unitless_bottom_eltype(eltype(a)) + return recursive_unitless_bottom_eltype(eltype(a)) end function recursive_unitless_bottom_eltype(a::Type{T}) where {T <: AbstractArray} - recursive_unitless_bottom_eltype(eltype(a)) + return recursive_unitless_bottom_eltype(eltype(a)) end function recursive_unitless_bottom_eltype(a::Type{T}) where {T <: Number} - eltype(a) == Number ? Float64 : typeof(one(eltype(a))) + return eltype(a) == Number ? Float64 : typeof(one(eltype(a))) end recursive_unitless_bottom_eltype(::Type{<:Enum{T}}) where {T} = T @@ -284,11 +322,11 @@ recursive_unitless_eltype(a) = recursive_unitless_eltype(eltype(a)) recursive_unitless_eltype(a::Type{Any}) = Any function recursive_unitless_eltype(a::Type{T}) where {T <: StaticArraysCore.StaticArray} - StaticArraysCore.similar_type(a, recursive_unitless_eltype(eltype(a))) + return StaticArraysCore.similar_type(a, recursive_unitless_eltype(eltype(a))) end function recursive_unitless_eltype(a::Type{T}) where {T <: Array} - Array{recursive_unitless_eltype(eltype(a)), ndims(a)} + return Array{recursive_unitless_eltype(eltype(a)), ndims(a)} end recursive_unitless_eltype(a::Type{T}) where {T <: Number} = typeof(one(eltype(a))) recursive_unitless_eltype(::Type{<:Enum{T}}) where {T} = T @@ -298,16 +336,16 @@ function recursive_mean(vecvec::Vector{T}) where {T <: AbstractArray} for i in eachindex(vecvec) out += vecvec[i] end - out / length(vecvec) + return out / length(vecvec) end # Fallback for scalars and general cases without Statistics function recursive_mean(x::AbstractArray{T}) where {T <: Number} - sum(x) / length(x) + return sum(x) / length(x) end function recursive_mean(x::Number) - x + return x end # From Iterators.jl. Moved here since Iterators.jl is not precompile safe anymore. diff --git a/src/vector_of_array.jl b/src/vector_of_array.jl index f2ff9aa8..81e7c9c2 100644 --- a/src/vector_of_array.jl +++ b/src/vector_of_array.jl @@ -62,8 +62,9 @@ A.t ``` """ mutable struct DiffEqArray{ - T, N, A, B, F, S, D <: Union{Nothing, ParameterTimeseriesCollection}} <: - AbstractDiffEqArray{T, N, A} + T, N, A, B, F, S, D <: Union{Nothing, ParameterTimeseriesCollection}, + } <: + AbstractDiffEqArray{T, N, A} u::A # A <: AbstractVector{<: AbstractArray{T, N - 1}} t::B p::F @@ -74,84 +75,108 @@ end struct AllObserved end -function Base.Array(VA::AbstractVectorOfArray{ - T, - N, - A -}) where {T, N, +function Base.Array( + VA::AbstractVectorOfArray{ + T, + N, + A, + } + ) where { + T, N, A <: AbstractVector{ <:AbstractVector, - }} - reduce(hcat, VA.u) -end -function Base.Array(VA::AbstractVectorOfArray{ - T, - N, - A -}) where {T, N, + }, + } + return reduce(hcat, VA.u) +end +function Base.Array( + VA::AbstractVectorOfArray{ + T, + N, + A, + } + ) where { + T, N, A <: - AbstractVector{<:Number}} - VA.u -end -function Base.Matrix(VA::AbstractVectorOfArray{ - T, - N, - A -}) where {T, N, + AbstractVector{<:Number}, + } + return VA.u +end +function Base.Matrix( + VA::AbstractVectorOfArray{ + T, + N, + A, + } + ) where { + T, N, A <: AbstractVector{ <:AbstractVector, - }} - reduce(hcat, VA.u) -end -function Base.Matrix(VA::AbstractVectorOfArray{ - T, - N, - A -}) where {T, N, + }, + } + return reduce(hcat, VA.u) +end +function Base.Matrix( + VA::AbstractVectorOfArray{ + T, + N, + A, + } + ) where { + T, N, A <: - AbstractVector{<:Number}} - Matrix(VA.u) -end -function Base.Vector(VA::AbstractVectorOfArray{ - T, - N, - A -}) where {T, N, + AbstractVector{<:Number}, + } + return Matrix(VA.u) +end +function Base.Vector( + VA::AbstractVectorOfArray{ + T, + N, + A, + } + ) where { + T, N, A <: AbstractVector{ <:AbstractVector, - }} - vec(reduce(hcat, VA.u)) -end -function Base.Vector(VA::AbstractVectorOfArray{ - T, - N, - A -}) where {T, N, + }, + } + return vec(reduce(hcat, VA.u)) +end +function Base.Vector( + VA::AbstractVectorOfArray{ + T, + N, + A, + } + ) where { + T, N, A <: - AbstractVector{<:Number}} - VA.u + AbstractVector{<:Number}, + } + return VA.u end function Base.Array(VA::AbstractVectorOfArray) vecs = vec.(VA.u) - Array(reshape(reduce(hcat, vecs), size(VA.u[1])..., length(VA.u))) + return Array(reshape(reduce(hcat, vecs), size(VA.u[1])..., length(VA.u))) end function Base.Array{U}(VA::AbstractVectorOfArray) where {U} vecs = vec.(VA.u) - Array(reshape(reduce(hcat, vecs), size(VA.u[1])..., length(VA.u))) + return Array(reshape(reduce(hcat, vecs), size(VA.u[1])..., length(VA.u))) end Base.convert(::Type{AbstractArray}, VA::AbstractVectorOfArray) = stack(VA.u) function Adapt.adapt_structure(to, VA::AbstractVectorOfArray) - VectorOfArray(Adapt.adapt.((to,), VA.u)) + return VectorOfArray(Adapt.adapt.((to,), VA.u)) end function Adapt.adapt_structure(to, VA::AbstractDiffEqArray) - DiffEqArray(Adapt.adapt.((to,), VA.u), Adapt.adapt(to, VA.t)) + return DiffEqArray(Adapt.adapt.((to,), VA.u), Adapt.adapt(to, VA.t)) end function VectorOfArray(vec::AbstractVector{T}, ::NTuple{N}) where {T, N} - VectorOfArray{eltype(T), N, typeof(vec)}(vec) + return VectorOfArray{eltype(T), N, typeof(vec)}(vec) end # Assume that the first element is representative of all other elements function VectorOfArray(vec::AbstractVector) @@ -162,10 +187,10 @@ function VectorOfArray(vec::AbstractVector) else A = typeof(vec) end - VectorOfArray{T, N + 1, A}(vec) + return VectorOfArray{T, N + 1, A}(vec) end function VectorOfArray(vec::AbstractVector{VT}) where {T, N, VT <: AbstractArray{T, N}} - VectorOfArray{T, N + 1, typeof(vec)}(vec) + return VectorOfArray{T, N + 1, typeof(vec)}(vec) end # allow multi-dimensional arrays as long as they're linearly indexed. @@ -181,11 +206,15 @@ Base.parent(vec::VectorOfArray) = vec.u #### 2-argument # first element representative -function DiffEqArray(vec::AbstractVector, ts::AbstractVector; discretes = nothing, - variables = nothing, parameters = nothing, independent_variables = nothing) - sys = SymbolCache(something(variables, []), +function DiffEqArray( + vec::AbstractVector, ts::AbstractVector; discretes = nothing, + variables = nothing, parameters = nothing, independent_variables = nothing + ) + sys = SymbolCache( + something(variables, []), something(parameters, []), - something(independent_variables, [])) + something(independent_variables, []) + ) _size = size(vec[1]) T = eltype(vec[1]) return DiffEqArray{ @@ -195,21 +224,27 @@ function DiffEqArray(vec::AbstractVector, ts::AbstractVector; discretes = nothin typeof(ts), Nothing, typeof(sys), - typeof(discretes) - }(vec, + typeof(discretes), + }( + vec, ts, nothing, sys, - discretes) + discretes + ) end # T and N from type -function DiffEqArray(vec::AbstractVector{VT}, ts::AbstractVector; +function DiffEqArray( + vec::AbstractVector{VT}, ts::AbstractVector; discretes = nothing, variables = nothing, parameters = nothing, - independent_variables = nothing) where {T, N, VT <: AbstractArray{T, N}} - sys = SymbolCache(something(variables, []), + independent_variables = nothing + ) where {T, N, VT <: AbstractArray{T, N}} + sys = SymbolCache( + something(variables, []), something(parameters, []), - something(independent_variables, [])) + something(independent_variables, []) + ) return DiffEqArray{ eltype(eltype(vec)), N + 1, @@ -217,46 +252,60 @@ function DiffEqArray(vec::AbstractVector{VT}, ts::AbstractVector; typeof(ts), Nothing, typeof(sys), - typeof(discretes) - }(vec, + typeof(discretes), + }( + vec, ts, nothing, sys, - discretes) + discretes + ) end #### 3-argument # NTuple, T from type -function DiffEqArray(vec::AbstractVector{T}, ts::AbstractVector, - ::NTuple{N, Int}; discretes = nothing) where {T, N} - DiffEqArray{ - eltype(T), N, typeof(vec), typeof(ts), Nothing, Nothing, typeof(discretes)}( +function DiffEqArray( + vec::AbstractVector{T}, ts::AbstractVector, + ::NTuple{N, Int}; discretes = nothing + ) where {T, N} + return DiffEqArray{ + eltype(T), N, typeof(vec), typeof(ts), Nothing, Nothing, typeof(discretes), + }( vec, ts, nothing, nothing, - discretes) + discretes + ) end # NTuple parameter -function DiffEqArray(vec::AbstractVector{VT}, ts::AbstractVector, p::NTuple{N2, Int}; - discretes = nothing) where {T, N, VT <: AbstractArray{T, N}, N2} - DiffEqArray{ - eltype(T), N + 1, typeof(vec), typeof(ts), typeof(p), Nothing, typeof(discretes)}( +function DiffEqArray( + vec::AbstractVector{VT}, ts::AbstractVector, p::NTuple{N2, Int}; + discretes = nothing + ) where {T, N, VT <: AbstractArray{T, N}, N2} + return DiffEqArray{ + eltype(T), N + 1, typeof(vec), typeof(ts), typeof(p), Nothing, typeof(discretes), + }( vec, ts, p, nothing, - discretes) + discretes + ) end # first element representative -function DiffEqArray(vec::AbstractVector, ts::AbstractVector, p; discretes = nothing, - variables = nothing, parameters = nothing, independent_variables = nothing) - sys = SymbolCache(something(variables, []), +function DiffEqArray( + vec::AbstractVector, ts::AbstractVector, p; discretes = nothing, + variables = nothing, parameters = nothing, independent_variables = nothing + ) + sys = SymbolCache( + something(variables, []), something(parameters, []), - something(independent_variables, [])) + something(independent_variables, []) + ) _size = size(vec[1]) T = eltype(vec[1]) return DiffEqArray{ @@ -266,52 +315,72 @@ function DiffEqArray(vec::AbstractVector, ts::AbstractVector, p; discretes = not typeof(ts), typeof(p), typeof(sys), - typeof(discretes) - }(vec, + typeof(discretes), + }( + vec, ts, p, sys, - discretes) + discretes + ) end # T and N from type -function DiffEqArray(vec::AbstractVector{VT}, ts::AbstractVector, p; +function DiffEqArray( + vec::AbstractVector{VT}, ts::AbstractVector, p; discretes = nothing, variables = nothing, parameters = nothing, - independent_variables = nothing) where {T, N, VT <: AbstractArray{T, N}} - sys = SymbolCache(something(variables, []), + independent_variables = nothing + ) where {T, N, VT <: AbstractArray{T, N}} + sys = SymbolCache( + something(variables, []), something(parameters, []), - something(independent_variables, [])) - DiffEqArray{eltype(T), N + 1, typeof(vec), typeof(ts), - typeof(p), typeof(sys), typeof(discretes)}(vec, + something(independent_variables, []) + ) + return DiffEqArray{ + eltype(T), N + 1, typeof(vec), typeof(ts), + typeof(p), typeof(sys), typeof(discretes), + }( + vec, ts, p, sys, - discretes) + discretes + ) end #### 4-argument # NTuple, T from type -function DiffEqArray(vec::AbstractVector{T}, ts::AbstractVector, - ::NTuple{N, Int}, p; discretes = nothing) where {T, N} - DiffEqArray{ - eltype(T), N, typeof(vec), typeof(ts), typeof(p), Nothing, typeof(discretes)}( +function DiffEqArray( + vec::AbstractVector{T}, ts::AbstractVector, + ::NTuple{N, Int}, p; discretes = nothing + ) where {T, N} + return DiffEqArray{ + eltype(T), N, typeof(vec), typeof(ts), typeof(p), Nothing, typeof(discretes), + }( vec, ts, p, nothing, - discretes) + discretes + ) end # NTuple parameter -function DiffEqArray(vec::AbstractVector{VT}, ts::AbstractVector, p::NTuple{N2, Int}, sys; - discretes = nothing) where {T, N, VT <: AbstractArray{T, N}, N2} - DiffEqArray{eltype(T), N + 1, typeof(vec), typeof(ts), - typeof(p), typeof(sys), typeof(discretes)}(vec, +function DiffEqArray( + vec::AbstractVector{VT}, ts::AbstractVector, p::NTuple{N2, Int}, sys; + discretes = nothing + ) where {T, N, VT <: AbstractArray{T, N}, N2} + return DiffEqArray{ + eltype(T), N + 1, typeof(vec), typeof(ts), + typeof(p), typeof(sys), typeof(discretes), + }( + vec, ts, p, sys, - discretes) + discretes + ) end # first element representative @@ -325,46 +394,64 @@ function DiffEqArray(vec::AbstractVector, ts::AbstractVector, p, sys; discretes typeof(ts), typeof(p), typeof(sys), - typeof(discretes) - }(vec, + typeof(discretes), + }( + vec, ts, p, sys, - discretes) + discretes + ) end # T and N from type -function DiffEqArray(vec::AbstractVector{VT}, ts::AbstractVector, p, sys; - discretes = nothing) where {T, N, VT <: AbstractArray{T, N}} - DiffEqArray{eltype(T), N + 1, typeof(vec), typeof(ts), - typeof(p), typeof(sys), typeof(discretes)}(vec, +function DiffEqArray( + vec::AbstractVector{VT}, ts::AbstractVector, p, sys; + discretes = nothing + ) where {T, N, VT <: AbstractArray{T, N}} + return DiffEqArray{ + eltype(T), N + 1, typeof(vec), typeof(ts), + typeof(p), typeof(sys), typeof(discretes), + }( + vec, ts, p, sys, - discretes) + discretes + ) end #### 5-argument # NTuple, T from type -function DiffEqArray(vec::AbstractVector{T}, ts::AbstractVector, - ::NTuple{N, Int}, p, sys; discretes = nothing) where {T, N} - DiffEqArray{ - eltype(T), N, typeof(vec), typeof(ts), typeof(p), typeof(sys), typeof(discretes)}( +function DiffEqArray( + vec::AbstractVector{T}, ts::AbstractVector, + ::NTuple{N, Int}, p, sys; discretes = nothing + ) where {T, N} + return DiffEqArray{ + eltype(T), N, typeof(vec), typeof(ts), typeof(p), typeof(sys), typeof(discretes), + }( vec, ts, p, sys, - discretes) + discretes + ) end has_discretes(::T) where {T <: AbstractDiffEqArray} = hasfield(T, :discretes) get_discretes(x) = getfield(x, :discretes) SymbolicIndexingInterface.is_timeseries(::Type{<:AbstractVectorOfArray}) = Timeseries() -function SymbolicIndexingInterface.is_parameter_timeseries(::Type{DiffEqArray{T, N, A, B, - F, S, D}}) where {T, N, A, B, F, S, D <: ParameterIndexingProxy} - Timeseries() +function SymbolicIndexingInterface.is_parameter_timeseries( + ::Type{ + DiffEqArray{ + T, N, A, B, + F, S, D, + }, + } + ) where {T, N, A, B, F, S, D <: ParameterIndexingProxy} + return Timeseries() end SymbolicIndexingInterface.state_values(A::AbstractDiffEqArray) = A.u SymbolicIndexingInterface.current_time(A::AbstractDiffEqArray) = A.t @@ -382,7 +469,8 @@ Base.IndexStyle(::Type{<:AbstractVectorOfArray}) = IndexCartesian() return eachindex(VA.u) end @inline function Base.eachindex( - ::IndexLinear, VA::AbstractVectorOfArray{T, N, <:AbstractVector{T}}) where {T, N} + ::IndexLinear, VA::AbstractVectorOfArray{T, N, <:AbstractVector{T}} + ) where {T, N} return eachindex(IndexLinear(), VA.u) end @inline Base.IteratorSize(::Type{<:AbstractVectorOfArray}) = Base.HasLength() @@ -391,14 +479,16 @@ end function Base.firstindex(VA::AbstractVectorOfArray{T, N, A}) where {T, N, A} N > 1 && Base.depwarn( "Linear indexing of `AbstractVectorOfArray` is deprecated. Change `A[i]` to `A.u[i]` ", - :firstindex) + :firstindex + ) return firstindex(VA.u) end function Base.lastindex(VA::AbstractVectorOfArray{T, N, A}) where {T, N, A} N > 1 && Base.depwarn( "Linear indexing of `AbstractVectorOfArray` is deprecated. Change `A[i]` to `A.u[i]` ", - :lastindex) + :lastindex + ) return lastindex(VA.u) end @@ -420,17 +510,25 @@ Base.getindex(A::AbstractVectorOfArray, I::AbstractArray{Int}) = A.u[I] Base.getindex(A::AbstractDiffEqArray, I::Int) = A.u[I] Base.getindex(A::AbstractDiffEqArray, I::AbstractArray{Int}) = A.u[I] -@deprecate Base.getindex(VA::AbstractVectorOfArray{T, N, A}, - I::Int) where {T, N, A <: Union{AbstractArray, AbstractVectorOfArray}} VA.u[I] false +@deprecate Base.getindex( + VA::AbstractVectorOfArray{T, N, A}, + I::Int +) where {T, N, A <: Union{AbstractArray, AbstractVectorOfArray}} VA.u[I] false -@deprecate Base.getindex(VA::AbstractVectorOfArray{T, N, A}, - I::AbstractArray{Int}) where {T, N, A <: Union{AbstractArray, AbstractVectorOfArray}} VA.u[I] false +@deprecate Base.getindex( + VA::AbstractVectorOfArray{T, N, A}, + I::AbstractArray{Int} +) where {T, N, A <: Union{AbstractArray, AbstractVectorOfArray}} VA.u[I] false -@deprecate Base.getindex(VA::AbstractDiffEqArray{T, N, A}, - I::AbstractArray{Int}) where {T, N, A <: Union{AbstractArray, AbstractVectorOfArray}} VA.u[I] false +@deprecate Base.getindex( + VA::AbstractDiffEqArray{T, N, A}, + I::AbstractArray{Int} +) where {T, N, A <: Union{AbstractArray, AbstractVectorOfArray}} VA.u[I] false -@deprecate Base.getindex(VA::AbstractDiffEqArray{T, N, A}, - i::Int) where {T, N, A <: Union{AbstractArray, AbstractVectorOfArray}} VA.u[i] false +@deprecate Base.getindex( + VA::AbstractDiffEqArray{T, N, A}, + i::Int +) where {T, N, A <: Union{AbstractArray, AbstractVectorOfArray}} VA.u[i] false __parameterless_type(T) = Base.typename(T).wrapper @@ -459,10 +557,10 @@ end Base.:(:)(stop::RaggedEnd) = RaggedRange(stop.dim, 1, 1, stop.offset) function Base.:(:)(start::Integer, stop::RaggedEnd) - RaggedRange(stop.dim, Int(start), 1, stop.offset) + return RaggedRange(stop.dim, Int(start), 1, stop.offset) end function Base.:(:)(start::Integer, step::Integer, stop::RaggedEnd) - RaggedRange(stop.dim, Int(start), Int(step), stop.offset) + return RaggedRange(stop.dim, Int(start), Int(step), stop.offset) end Base.broadcastable(x::RaggedRange) = Ref(x) @@ -476,20 +574,24 @@ Base.broadcastable(x::RaggedRange) = Ref(x) end Base.@propagate_inbounds function _getindex( - A::AbstractVectorOfArray, ::NotSymbolic, ::Colon, I::Int) - A.u[I] + A::AbstractVectorOfArray, ::NotSymbolic, ::Colon, I::Int + ) + return A.u[I] end -Base.@propagate_inbounds function _getindex(A::AbstractVectorOfArray, ::NotSymbolic, - I::Union{Int, AbstractArray{Int}, AbstractArray{Bool}, Colon}...) - if last(I) isa Int +Base.@propagate_inbounds function _getindex( + A::AbstractVectorOfArray, ::NotSymbolic, + I::Union{Int, AbstractArray{Int}, AbstractArray{Bool}, Colon}... + ) + return if last(I) isa Int A.u[last(I)][Base.front(I)...] else stack(getindex.(A.u[last(I)], tuple.(Base.front(I))...)) end end Base.@propagate_inbounds function _getindex( - VA::AbstractVectorOfArray, ::NotSymbolic, ii::CartesianIndex) + VA::AbstractVectorOfArray, ::NotSymbolic, ii::CartesianIndex + ) ti = Tuple(ii) i = last(ti) jj = CartesianIndex(Base.front(ti)) @@ -498,13 +600,16 @@ end Base.@propagate_inbounds function _getindex( A::AbstractVectorOfArray, ::NotSymbolic, ::Colon, - I::Union{AbstractArray{Int}, AbstractArray{Bool}}) - VectorOfArray(A.u[I]) + I::Union{AbstractArray{Int}, AbstractArray{Bool}} + ) + return VectorOfArray(A.u[I]) end -Base.@propagate_inbounds function _getindex(A::AbstractDiffEqArray, ::NotSymbolic, ::Colon, - I::Union{AbstractArray{Int}, AbstractArray{Bool}}) - DiffEqArray(A.u[I], A.t[I], parameter_values(A), symbolic_container(A)) +Base.@propagate_inbounds function _getindex( + A::AbstractDiffEqArray, ::NotSymbolic, ::Colon, + I::Union{AbstractArray{Int}, AbstractArray{Bool}} + ) + return DiffEqArray(A.u[I], A.t[I], parameter_values(A), symbolic_container(A)) end struct ParameterIndexingError <: Exception @@ -512,47 +617,61 @@ struct ParameterIndexingError <: Exception end function Base.showerror(io::IO, pie::ParameterIndexingError) - print(io, - "Indexing with parameters is deprecated. Use `getp(A, $(pie.sym))` for parameter indexing.") + return print( + io, + "Indexing with parameters is deprecated. Use `getp(A, $(pie.sym))` for parameter indexing." + ) end # Symbolic Indexing Methods for (symtype, elsymtype, valtype, errcheck) in [ - (ScalarSymbolic, SymbolicIndexingInterface.SymbolicTypeTrait, Any, - :(is_parameter(A, sym) && !is_timeseries_parameter(A, sym))), - (ArraySymbolic, SymbolicIndexingInterface.SymbolicTypeTrait, Any, - :(is_parameter(A, sym) && !is_timeseries_parameter(A, sym))), - (NotSymbolic, SymbolicIndexingInterface.SymbolicTypeTrait, - Union{<:Tuple, <:AbstractArray}, - :(all(x -> is_parameter(A, x) && !is_timeseries_parameter(A, x), sym))) -] - @eval Base.@propagate_inbounds function _getindex(A::AbstractDiffEqArray, ::$symtype, - ::$elsymtype, sym::$valtype, arg...) + ( + ScalarSymbolic, SymbolicIndexingInterface.SymbolicTypeTrait, Any, + :(is_parameter(A, sym) && !is_timeseries_parameter(A, sym)), + ), + ( + ArraySymbolic, SymbolicIndexingInterface.SymbolicTypeTrait, Any, + :(is_parameter(A, sym) && !is_timeseries_parameter(A, sym)), + ), + ( + NotSymbolic, SymbolicIndexingInterface.SymbolicTypeTrait, + Union{<:Tuple, <:AbstractArray}, + :(all(x -> is_parameter(A, x) && !is_timeseries_parameter(A, x), sym)), + ), + ] + @eval Base.@propagate_inbounds function _getindex( + A::AbstractDiffEqArray, ::$symtype, + ::$elsymtype, sym::$valtype, arg... + ) if $errcheck throw(ParameterIndexingError(sym)) end - getu(A, sym)(A, arg...) + return getu(A, sym)(A, arg...) end end -Base.@propagate_inbounds function _getindex(A::AbstractDiffEqArray, ::ScalarSymbolic, - ::NotSymbolic, ::SymbolicIndexingInterface.SolvedVariables, args...) +Base.@propagate_inbounds function _getindex( + A::AbstractDiffEqArray, ::ScalarSymbolic, + ::NotSymbolic, ::SymbolicIndexingInterface.SolvedVariables, args... + ) return getindex(A, variable_symbols(A), args...) end -Base.@propagate_inbounds function _getindex(A::AbstractDiffEqArray, ::ScalarSymbolic, - ::NotSymbolic, ::SymbolicIndexingInterface.AllVariables, args...) +Base.@propagate_inbounds function _getindex( + A::AbstractDiffEqArray, ::ScalarSymbolic, + ::NotSymbolic, ::SymbolicIndexingInterface.AllVariables, args... + ) return getindex(A, all_variable_symbols(A), args...) end @inline _column_indices(VA::AbstractVectorOfArray, idx) = idx === Colon() ? - eachindex(VA.u) : idx + eachindex(VA.u) : idx @inline function _column_indices(VA::AbstractVectorOfArray, idx::AbstractArray{Bool}) - findall(idx) + return findall(idx) end @inline function _column_indices(VA::AbstractVectorOfArray, idx::RaggedEnd) # RaggedEnd with dim=0 means it's just a plain index stored in offset - idx.dim == 0 ? idx.offset : idx + return idx.dim == 0 ? idx.offset : idx end @inline _resolve_ragged_index(idx, ::AbstractVectorOfArray, ::Any) = idx @@ -574,9 +693,12 @@ end return Base.range(idx.start; step = idx.step, stop = stop_val) end @inline function _resolve_ragged_index( - idx::AbstractRange{<:RaggedEnd}, VA::AbstractVectorOfArray, col) - return Base.range(_resolve_ragged_index(first(idx), VA, col); step = step(idx), - stop = _resolve_ragged_index(last(idx), VA, col)) + idx::AbstractRange{<:RaggedEnd}, VA::AbstractVectorOfArray, col + ) + return Base.range( + _resolve_ragged_index(first(idx), VA, col); step = step(idx), + stop = _resolve_ragged_index(last(idx), VA, col) + ) end @inline function _resolve_ragged_index(idx::Base.Slice, VA::AbstractVectorOfArray, col) return Base.Slice(_resolve_ragged_index(idx.indices, VA, col)) @@ -585,11 +707,13 @@ end return CartesianIndex(_resolve_ragged_indices(Tuple(idx), VA, col)...) end @inline function _resolve_ragged_index( - idx::AbstractArray{<:RaggedEnd}, VA::AbstractVectorOfArray, col) + idx::AbstractArray{<:RaggedEnd}, VA::AbstractVectorOfArray, col + ) return map(i -> _resolve_ragged_index(i, VA, col), idx) end @inline function _resolve_ragged_index( - idx::AbstractArray{<:RaggedRange}, VA::AbstractVectorOfArray, col) + idx::AbstractArray{<:RaggedRange}, VA::AbstractVectorOfArray, col + ) return map(i -> _resolve_ragged_index(i, VA, col), idx) end @inline function _resolve_ragged_index(idx::AbstractArray, VA::AbstractVectorOfArray, col) @@ -597,7 +721,7 @@ end end @inline function _resolve_ragged_indices(idxs::Tuple, VA::AbstractVectorOfArray, col) - map(i -> _resolve_ragged_index(i, VA, col), idxs) + return map(i -> _resolve_ragged_index(i, VA, col), idxs) end @inline function _has_ragged_end(x) @@ -609,7 +733,7 @@ end if x isa AbstractArray el = eltype(x) return el <: Union{RaggedEnd, RaggedRange} || - (el === Any && any(_has_ragged_end, x)) + (el === Any && any(_has_ragged_end, x)) end x isa Tuple && return any(_has_ragged_end, x) return false @@ -666,33 +790,47 @@ end if all(idx -> idx === Colon(), resolved_prefix) (resolved_prefix..., ntuple(_ -> Colon(), n_missing)...) else - (resolved_prefix..., - (lastindex(A.u[cols], length(resolved_prefix) + i) for i in 1:n_missing)...) + ( + resolved_prefix..., + (lastindex(A.u[cols], length(resolved_prefix) + i) for i in 1:n_missing)..., + ) end else resolved_prefix end return A.u[cols][padded...] else - return VectorOfArray([begin - resolved_prefix = _resolve_ragged_indices(prefix, A, col) - inner_nd = ndims(A.u[col]) - n_missing = inner_nd - length(resolved_prefix) - padded = if n_missing > 0 - if all(idx -> idx === Colon(), resolved_prefix) - (resolved_prefix..., - ntuple(_ -> Colon(), n_missing)...) - else - (resolved_prefix..., - (lastindex(A.u[col], - length(resolved_prefix) + i) for i in 1:n_missing)...) - end - else - resolved_prefix - end - A.u[col][padded...] - end - for col in cols]) + return VectorOfArray( + [ + begin + resolved_prefix = _resolve_ragged_indices(prefix, A, col) + inner_nd = ndims(A.u[col]) + n_missing = inner_nd - length(resolved_prefix) + padded = if n_missing > 0 + if all(idx -> idx === Colon(), resolved_prefix) + ( + resolved_prefix..., + ntuple(_ -> Colon(), n_missing)..., + ) + else + ( + resolved_prefix..., + ( + lastindex( + A.u[col], + length(resolved_prefix) + i + ) for i in 1:n_missing + )..., + ) + end + else + resolved_prefix + end + A.u[col][padded...] + end + for col in cols + ] + ) end end @@ -734,14 +872,16 @@ end resolved = _resolve_ragged_indices(prefix, A, col_idxs) inner_nd = ndims(A.u[col_idxs]) padded = ( - resolved..., ntuple(_ -> Colon(), max(inner_nd - length(resolved), 0))...) + resolved..., ntuple(_ -> Colon(), max(inner_nd - length(resolved), 0))..., + ) return A.u[col_idxs][padded...] end vals = map(col_idxs) do col resolved = _resolve_ragged_indices(prefix, A, col) inner_nd = ndims(A.u[col]) padded = ( - resolved..., ntuple(_ -> Colon(), max(inner_nd - length(resolved), 0))...) + resolved..., ntuple(_ -> Colon(), max(inner_nd - length(resolved), 0))..., + ) A.u[col][padded...] end return stack(vals) @@ -768,12 +908,12 @@ Base.@propagate_inbounds function Base.getindex(A::AbstractVectorOfArray, _arg, symtype = symbolic_type(_arg) elsymtype = symbolic_type(eltype(_arg)) - if symtype == NotSymbolic() && elsymtype == NotSymbolic() + return if symtype == NotSymbolic() && elsymtype == NotSymbolic() if _has_ragged_end(_arg, args...) return _ragged_getindex(A, _arg, args...) end if _arg isa Union{Tuple, AbstractArray} && - any(x -> symbolic_type(x) != NotSymbolic(), _arg) + any(x -> symbolic_type(x) != NotSymbolic(), _arg) _getindex(A, symtype, elsymtype, _arg, args...) else _getindex(A, symtype, _arg, args...) @@ -786,73 +926,98 @@ Base.@propagate_inbounds function Base.getindex(A::AbstractVectorOfArray, _arg, end Base.@propagate_inbounds function Base.getindex( - A::Adjoint{T, <:AbstractVectorOfArray}, idxs...) where {T} + A::Adjoint{T, <:AbstractVectorOfArray}, idxs... + ) where {T} return getindex(A.parent, reverse(to_indices(A, idxs))...) end function _observed(A::AbstractDiffEqArray{T, N}, sym, i::Int) where {T, N} - observed(A, sym)(A.u[i], A.p, A.t[i]) + return observed(A, sym)(A.u[i], A.p, A.t[i]) end function _observed(A::AbstractDiffEqArray{T, N}, sym, i::AbstractArray{Int}) where {T, N} - observed(A, sym).(A.u[i], (A.p,), A.t[i]) + return observed(A, sym).(A.u[i], (A.p,), A.t[i]) end function _observed(A::AbstractDiffEqArray{T, N}, sym, ::Colon) where {T, N} - observed(A, sym).(A.u, (A.p,), A.t) + return observed(A, sym).(A.u, (A.p,), A.t) end -Base.@propagate_inbounds function Base.setindex!(VA::AbstractVectorOfArray{T, N}, v, - ::Colon, I::Int) where {T, N} - VA.u[I] = v +Base.@propagate_inbounds function Base.setindex!( + VA::AbstractVectorOfArray{T, N}, v, + ::Colon, I::Int + ) where {T, N} + return VA.u[I] = v end Base.@propagate_inbounds Base.setindex!(VA::AbstractVectorOfArray, v, I::Int) = Base.setindex!( - VA.u, v, I) -@deprecate Base.setindex!(VA::AbstractVectorOfArray{T, N, A}, v, - I::Int) where {T, N, A <: Union{AbstractArray, AbstractVectorOfArray}} Base.setindex!( - VA.u, v, I) false + VA.u, v, I +) +@deprecate Base.setindex!( + VA::AbstractVectorOfArray{T, N, A}, v, + I::Int +) where {T, N, A <: Union{AbstractArray, AbstractVectorOfArray}} Base.setindex!( + VA.u, v, I +) false -Base.@propagate_inbounds function Base.setindex!(VA::AbstractVectorOfArray{T, N}, v, - ::Colon, I::Colon) where {T, N} - VA.u[I] = v +Base.@propagate_inbounds function Base.setindex!( + VA::AbstractVectorOfArray{T, N}, v, + ::Colon, I::Colon + ) where {T, N} + return VA.u[I] = v end Base.@propagate_inbounds Base.setindex!(VA::AbstractVectorOfArray, v, I::Colon) = Base.setindex!( - VA.u, v, I) -@deprecate Base.setindex!(VA::AbstractVectorOfArray{T, N, A}, v, - I::Colon) where {T, N, A <: Union{AbstractArray, AbstractVectorOfArray}} Base.setindex!( - VA.u, v, I) false + VA.u, v, I +) +@deprecate Base.setindex!( + VA::AbstractVectorOfArray{T, N, A}, v, + I::Colon +) where {T, N, A <: Union{AbstractArray, AbstractVectorOfArray}} Base.setindex!( + VA.u, v, I +) false -Base.@propagate_inbounds function Base.setindex!(VA::AbstractVectorOfArray{T, N}, v, - ::Colon, I::AbstractArray{Int}) where {T, N} - VA.u[I] = v +Base.@propagate_inbounds function Base.setindex!( + VA::AbstractVectorOfArray{T, N}, v, + ::Colon, I::AbstractArray{Int} + ) where {T, N} + return VA.u[I] = v end Base.@propagate_inbounds Base.setindex!(VA::AbstractVectorOfArray, v, I::AbstractArray{Int}) = Base.setindex!( - VA.u, v, I) -@deprecate Base.setindex!(VA::AbstractVectorOfArray{T, N, A}, v, - I::AbstractArray{Int}) where {T, N, A <: Union{AbstractArray, AbstractVectorOfArray}} Base.setindex!( - VA, v, :, I) false + VA.u, v, I +) +@deprecate Base.setindex!( + VA::AbstractVectorOfArray{T, N, A}, v, + I::AbstractArray{Int} +) where {T, N, A <: Union{AbstractArray, AbstractVectorOfArray}} Base.setindex!( + VA, v, :, I +) false Base.@propagate_inbounds function Base.setindex!( VA::AbstractVectorOfArray{T, N}, v, i::Int, - ::Colon) where {T, N} + ::Colon + ) where {T, N} for j in 1:length(VA.u) VA.u[j][i] = v[j] end return v end -Base.@propagate_inbounds function Base.setindex!(VA::AbstractVectorOfArray{T, N}, x, - ii::CartesianIndex) where {T, N} +Base.@propagate_inbounds function Base.setindex!( + VA::AbstractVectorOfArray{T, N}, x, + ii::CartesianIndex + ) where {T, N} ti = Tuple(ii) i = last(ti) jj = CartesianIndex(Base.front(ti)) return VA.u[i][jj] = x end -Base.@propagate_inbounds function Base.setindex!(VA::AbstractVectorOfArray{T, N}, +Base.@propagate_inbounds function Base.setindex!( + VA::AbstractVectorOfArray{T, N}, x, - idxs::Union{Int, Colon, CartesianIndex, AbstractArray{Int}, AbstractArray{Bool}}...) where { - T, N} + idxs::Union{Int, Colon, CartesianIndex, AbstractArray{Int}, AbstractArray{Bool}}... + ) where { + T, N, + } v = view(VA, idxs...) # error message copied from Base by running `ones(3, 3, 3)[:, 2, :] = 2` if length(v) != length(x) @@ -872,9 +1037,11 @@ end Base.axes(VA::AbstractVectorOfArray) = Base.OneTo.(size(VA)) Base.axes(VA::AbstractVectorOfArray, d::Int) = Base.OneTo(size(VA)[d]) -Base.@propagate_inbounds function Base.setindex!(VA::AbstractVectorOfArray{T, N}, v, - I::Int...) where {T, N} - VA.u[I[end]][Base.front(I)...] = v +Base.@propagate_inbounds function Base.setindex!( + VA::AbstractVectorOfArray{T, N}, v, + I::Int... + ) where {T, N} + return VA.u[I[end]][Base.front(I)...] = v end function Base.:(==)(A::AbstractVectorOfArray, B::AbstractVectorOfArray) @@ -888,13 +1055,13 @@ Base.:(==)(A::AbstractArray, B::AbstractVectorOfArray) = B == A # The iterator will be over the subarrays of the container, not the individual elements # unlike an true AbstractArray function Base.iterate(VA::AbstractVectorOfArray, state = 1) - state >= length(VA.u) + 1 ? nothing : (VA[:, state], state + 1) + return state >= length(VA.u) + 1 ? nothing : (VA[:, state], state + 1) end tuples(VA::DiffEqArray) = tuple.(VA.t, VA.u) # Growing the array simply adds to the container vector function _copyfield(VA, fname) - if fname == :u + return if fname == :u copy(VA.u) elseif fname == :t copy(VA.t) @@ -903,7 +1070,7 @@ function _copyfield(VA, fname) end end function Base.copy(VA::AbstractVectorOfArray) - typeof(VA)((_copyfield(VA, fname) for fname in fieldnames(typeof(VA)))...) + return typeof(VA)((_copyfield(VA, fname) for fname in fieldnames(typeof(VA)))...) end function Base.zero(VA::AbstractVectorOfArray) @@ -917,7 +1084,7 @@ Base.sizehint!(VA::AbstractVectorOfArray{T, N}, i) where {T, N} = sizehint!(VA.u Base.reverse!(VA::AbstractVectorOfArray) = reverse!(VA.u) Base.reverse(VA::AbstractVectorOfArray) = VectorOfArray(reverse(VA.u)) function Base.reverse(VA::AbstractDiffEqArray) - DiffEqArray(reverse(VA.u), VA.t, parameter_values(VA), symbolic_container(VA)) + return DiffEqArray(reverse(VA.u), VA.t, parameter_values(VA), symbolic_container(VA)) end function Base.resize!(VA::AbstractVectorOfArray, i::Integer) @@ -925,21 +1092,23 @@ function Base.resize!(VA::AbstractVectorOfArray, i::Integer) error("resize! is not allowed on AbstractVectorOfArray with a sys") end Base.resize!(VA.u, i) - if Base.hasproperty(VA, :t) && VA.t !== nothing + return if Base.hasproperty(VA, :t) && VA.t !== nothing Base.resize!(VA.t, i) end end function Base.pointer(VA::AbstractVectorOfArray) - Base.pointer(VA.u) + return Base.pointer(VA.u) end function Base.push!(VA::AbstractVectorOfArray{T, N}, new_item::AbstractArray) where {T, N} - push!(VA.u, new_item) + return push!(VA.u, new_item) end -function Base.append!(VA::AbstractVectorOfArray{T, N}, - new_item::AbstractVectorOfArray{T, N}) where {T, N} +function Base.append!( + VA::AbstractVectorOfArray{T, N}, + new_item::AbstractVectorOfArray{T, N} + ) where {T, N} for item in copy(new_item) push!(VA, item) end @@ -947,12 +1116,14 @@ function Base.append!(VA::AbstractVectorOfArray{T, N}, end function Base.stack(VA::AbstractVectorOfArray; dims = :) - stack(stack.(VA.u); dims) + return stack(stack.(VA.u); dims) end # AbstractArray methods -function Base.view(A::AbstractVectorOfArray{T, N, <:AbstractVector{T}}, - I::Vararg{Any, M}) where {T, N, M} +function Base.view( + A::AbstractVectorOfArray{T, N, <:AbstractVector{T}}, + I::Vararg{Any, M} + ) where {T, N, M} @inline if length(I) == 1 J = map(i -> Base.unalias(A, i), to_indices(A, I)) @@ -962,7 +1133,7 @@ function Base.view(A::AbstractVectorOfArray{T, N, <:AbstractVector{T}}, J = map(i -> Base.unalias(A, i), to_indices(A, I)) end @boundscheck checkbounds(A, J...) - SubArray(A, J) + return SubArray(A, J) end function Base.view(A::AbstractVectorOfArray, I::Vararg{Any, M}) where {M} @inline @@ -983,24 +1154,28 @@ function Base.view(A::AbstractVectorOfArray, I::Vararg{Any, M}) where {M} end J = map(i -> Base.unalias(A, i), to_indices(A, I)) @boundscheck checkbounds(A, J...) - SubArray(A, J) + return SubArray(A, J) end function Base.SubArray(parent::AbstractVectorOfArray, indices::Tuple) @inline - SubArray(IndexStyle(Base.viewindexing(indices), IndexStyle(parent)), parent, - Base.ensure_indexable(indices), Base.index_dimsum(indices...)) + return SubArray( + IndexStyle(Base.viewindexing(indices), IndexStyle(parent)), parent, + Base.ensure_indexable(indices), Base.index_dimsum(indices...) + ) end Base.isassigned(VA::AbstractVectorOfArray, idxs...) = checkbounds(Bool, VA, idxs...) function Base.check_parent_index_match( - ::RecursiveArrayTools.AbstractVectorOfArray{T, N}, ::NTuple{N, Bool}) where {T, N} - nothing + ::RecursiveArrayTools.AbstractVectorOfArray{T, N}, ::NTuple{N, Bool} + ) where {T, N} + return nothing end Base.ndims(::AbstractVectorOfArray{T, N}) where {T, N} = N Base.ndims(::Type{<:AbstractVectorOfArray{T, N}}) where {T, N} = N function Base.checkbounds( ::Type{Bool}, VA::AbstractVectorOfArray{T, N, <:AbstractVector{T}}, - idxs...) where {T, N} + idxs... + ) where {T, N} if _has_ragged_end(idxs...) return _checkbounds_ragged(Bool, VA, idxs...) end @@ -1024,10 +1199,12 @@ function Base.checkbounds(::Type{Bool}, VA::AbstractVectorOfArray, idx...) end end function Base.checkbounds(VA::AbstractVectorOfArray, idx...) - checkbounds(Bool, VA, idx...) || throw(BoundsError(VA, idx)) + return checkbounds(Bool, VA, idx...) || throw(BoundsError(VA, idx)) end -function Base.copyto!(dest::AbstractVectorOfArray{T, N}, - src::AbstractVectorOfArray{T2, N}) where {T, T2, N} +function Base.copyto!( + dest::AbstractVectorOfArray{T, N}, + src::AbstractVectorOfArray{T2, N} + ) where {T, T2, N} for (i, j) in zip(eachindex(dest.u), eachindex(src.u)) if ArrayInterface.ismutable(dest.u[i]) || dest.u[i] isa AbstractVectorOfArray copyto!(dest.u[i], src.u[j]) @@ -1035,9 +1212,11 @@ function Base.copyto!(dest::AbstractVectorOfArray{T, N}, dest.u[i] = StaticArraysCore.similar_type(dest.u[i])(src.u[j]) end end + return end function Base.copyto!( - dest::AbstractVectorOfArray{T, N}, src::AbstractArray{T2, N}) where {T, T2, N} + dest::AbstractVectorOfArray{T, N}, src::AbstractArray{T2, N} + ) where {T, T2, N} for (i, slice) in zip(eachindex(dest.u), eachslice(src, dims = ndims(src))) if ArrayInterface.ismutable(dest.u[i]) || dest.u[i] isa AbstractVectorOfArray copyto!(dest.u[i], slice) @@ -1045,12 +1224,14 @@ function Base.copyto!( dest.u[i] = StaticArraysCore.similar_type(dest.u[i])(slice) end end - dest + return dest end -function Base.copyto!(dest::AbstractVectorOfArray{T, N, <:AbstractVector{T}}, - src::AbstractVector{T2}) where {T, T2, N} +function Base.copyto!( + dest::AbstractVectorOfArray{T, N, <:AbstractVector{T}}, + src::AbstractVector{T2} + ) where {T, T2, N} copyto!(dest.u, src) - dest + return dest end # Required for broadcasted setindex! when slicing across subarrays # E.g. if `va = VectorOfArray([rand(3, 3) for i in 1:5])` @@ -1060,9 +1241,11 @@ Base.@propagate_inbounds function Base.maybeview(A::AbstractVectorOfArray, I...) end # Operations -function Base.isapprox(A::AbstractVectorOfArray, +function Base.isapprox( + A::AbstractVectorOfArray, B::Union{AbstractVectorOfArray, AbstractArray}; - kwargs...) + kwargs... + ) return all(isapprox.(A, B; kwargs...)) end @@ -1072,17 +1255,20 @@ end for op in [:(Base.:-), :(Base.:+)] @eval function ($op)(A::AbstractVectorOfArray, B::AbstractVectorOfArray) - ($op).(A, B) + return ($op).(A, B) end - @eval Base.@propagate_inbounds function ($op)(A::AbstractVectorOfArray, - B::AbstractArray) + @eval Base.@propagate_inbounds function ($op)( + A::AbstractVectorOfArray, + B::AbstractArray + ) @boundscheck length(A) == length(B) - VectorOfArray([($op).(a, b) for (a, b) in zip(A, B)]) + return VectorOfArray([($op).(a, b) for (a, b) in zip(A, B)]) end @eval Base.@propagate_inbounds function ($op)( - A::AbstractArray, B::AbstractVectorOfArray) + A::AbstractArray, B::AbstractVectorOfArray + ) @boundscheck length(A) == length(B) - VectorOfArray([($op).(a, b) for (a, b) in zip(A, B)]) + return VectorOfArray([($op).(a, b) for (a, b) in zip(A, B)]) end end @@ -1113,24 +1299,30 @@ Base.eltype(::Type{<:AbstractVectorOfArray{T}}) where {T} = T end end -function Base.similar(vec::VectorOfArray{ - T, N, AT}) where {T, N, AT <: AbstractArray{<:AbstractArray{T}}} +function Base.similar( + vec::VectorOfArray{ + T, N, AT, + } + ) where {T, N, AT <: AbstractArray{<:AbstractArray{T}}} return VectorOfArray(similar.(Base.parent(vec))) end -function Base.similar(vec::VectorOfArray{ - T, N, AT}) where {T, N, AT <: AbstractArray{<:StaticArraysCore.StaticVecOrMat{T}}} +function Base.similar( + vec::VectorOfArray{ + T, N, AT, + } + ) where {T, N, AT <: AbstractArray{<:StaticArraysCore.StaticVecOrMat{T}}} # this avoids behavior such as similar(SVector) returning an MVector return VectorOfArray(similar(Base.parent(vec))) end @inline function Base.similar(VA::VectorOfArray, ::Type{T} = eltype(VA)) where {T} - VectorOfArray(similar.(VA.u, T)) + return VectorOfArray(similar.(VA.u, T)) end @inline function Base.similar(VA::VectorOfArray, dims::N) where {N <: Number} l = length(VA) - if dims <= l + return if dims <= l VectorOfArray(similar.(VA.u[1:dims])) else VectorOfArray([similar.(VA.u); [similar(VA.u[end]) for _ in (l + 1):dims]]) @@ -1175,11 +1367,11 @@ end # statistics @inline Base.sum(VA::AbstractVectorOfArray; kwargs...) = sum(identity, VA; kwargs...) @inline function Base.sum(f, VA::AbstractVectorOfArray; kwargs...) - mapreduce(f, Base.add_sum, VA; kwargs...) + return mapreduce(f, Base.add_sum, VA; kwargs...) end @inline Base.prod(VA::AbstractVectorOfArray; kwargs...) = prod(identity, VA; kwargs...) @inline function Base.prod(f, VA::AbstractVectorOfArray; kwargs...) - mapreduce(f, Base.mul_prod, VA; kwargs...) + return mapreduce(f, Base.mul_prod, VA; kwargs...) end @inline Base.adjoint(VA::AbstractVectorOfArray) = Adjoint(VA) @@ -1192,7 +1384,7 @@ function Base.show(io::IO, m::MIME"text/plain", x::AbstractVectorOfArray) (println(io, summary(x), ':'); show(io, m, x.u)) end function Base.summary(A::AbstractVectorOfArray{T, N}) where {T, N} - string("VectorOfArray{", T, ",", N, "}") + return string("VectorOfArray{", T, ",", N, "}") end function Base.show(io::IO, m::MIME"text/plain", x::AbstractDiffEqArray) @@ -1205,9 +1397,9 @@ end end @recipe function f(VA::AbstractDiffEqArray) xguide --> isempty(independent_variable_symbols(VA)) ? "" : - independent_variable_symbols(VA)[1] + independent_variable_symbols(VA)[1] label --> isempty(variable_symbols(VA)) ? "" : - reshape(string.(variable_symbols(VA)), 1, :) + reshape(string.(variable_symbols(VA)), 1, :) VA.t, VA' end @recipe function f(VA::DiffEqArray{T, 1}) where {T} @@ -1217,11 +1409,12 @@ end Base.map(f, A::RecursiveArrayTools.AbstractVectorOfArray) = map(f, A.u) function Base.mapreduce(f, op, A::AbstractVectorOfArray; kwargs...) - mapreduce(f, op, view(A, ntuple(_ -> :, ndims(A))...); kwargs...) + return mapreduce(f, op, view(A, ntuple(_ -> :, ndims(A))...); kwargs...) end function Base.mapreduce( - f, op, A::AbstractVectorOfArray{T, 1, <:AbstractVector{T}}; kwargs...) where {T} - mapreduce(f, op, A.u; kwargs...) + f, op, A::AbstractVectorOfArray{T, 1, <:AbstractVector{T}}; kwargs... + ) where {T} + return mapreduce(f, op, A.u; kwargs...) end ## broadcasting @@ -1232,20 +1425,26 @@ VectorOfArrayStyle(::Val{N}) where {N} = VectorOfArrayStyle{N}() # The order is important here. We want to override Base.Broadcast.DefaultArrayStyle to return another Base.Broadcast.DefaultArrayStyle. Broadcast.BroadcastStyle(a::VectorOfArrayStyle, ::Base.Broadcast.DefaultArrayStyle{0}) = a -function Broadcast.BroadcastStyle(::VectorOfArrayStyle{N}, - a::Base.Broadcast.DefaultArrayStyle{M}) where {M, N} - Base.Broadcast.DefaultArrayStyle(Val(max(M, N))) -end -function Broadcast.BroadcastStyle(::VectorOfArrayStyle{N}, - a::Base.Broadcast.AbstractArrayStyle{M}) where {M, N} - typeof(a)(Val(max(M, N))) -end -function Broadcast.BroadcastStyle(::VectorOfArrayStyle{M}, - ::VectorOfArrayStyle{N}) where {M, N} - VectorOfArrayStyle(Val(max(M, N))) +function Broadcast.BroadcastStyle( + ::VectorOfArrayStyle{N}, + a::Base.Broadcast.DefaultArrayStyle{M} + ) where {M, N} + return Base.Broadcast.DefaultArrayStyle(Val(max(M, N))) +end +function Broadcast.BroadcastStyle( + ::VectorOfArrayStyle{N}, + a::Base.Broadcast.AbstractArrayStyle{M} + ) where {M, N} + return typeof(a)(Val(max(M, N))) +end +function Broadcast.BroadcastStyle( + ::VectorOfArrayStyle{M}, + ::VectorOfArrayStyle{N} + ) where {M, N} + return VectorOfArrayStyle(Val(max(M, N))) end function Broadcast.BroadcastStyle(::Type{<:AbstractVectorOfArray{T, N}}) where {T, N} - VectorOfArrayStyle{N}() + return VectorOfArrayStyle{N}() end # make vectorofarrays broadcastable so they aren't collected Broadcast.broadcastable(x::AbstractVectorOfArray) = x @@ -1280,18 +1479,20 @@ end copy(unpack_voa(bc, i)) end end - VectorOfArray(rewrap(parent, u)) + return VectorOfArray(rewrap(parent, u)) end rewrap(::Array, u) = u rewrap(parent, u) = convert(typeof(parent), u) for (type, N_expr) in [ - (Broadcast.Broadcasted{<:VectorOfArrayStyle}, :(narrays(bc))), - (Broadcast.Broadcasted{<:Broadcast.DefaultArrayStyle}, :(length(dest.u))) -] - @eval @inline function Base.copyto!(dest::AbstractVectorOfArray, - bc::$type) + (Broadcast.Broadcasted{<:VectorOfArrayStyle}, :(narrays(bc))), + (Broadcast.Broadcasted{<:Broadcast.DefaultArrayStyle}, :(length(dest.u))), + ] + @eval @inline function Base.copyto!( + dest::AbstractVectorOfArray, + bc::$type + ) bc = Broadcast.flatten(bc) N = $N_expr @inbounds for i in 1:N @@ -1313,7 +1514,7 @@ for (type, N_expr) in [ dest[:, i] = copy(unpack_voa(bc, i)) end end - dest + return dest end end @@ -1330,10 +1531,14 @@ narrays(bc::Broadcast.Broadcasted) = _narrays(bc.args) narrays(A, Bs...) = common_length(narrays(A), _narrays(Bs)) function common_length(a, b) - a == 0 ? b : - (b == 0 ? a : - (a == b ? a : - throw(DimensionMismatch("number of arrays must be equal")))) + return a == 0 ? b : + ( + b == 0 ? a : + ( + a == b ? a : + throw(DimensionMismatch("number of arrays must be equal")) + ) + ) end _narrays(args::AbstractVectorOfArray) = length(args.u) @@ -1343,19 +1548,19 @@ _narrays(::Any) = 0 # drop axes because it is easier to recompute @inline function unpack_voa(bc::Broadcast.Broadcasted{Style}, i) where {Style} - Broadcast.Broadcasted{Style}(bc.f, unpack_args_voa(i, bc.args)) + return Broadcast.Broadcasted{Style}(bc.f, unpack_args_voa(i, bc.args)) end @inline function unpack_voa(bc::Broadcast.Broadcasted{<:VectorOfArrayStyle}, i) - Broadcast.Broadcasted(bc.f, unpack_args_voa(i, bc.args)) + return Broadcast.Broadcasted(bc.f, unpack_args_voa(i, bc.args)) end unpack_voa(x, ::Any) = x unpack_voa(x::AbstractVectorOfArray, i) = x.u[i] function unpack_voa(x::AbstractArray{T, N}, i) where {T, N} - @view x[ntuple(x -> Colon(), N - 1)..., i] + return @view x[ntuple(x -> Colon(), N - 1)..., i] end @inline function unpack_args_voa(i, args::Tuple) - (unpack_voa(args[1], i), unpack_args_voa(i, Base.tail(args))...) + return (unpack_voa(args[1], i), unpack_args_voa(i, Base.tail(args))...) end unpack_args_voa(i, args::Tuple{Any}) = (unpack_voa(args[1], i),) unpack_args_voa(::Any, args::Tuple{}) = () diff --git a/test/adjoints.jl b/test/adjoints.jl index a390c33a..6eefb906 100644 --- a/test/adjoints.jl +++ b/test/adjoints.jl @@ -2,11 +2,11 @@ using RecursiveArrayTools, Zygote, ForwardDiff, Test using SciMLBase function loss(x) - sum(abs2, Array(VectorOfArray([x .* i for i in 1:5]))) + return sum(abs2, Array(VectorOfArray([x .* i for i in 1:5]))) end function loss2(x) - sum(abs2, Array(DiffEqArray([x .* i for i in 1:5], 1:5))) + return sum(abs2, Array(DiffEqArray([x .* i for i in 1:5], 1:5))) end function loss3(x) @@ -16,7 +16,7 @@ function loss3(x) tmp += y[i, j] end - tmp + return tmp end function loss4(x) @@ -26,17 +26,17 @@ function loss4(x) tmp += y[i, j] end - tmp + return tmp end function loss5(x) - sum(abs2, Array(ArrayPartition([x .* i for i in 1:5]...))) + return sum(abs2, Array(ArrayPartition([x .* i for i in 1:5]...))) end function loss6(x) _x = ArrayPartition([x .* i for i in 1:5]...) _prob = ODEProblem((u, p, t) -> u, _x, (0, 1)) - sum(abs2, Array(_prob.u0)) + return sum(abs2, Array(_prob.u0)) end function loss7(x) @@ -89,7 +89,7 @@ loss(x) @test Zygote.gradient(loss7, x)[1] == ForwardDiff.gradient(loss7, x) @test Zygote.gradient(loss8, x)[1] == ForwardDiff.gradient(loss8, x) @test ForwardDiff.derivative(loss9, 0.0) == - VectorOfArray([collect((3i):(3i + 3)) for i in 1:5]) + VectorOfArray([collect((3i):(3i + 3)) for i in 1:5]) @test Zygote.gradient(loss10, x)[1] == ForwardDiff.gradient(loss10, x) @test Zygote.gradient(loss11, x)[1] == ForwardDiff.gradient(loss11, x) diff --git a/test/basic_indexing.jl b/test/basic_indexing.jl index 2b87676f..dc5e606b 100644 --- a/test/basic_indexing.jl +++ b/test/basic_indexing.jl @@ -15,9 +15,11 @@ fill!(mulX, 0) mulX .= sqrt.(abs.(testva .* X)) @test mulX == ref -@test Array(testva) == [1 4 7 - 2 5 8 - 3 6 9] +@test Array(testva) == [ + 1 4 7 + 2 5 8 + 3 6 9 +] @test testa[1:2, 1:2] == [1 4; 2 5] @test testva[1:2, 1:2] == [1 4; 2 5] @@ -25,9 +27,11 @@ mulX .= sqrt.(abs.(testva .* X)) t = [1, 2, 3] diffeq = DiffEqArray(recs, t) -@test Array(diffeq) == [1 4 7 - 2 5 8 - 3 6 9] +@test Array(diffeq) == [ + 1 4 7 + 2 5 8 + 3 6 9 +] @test diffeq[1:2, 1:2] == [1 4; 2 5] # # ndims == 2 @@ -318,7 +322,7 @@ for i in 1:2:5 end testva[CartesianIndex(3, 3, 5)] = 64.0 @test testva[:, 5][3, 3] == 64.0 -@test_throws ArgumentError testva[2, 1:2, :]=108.0 +@test_throws ArgumentError testva[2, 1:2, :] = 108.0 testva[2, 1:2, :] .= 108.0 for i in 1:5 @test all(testva[:, i][2, 1:2] .== 108.0) diff --git a/test/downstream/downstream_events.jl b/test/downstream/downstream_events.jl index f67cdfec..0bdfdfb8 100644 --- a/test/downstream/downstream_events.jl +++ b/test/downstream/downstream_events.jl @@ -3,17 +3,17 @@ u0 = ArrayPartition(SVector{1}(50.0), SVector{1}(0.0)) tspan = (0.0, 15.0) function f(u, p, t) - ArrayPartition(SVector{1}(u[2]), SVector{1}(-9.81)) + return ArrayPartition(SVector{1}(u[2]), SVector{1}(-9.81)) end prob = ODEProblem(f, u0, tspan) function condition(u, t, integrator) # Event when event_f(u,t,k) == 0 - u[1] + return u[1] end affect! = nothingf = affect_neg! = function (integrator) - integrator.u = ArrayPartition(SVector{1}(integrator.u[1]), SVector{1}(-integrator.u[2])) + return integrator.u = ArrayPartition(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 4aab1598..6e74197b 100644 --- a/test/downstream/odesolve.jl +++ b/test/downstream/odesolve.jl @@ -2,7 +2,7 @@ using OrdinaryDiffEq, NLsolve, RecursiveArrayTools, Test, ArrayInterface, Static function lorenz(du, u, p, t) du[1] = 10.0 * (u[2] - u[1]) du[2] = u[1] * (28.0 - u[3]) - u[2] - du[3] = u[1] * u[2] - (8 / 3) * u[3] + return du[3] = u[1] * u[2] - (8 / 3) * u[3] end u0 = ArrayPartition([1.0, 0.0], [0.0]) @test ArrayInterface.zeromatrix(u0) isa Matrix @@ -22,6 +22,7 @@ function mymodel(F, vars) F.x[i][2, 1] = (x[2, 1] + 3) * (x[2, 2]^3 - 7) + 19.0 F.x[i][2, 2] = sin(x[2, 2] * exp(x[2, 1]) - 3) end + 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]) @@ -32,28 +33,40 @@ nlsolve(mymodel, u0) # Nested ArrayPartition solves function dyn(u, p, t) - ArrayPartition(ArrayPartition(zeros(1), [0.0]), - ArrayPartition(zeros(1), [0.0])) + return ArrayPartition( + ArrayPartition(zeros(1), [0.0]), + ArrayPartition(zeros(1), [0.0]) + ) end @test solve( - ODEProblem(dyn, - ArrayPartition(ArrayPartition(zeros(1), [-1.0]), - ArrayPartition(zeros(1), [0.75])), - (0.0, 1.0)), - AutoTsit5(Rodas5())).retcode == ReturnCode.Success + ODEProblem( + dyn, + ArrayPartition( + ArrayPartition(zeros(1), [-1.0]), + ArrayPartition(zeros(1), [0.75]) + ), + (0.0, 1.0) + ), + AutoTsit5(Rodas5()) +).retcode == ReturnCode.Success @test_broken solve( - ODEProblem(dyn, - ArrayPartition(ArrayPartition(zeros(1), [-1.0]), - ArrayPartition(zeros(1), [0.75])), - (0.0, 1.0)), - Rodas5()).retcode == ReturnCode.Success + ODEProblem( + dyn, + ArrayPartition( + ArrayPartition(zeros(1), [-1.0]), + ArrayPartition(zeros(1), [0.75]) + ), + (0.0, 1.0) + ), + Rodas5() +).retcode == ReturnCode.Success function rhs!(duu::VectorOfArray, uu::VectorOfArray, p, t) du = parent(duu) u = parent(uu) - du .= u + return du .= u end u = fill(SVector{2}(ones(2)), 2, 3) diff --git a/test/downstream/symbol_indexing.jl b/test/downstream/symbol_indexing.jl index 7299456f..b420d80c 100644 --- a/test/downstream/symbol_indexing.jl +++ b/test/downstream/symbol_indexing.jl @@ -7,16 +7,22 @@ include("../testutils.jl") @variables x(t) @parameters τ @variables RHS(t) -@mtkbuild fol_separate = ODESystem([RHS ~ (1 - x) / τ, - D(x) ~ RHS], t) +@mtkbuild fol_separate = ODESystem( + [ + RHS ~ (1 - x) / τ, + D(x) ~ RHS, + ], t +) prob = ODEProblem(fol_separate, [x => 0.0], (0.0, 10.0), [τ => 3.0]) sol = solve(prob, Tsit5()) -sol_new = DiffEqArray(sol.u[1:10], +sol_new = DiffEqArray( + sol.u[1:10], sol.t[1:10], sol.prob.p, - sol) + sol +) @test sol_new[RHS] ≈ (1 .- sol_new[x]) ./ 3.0 @test sol_new[t] ≈ sol_new.t @@ -27,8 +33,12 @@ sol_new = DiffEqArray(sol.u[1:10], @test all(isequal.(all_variable_symbols(sol), all_variable_symbols(sol_new))) @test all(isequal.(all_variable_symbols(sol), [x, RHS])) @test all(isequal.(all_symbols(sol), all_symbols(sol_new))) -@test all([any(isequal(sym), all_symbols(sol)) - for sym in [x, RHS, τ, t, Initial(x), Initial(RHS)]]) +@test all( + [ + any(isequal(sym), all_symbols(sol)) + for sym in [x, RHS, τ, t, Initial(x), Initial(RHS)] + ] +) @test sol[solvedvariables] == sol[[x]] @test sol_new[solvedvariables] == sol_new[[x]] @test sol[allvariables] == sol[[x, RHS]] @@ -50,18 +60,26 @@ test_tables_interface(sol_new, [:timestamp, Symbol("x(t)")], hcat(sol_new[t], so # Two components @variables y(t) @parameters α β γ δ -@mtkbuild lv = ODESystem([D(x) ~ α * x - β * x * y, - D(y) ~ δ * x * y - γ * x * y], t) +@mtkbuild lv = ODESystem( + [ + D(x) ~ α * x - β * x * y, + D(y) ~ δ * x * y - γ * x * y, + ], t +) -prob = ODEProblem(lv, [x => 1.0, y => 1.0], (0.0, 10.0), - [α => 1.5, β => 1.0, γ => 3.0, δ => 1.0]) +prob = ODEProblem( + lv, [x => 1.0, y => 1.0], (0.0, 10.0), + [α => 1.5, β => 1.0, γ => 3.0, δ => 1.0] +) sol = solve(prob, Tsit5()) ts = 0:0.5:10 sol_ts = sol(ts) @assert sol_ts isa DiffEqArray -test_tables_interface(sol_ts, [:timestamp, Symbol("x(t)"), Symbol("y(t)")], - hcat(ts, Array(sol_ts)')) +test_tables_interface( + sol_ts, [:timestamp, Symbol("x(t)"), Symbol("y(t)")], + hcat(ts, Array(sol_ts)') +) # Test issue 508: Cannot call `to_index(::RaggedEnd)` with symbolic indexing and end @testset "Symbolic indexing with end (issue #508)" begin @@ -73,10 +91,12 @@ end # Array variables using LinearAlgebra -sts = @variables x(t)[1:3]=[1, 2, 3.0] y(t)=1.0 +sts = @variables x(t)[1:3] = [1, 2, 3.0] y(t) = 1.0 ps = @parameters p[1:3] = [1, 2, 3] -eqs = [collect(D.(x) .~ x) - D(y) ~ norm(collect(x)) * y - x[1]] +eqs = [ + collect(D.(x) .~ x) + D(y) ~ norm(collect(x)) * y - x[1] +] @mtkbuild sys = ODESystem(eqs, t, sts, ps) prob = ODEProblem(sys, [], (0, 1.0)) sol = solve(prob, Tsit5()) diff --git a/test/gpu/vectorofarray_gpu.jl b/test/gpu/vectorofarray_gpu.jl index dfb63292..bb5ee76a 100644 --- a/test/gpu/vectorofarray_gpu.jl +++ b/test/gpu/vectorofarray_gpu.jl @@ -32,7 +32,7 @@ mc = Array(m) p = cu([1.0, 2.0]) function f(p) x = VectorOfArray([p, p]) - sum(CuArray(x)) + return sum(CuArray(x)) end Zygote.gradient(f, p) diff --git a/test/interface_tests.jl b/test/interface_tests.jl index 18b8853d..60d652c6 100644 --- a/test/interface_tests.jl +++ b/test/interface_tests.jl @@ -89,8 +89,10 @@ arrvb = Array(testvb) # view testvc = VectorOfArray([rand(1:10, 3, 3) for _ in 1:3]) arrvc = Array(testvc) -for idxs in [(2, 2, :), (2, :, 2), (:, 2, 2), (:, :, 2), (:, 2, :), (2, :, :), (:, :, :), - (1:2, 1:2, Bool[1, 0, 1]), (1:2, Bool[1, 0, 1], 1:2), (Bool[1, 0, 1], 1:2, 1:2)] +for idxs in [ + (2, 2, :), (2, :, 2), (:, 2, 2), (:, :, 2), (:, 2, :), (2, :, :), (:, :, :), + (1:2, 1:2, Bool[1, 0, 1]), (1:2, Bool[1, 0, 1], 1:2), (Bool[1, 0, 1], 1:2, 1:2), + ] arr_view = view(arrvc, idxs...) voa_view = view(testvc, idxs...) @test size(arr_view) == size(voa_view) @@ -101,10 +103,10 @@ testvc = VectorOfArray(collect(1:10)) arrvc = Array(testvc) bool_idx = rand(Bool, 10) for (voaidx, arridx) in [ - ((:,), (:,)), - ((3:5,), (3:5,)), - ((bool_idx,), (bool_idx,)) -] + ((:,), (:,)), + ((3:5,), (3:5,)), + ((bool_idx,), (bool_idx,)), + ] arr_view = view(arrvc, arridx...) voa_view = view(testvc.u, voaidx...) @test size(arr_view) == size(voa_view) @@ -117,7 +119,7 @@ end testva = VectorOfArray([VectorOfArray([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] + [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] # convert array from VectorOfArray/DiffEqArray t = 1:8 @@ -167,21 +169,29 @@ 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 = 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) + ), + ] +) arr = rand(3, 2, 2, 3) copyto!(testva, arr) @test Array(testva) == arr @@ -235,7 +245,7 @@ u2 = VectorOfArray([fill(4, SVector{2, Float64}), 2 .* ones(SVector{2, Float64}) u3 = VectorOfArray([fill(4, SVector{2, Float64}), 2 .* ones(SVector{2, Float64})]) function f(u1, u2, u3) - u3 .= u1 .+ u2 + return u3 .= u1 .+ u2 end f(u1, u2, u3) @test (@allocated f(u1, u2, u3)) == 0 @@ -249,7 +259,7 @@ z .= zz @test z == VectorOfArray([fill(4, SVector{2, Float64}), fill(2, SVector{2, Float64})]) function f!(z, zz) - z .= zz + return z .= zz end f!(z, zz) @test (@allocated f!(z, zz)) == 0 @@ -258,13 +268,13 @@ z .= 0.1 @test z == VectorOfArray([fill(0.1, SVector{2, Float64}), fill(0.1, SVector{2, Float64})]) function f2!(z) - z .= 0.1 + return z .= 0.1 end f2!(z) @test (@allocated f2!(z)) == 0 function f3!(z, zz) - @.. broadcast=false z=zz + return @.. broadcast = false z = zz end f3!(z, zz) @test z == VectorOfArray([fill(4, SVector{2, Float64}), fill(2, SVector{2, Float64})]) diff --git a/test/named_array_partition_tests.jl b/test/named_array_partition_tests.jl index a3c1d952..bec8cd5c 100644 --- a/test/named_array_partition_tests.jl +++ b/test/named_array_partition_tests.jl @@ -7,7 +7,7 @@ using RecursiveArrayTools, ArrayInterface, Test @test typeof(similar(x)) <: NamedArrayPartition @test typeof(similar(x, Int)) <: NamedArrayPartition @test x.a ≈ ones(10) - @test typeof(x .+ x[1:end]) <: Vector # test broadcast precedence + @test typeof(x .+ x[1:end]) <: Vector # test broadcast precedence @test all(x .== x[1:end]) @test ArrayInterface.zeromatrix(x) isa Matrix @test size(ArrayInterface.zeromatrix(x)) == (30, 30) @@ -28,8 +28,10 @@ using RecursiveArrayTools, ArrayInterface, Test using StructArrays using StaticArrays: SVector - x = NamedArrayPartition(a = StructArray{SVector{2, Float64}}((ones(5), 2 * ones(5))), - b = StructArray{SVector{2, Float64}}((3 * ones(2, 2), 4 * ones(2, 2)))) + x = NamedArrayPartition( + a = StructArray{SVector{2, Float64}}((ones(5), 2 * ones(5))), + b = StructArray{SVector{2, Float64}}((3 * ones(2, 2), 4 * ones(2, 2))) + ) @test typeof(x.a) <: StructVector{<:SVector{2}} @test typeof(x.b) <: StructArray{<:SVector{2}, 2} @test typeof((x -> x[1]).(x)) <: NamedArrayPartition diff --git a/test/partitions_and_static_arrays.jl b/test/partitions_and_static_arrays.jl index d5106161..7eac8809 100644 --- a/test/partitions_and_static_arrays.jl +++ b/test/partitions_and_static_arrays.jl @@ -1,7 +1,11 @@ using Test, RecursiveArrayTools, StaticArrays -p = ArrayPartition((zeros(Float32, 2), zeros(SMatrix{2, 2, Int64}, 2), - zeros(SVector{3, Float64}, 2))) +p = ArrayPartition( + ( + 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 diff --git a/test/partitions_test.jl b/test/partitions_test.jl index cf0d8c92..53429740 100644 --- a/test/partitions_test.jl +++ b/test/partitions_test.jl @@ -202,7 +202,7 @@ _broadcast_wrapper(y) = _scalar_op.(y) S = [ ((1,), (2,)) => ((1,), (2,)), ((3, 2), (2,)) => ((3, 2), (2,)), - ((3, 2), (2,)) => ((3,), (3,), (2,)) + ((3, 2), (2,)) => ((3,), (3,), (2,)), ] for sizes in S @@ -220,13 +220,13 @@ xce0 = ArrayPartition(zeros(2), [0.0]) xcde0 = copy(xce0) function foo(y, x) y .= y .+ x - nothing + return nothing end foo(xcde0, xce0) #@test 0 == @allocated foo(xcde0, xce0) function foo2(y, x) y .= y .+ 2 .* x - nothing + return nothing end foo2(xcde0, xce0) #@test 0 == @allocated foo(xcde0, xce0) @@ -245,13 +245,15 @@ Base.IndexStyle(::MyType) = IndexLinear() Base.BroadcastStyle(::Type{<:MyType}) = Broadcast.ArrayStyle{MyType}() -function Base.similar(bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{MyType}}, - ::Type{T}) where {T} - similar(find_mt(bc), T) +function Base.similar( + bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{MyType}}, + ::Type{T} + ) where {T} + return similar(find_mt(bc), T) end function Base.similar(bc::Broadcast.Broadcasted{Broadcast.ArrayStyle{MyType}}) - similar(find_mt(bc)) + return similar(find_mt(bc)) end find_mt(bc::Base.Broadcast.Broadcasted) = find_mt(bc.args) @@ -277,21 +279,28 @@ up = 2 .* ap .+ 1 @test typeof(ap) == typeof(up) @testset "ArrayInterface.ismutable(ArrayPartition($a, $b)) == $r" for (a, b, r) in ( - (1, - 2, - false), - ([ - 1 - ], - 2, - false), - ([ - 1 - ], - [ - 2 - ], - true)) + ( + 1, + 2, + false, + ), + ( + [ + 1, + ], + 2, + false, + ), + ( + [ + 1, + ], + [ + 2, + ], + true, + ), + ) @test ArrayInterface.ismutable(ArrayPartition(a, b)) == r end @@ -316,9 +325,14 @@ end @testset "Copy and zero with type changing array" begin # Motivating use case for this is ArrayPartitions of Arrow arrays which are mmap:ed and change type when copied struct TypeChangingArray{T, N} <: AbstractArray{T, N} end - Base.copy(::TypeChangingArray{ - T, N}) where {T, N} = Array{T, N}(undef, - ntuple(_ -> 0, N)) + Base.copy( + ::TypeChangingArray{ + T, N, + } + ) where {T, N} = Array{T, N}( + undef, + ntuple(_ -> 0, N) + ) Base.zero(::TypeChangingArray{T, N}) where {T, N} = zeros(T, ntuple(_ -> 0, N)) a = ArrayPartition(TypeChangingArray{Int, 2}(), TypeChangingArray{Float32, 2}()) diff --git a/test/runtests.jl b/test/runtests.jl index 647eacfc..60719835 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -8,13 +8,13 @@ const GROUP = get(ENV, "GROUP", "All") function activate_downstream_env() Pkg.activate("downstream") Pkg.develop(PackageSpec(path = dirname(@__DIR__))) - Pkg.instantiate() + return Pkg.instantiate() end function activate_gpu_env() Pkg.activate("gpu") Pkg.develop(PackageSpec(path = dirname(@__DIR__))) - Pkg.instantiate() + return Pkg.instantiate() end @time begin diff --git a/test/symbolic_indexing_interface_test.jl b/test/symbolic_indexing_interface_test.jl index f7105005..22b0beb6 100644 --- a/test/symbolic_indexing_interface_test.jl +++ b/test/symbolic_indexing_interface_test.jl @@ -4,12 +4,14 @@ t = 0.0:0.1:1.0 f(x) = 2x f2(x) = 3x -dx = DiffEqArray([[f(x), f2(x)] for x in t], +dx = DiffEqArray( + [[f(x), f2(x)] for x in t], t, [1.0, 2.0]; variables = [:a, :b], parameters = [:p, :q], - independent_variables = [:t]) + independent_variables = [:t] +) @test dx[:t] == t @test dx[:a] == [f(x) for x in t] @test dx[:a, 2] ≈ f(t[2]) @@ -43,7 +45,7 @@ get_tuple = getu(dx, (:a, :b)) @test is_parameter.((dx,), [:a, :b, :p, :q, :t]) == [false, false, true, true, false] @test parameter_index.((dx,), [:a, :b, :p, :q, :t]) == [nothing, nothing, 1, 2, nothing] @test is_independent_variable.((dx,), [:a, :b, :p, :q, :t]) == - [false, false, false, false, true] + [false, false, false, false, true] @test variable_symbols(dx) == all_variable_symbols(dx) == [:a, :b] @test parameter_symbols(dx) == [:p, :q] @test independent_variable_symbols(dx) == [:t] diff --git a/test/testutils.jl b/test/testutils.jl index 45b98b38..1efefb73 100644 --- a/test/testutils.jl +++ b/test/testutils.jl @@ -4,8 +4,10 @@ using Tables: IteratorInterfaceExtensions # Test Tables interface with row access + IteratorInterfaceExtensions for QueryVerse # (see https://tables.juliadata.org/stable/#Testing-Tables.jl-Implementations) -function test_tables_interface(x::AbstractDiffEqArray, names::Vector{Symbol}, - values::Matrix) +function test_tables_interface( + x::AbstractDiffEqArray, names::Vector{Symbol}, + values::Matrix + ) @assert length(names) == size(values, 2) # AbstractDiffEqArray is a table with row access @@ -31,7 +33,7 @@ function test_tables_interface(x::AbstractDiffEqArray, names::Vector{Symbol}, @test propertynames(row) == Tables.columnnames(row) == names for (j, name) in enumerate(names) @test getproperty(row, name) == Tables.getcolumn(row, name) == - Tables.getcolumn(row, j) == values[i, j] + Tables.getcolumn(row, j) == values[i, j] end end @@ -46,7 +48,7 @@ function test_tables_interface(x::AbstractDiffEqArray, names::Vector{Symbol}, @test propertynames(coltbl) == Tables.columnnames(coltbl) == Tuple(names) for (i, name) in enumerate(names) @test getproperty(coltbl, name) == Tables.getcolumn(coltbl, name) == - Tables.getcolumn(coltbl, i) == values[:, i] + Tables.getcolumn(coltbl, i) == values[:, i] end # IteratorInterfaceExtensions @@ -60,5 +62,5 @@ function test_tables_interface(x::AbstractDiffEqArray, names::Vector{Symbol}, end end - nothing + return nothing end diff --git a/test/utils_test.jl b/test/utils_test.jl index 9b9dbded..d3bb349d 100644 --- a/test/utils_test.jl +++ b/test/utils_test.jl @@ -8,8 +8,10 @@ data = convert(Array, randomized) ## Test means A = [[1 2; 3 4], [1 3; 4 6], [5 6; 7 8]] -@test recursive_mean(A) ≈ [2.33333333 3.666666666 - 4.6666666666 6.0] +@test recursive_mean(A) ≈ [ + 2.33333333 3.666666666 + 4.6666666666 6.0 +] A = zeros(5, 5) @test recursive_unitless_eltype(A) == Float64 @@ -53,7 +55,7 @@ function test_recursive_bottom_eltype() # It should return expected type for an array of vectors of chars AVval = [@SVector [val, val] for i in 1:5] - @test recursive_bottom_eltype(AVval) == expected_type + return @test recursive_bottom_eltype(AVval) == expected_type end # testing chars @@ -70,7 +72,7 @@ function test_recursive_bottom_eltype() # testing float values test_value(1.0, Float64) - test_value(1.0u"kg", eltype(1.0u"kg")) + return test_value(1.0u"kg", eltype(1.0u"kg")) end test_recursive_bottom_eltype()