Open
Description
So at this stage I am starting to be uncertain exactly what is intended to work and what is not intended to work. At least here is a summary of the tests I have broken, and which works and which do not work. There are definitely some oddities going on here.
# Create model and fetch the conservation parameter (Γ).
t = default_t()
@parameters k1 k2
@species X1(t) X2(t)
rxs = [
Reaction(k1, [X1], [X2]),
Reaction(k2, [X2], [X1])
]
@named rs = ReactionSystem(rxs, t)
osys = convert(ODESystem, complete(rs); remove_conserved = true)
osys = complete(osys)
@unpack Γ = osys
# Creates an `ODEProblem`.
u0 = [X1 => 1.0, X2 => 2.0]
ps = [k1 => 0.1, k2 => 0.2]
oprob = ODEProblem(osys, u0, (0.0, 1.0), ps)
# Check `ODEProblem` content.
oprob[X1] == 1.0
oprob[X2] == 2.0
oprob.ps[k1] == 0.1
oprob.ps[k2] == 0.2
oprob.ps[Γ[1]] == 3.0
# Attempts to update problem by giving new values for `X2` (broken)
@test_broken oprob[X2] = 20.0
@test_broken oprob_new = remake(oprob; u0 = [X1 => 10.0, X2 => 20.0])
# Updates problem using `remake` and check that the new values are correct.
oprob_new = remake(oprob; u0 = [X1 => 10.0])
@test oprob_new[X1] == 10.0
@test_broken oprob_new[X2] == 2.0 # Currently -7.
@test_broken oprob_new.ps[Γ[1]] == 12.0 # Currently 3.0.
integrator = init(oprob_new, Tsit5())
@test integrator[X1] == 10.0
@test_broken integrator[X2] == 2.0 # Currently -7.
@test_broken integrator.ps[Γ[1]] == 12.0 # Currently 3.0
# Updates problem using normal indexing (uncertain exactly what intended behaviour here should be).
oprob[X1] = 10.0
@test oprob[X1] == 10.0
@test_broken oprob[X2] == 2.0 # Currently -7.
@test_broken oprob.ps[Γ[1]] == 12.0 # Currently 3.0.
integrator = init(oprob, Tsit5())
@test integrator[X1] == 10.0
@test_broken integrator[X2] == 2.0 # Currently -7.
@test_broken integrator.ps[Γ[1]] == 12.0 # Currently 3.0.
I also have some general MTK tests, where remake
actually works now (except that I thought that it wasn't meant to any longer).
# Checks that initial conditions/paraemters dpending on other initial conditions/parameters
# as defaults are updated correctly.
# Checks using normal indexing and `remake`.
# Checs effect on updated problem and integrators initiatedfrom it.
# An issue discussing what should, and should not, work is here: https://github.com/SciML/ModelingToolkit.jl/issues/2733
let
# Creates the `ReactionSystem` (with defaults and an observable).
@parameters k1
@species X1(t)
@parameters k2 = X1
@species X2(t) = k1
@variables O(t)
rxs = [
Reaction(k1, [X1], [X2]),
Reaction(k2, [X2], [X1])
]
observed = [O ~ X1 + X2 + k1 + k2]
@named rs = ReactionSystem(rxs, t; observed)
rs = complete(rs)
# Creates the various problem types.
u0 = [X1 => 1]
ps = [k1 => 10]
oprob = ODEProblem(rs, u0, (0.0, 1.0), ps)
sprob = SDEProblem(rs, u0, (0.0, 1.0), ps)
dprob = DiscreteProblem(rs, u0, (0.0, 1.0), ps)
jprob = JumpProblem(rs, dprob, Direct())
nprob = NonlinearProblem(rs, u0, ps)
@test_broken false # ssprob = SteadyStateProblem(rs, u0, ps) # Cannot generate integrators from `SteadyStateProblem`s (https://github.com/SciML/SteadyStateDiffEq.jl/issues/79).
probs = [oprob, sprob, jprob, nprob, ssprob]
solvers = [Tsit5(), ImplicitEM(), SSAStepper(), NewtonRaphson(), DynamicSS(Tsit5())]
# Checks that values depending on defaults are updated correctly. Checks values both in original
# problem and in the initialised integrator. Only uses single symbolic when indexing (other
# alternatives should have been checked elsewhere).
for (prob, solver) in zip(deepcopy(probs), solvers)
# Checks when updating using `remake` indexing. I *think* this *should* update values (in the
# updated problem) that depend on default (the integrator should have the correct values).
prob_new = remake(prob; u0 = [X1 => 2], p = [k1 => 20])
@test prob_new[X1] == 2
@test prob_new[X2] == 20
@test prob_new.ps[k1] == 20
@test prob_new.ps[k2] == 2
@test prob_new[O] == 44
integrator = init(prob_new, solver)
@test integrator[X1] == 2
@test integrator[X2] == 20
@test integrator.ps[k1] == 20
@test integrator.ps[k2] == 2
@test integrator[O] == 44
# Checks when updating using normal indexing. I *think* this *should not* update values (in
# the updated problem) that depend on default (the integrator should have the correct values).
prob[X1] = 3
prob.ps[k1] = 30
@test prob[X1] == 3
@test prob[X2] == 10
@test prob.ps[k1] == 30
@test prob.ps[k2] == 1
@test prob[O] == 44
integrator = init(prob, solver)
@test integrator[X1] == 3
@test_broken integrator[X2] == 30
@test integrator.ps[k1] == 30
@test_broken integrator.ps[k2] == 3
@test_broken integrator[O] == 66
end
end