You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/src/steady_state_functionality/steady_state_stability_computation.md
+9Lines changed: 9 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,9 @@
1
1
# Steady state stability computation
2
2
After system steady states have been found using [HomotopyContinuation.jl](@ref homotopy_continuation), [NonlinearSolve.jl](@ref nonlinear_solve), or other means, their stability can be computed using Catalyst's `steady_state_stability` function. Systems with conservation laws will automatically have these removed, permitting stability computation on systems with singular Jacobian.
3
3
4
+
!!! warn
5
+
Catalyst currently computes steady state stabilities using the naive approach of checking whether a system's largest eigenvalue is negative. While more advanced stability computation methods exist (and would be a welcome addition to Catalyst), there is no direct plans to implement these.
It is possible to designate that a [sparse Jacobian](@ref ref) should be used using the `sparse = true` option (either to `steady_state_jac` or directly to `steady_state_stability`):
is_autonomous(rs) ||error("Attempting to compute steady state for non-autonomous system (e.g. does some rate depend on $(rs.iv)?), this is not possible.")
6
+
if!is_autonomous(rs)
7
+
error("Attempting to create a `BifurcationProblem` for a non-autonomous system (e.g. where some rate depend on $(rs.iv)). This is not possible.")
8
+
end
7
9
8
10
# Converts symbols to symbolics.
9
11
(bif_par isa Symbol) && (bif_par = ModelingToolkit.get_var_to_name(rs)[bif_par])
Copy file name to clipboardExpand all lines: ext/CatalystHomotopyContinuationExtension/homotopy_continuation_extension.jl
+3-1Lines changed: 3 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -36,7 +36,9 @@ Notes:
36
36
```
37
37
"""
38
38
function Catalyst.hc_steady_states(rs::ReactionSystem, ps; filter_negative=true, neg_thres=-1e-20, u0=[], kwargs...)
39
-
is_autonomous(rs) ||error("Attempting to compute steady state for non-autonomous system (e.g. does some rate depend on $(rs.iv)?), this is not possible.")
39
+
if!is_autonomous(rs)
40
+
error("Attempting to compute steady state for a non-autonomous system (e.g. where some rate depend on $(rs.iv)). This is not possible.")
error("Attempting to convert a non-autonomous `ReactionSystem` (e.g. where some rate depend on $(rs.iv)) to a `NonlinearSystem`. This is not possible. if you are intending to compute system steady states, consider creating and solving a `SteadyStateProblem.")
Compute the stability of a steady state (Returned as a `Bool`, with `true` indicating stability).
7
8
8
9
Arguments:
9
10
- `u`: The steady state for which we want to compute stability.
10
-
- `rs`: The reaction system model for which we want to compute stability.
11
+
- `rs`: The `ReactionSystem` model for which we want to compute stability.
11
12
- `p`: The parameter set for which we want to compute stability.
12
-
- `sparse=false`: If we wish to create a sparse Jacobian for the stability computation.
13
-
- `ss_jac = steady_state_jac(u, rs; sparse=sparse)`: It is possible to pre-compute the Jacobian used for stability computation using `steady_state_jac`. If stability is computed for many states, precomputing the Jacobian may speed up evaluation.
14
-
- `t = Inf`: The time point at which stability is computed.
15
-
- `non_autonomous_warn = true`: If the system is non-autonomous (e.g. a rate depends on t), a warning will be given. Set this to false to remove that. Alternatively, specify a nonInf value for `t`.
13
+
- `sparse = false`: If we wish to create a sparse Jacobian for the stability computation.
14
+
- `ss_jac = steady_state_jac(u, rs; sparse = sparse)`: It is possible to pre-compute the
15
+
Jacobian used for stability computation using `steady_state_jac`. If stability is computed
16
+
for many states, precomputing the Jacobian may speed up evaluation.
16
17
17
18
Example:
18
19
```julia
@@ -22,45 +23,49 @@ rn = @reaction_network begin
22
23
end
23
24
p = [:p => 1.0, :d => 0.5]
24
25
25
-
# Finds (the trivial) steady state, and computes stability.
26
+
# Finds (the trivial) steady state, and computes its stability.
26
27
steady_state = [2.0]
27
28
steady_state_stability(steady_state, rn, p)
28
-
```
29
29
30
30
Notes:
31
-
y states (each being a `Vector`) is provided as `u`, stability is computed for each state separately.
31
+
- The input `u` can (currently) be both a vector of values (like `[1.0, 2.0]`) and a vector map
32
+
(like `[X => 1.0, Y => 2.0]`). The reason is that most methods for computing stability only
33
+
produces vectors of values. However, if possible, it is recommended to work with values on the
ss_jac =steady_state_jac(rs; u0 = u, sparse = sparse))
36
39
# Warning checks.
37
-
!is_autonomous(rs) && non_autonomous_warn &&@warn"Attempting to compute stability for a non-autonomous system. Set `non_autonomous_warn = false` to disable this warning."
38
-
39
-
# Because Jacobian currently requires u and p to be a normal vector.
40
-
# Can be removed once this get fixed in MTK.
41
-
if (u isa Vector{<:Pair}) || (u isa Dict)
42
-
u_dict =Dict(symmap_to_varmap(rs, u))
43
-
u = [u_dict[var] for var instates(rs)]
40
+
if!is_autonomous(rs)
41
+
error("Attempting to compute stability for a non-autonomous system (e.g. where some rate depend on $(rs.iv)). This is not possible.")
44
42
end
45
-
if (p isa Vector{<:Pair}) || (p isa Dict)
46
-
p_dict =Dict(symmap_to_varmap(rs, p))
47
-
p = [p_dict[var] for var inparameters(rs)]
43
+
44
+
# If `u` is a vector of values, we convert it to a map. Also, if there are conservation laws,
45
+
# corresponding values must be eliminated from `u`.
46
+
u =steady_state_u_conversion(u, rs)
47
+
iflength(u) >length(unknowns(ss_jac.f.sys))
48
+
u =filter(u_v ->any(isequal(u_v[1]), unknowns(ss_jac.f.sys)), u)
48
49
end
49
50
50
51
# Computes stability (by checking that the real part of all eigenvalues are negative).
51
-
jac =ss_jac(u, p, Inf)
52
-
returnmaximum(real.(eigvals(jac))) <0
53
-
end
54
-
# Computes the stability for a vector of steady states.
Creates the Jacobian function which can be used as input to `steady_state_stability`. Useful when
63
+
a large number of stability computation has to be carried out in a performant manner.
62
64
63
-
Creates the Jacobian function which can be used as input to `steady_state_stability`. Useful when a large number of stability computation has to be carried out in a performant manner.
65
+
Arguments:
66
+
- `rs`: The reaction system model for which we want to compute stability.
67
+
- `u0 = []`: For systems with conservation laws, a `u` is required to compute the conserved quantities.
68
+
- `sparse = false`: If we wish to create a sparse Jacobian for the stability computation.
# If u0 is a vector of values, must be converted to something MTK understands.
88
-
if (u0 isa Vector{<:Number})
89
-
iflength(u0) ==length(states(rs))
90
-
u0 =Pair.(states(rs), u0)
91
-
elseif!isempty(u0)
92
-
error("You are trying to compute a stability matrix, providing u0 to compute conservation laws. Your provided u0 vector has length < the number of system states. If you provide a u0 vector, these have to be identical.")
93
-
end
94
-
end
95
93
96
94
# Converts u0 to values MTK understands, and checks that potential conservation laws are accounted for.
error("You are trying to generate a stability Jacobian, providing u0 to compute conservation laws. Your provided u0 vector has length < the number of system states. If you provide a u0 vector, these have to be identical.")
0 commit comments