Skip to content

Commit dde952c

Browse files
committed
add test of ReactionSystem
1 parent e9ee923 commit dde952c

File tree

2 files changed

+77
-15
lines changed

2 files changed

+77
-15
lines changed

src/systems/reaction/reactionsystem.jl

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,24 @@ end
1111
function Reaction(rate, subs, prods, substoich, prodstoich;
1212
netstoich=nothing, only_use_rate=false, kwargs...)
1313

14-
ns = isnothing(netstoich) ? get_netstoich(subs, prods, substoich, prodstoich) : netstoich
15-
Reaction(rate, subs, prods, substoich, prodstoich, ns, only_use_rate)
14+
subsv = isnothing(subs) ? Vector{Operation}() : subs
15+
prodsv = isnothing(prods) ? Vector{Operation}() : prods
16+
ns = isnothing(netstoich) ? get_netstoich(subsv, prodsv, substoich, prodstoich) : netstoich
17+
Reaction(rate, subsv, prodsv, substoich, prodstoich, ns, only_use_rate)
1618
end
1719

1820
# three argument constructor assumes stoichiometric coefs are one and integers
19-
Reaction(rate, subs, prods; kwargs...) = Reaction(rate, subs, prods,
20-
ones(Int,length(subs)),
21-
ones(Int,length(prods));
22-
kwargs...)
21+
function Reaction(rate, subs, prods; kwargs...)
22+
23+
sstoich = isnothing(subs) ? Int[] : ones(Int,length(subs))
24+
pstoich = isnothing(prods) ? Int[] : ones(Int,length(prods))
25+
Reaction(rate, subs, prods, sstoich, pstoich; kwargs...)
26+
end
2327

2428
# calculates the net stoichiometry of a reaction as a vector of pairs (sub,substoich)
2529
function get_netstoich(subs, prods, sstoich, pstoich)
2630
# stoichiometry as a Dictionary
27-
nsdict = Dict(sub.op => -sstoich[i] for (i,sub) in enumerate(subs))
31+
nsdict = Dict{Variable,eltype(sstoich)}(sub.op => -sstoich[i] for (i,sub) in enumerate(subs))
2832
for (i,p) in enumerate(prods)
2933
coef = pstoich[i]
3034
prod = p.op

test/reactionsystem.jl

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,68 @@
1-
using ModelingToolkit
2-
3-
@parameters t a b c
4-
@variables x(t) y(t) z(t)
5-
rxs = [Reaction(a,[x],[y]),
6-
Reaction(b,[y],[x]),
7-
Reaction(c,[x,y],[x])]
8-
rs = ReactionSystem(rxs,t,[x,y],[a,b])
1+
using ModelingToolkit, LinearAlgebra
2+
3+
@parameters t k[1:13]
4+
@variables A(t) B(t) C(t) D(t)
5+
rxs = [Reaction(k[1], nothing, [A]), # 0 -> A
6+
Reaction(k[2], [B], nothing), # B -> 0
7+
Reaction(k[3],[A],[C]), # A -> C
8+
Reaction(k[4], [C], [A,B]), # C -> A + B
9+
Reaction(k[5], [C], [A], [1], [2]), # C -> A + A
10+
Reaction(k[6], [A,B], [C]), # A + B -> C
11+
Reaction(k[7], [B], [A], [2], [1]), # 2B -> A
12+
Reaction(k[8], [A,B], [A,C]), # A + B -> A + C
13+
Reaction(k[9], [A,B], [C,D]), # A + B -> C + D
14+
Reaction(k[10], [A], [C,D], [2], [1,1]), # 2A -> C + D
15+
Reaction(k[11], [A], [A,B], [2], [1,1]), # 2A -> A + B
16+
Reaction(k[12], [A,B,C], [C,D], [1,3,4], [2, 3]), # A+3B+4C -> 2C + 3D
17+
Reaction(k[13]*A/(2+A), [A], nothing; only_use_rate=true) # A -> 0 with custom rate
18+
]
19+
rs = ReactionSystem(rxs,t,[A,B,C,D],k)
920
odesys = convert(ODESystem,rs)
1021
sdesys = convert(SDESystem,rs)
22+
23+
# hard coded ODE rhs
24+
function oderhs(u,k,t)
25+
A = u[1]; B = u[2]; C = u[3]; D = u[4];
26+
du = zeros(eltype(u),4)
27+
du[1] = k[1] - k[3]*A + k[4]*C + 2*k[5]*C - k[6]*A*B + k[7]*B^2/2 - k[9]*A*B - k[10]*A^2 - k[11]*A^2/2 - k[12]*A*B^3*C^4/144 - k[13]*A/(2+A)
28+
du[2] = -k[2]*B + k[4]*C - k[6]*A*B - k[7]*B^2 - k[8]*A*B - k[9]*A*B + k[11]*A^2/2 - 3*k[12]*A*B^3*C^4/144
29+
du[3] = k[3]*A - k[4]*C - k[5]*C + k[6]*A*B + k[8]*A*B + k[9]*A*B + k[10]*A^2/2 - 2*k[12]*A*B^3*C^4/144
30+
du[4] = k[9]*A*B + k[10]*A^2/2 + 3*k[12]*A*B^3*C^4/144
31+
du
32+
end
33+
34+
# sde noise coefs
35+
function sdenoise(u,k,t)
36+
A = u[1]; B = u[2]; C = u[3]; D = u[4];
37+
G = zeros(eltype(u),length(k),length(u))
38+
z = zero(eltype(u))
39+
40+
G = [sqrt(k[1]) z z z;
41+
z -sqrt(k[2]*B) z z;
42+
-sqrt(k[3]*A) z sqrt(k[3]*A) z;
43+
sqrt(k[4]*C) sqrt(k[4]*C) -sqrt(k[4]*C) z;
44+
2*sqrt(k[5]*C) z -sqrt(k[5]*C) z;
45+
-sqrt(k[6]*A*B) -sqrt(k[6]*A*B) sqrt(k[6]*A*B) z;
46+
sqrt(k[7]*B^2/2) -2*sqrt(k[7]*B^2/2) z z;
47+
z -sqrt(k[8]*A*B) sqrt(k[8]*A*B) z;
48+
-sqrt(k[9]*A*B) -sqrt(k[9]*A*B) sqrt(k[9]*A*B) sqrt(k[9]*A*B);
49+
-2*sqrt(k[10]*A^2/2) z sqrt(k[10]*A^2/2) sqrt(k[10]*A^2/2);
50+
-sqrt(k[11]*A^2/2) sqrt(k[11]*A^2/2) z z;
51+
-sqrt(k[12]*A*B^3*C^4/144) -3*sqrt(k[12]*A*B^3*C^4/144) -2*sqrt(k[12]*A*B^3*C^4/144) 3*sqrt(k[12]*A*B^3*C^4/144);
52+
-sqrt(k[13]*A/(2+A)) z z z]'
53+
54+
return G
55+
end
56+
57+
# test by evaluating drift and diffusion terms
58+
p = rand(length(k))
59+
u = rand(length(k))
60+
t = 0.
61+
du = oderhs(u,p,t)
62+
G = sdenoise(u,p,t)
63+
sdesys = convert(SDESystem,rs)
64+
sf = SDEFunction{false}(sdesys, states(rs), parameters(rs))
65+
du2 = sf.f(u,p,t)
66+
@test norm(du-du2) < 100*eps()
67+
G2 = sf.g(u,p,t)
68+
@test norm(G-G2) < 100*eps()

0 commit comments

Comments
 (0)