Get Started
using FindSteadyStates
using DifferentialEquationsCreate Differential Equation System
The standard way to create DE system is to create a derivative function in the form of f(du,u,p,t) with preallocated derivatives (du), initial variables ('u'), parameters (p) and time ('t')
function bistable_ode!(du, u, p ,t)
s1, s2 = u
K1, K2, k1, k2, k3, k4, n1 , n2 = p
du[1] = k1 / (1 + (s2/K2)^n1) - k3*s1
du[2] = k2/ (1 + (s1/K1)^n2) - k4*s2
endOne may want to use NameTuple like LabelledArrays to create Tuple array and apply to the ode function. However, this may cause getindex undefined error for Jacobian Calculation via ModelingToolkit, but still safe with solving steady states with NameTuple as returns.
Create DE Problem for Solving
de = DEsteady(func = bistable_ode!,
p = [1.,1.,20.,20.,5.,5.,4.,4.],
u0 = [3.,1.],
method = SSRootfind()
)The DEsteady.method will further be used for DifferentialEquation.solve. Both dynamic solver (Dynamicss which reaches steady states by solving DE) and root finding (SSRootfind) can get the stable point. However, only SSRootfind can find the saddle point if the initial values is near by.
The system is now well organized and ready to be solved.
sol = solve(de)u: 2-element Vector{Float64}:
3.999999765270408
0.015564205973794263Exploring the initial states
To find all the steady states, one needs to sample the initial state by grid or random search. To begin with, the ParameterGrid (grid search) and ParameterRandom (random search) are useful generator for iterating and returning the parameter set.
param_rand = ParameterRandom(
methods= [
Uniform(0.,100.),
Log_uniform(0.001,100.)
],
len= 100
)100-element ParameterRandom:
[10.821764717620564, 0.11026595580735826]
[34.22882838788694, 0.3962071042085722]
[42.02523989863707, 5.4130282841496635]
[75.92672473126962, 0.7753515415395362]
[50.93968252719916, 4.272048989618616]
[35.02477589373603, 0.006353349770769713]
[57.73519735635807, 0.020128191940175972]
[73.99855981459717, 98.21949281544694]
[64.54815910813933, 0.01190112641853788]
[60.837879167785815, 1.017608960880024]
⋮
[35.415111693866905, 0.234915382629302]
[80.33897992385212, 0.3424574017104499]
[7.962538195307234, 5.262034886394346]
[47.17289449608164, 1.2881758335198525]
[41.5945031618386, 0.009360372283148085]
[42.33656784321366, 0.0012577849562660564]
[69.71371438450757, 45.5633301806911]
[76.25244379634456, 21.992730395204273]
[3.93020516798247, 2.2381079230835743] param_grid = ParameterGrid([
[0.,100.,100],
[0.,100.,100]
])10000-element ParameterGrid:
[0.0, 0.0]
[1.0101010101010102, 0.0]
[2.0202020202020203, 0.0]
[3.0303030303030303, 0.0]
[4.040404040404041, 0.0]
[5.050505050505051, 0.0]
[6.0606060606060606, 0.0]
[7.070707070707071, 0.0]
[8.080808080808081, 0.0]
[9.090909090909092, 0.0]
⋮
[91.91919191919193, 100.0]
[92.92929292929294, 100.0]
[93.93939393939395, 100.0]
[94.94949494949496, 100.0]
[95.95959595959597, 100.0]
[96.96969696969697, 100.0]
[97.97979797979798, 100.0]
[98.98989898989899, 100.0]
[100.0, 100.0]Solve solutions with multi-threading
Random Search
sols_rand = solve(de, param_rand)EnsembleSolution Solution of length 100 with uType:
SciMLBase.NonlinearSolution{Float64, 1, Vector{Float64}, Vector{Float64}, SteadyStateProblem{Vector{Float64}, true, Vector{Float64}, ODEFunction{true, typeof(Main.bistable_ode!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, SSRootfind{SteadyStateDiffEq.var"#2#4"}, Nothing, Nothing}Grid Search
sols_grid = solve(de, param_grid)EnsembleSolution Solution of length 10000 with uType:
SciMLBase.NonlinearSolution{Float64, 1, Vector{Float64}, Vector{Float64}, SteadyStateProblem{Vector{Float64}, true, Vector{Float64}, ODEFunction{true, typeof(Main.bistable_ode!), LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}, Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}}, SSRootfind{SteadyStateDiffEq.var"#2#4"}, Nothing, Nothing}