@@ -121,6 +121,49 @@ function assemble_diffusion(rs)
121
121
eqs
122
122
end
123
123
124
+ function assemble_jumps (rs)
125
+ eqs = Vector {Union{ConstantRateJump, MassActionJump, VariableRateJump}} ()
126
+
127
+ for rx in rs. eqs
128
+ rl = jumpratelaw (rx)
129
+ affect = Vector {Equation} ()
130
+ for (spec,stoich) in rx. netstoich
131
+ push! (affect,var2op (spec) ~ var2op (spec) + stoich)
132
+ end
133
+ if any (isequal .(var2op (rs. iv),get_variables (rx. rate)))
134
+ push! (eqs,VariableRateJump (rl,affect))
135
+ elseif rx. only_use_rate || any ([isequal (state,r_op) for state in rs. states, r_op in getfield .(get_variables (rx. rate),:op )])
136
+ push! (eqs,ConstantRateJump (rl,affect))
137
+ else
138
+ reactant_stoch = isempty (rx. substoich) ? [0 => 1 ] : Pair .(var2op .(getfield .(rx. substrates,:op )),rx. substoich)
139
+ net_stoch = map (p -> Pair (var2op (p[1 ]),p[2 ]),rx. netstoich)
140
+ push! (eqs,MassActionJump (rx. rate, reactant_stoch, net_stoch))
141
+ end
142
+ end
143
+ eqs
144
+ end
145
+
146
+ # Calculate the Jump rate law (like ODE, but uses X instead of X(t).
147
+ # The former generates a "MethodError: objects of type Int64 are not callable" when trying to solve the problem.
148
+ function jumpratelaw (rx)
149
+ @unpack rate, substrates, substoich, only_use_rate = rx
150
+ rl = deepcopy (rate)
151
+ foreach (op -> substitute_expr! (rl,op=> var2op (op. op)), get_variables (rx. rate))
152
+ if ! only_use_rate
153
+ coef = one (eltype (substoich))
154
+ for (i,stoich) in enumerate (substoich)
155
+ coef *= factorial (stoich)
156
+ rl *= isone (stoich) ? var2op (substrates[i]. op) : var2op (substrates[i]. op)^ stoich
157
+ end
158
+ (! isone (coef)) && (rl /= coef)
159
+ end
160
+ rl
161
+ end
162
+
163
+ function var2op (var)
164
+ Operation (var,Vector {Expression} ())
165
+ end
166
+
124
167
function Base. convert (:: Type{<:ODESystem} ,rs:: ReactionSystem )
125
168
eqs = assemble_drift (rs)
126
169
ODESystem (eqs,rs. iv,rs. states,rs. ps,name= rs. name,
@@ -133,3 +176,9 @@ function Base.convert(::Type{<:SDESystem},rs::ReactionSystem)
133
176
SDESystem (eqs,noiseeqs,rs. iv,rs. states,rs. ps,
134
177
name= rs. name,systems= convert .(SDESystem,rs. systems))
135
178
end
179
+
180
+ function Base. convert (:: Type{<:JumpSystem} ,rs:: ReactionSystem )
181
+ eqs = assemble_jumps (rs)
182
+ JumpSystem (eqs,rs. iv,rs. states,rs. ps,name= rs. name,
183
+ systems= convert .(JumpSystem,rs. systems))
184
+ end
0 commit comments