@@ -188,25 +188,34 @@ function oderatelaw(rx; combinatoric_ratelaw=true)
188
188
rl
189
189
end
190
190
191
- function assemble_drift (rs; combinatoric_ratelaws= true )
192
- D = Differential (rs. iv)
193
- eqs = [D (x) ~ 0 for x in rs. states]
191
+ function assemble_oderhs (rs; combinatoric_ratelaws= true )
194
192
species_to_idx = Dict ((x => i for (i,x) in enumerate (rs. states)))
195
-
193
+ rhsvec = [ Num ( 0 ) for i in eachindex (rs . states)]
196
194
for rx in rs. eqs
197
195
rl = oderatelaw (rx; combinatoric_ratelaw= combinatoric_ratelaws)
198
196
for (spec,stoich) in rx. netstoich
199
197
i = species_to_idx[spec]
200
- if _iszero (eqs [i]. rhs )
201
- signedrl = (stoich > zero (stoich)) ? rl : - rl
202
- rhs = isone (abs (stoich)) ? signedrl : stoich * rl
198
+ if _iszero (rhsvec [i])
199
+ signedrl = (stoich > zero (stoich)) ? rl : - rl
200
+ rhsvec[i] = isone (abs (stoich)) ? signedrl : stoich * rl
203
201
else
204
- Δspec = isone (abs (stoich)) ? rl : abs (stoich) * rl
205
- rhs = (stoich > zero (stoich)) ? (eqs [i]. rhs + Δspec) : (eqs [i]. rhs - Δspec)
202
+ Δspec = isone (abs (stoich)) ? rl : abs (stoich) * rl
203
+ rhsvec[i] = (stoich > zero (stoich)) ? (rhsvec [i] + Δspec) : (rhsvec [i] - Δspec)
206
204
end
207
- eqs[i] = Equation (eqs[i]. lhs, rhs)
208
205
end
209
206
end
207
+
208
+ rhsvec
209
+ end
210
+
211
+ function assemble_drift (rs; combinatoric_ratelaws= true , as_odes= true )
212
+ rhsvec = assemble_oderhs (rs; combinatoric_ratelaws= combinatoric_ratelaws)
213
+ if as_odes
214
+ D = Differential (rs. iv)
215
+ eqs = [Equation (D (x),rhs) for (x,rhs) in zip (rs. states,rhsvec)]
216
+ else
217
+ eqs = [Equation (Num (0 ),rhs) for rhs in rhsvec]
218
+ end
210
219
eqs
211
220
end
212
221
@@ -383,6 +392,24 @@ function Base.convert(::Type{<:ODESystem}, rs::ReactionSystem; combinatoric_rate
383
392
systems= convert .(ODESystem,rs. systems))
384
393
end
385
394
395
+ """
396
+ ```julia
397
+ Base.convert(::Type{<:NonlinearSystem},rs::ReactionSystem)
398
+ ```
399
+
400
+ Convert a [`ReactionSystem`](@ref) to an [`NonlinearSystem`](@ref).
401
+
402
+ Notes:
403
+ - `combinatoric_ratelaws=true` uses factorial scaling factors in calculating the rate
404
+ law, i.e. for `2S -> 0` at rate `k` the ratelaw would be `k*S^2/2!`. If
405
+ `combinatoric_ratelaws=false` then the ratelaw is `k*S^2`, i.e. the scaling factor is
406
+ ignored.
407
+ """
408
+ function Base. convert (:: Type{<:NonlinearSystem} ,rs:: ReactionSystem ; combinatoric_ratelaws= true )
409
+ eqs = assemble_drift (rs; combinatoric_ratelaws= combinatoric_ratelaws, as_odes= false )
410
+ NonlinearSystem (eqs,rs. states,rs. ps,name= rs. name,systems= convert .(NonlinearSystem,rs. systems))
411
+ end
412
+
386
413
"""
387
414
```julia
388
415
Base.convert(::Type{<:SDESystem},rs::ReactionSystem)
@@ -450,55 +477,29 @@ function Base.convert(::Type{<:JumpSystem},rs::ReactionSystem; combinatoric_rate
450
477
end
451
478
452
479
453
- """
454
- ```julia
455
- Base.convert(::Type{<:NonlinearSystem},rs::ReactionSystem)
456
- ```
457
-
458
- Convert a [`ReactionSystem`](@ref) to an [`NonlinearSystem`](@ref).
459
-
460
- Notes:
461
- - `combinatoric_ratelaws=true` uses factorial scaling factors in calculating the rate
462
- law, i.e. for `2S -> 0` at rate `k` the ratelaw would be `k*S^2/2!`. If
463
- `combinatoric_ratelaws=false` then the ratelaw is `k*S^2`, i.e. the scaling factor is
464
- ignored.
465
- """
466
- function Base. convert (:: Type{<:NonlinearSystem} ,rs:: ReactionSystem ; combinatoric_ratelaws= true )
467
- states_swaps = value .(rs. states)
468
- eqs = map (eq -> 0 ~ make_sub! (eq,states_swaps),getproperty .(assemble_drift (rs; combinatoric_ratelaws= combinatoric_ratelaws),:rhs ))
469
- NonlinearSystem (eqs,rs. states,rs. ps,name= rs. name,
470
- systems= convert .(NonlinearSystem,rs. systems))
471
- end
472
-
473
- # Used for Base.convert(::Type{<:NonlinearSystem},rs::ReactionSystem) only, should likely be removed.
474
- function make_sub! (eq,states_swaps)
475
- for (i,arg) in enumerate (eq. args)
476
- if any (isequal .(states_swaps,arg))
477
- eq. args[i] = var2op (arg. op)
478
- else
479
- make_sub! (arg,states_swaps)
480
- end
481
- end
482
- return eq
483
- end
484
-
485
480
# ## Converts a reaction system to ODE or SDE problems ###
486
481
487
482
488
483
# ODEProblem from AbstractReactionNetwork
489
- function DiffEqBase. ODEProblem (rs:: ReactionSystem , u0:: Union{AbstractArray, Number} , tspan, p= DiffEqBase. NullParameters (), args... ; kwargs... )
484
+ function DiffEqBase. ODEProblem (rs:: ReactionSystem , u0, tspan, p= DiffEqBase. NullParameters (), args... ; kwargs... )
490
485
return ODEProblem (convert (ODESystem,rs),u0,tspan,p, args... ; kwargs... )
491
486
end
492
487
488
+ # NonlinearProblem from AbstractReactionNetwork
489
+ function DiffEqBase. NonlinearProblem (rs:: ReactionSystem , u0, p= DiffEqBase. NullParameters (), args... ; kwargs... )
490
+ return NonlinearProblem (convert (NonlinearSystem,rs), u0, p, args... ; kwargs... )
491
+ end
492
+
493
+
493
494
# SDEProblem from AbstractReactionNetwork
494
- function DiffEqBase. SDEProblem (rs:: ReactionSystem , u0:: Union{AbstractArray, Number} , tspan, p= DiffEqBase. NullParameters (), args... ; noise_scaling= nothing , kwargs... )
495
+ function DiffEqBase. SDEProblem (rs:: ReactionSystem , u0, tspan, p= DiffEqBase. NullParameters (), args... ; noise_scaling= nothing , kwargs... )
495
496
sde_sys = convert (SDESystem,rs,noise_scaling= noise_scaling)
496
497
p_matrix = zeros (length (rs. states), length (rs. eqs))
497
498
return SDEProblem (sde_sys,u0,tspan,p,args... ; noise_rate_prototype= p_matrix,kwargs... )
498
499
end
499
500
500
501
# DiscreteProblem from AbstractReactionNetwork
501
- function DiffEqBase. DiscreteProblem (rs:: ReactionSystem , u0:: Union{AbstractArray, Number} , tspan:: Tuple , p= DiffEqBase. NullParameters (), args... ; kwargs... )
502
+ function DiffEqBase. DiscreteProblem (rs:: ReactionSystem , u0, tspan:: Tuple , p= DiffEqBase. NullParameters (), args... ; kwargs... )
502
503
return DiscreteProblem (convert (JumpSystem,rs), u0,tspan,p, args... ; kwargs... )
503
504
end
504
505
@@ -508,7 +509,7 @@ function DiffEqJump.JumpProblem(rs::ReactionSystem, prob, aggregator, args...; k
508
509
end
509
510
510
511
# SteadyStateProblem from AbstractReactionNetwork
511
- function DiffEqBase. SteadyStateProblem (rs:: ReactionSystem , u0:: Union{AbstractArray, Number} , p= DiffEqBase. NullParameters (), args... ; kwargs... )
512
+ function DiffEqBase. SteadyStateProblem (rs:: ReactionSystem , u0, p= DiffEqBase. NullParameters (), args... ; kwargs... )
512
513
return SteadyStateProblem (ODEFunction (convert (ODESystem,rs)),u0,p, args... ; kwargs... )
513
514
end
514
515
0 commit comments