Catalyst.jl
Catalyst.jl copied to clipboard
Equations and events reupload
I have tried to rebase https://github.com/SciML/Catalyst.jl/pull/736 on master. Unfortunately, there have been too many changes, and it is not feasible anymore. This PR builds that one.
Creating events in the DSL
MTK does not currently have a wrapper around the @continuous_events
or @discrete_events
options. However, we here use the same syntax as for programmatic description, but in a begin ... end
block, with one event on each line. If there is only a single event, it can just be given after @X_events
.
# When t == 2.5, increase p by 0.2.
rs = @reaction_network begin
@continuous_events begin
[t ~ 2.5] => [p ~ p + 0.2]
end
(p,d), 0 <--> X
end
# Every 2.0 time unit, increase d by 0.2.
rs = @reaction_network begin
@discrete_events begin
2.0 => [d ~ d + 0.2]
end
(p,d), 0 <--> X
end
# At time unit 2.0, increase d by 0.2.
rs = @reaction_network begin
@discrete_events begin
[2.0] => [d ~ d + 0.2]
end
(p,d), 0 <--> X
end
# After every timestep, if X > 0.2, increase d by 0.2.
rs = @reaction_network begin
@discrete_events begin
(X > 0.1) => [d ~ d + 0.2]
end
(p,d), 0 <--> X
end
Creating equations in the DSL
Equations use the @equations
option. This utilises some MTK stuff, but the notation is similar as when creating stuff programmatically. Both differential and algebraic equations are supported.
rs_dsl = @reaction_network hybrid_rs begin
@variables X2
@parameters v
@equations begin
D(V) ~ X - v*V
X2 ~ 2*X
end
(p,d), 0 <--> X
end
Parameters and variables used within equations must be declared as such The exception is if we have a differential equation on the form
D(sym) ~ ...
where sym
is a single symbol. Here, sym
is inferred to be a variable (it can still be declared in @variables
, if you e.g. want to attach metadata). In these cases, D
is inferred to be a differential with respect to the independent variable.
It is also possible to create new differentials using the @differentials
option:
rs_dsl = @reaction_network hybrid_rs begin
@differentials begin
DD = Differential(t)
end
@variables V(t)
@equations begin
DD(V) ~ -V
end
(p,d), 0 <--> X
end
these can then be used in equations. Note that if a non-default differential is used, the V
variable have to be decalred.
Working with hybrid equations
These work like before, however, with the following additions:
- Algebraic equations can now be used. These require using
structural_simplify
on the finalXSystem
. All relevant problem calls now have astructural_simpligy = false
kwarg. Setting this totrue
ensures thatstructural_simplify
(notcompelte
) is called on the internally createdODESystem
. - Hybrid systems can now be used to create Nonlinear Systems. When this happens, andy term
D(...)
(whereD
is some differential) are automatically set to0
). - Hybrid systems can be converted into SDEs. Currently, we do not support adding noise equations to variables (which would have to be done at a later point).
There are a couple of things which are broken, awaiting fixes in MTK, but these are rather tangential, and the main functionality works well.
Please keep this PR, which is getting humongous, focused on the changes needed for the DSL functionality. Style changes because you find something personally confusing, which others find standard and easy to read, should not be made as part of this PR.
Such changes can be discussed in an issue, and if we want to make changes, a re-styling PR can be made.
Needs a new MTK release to pass tests, I will finish writing the description of how the equations work after lunch.
Figured I should have another go through and see if I missed anything, and was immediately punished. On the plus side I discovered another MTK bug: https://github.com/SciML/SciMLBase.jl/issues...
Ok, I've updated to the new MTK version where this was fixed, all good now.