Skip to content

Commit 88dfa07

Browse files
Merge pull request #1055 from DhairyaLGandhi/dg/v10
Update observables + AD tests with MTK v10
2 parents dc7e5bf + cd8d68d commit 88dfa07

File tree

7 files changed

+147
-143
lines changed

7 files changed

+147
-143
lines changed

.github/workflows/Tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ jobs:
3232
group:
3333
- "Core"
3434
- "Downstream"
35+
- "SymbolicIndexingInterface"
3536
- "QA"
3637
- "Python"
3738
uses: "SciML/.github/.github/workflows/tests.yml@v1"

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ StaticArraysCore = "1.4"
9393
Statistics = "1.10"
9494
SymbolicIndexingInterface = "0.3.36"
9595
Tables = "1.11"
96-
Zygote = "0.6.67, 0.7"
96+
Zygote = "0.7.10"
9797
julia = "1.10"
9898

9999
[extras]

test/downstream/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ DelayDiffEq = "5"
3636
DiffEqCallbacks = "3, 4"
3737
ForwardDiff = "0.10, 1"
3838
JumpProcesses = "9.10"
39-
ModelingToolkit = "10.0"
39+
ModelingToolkit = "10.0.4"
4040
ModelingToolkitStandardLibrary = "2.7"
4141
NonlinearSolve = "2, 3, 4"
4242
Optimization = "4"

test/downstream/modelingtoolkit_remake.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ eqs = [D(x) ~ σ * (y - x),
1818
D(y) ~ x *- z) - y,
1919
D(z) ~ x * y - β * z]
2020

21-
@named sys = System(eqs, t; parameter_dependencies = [q => 3β])
21+
@named sys = System(eqs, t; parameter_dependencies = [q ~ 3β])
2222
sys = complete(sys)
2323
u0 = [x => 1.0,
2424
y => 0.0,
@@ -70,7 +70,7 @@ push!(probs, OptimizationProblem(optsys, u0, p))
7070
k = ShiftIndex(t)
7171
@mtkcompile discsys = System(
7272
[x ~ x(k - 1) * ρ + y(k - 2), y ~ y(k - 1) * σ - z(k - 2), z ~ z(k - 1) * β + x(k - 2)],
73-
t; defaults = [x => 1.0, y => 1.0, z => 1.0])
73+
t; defaults = [x => 1.0, y => 1.0, z => 1.0, x(k-1) => 0.0, y(k-1) => 0.0, z(k-1) => 0.0])
7474
# Roundabout method to avoid having to specify values for previous timestep
7575
discprob = DiscreteProblem(discsys, p, (0, 10))
7676
for (var, v) in u0
@@ -338,7 +338,7 @@ end
338338
@testset "Lazy initialization" begin
339339
@variables _x(..) [guess = 1.0] y(t) [guess = 1.0]
340340
@parameters p=1.0 [guess = 1.0]
341-
@brownian a
341+
@brownians a
342342
x = _x(t)
343343

344344
initprob = NonlinearProblem(nothing) do args...

test/downstream/observables_autodiff.jl

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,16 @@ sol = solve(prob, Tsit5())
3333
gs, = gradient(sol) do sol
3434
sum(sol[sys.w])
3535
end
36-
du_ = [0.0, 1.0, 1.0, 1.0]
37-
du = [du_ for _ in sol.u]
36+
du_ = [1.0, 1.0, 1.0, 0.0]
37+
du = [du_ for _ in sol[[D(x), x, y, z]]]
3838
@test du == gs.u
3939

4040
# Observable in a vector
4141
gs, = gradient(sol) do sol
4242
sum(sum.(sol[[sys.w, sys.x]]))
4343
end
44-
du_ = [0.0, 1.0, 1.0, 2.0]
45-
du = [du_ for _ in sol.u]
44+
du_ = [1.0, 1.0, 2.0, 0.0]
45+
du = [du_ for _ in sol[[D(x), x, y, z]]]
4646
@test du == gs.u
4747
end
4848

@@ -118,14 +118,19 @@ end
118118
end
119119

120120
@testset "Adjoints with DAE" begin
121-
gs_mtkp, gs_p_new = gradient(prob.p, prob.p.tunable) do p, new_tunables
121+
model = create_model()
122+
sys = mtkcompile(model)
123+
prob = ODEProblem(sys, [], (0.0, 1.0))
124+
tunables, _, _ = SS.canonicalize(SS.Tunable(), prob.p)
125+
126+
gs_mtkp, gs_p_new = gradient(prob.p, tunables) do p, new_tunables
122127
new_p = SS.replace(SS.Tunable(), p, new_tunables)
123128
new_prob = remake(prob, p = new_p)
124129
sol = solve(new_prob, Rodas4())
125-
mean(abs.(sol[sys.ampermeter.i] .- gt))
126130
sum(sol[sys.ampermeter.i])
127131
end
128132

129133
@test isnothing(gs_mtkp)
130-
@test length(gs_p_new) == length(p_new)
134+
@test !isnothing(gs_p_new)
135+
@test length(gs_p_new) == length(tunables)
131136
end

test/downstream/solution_interface.jl

Lines changed: 120 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,29 @@ using Plots: Plots, plot
66

77
### Tests on non-layered model (everything should work). ###
88

9-
@parameters a b c d
10-
@variables s1(t) s2(t)
9+
@testset "Basic indexing" begin
10+
@parameters a b c d
11+
@variables s1(t) s2(t)
12+
13+
eqs = [D(s1) ~ a * s1 / (1 + s1 + s2) - b * s1,
14+
D(s2) ~ +c * s2 / (1 + s1 + s2) - d * s2]
15+
16+
@mtkcompile population_model = System(eqs, t)
17+
18+
# Tests on ODEProblem.
19+
u0 = [s1 => 2.0, s2 => 1.0]
20+
p = [a => 2.0, b => 1.0, c => 1.0, d => 1.0]
21+
tspan = (0.0, 1000000.0)
22+
oprob = ODEProblem(population_model, [u0; p], tspan)
23+
sol = solve(oprob, Rodas4())
24+
25+
@test sol[s1] == sol[population_model.s1] == sol[:s1]
26+
@test sol[s2] == sol[population_model.s2] == sol[:s2]
27+
@test sol[s1][end] 1.0
28+
@test_throws Exception sol[a]
29+
@test_throws Exception sol[population_model.a]
30+
@test_throws Exception sol[:a]
1131

12-
eqs = [D(s1) ~ a * s1 / (1 + s1 + s2) - b * s1,
13-
D(s2) ~ +c * s2 / (1 + s1 + s2) - d * s2]
14-
15-
@mtkcompile population_model = System(eqs, t)
16-
17-
# Tests on ODEProblem.
18-
u0 = [s1 => 2.0, s2 => 1.0]
19-
p = [a => 2.0, b => 1.0, c => 1.0, d => 1.0]
20-
tspan = (0.0, 1000000.0)
21-
oprob = ODEProblem(population_model, [u0; p], tspan)
22-
sol = solve(oprob, Rodas4())
23-
24-
@test sol[s1] == sol[population_model.s1] == sol[:s1]
25-
@test sol[s2] == sol[population_model.s2] == sol[:s2]
26-
@test sol[s1][end] 1.0
27-
@test_throws Exception sol[a]
28-
@test_throws Exception sol[population_model.a]
29-
@test_throws Exception sol[:a]
30-
31-
@testset "plot ODE solution" begin
3232
Plots.unicodeplots()
3333
f = ODEFunction((u, p, t) -> -u, analytic = (u0, p, t) -> u0 * exp(-t))
3434

@@ -49,104 +49,104 @@ sol = solve(oprob, Rodas4())
4949
sol = solve(ode, Tsit5())
5050
@test_nowarn plot(sol)
5151
@test_nowarn plot(sol; plot_analytic = true)
52-
end
53-
54-
# Tests on SDEProblem
55-
noiseeqs = [0.1 * s1,
56-
0.1 * s2]
57-
@named noisy_population_model = SDESystem(population_model, noiseeqs)
58-
noisy_population_model = complete(noisy_population_model)
59-
sprob = SDEProblem(noisy_population_model, [u0; p], (0.0, 100.0))
60-
sol = solve(sprob, ImplicitEM())
61-
62-
@test sol[s1] == sol[noisy_population_model.s1] == sol[:s1]
63-
@test sol[s2] == sol[noisy_population_model.s2] == sol[:s2]
64-
@test_throws Exception sol[a]
65-
@test_throws Exception sol[noisy_population_model.a]
66-
@test_throws Exception sol[:a]
67-
@test_nowarn sol(0.5, idxs = noisy_population_model.s1)
68-
### Tests on layered model (some things should not work). ###
69-
70-
@parameters σ ρ β
71-
@variables x(t) y(t) z(t)
72-
73-
eqs = [D(x) ~ σ * (y - x),
74-
D(y) ~ x *- z) - y,
75-
D(z) ~ x * y - β * z]
76-
77-
@named lorenz1 = System(eqs, t)
78-
@named lorenz2 = System(eqs, t)
79-
80-
@parameters γ
81-
@variables a(t) α(t)
82-
connections = [0 ~ lorenz1.x + lorenz2.y + a * γ,
83-
α ~ 2lorenz1.x + a * γ]
84-
@mtkcompile sys = System(connections, t, [a, α], [γ], systems = [lorenz1, lorenz2])
85-
86-
u0 = [lorenz1.x => 1.0,
87-
lorenz1.y => 0.0,
88-
lorenz1.z => 0.0,
89-
lorenz2.x => 0.0,
90-
lorenz2.y => 1.0,
91-
lorenz2.z => 0.0]
9252

93-
p = [lorenz1.σ => 10.0,
94-
lorenz1.ρ => 28.0,
95-
lorenz1.β => 8 / 3,
96-
lorenz2.σ => 10.0,
97-
lorenz2.ρ => 28.0,
98-
lorenz2.β => 8 / 3,
99-
γ => 2.0]
100-
101-
tspan = (0.0, 100.0)
102-
prob = ODEProblem(sys, [u0; p], tspan)
103-
sol = solve(prob, Rodas4())
104-
105-
@test_throws ArgumentError sol[x]
106-
@test in(sol[lorenz1.x], [getindex.(sol.u, i) for i in 1:length(unknowns(sol.prob.f.sys))])
107-
@test_throws KeyError sol[:x]
108-
109-
### Non-symbolic indexing tests
110-
@test sol[:, 1] isa AbstractVector
111-
@test sol[:, 1:2] isa AbstractDiffEqArray
112-
@test sol[:, [1, 2]] isa AbstractDiffEqArray
113-
114-
sol1 = sol(0.0:1.0:10.0)
115-
@test sol1.u isa Vector
116-
@test first(sol1.u) isa Vector
117-
@test length(sol1.u) == 11
118-
@test length(sol1.t) == 11
119-
120-
sol2 = sol(0.1)
121-
@test sol2 isa Vector
122-
@test length(sol2) == length(unknowns(sys))
123-
@test first(sol2) isa Real
124-
125-
sol3 = sol(0.0:1.0:10.0, idxs = [lorenz1.x, lorenz2.x])
126-
127-
sol7 = sol(0.0:1.0:10.0, idxs = [2, 1])
128-
@test sol7.u isa Vector
129-
@test first(sol7.u) isa Vector
130-
@test length(sol7.u) == 11
131-
@test length(sol7.t) == 11
132-
@test collect(sol7[t]) sol3.t
133-
@test collect(sol7[t, 1:5]) sol3.t[1:5]
134-
135-
sol8 = sol(0.1, idxs = [2, 1])
136-
@test sol8 isa Vector
137-
@test length(sol8) == 2
138-
@test first(sol8) isa Real
139-
140-
sol9 = sol(0.0:1.0:10.0, idxs = 2)
141-
@test sol9.u isa Vector
142-
@test first(sol9.u) isa Real
143-
@test length(sol9.u) == 11
144-
@test length(sol9.t) == 11
145-
@test collect(sol9[t]) sol3.t
146-
@test collect(sol9[t, 1:5]) sol3.t[1:5]
147-
148-
sol10 = sol(0.1, idxs = 2)
149-
@test sol10 isa Real
53+
# Tests on SDEProblem
54+
noiseeqs = [0.1 * s1,
55+
0.1 * s2]
56+
@named noisy_population_model = SDESystem(population_model, noiseeqs)
57+
noisy_population_model = complete(noisy_population_model)
58+
sprob = SDEProblem(noisy_population_model, [u0; p], (0.0, 100.0))
59+
sol = solve(sprob, ImplicitEM())
60+
61+
@test sol[s1] == sol[noisy_population_model.s1] == sol[:s1]
62+
@test sol[s2] == sol[noisy_population_model.s2] == sol[:s2]
63+
@test_throws Exception sol[a]
64+
@test_throws Exception sol[noisy_population_model.a]
65+
@test_throws Exception sol[:a]
66+
@test_nowarn sol(0.5, idxs = noisy_population_model.s1)
67+
### Tests on layered model (some things should not work). ###
68+
69+
@parameters σ ρ β
70+
@variables x(t) y(t) z(t)
71+
72+
eqs = [D(x) ~ σ * (y - x),
73+
D(y) ~ x *- z) - y,
74+
D(z) ~ x * y - β * z]
75+
76+
@named lorenz1 = System(eqs, t)
77+
@named lorenz2 = System(eqs, t)
78+
79+
@parameters γ
80+
@variables a(t) α(t)
81+
connections = [0 ~ lorenz1.x + lorenz2.y + a * γ,
82+
α ~ 2lorenz1.x + a * γ]
83+
@mtkcompile sys = System(connections, t, [a, α], [γ], systems = [lorenz1, lorenz2])
84+
85+
u0 = [lorenz1.x => 1.0,
86+
lorenz1.y => 0.0,
87+
lorenz1.z => 0.0,
88+
lorenz2.x => 0.0,
89+
lorenz2.y => 1.0,
90+
lorenz2.z => 0.0]
91+
92+
p = [lorenz1.σ => 10.0,
93+
lorenz1.ρ => 28.0,
94+
lorenz1.β => 8 / 3,
95+
lorenz2.σ => 10.0,
96+
lorenz2.ρ => 28.0,
97+
lorenz2.β => 8 / 3,
98+
γ => 2.0]
99+
100+
tspan = (0.0, 100.0)
101+
prob = ODEProblem(sys, [u0; p], tspan)
102+
sol = solve(prob, Rodas4())
103+
104+
@test_throws ArgumentError sol[x]
105+
@test in(sol[lorenz1.x], [getindex.(sol.u, i) for i in 1:length(unknowns(sol.prob.f.sys))])
106+
@test_throws KeyError sol[:x]
107+
108+
### Non-symbolic indexing tests
109+
@test sol[:, 1] isa AbstractVector
110+
@test sol[:, 1:2] isa AbstractDiffEqArray
111+
@test sol[:, [1, 2]] isa AbstractDiffEqArray
112+
113+
sol1 = sol(0.0:1.0:10.0)
114+
@test sol1.u isa Vector
115+
@test first(sol1.u) isa Vector
116+
@test length(sol1.u) == 11
117+
@test length(sol1.t) == 11
118+
119+
sol2 = sol(0.1)
120+
@test sol2 isa Vector
121+
@test length(sol2) == length(unknowns(sys))
122+
@test first(sol2) isa Real
123+
124+
sol3 = sol(0.0:1.0:10.0, idxs = [lorenz1.x, lorenz2.x])
125+
126+
sol7 = sol(0.0:1.0:10.0, idxs = [2, 1])
127+
@test sol7.u isa Vector
128+
@test first(sol7.u) isa Vector
129+
@test length(sol7.u) == 11
130+
@test length(sol7.t) == 11
131+
@test collect(sol7[t]) sol3.t
132+
@test collect(sol7[t, 1:5]) sol3.t[1:5]
133+
134+
sol8 = sol(0.1, idxs = [2, 1])
135+
@test sol8 isa Vector
136+
@test length(sol8) == 2
137+
@test first(sol8) isa Real
138+
139+
sol9 = sol(0.0:1.0:10.0, idxs = 2)
140+
@test sol9.u isa Vector
141+
@test first(sol9.u) isa Real
142+
@test length(sol9.u) == 11
143+
@test length(sol9.t) == 11
144+
@test collect(sol9[t]) sol3.t
145+
@test collect(sol9[t, 1:5]) sol3.t[1:5]
146+
147+
sol10 = sol(0.1, idxs = 2)
148+
@test sol10 isa Real
149+
end
150150

151151
@testset "Plot idxs" begin
152152
@variables x(t) y(t)
@@ -198,7 +198,7 @@ end
198198
(0.0, 1.0); build_initializeprob = false)
199199
dae_sol = solve(prob, DFBDF(); save_idxs = [x])
200200

201-
@brownian a b
201+
@brownians a b
202202
@mtkcompile sys = System([D(x) ~ x + p * y + x * a, D(y) ~ 2p + x^2 + y * b], t)
203203
xidx = variable_index(sys, x)
204204
prob = SDEProblem(sys, [x => 1.0, y => 2.0, p => 2.0], (0.0, 1.0))

test/runtests.jl

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -123,27 +123,25 @@ end
123123
end
124124
end
125125

126-
if !is_APPVEYOR && (GROUP == "Downstream" || GROUP == "SymbolicIndexingInterface")
126+
if !is_APPVEYOR && GROUP == "SymbolicIndexingInterface"
127127
if GROUP != "Downstream"
128128
activate_downstream_env()
129129
end
130-
@time @safetestset "ModelingToolkit Remake" begin
131-
include("downstream/modelingtoolkit_remake.jl")
132-
end
133130
@time @safetestset "Symbol and integer based indexing of interpolated solutions" begin
134131
include("downstream/comprehensive_indexing.jl")
135132
end
136-
if VERSION >= v"1.8"
137-
@time @safetestset "Symbol and integer based indexing of integrators" begin
138-
include("downstream/integrator_indexing.jl")
139-
end
140-
@time @safetestset "Problem Indexing" begin
141-
include("downstream/problem_interface.jl")
142-
end
133+
@time @safetestset "Symbol and integer based indexing of integrators" begin
134+
include("downstream/integrator_indexing.jl")
135+
end
136+
@time @safetestset "Problem Indexing" begin
137+
include("downstream/problem_interface.jl")
143138
end
144139
@time @safetestset "Adjoints" begin
145140
include("downstream/adjoints.jl")
146141
end
142+
@time @safetestset "ModelingToolkit Remake" begin
143+
include("downstream/modelingtoolkit_remake.jl")
144+
end
147145
end
148146

149147
if !is_APPVEYOR && GROUP == "Python"

0 commit comments

Comments
 (0)