Skip to content

Commit 2b87e41

Browse files
committed
add correctness test
1 parent 800e2e8 commit 2b87e41

File tree

3 files changed

+188
-146
lines changed

3 files changed

+188
-146
lines changed

src/reaction.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,9 @@ Notes: The following values are possible:
701701
VariableRateJump # forces a VariableRateJump
702702
end
703703

704+
const JUMP_SCALES = (PhysicalScale.Jump, PhysicalScale.VariableRateJump)
705+
const NON_CONSTANT_JUMP_SCALES = (PhysicalScale.ODE, PhysicalScale.SDE, PhysicalScale.VariableRateJump)
706+
704707
"""
705708
has_physical_scale(rx::Reaction)
706709

src/reactionsystem_conversions.jl

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -328,14 +328,15 @@ function get_depgraph(rs)
328328
eqeq_dependencies(jdeps, vdeps).fadjlist
329329
end
330330

331+
# note that reactions that are not constant rate are treated as vrjs here
331332
function classify_vrjs(rs, physcales)
332333
# first we determine vrjs with an explicit time-dependent rate
333334
rxs = get_rxs(rs)
334335
isvrjvec = falses(length(rxs))
335336
havevrjs = false
336337
rxvars = Set()
337338
for (i, rx) in enumerate(rxs)
338-
if physcales[i] == PhysicalScale.VariableRateJump
339+
if physcales[i] in NON_CONSTANT_JUMP_SCALES
339340
isvrjvec[i] = true
340341
havevrjs = true
341342
continue
@@ -368,7 +369,7 @@ function classify_vrjs(rs, physcales)
368369
end
369370

370371
function assemble_jumps(rs; combinatoric_ratelaws = true, physical_scales = nothing,
371-
expand_catalyst_funs = true)
372+
expand_catalyst_funs = true, save_positions = (true, true))
372373
meqs = MassActionJump[]
373374
ceqs = ConstantRateJump[]
374375
veqs = VariableRateJump[]
@@ -380,15 +381,18 @@ function assemble_jumps(rs; combinatoric_ratelaws = true, physical_scales = noth
380381
else
381382
physcales = physical_scales
382383
end
383-
jump_scales = (PhysicalScale.Jump, PhysicalScale.VariableRateJump)
384-
(isempty(get_rxs(rs)) || !any(in(jump_scales), physcales)) &&
384+
385+
(isempty(get_rxs(rs)) || !any(in(JUMP_SCALES), physcales)) &&
385386
error("Must have at least one reaction that will be represented as a jump when constructing a JumpSystem.")
387+
388+
# note isvrjvec indicates which reactions are not constant rate jumps
389+
# it may be that a given jump has isvrjvec[i] = true but has a physical
386390
isvrjvec = classify_vrjs(rs, physcales)
387391

388392
rxvars = []
389393
for (i, rx) in enumerate(rxs)
390394
# only process reactions that should give jumps
391-
(physcales[i] in jump_scales) || continue
395+
(physcales[i] in JUMP_SCALES) || continue
392396

393397
empty!(rxvars)
394398
(rx.rate isa Symbolic) && get_variables!(rxvars, rx.rate)
@@ -405,7 +409,7 @@ function assemble_jumps(rs; combinatoric_ratelaws = true, physical_scales = noth
405409
(!drop_dynamics(spec)) && push!(affect, spec ~ spec + stoich)
406410
end
407411
if isvrj
408-
push!(veqs, VariableRateJump(rl, affect))
412+
push!(veqs, VariableRateJump(rl, affect; save_positions))
409413
else
410414
push!(ceqs, ConstantRateJump(rl, affect))
411415
end
@@ -760,12 +764,15 @@ Notes:
760764
- `expand_catalyst_funs = true`, replaces Catalyst defined functions like `hill(A,B,C,D)`
761765
with their rational function representation when converting to another system type. Set to
762766
`false`` to disable.
767+
- `save_positions = (true, true)`, indicates whether for any reaction classified as a
768+
`VariableRateJump` to save the solution before and/or after the jump occurs. Defaults to
769+
true for both.
763770
"""
764771
function Base.convert(::Type{<:JumpSystem}, rs::ReactionSystem; name = nameof(rs),
765772
combinatoric_ratelaws = get_combinatoric_ratelaws(rs),
766773
remove_conserved = nothing, checks = false, default_u0 = Dict(), default_p = Dict(),
767774
defaults = _merge(Dict(default_u0), Dict(default_p)), expand_catalyst_funs = true,
768-
physical_scales = nothing, kwargs...)
775+
save_positions = (true, true), physical_scales = nothing, kwargs...)
769776
iscomplete(rs) || error(COMPLETENESS_ERROR)
770777
spatial_convert_err(rs::ReactionSystem, JumpSystem)
771778
(remove_conserved !== nothing) &&
@@ -782,7 +789,8 @@ function Base.convert(::Type{<:JumpSystem}, rs::ReactionSystem; name = nameof(rs
782789
error("Physical scales must currently be one of $admissible_scales for hybrid systems.")
783790

784791
# basic jump states and equations
785-
eqs = assemble_jumps(flatrs; combinatoric_ratelaws, expand_catalyst_funs, physical_scales)
792+
eqs = assemble_jumps(flatrs; combinatoric_ratelaws, expand_catalyst_funs,
793+
physical_scales, save_positions)
786794
ists, ispcs = get_indep_sts(flatrs)
787795

788796
# handle coupled ODEs and BC species
@@ -921,13 +929,36 @@ struct JumpInputs{S <: MT.JumpSystem, T <: SciMLBase.AbstractODEProblem}
921929
end
922930

923931
"""
924-
jumpinput = JumpInputs(rs::ReactionSystem, u0, tspan,
925-
p = DiffEqBase.NullParameters;
926-
name = nameof(rs),
927-
combinatoric_ratelaws = get_combinatoric_ratelaws(rs),
928-
checks = false, kwargs...)
932+
```julia
933+
JumpInputs(rs::ReactionSystem, u0, tspan,
934+
p = DiffEqBase.NullParameters;
935+
name = nameof(rs),
936+
combinatoric_ratelaws = get_combinatoric_ratelaws(rs),
937+
checks = false, physical_scales = nothing,
938+
expand_catalyst_funs = true,
939+
save_positions = (true, true),
940+
remake_warn = true, kwargs...)
941+
```
942+
943+
Constructs the input to build a JumpProblem for the given reaction system.
929944
930-
Constructs the input to build a JumpProblem for the given reaction system.
945+
Keyword args and default values:
946+
- `combinatoric_ratelaws=true` uses factorial scaling factors in calculating the rate law,
947+
i.e. for `2S -> 0` at rate `k` the ratelaw would be `k*S*(S-1)/2!`. Set
948+
`combinatoric_ratelaws=false` for a ratelaw of `k*S*(S-1)`, i.e. the scaling factor is
949+
ignored. Defaults to the value given when the `ReactionSystem` was constructed (which
950+
itself defaults to true).
951+
- `expand_catalyst_funs = true`, replaces Catalyst defined functions like `hill(A,B,C,D)`
952+
with their rational function representation when converting to another system type. Set to
953+
`false`` to disable.
954+
- `remake_warn = true`, if `true`, a warning is thrown if the system includes ODEs, variable
955+
rate jumps, or continuous events. This is because `remake` does not work for such
956+
problems, and instead both `JumpInputs` and then `JumpProblem` must be called again if one
957+
wishs to change any parameter or initial condition values. This warning can be disabled by
958+
passing `remake_warn = false`.
959+
- `save_positions = (true, true)`, indicates whether for any reaction classified as a
960+
`VariableRateJump` whether to save the solution before and/or after the jump occurs.
961+
Defaults to true for both.
931962
932963
Example:
933964
```julia
@@ -953,13 +984,17 @@ plot(sol, idxs = :A)
953984
"""
954985
function JumpInputs(rs::ReactionSystem, u0, tspan, p = DiffEqBase.NullParameters();
955986
name = nameof(rs), combinatoric_ratelaws = get_combinatoric_ratelaws(rs),
956-
checks = false, physical_scales = nothing, expand_catalyst_funs = true, kwargs...)
987+
checks = false, physical_scales = nothing, expand_catalyst_funs = true,
988+
save_positions = (true, true), remake_warn = true, kwargs...)
957989
jsys = complete(convert(JumpSystem, rs; name, combinatoric_ratelaws, checks,
958-
physical_scales, expand_catalyst_funs))
990+
physical_scales, expand_catalyst_funs, save_positions))
959991

960992
if MT.has_variableratejumps(jsys) || MT.has_equations(jsys) ||
961993
!isempty(MT.continuous_events(jsys))
962994
prob = ODEProblem(jsys, u0, tspan, p; kwargs...)
995+
if remake_warn
996+
@warn "JumpInputs has detected the system includes ODEs, variable rate jumps, or continuous events. Please note that currently remake does not work for such problems, and both JumpInputs and then JumpProblem must be called again if you wish to change any parameter or initial condition values. This warning can be disabled by passing JumpInputs the keyword argument `remake_warn = false`."
997+
end
963998
else
964999
prob = DiscreteProblem(jsys, u0, tspan, p; kwargs...)
9651000
end

0 commit comments

Comments
 (0)