1
1
# ## Prepares Tests ###
2
2
3
3
# Fetch packages.
4
- using Catalyst, DiffEqBase, Test
4
+ using Catalyst, DiffEqBase, OrdinaryDiffEqRosenbrock, Test
5
5
6
6
# Sets stable rng number.
7
7
using StableRNGs
19
19
(3.0 , 1.0 ), ∅ ↔ Y
20
20
(5.0 , 2.0 ), X + Y ↔ XY
21
21
end
22
-
22
+
23
23
test_jac = jac_eval (jacobian_network_1, [:X => 1.0 , :Y => 1.0 , :XY => 1.0 ], [], 0.0 )
24
24
real_jac = [- 6.0 - 5.0 2.0 ; - 5.0 - 6.0 2.0 ; 5.0 5.0 - 2.0 ]
25
25
@test test_jac == real_jac
33
33
(p3 * X, 1.0 ), X + Y ↔ XY
34
34
end
35
35
@unpack X, Y, XY, p1, p2, p3 = jacobian_network_2
36
-
36
+
37
37
for factor in [1e-2 , 1e-1 , 1e0 , 1e1 , 1e2 ], repeat in 1 : 10
38
38
u = Dict (rnd_u0 (jacobian_network_2, rng; factor))
39
39
p = Dict (rnd_ps (jacobian_network_2, rng; factor))
67
67
p[k3]* u[B] p[k3]* u[A] - p[k4]- 3 * p[k5] * u[C]^ 2 / 2 ]
68
68
@test test_jac ≈ real_jac
69
69
end
70
- end
70
+ end
71
+
72
+ # Checks that the Jacobians (dense and sparse) are identical for different system types.
73
+ let
74
+ # Creates model (vaguely messy model without conserved quantities).
75
+ rn = @reaction_network begin
76
+ (p,d), 0 <--> (X,Y)
77
+ (k1,k2), X + Y <--> XY
78
+ (k1,k2), X + 2 Y <--> XY2
79
+ (k1,k2), XY + XY2 <--> X2Y3
80
+ d, (XY2,X2Y3) --> 0
81
+ mm (X2Y3,v,K), 0 --> Z
82
+ (k3,k4), 3 Z <--> Z3
83
+ 1.0 , X3 --> 0
84
+ end
85
+
86
+ # Performs tests for different randomised values (to be thoroughly sure).
87
+ for factor in [0.1 , 1.0 , 10.0 ]
88
+ # Creates randomised species and parameter values. Generates jacobians (dense/sparse).
89
+ u0 = rnd_u0 (rn, rng; factor)
90
+ ps = rnd_ps (rn, rng; factor)
91
+ oprob_jac = ODEProblem (rn, u0, 1.0 , ps; jac = true , sparse = false )
92
+ oprob_sjac = ODEProblem (rn, u0, 1.0 , ps; jac = true , sparse = true )
93
+ sprob_jac = SDEProblem (rn, u0, 1.0 , ps; jac = true , sparse = false )
94
+ sprob_sjac = SDEProblem (rn, u0, 1.0 , ps; jac = true , sparse = true )
95
+ nlprob_jac = NonlinearProblem (rn, u0, ps; jac = true , sparse = false )
96
+ nlprob_sjac = NonlinearProblem (rn, u0, ps; jac = true , sparse = true )
97
+
98
+ # Checks that Jacobians ar identical.
99
+ function eval_jac (prob, sparse)
100
+ J = sparse ? deepcopy (prob. f. jac_prototype) : zeros (length (prob. u0), length (prob. u0))
101
+ ModelingToolkit. is_time_dependent (prob) ? prob. f. jac (J, prob. u0, prob. p, 0.0 ) : prob. f. jac (J, prob. u0, prob. p)
102
+ return J
103
+ end
104
+ @test eval_jac (oprob_jac, false ) == eval_jac (sprob_jac, false ) == eval_jac (nlprob_jac, false )
105
+ @test_broken eval_jac (oprob_sjac, true ) == eval_jac (sprob_sjac, true ) == eval_jac (nlprob_sjac, true ) # https://github.com/SciML/ModelingToolkit.jl/issues/3527
106
+ end
107
+ end
108
+
109
+ # ## Sparse Jacobian Tests ###
110
+
111
+ # Checks that generated dense/sparse Jacobians are identical.
112
+ let
113
+ # Creates model (vaguely messy model without conserved quantities).
114
+ # Model includes a time-dependent reaction.
115
+ rn = @reaction_network begin
116
+ (p,d), 0 <--> (X,Y,Z)
117
+ k1, X + Y --> XY
118
+ k2, X + 2 Z --> XZ2
119
+ k3, Y3 + X2 --> Y3Z2
120
+ k4, X + Y + Z --> XYZ
121
+ k5, XZ2 + Y3Z2 --> XY3Z4
122
+ k6, XYZ + XYZ --> X2Y2Z2
123
+ d, (XY3Z4, X2Y2Z2) --> 0
124
+ X + Y, V --> 0
125
+ k7/ (1 + t), 2 V --> V2
126
+ Z, V2 --> 0
127
+ end
128
+
129
+ # Performs tests for different randomised values (to be thoroughly sure).
130
+ for factor in [0.1 , 1.0 , 10.0 ]
131
+ # Creates randomised species and parameter values. Generates jacobians (dense/sparse).
132
+ u0 = rnd_u0 (rn, rng; factor)
133
+ t_val = factor* rand ()
134
+ ps = rnd_ps (rn, rng; factor)
135
+ jac = jac_eval (rn, u0, ps, t_val; sparse = false )
136
+ jac_sparse = jac_eval (rn, u0, ps, t_val; sparse = true )
137
+
138
+ # Check correctness (both by converting to sparse jac to dense, and through multiplication with other matrix).
139
+ @test Matrix (jac_sparse) == jac
140
+ mat = factor* rand (rng, length (u0), length (u0))
141
+ @test jac_sparse * mat ≈ jac * mat
142
+ end
143
+ end
144
+
145
+ # Tests that simulations with different Jacobian and sparsity options are identical.
146
+ let
147
+ # Creates model (vaguely messy model without conserved quantities).
148
+ rn = @reaction_network begin
149
+ (v0 + mm (X,v,K),d), 0 <--> X + 2 Y
150
+ (k1,k2), X + Y <--> XY
151
+ (k1,k2), X + Y2 <--> XY2
152
+ (k3,k4), XY + XY2 <--> X2Y3
153
+ 1.0 , (XY,XY2,X2Y3) --> 0
154
+ mm (X2Y3,v,K), 0 --> Z
155
+ (k3* X,k4* Y), 3 Z <--> Z3
156
+ d, Z --> 0
157
+ end
158
+
159
+ # Generates initial conditions and parameter values. Creates problems with/o (sparse/dense) jacobian.
160
+ u0 = rnd_u0 (rn, rng)
161
+ ps = rnd_ps (rn, rng)
162
+ oprob = ODEProblem (rn, u0, 1.0 , ps; jac = false , sparse = false )
163
+ oprob_j = ODEProblem (rn, u0, 1.0 , ps; jac = true , sparse = false )
164
+ oprob_s = ODEProblem (rn, u0, 1.0 , ps; jac = false , sparse = true )
165
+ oprob_js = ODEProblem (rn, u0, 1.0 , ps; jac = true , sparse = true )
166
+
167
+ # Simulates system with implicit solver. Checks that all solutions are identical.
168
+ sol = solve (oprob, Rosenbrock23 (), saveat = 0.1 , abstol = 1e-8 , reltol = 1e-8 )
169
+ sol_j = solve (oprob_j, Rosenbrock23 (), saveat = 0.1 , abstol = 1e-8 , reltol = 1e-8 )
170
+ sol_s = solve (oprob_s, Rosenbrock23 (), saveat = 0.1 , abstol = 1e-8 , reltol = 1e-8 )
171
+ sol_js = solve (oprob_js, Rosenbrock23 (), saveat = 0.1 , abstol = 1e-8 , reltol = 1e-8 )
172
+ @test sol ≈ sol_j ≈ sol_s ≈ sol_js
173
+ end
0 commit comments