Skip to content

Commit 55790c8

Browse files
committed
Creation of empty ComponentArrays. Closes #81
1 parent 4af65c5 commit 55790c8

File tree

3 files changed

+123
-1
lines changed

3 files changed

+123
-1
lines changed

src/componentarray.jl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ end
5959

6060
# Entry from NamedTuple, Dict, or kwargs
6161
ComponentArray{T}(nt::NamedTuple) where T = ComponentArray(make_carray_args(T, nt)...)
62+
ComponentArray{T}(::NamedTuple{(), Tuple{}}) where T = ComponentArray(T[], (FlatAxis(),))
6263
ComponentArray(nt::NamedTuple) = ComponentArray(make_carray_args(nt)...)
64+
ComponentArray(::NamedTuple{(), Tuple{}}) = ComponentArray(Any[], (FlatAxis(),))
6365
ComponentArray(d::AbstractDict) = ComponentArray(NamedTuple{Tuple(keys(d))}(values(d)))
6466
ComponentArray{T}(;kwargs...) where T = ComponentArray{T}((;kwargs...))
6567
ComponentArray(;kwargs...) = ComponentArray((;kwargs...))
@@ -68,6 +70,7 @@ ComponentArray(x::ComponentArray) = x
6870
ComponentArray{T}(x::ComponentArray) where {T} = T.(x)
6971
(CA::Type{<:ComponentArray{T,N,A,Ax}})(x::ComponentArray) where {T,N,A,Ax} = ComponentArray(T.(getdata(x)), getaxes(x))
7072

73+
7174
## Some aliases
7275
"""
7376
x = ComponentVector(nt::NamedTuple)
@@ -109,6 +112,9 @@ ComponentMatrix(data::AbstractArray, ax...) = throw(DimensionMismatch("A `Compon
109112
ComponentMatrix(x::ComponentMatrix) = x
110113
ComponentMatrix{T}(x::ComponentMatrix) where {T} = T.(x)
111114

115+
ComponentMatrix() = ComponentMatrix(Array{Any}(undef, 0, 0), (FlatAxis(), FlatAxis()))
116+
ComponentMatrix{T}() where {T} = ComponentMatrix(Array{T}(undef, 0, 0), (FlatAxis(), FlatAxis()))
117+
112118
const CArray = ComponentArray
113119
const CVector = ComponentVector
114120
const CMatrix = ComponentMatrix
@@ -119,12 +125,14 @@ const AdjOrTransComponentArray{T, A} = Union{Adjoint{T, A}, Transpose{T, A}} whe
119125

120126
## Constructor helpers
121127
# For making ComponentArrays from named tuples
128+
make_carray_args(::NamedTuple{(), Tuple{}}) = (Any[], FlatAxis())
129+
make_carray_args(::Type{T}, ::NamedTuple{(), Tuple{}}) where {T} = (T[], FlatAxis())
122130
function make_carray_args(nt)
123131
data, ax = make_carray_args(Vector, nt)
124132
data = length(data)==1 ? [data[1]] : reduce(vcat, data)
125133
return (data, ax)
126134
end
127-
make_carray_args(T::Type, nt) = make_carray_args(Vector{T}, nt)
135+
make_carray_args(::Type{T}, nt) where {T} = make_carray_args(Vector{T}, nt)
128136
function make_carray_args(A::Type{<:AbstractArray}, nt)
129137
data, idx = make_idx([], nt, 0)
130138
return (A(data), Axis(idx))

test/diffeq_tests.jl

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
using ComponentArrays
2+
using DifferentialEquations
3+
using LabelledArrays
4+
using Sundials
5+
using Test
6+
using Unitful
7+
8+
@testset "Performance" begin
9+
@testset "Issue 36" begin
10+
function f1(du,u,p,t)
11+
du.x .= -1 .* u.x .* u.y .* p[1]
12+
du.y .= -1 .* u.y .* p[2]
13+
end
14+
15+
n = 100
16+
17+
p = [0.1,0.1]
18+
19+
lu_0 = @LArray fill(1000.0,2*n) (x=(1:n), y=(n+1:2*n))
20+
cu_0 = ComponentArray(x=fill(1000.0, n), y=fill(1000.0, n))
21+
22+
lprob1 = ODEProblem(f1,lu_0,(0,100.0),p)
23+
cprob1 = ODEProblem(f1,cu_0,(0,100.0),p)
24+
25+
solve(lprob1, Rodas5());
26+
solve(lprob1, Rodas5(autodiff=false));
27+
solve(cprob1, Rodas5());
28+
solve(cprob1, Rodas5(autodiff=false));
29+
30+
ltime1 = @elapsed lsol1 = solve(lprob1, Rodas5());
31+
ltime2 = @elapsed lsol2 = solve(lprob1, Rodas5(autodiff=false));
32+
ctime1 = @elapsed csol1 = solve(cprob1, Rodas5());
33+
ctime2 = @elapsed csol2 = solve(cprob1, Rodas5(autodiff=false));
34+
35+
@test (ctime1 - ltime1)/ltime1 < 0.3
36+
@test (ctime2 - ltime2)/ltime2 < 0.3
37+
end
38+
39+
@testset "Slack Issue 2021-2-19" begin
40+
DifferentialEquations.DiffEqBase.diffeqbc(x::ComponentArray) = DifferentialEquations.DiffEqBase.DiffEqBC(x)
41+
42+
function heat_conduction(du,u,p,t)
43+
nknots = 100
44+
= (1.0/(nknots+1))^2
45+
du .= zero(eltype(u))
46+
u₃ = @view u[3:end]
47+
u₂ = @view u[2:end-1]
48+
u₁ = @view u[1:end-2]
49+
@. du[2:end-1] = (u₃ - 2*u₂ + u₁)/
50+
nothing
51+
end
52+
53+
t0, t1 = 0.0, 1.0
54+
u0 = randn(300)
55+
u0_ca = ComponentArray(a=u0[1:100],b=u0[101:200],c=u0[201:300])
56+
u0_la = @LArray u0 (a=1:100, b=101:200, c=201:300)
57+
58+
cprob = ODEProblem(heat_conduction, u0_ca, (t0, t1))
59+
lprob = ODEProblem(heat_conduction, u0_la, (t0, t1))
60+
prob = ODEProblem(heat_conduction, u0, (t0, t1))
61+
62+
solve(cprob, Tsit5(), saveat=0.2)
63+
solve(lprob, Tsit5(), saveat=0.2)
64+
solve(prob, Tsit5(), saveat=0.2)
65+
66+
ctime = @elapsed solve(cprob, Tsit5(), saveat=0.2)
67+
ltime = @elapsed solve(lprob, Tsit5(), saveat=0.2)
68+
time = @elapsed solve(prob, Tsit5(), saveat=0.2)
69+
70+
@test (ctime - time)/time < 0.1
71+
@test (ctime - ltime)/ltime < 0.05
72+
end
73+
end
74+
75+
@testset "Issue 53" begin
76+
x0 = ComponentArray(x=ones(10))
77+
prob = ODEProblem((u,p,t)->u, x0, (0.,1.))
78+
sol = solve(prob, CVODE_BDF(linear_solver=:BCG), reltol=1e-15, abstol=1e-15)
79+
@test sol(1)[1] exp(1)
80+
end
81+
82+
@testset "Issue 55" begin
83+
f!(D, x, p, t) = nothing
84+
x0 = ComponentArray(x=zeros(4))
85+
prob = ODEProblem(f!, x0, (0.0, 1.0), 0.0)
86+
sol = solve(prob, Rodas4())
87+
@test sol[1] == x0
88+
end
89+
90+
@testset "Unitful" begin
91+
tspan = (0.0u"s", 10.0u"s")
92+
pos = 0.0u"m"
93+
vel = 0.0u"m/s"
94+
x0 = ComponentArray(pos=pos, vel=vel)
95+
F(t) = 1
96+
97+
# double integrator in state-space form
98+
A = Union{typeof(0u"s^-1"), typeof(0u"s^-2"), Int}[0u"s^-1" 1; 0u"s^-2" 0u"s^-1"]
99+
B = Union{typeof(0u"m/s"), typeof(1u"m/s^2")}[0u"m/s"; 1u"m/s^2"]
100+
di(x,u,t) = A*x .+ B*u(t)
101+
102+
prob = ODEProblem(di, x0, tspan, F)
103+
sol = solve(prob, Tsit5())
104+
@test unit(sol[end].pos) == u"m"
105+
@test unit(sol[end].vel) == u"m/s"
106+
end

test/runtests.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ end
9393

9494
# Issue #61
9595
@test ComponentArray(x=1) isa ComponentArray{Int}
96+
97+
# Issue #81
98+
@test ComponentArray() isa ComponentArray
99+
@test ComponentVector() isa ComponentVector
100+
@test ComponentMatrix() isa ComponentMatrix
101+
@test ComponentArray{Float32}() isa ComponentArray{Float32}
102+
@test ComponentVector{Float32}() isa ComponentVector{Float32}
103+
@test ComponentMatrix{Float32}() isa ComponentMatrix{Float32}
96104
end
97105

98106
@testset "Attributes" begin

0 commit comments

Comments
 (0)