@@ -188,25 +188,34 @@ function oderatelaw(rx; combinatoric_ratelaw=true)
188188 rl
189189end
190190
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 )
194192 species_to_idx = Dict ((x => i for (i,x) in enumerate (rs. states)))
195-
193+ rhsvec = [ Num ( 0 ) for i in eachindex (rs . states)]
196194 for rx in rs. eqs
197195 rl = oderatelaw (rx; combinatoric_ratelaw= combinatoric_ratelaws)
198196 for (spec,stoich) in rx. netstoich
199197 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
203201 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)
206204 end
207- eqs[i] = Equation (eqs[i]. lhs, rhs)
208205 end
209206 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
210219 eqs
211220end
212221
@@ -383,6 +392,24 @@ function Base.convert(::Type{<:ODESystem}, rs::ReactionSystem; combinatoric_rate
383392 systems= convert .(ODESystem,rs. systems))
384393end
385394
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+
386413"""
387414```julia
388415Base.convert(::Type{<:SDESystem},rs::ReactionSystem)
@@ -450,55 +477,29 @@ function Base.convert(::Type{<:JumpSystem},rs::ReactionSystem; combinatoric_rate
450477end
451478
452479
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-
485480# ## Converts a reaction system to ODE or SDE problems ###
486481
487482
488483# 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... )
490485 return ODEProblem (convert (ODESystem,rs),u0,tspan,p, args... ; kwargs... )
491486end
492487
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+
493494# 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... )
495496 sde_sys = convert (SDESystem,rs,noise_scaling= noise_scaling)
496497 p_matrix = zeros (length (rs. states), length (rs. eqs))
497498 return SDEProblem (sde_sys,u0,tspan,p,args... ; noise_rate_prototype= p_matrix,kwargs... )
498499end
499500
500501# 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... )
502503 return DiscreteProblem (convert (JumpSystem,rs), u0,tspan,p, args... ; kwargs... )
503504end
504505
@@ -508,7 +509,7 @@ function DiffEqJump.JumpProblem(rs::ReactionSystem, prob, aggregator, args...; k
508509end
509510
510511# 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... )
512513 return SteadyStateProblem (ODEFunction (convert (ODESystem,rs)),u0,p, args... ; kwargs... )
513514end
514515
0 commit comments