Skip to content

Commit 5b3a093

Browse files
authored
Merge pull request #541 from SciML/HCTutorial
Homotopy continuation tutorial
2 parents 33a988d + 47486fb commit 5b3a093

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Catalyst = "479239e8-5488-4da2-87a7-35f2df7eef83"
44
DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa"
55
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
66
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
7+
HomotopyContinuation = "f213a82b-91d6-5c5d-acf7-10f1c761b327"
78
Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
89
ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78"
910
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"

docs/pages.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ pages = Any["Home" => "index.md",
66
"tutorials/compositional_modeling.md",
77
"tutorials/symbolic_stoich.md",
88
"tutorials/reaction_network_representation.md",
9+
"tutorials/homotopy_continuation_tutorial.md",
910
"tutorials/bifurcation_diagram.md",
1011
"tutorials/parameter_estimation.md",
1112
"tutorials/generating_reactions_programmatically.md"],
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Finding Steady States through Homotopy Continuation
2+
3+
The steady states of a dynamical system ${dx \over dt} = f(x)$ can be found by solving $0 = f(x)$. This is typically a hard problem, and generally, there is no method that guarantees to find all steady states for a system that has multiple ones. However, most CRNs generate polynomial systems (the main exception is when Hill functions with non-integer exponents are used). The roots of these can reliably be found through a *homotopy continuation* algorithm. This is implemented in Julia through the [HomotopyContinuation.jl](https://www.juliahomotopycontinuation.org/) package. In this tutorial, we will demonstrate how homotopy continuation can be used to find the steady states of a CNR implemented in Catalyst.
4+
5+
## Basic Example
6+
For this tutorial, we will use a model from the Wilhem (2009) paper (which demonstrates bistability in a small CRN). We declare the model and the parameter set for which we want to find the steady states:
7+
```@example hc1
8+
using Catalyst
9+
wilhelm_2009_model = @reaction_network begin
10+
k1, Y --> 2X
11+
k2, 2X --> X + Y
12+
k3, X + Y --> Y
13+
k4, X --> 0
14+
end k1 k2 k3 k4
15+
p = [:k1 => 8.0, :k2 => 2.0, :k3 => 1.0, :k4 => 1.5]
16+
```
17+
Next, we will need to extract the actual equations from our model. In addition, we will substitute in our parameter values.
18+
```@example hc1
19+
ns = convert(NonlinearSystem,wilhelm_2009_model)
20+
subs = Dict(Pair.(ModelingToolkit.parameters(ns),last.(p)))
21+
new_eqs = map(eq -> substitute(eq.rhs,subs), equations(ns))
22+
```
23+
Finally, we use the `as_polynomial` function to read our symbolic expression as a polynomial, within it, we can apply homotopy continuation's `solve` command to find the roots. In addition, we use the `real_solutions` to filter away imaginary roots (as CRNs' states typically are non-imaginary):
24+
```@example hc1
25+
using HomotopyContinuation
26+
sols = real_solutions(as_polynomial((f, x...) -> HomotopyContinuation.solve(collect(x)), new_eqs...))
27+
```
28+
While it is not the case for this CRN, we note that some solutions with negative species concentrations may still appear. Typically, these will need to be filtered away as well.
29+
30+
## Rational Polynomial Systems
31+
It is not uncommon for CRNs to generate systems corresponding to rational multivariate polynomials (e.g. through Hill functions). The roots of these can also be found using homotopy continuation. An expanded tutorial for this will be published once some awaited improvements to the `as_polynomial` function are completed.
32+
33+
## Systems with Conservation Laws
34+
Finally, some systems are underdetermined, and have an infinite number of possible steady states. These are typically systems containing a conservation law, e.g.
35+
```@example hc3
36+
using Catalyst
37+
two_state_model = @reaction_network begin
38+
(k1,k2), X1 <--> X2
39+
end k1 k2
40+
```
41+
However, the conservation laws can be computed using the `conservationlaws` function. By supplying these, as well as fixed concentrations (in this case the total amount of *X*, that is *X1+X2*), steady states can be found. First, we set the default values of the system's initial conditions and steady states. This will allow the system to automatically find the conserved amounts.
42+
```@example hc3
43+
setdefaults!(two_state_model, [:X1 => 1.0, :X2 => 1.0, :k1 => 2.0, :k2 => 1.0])
44+
```
45+
Next, we create a `NonlinearSystem`, while also removing the redundant equation.
46+
```@example hc3
47+
ns = convert(NonlinearSystem,two_state_model; remove_conserved=true)
48+
```
49+
Again, we will create the dictionary for parameter values that we will sub in. However, we will do it slightly differently so that the conserved quantitites are accoutned for.
50+
```@example hc3
51+
const MT = ModelingToolkit
52+
subs = Dict(MT.parameters(ns) .=> MT.varmap_to_vars([], MT.parameters(ns); defaults=MT.defaults(ns)))
53+
```
54+
We now extract the equation produced by the conservation law, and then sub in the parameter values creating a final set of equations (like previously). Unlike previously, we have to do `eq.rhs-eq.lhs`, as `cons_eq` may contain important information on both the lhs and rhs.
55+
```@example hc3
56+
cons_eq = conservedequations(two_state_model)
57+
new_eqs = map(eq -> substitute(eq.rhs-eq.lhs,subs), [equations(ns)...;cons_eq...])
58+
```
59+
Finally, we compute the solution:
60+
```@example hc3
61+
using HomotopyContinuation
62+
sols = real_solutions(as_polynomial((f, x...) -> HomotopyContinuation.solve(collect(x)), new_eqs...))
63+
```

0 commit comments

Comments
 (0)