#DifferentialEquations.jl Example
This example shows the basic usage of the AmbientForcing and DifferentialEquation.jl. We adopt the Robertson Example from the DifferentialEquation Docs.
We begin by load all necessary deps:
using AmbientForcing, Distributions, OrdinaryDiffEq
Then we define our differential equation:
function rober(du, u, p, t)
y₁, y₂, y₃ = u
du[1] = -0.04 * y₁ + 1e4 * y₂ * y₃
du[2] = 0.04 * y₁ - 1e4 * y₂ * y₃ - 3e7 * y₂^2
du[3] = y₁ + y₂ + y₃ - 1
nothing
end
rober (generic function with 1 method)
We create the mass matrix $M$, the last row depicts our constraint:
M = [1.0 0 0
0 1.0 0
0 0 0]
3×3 Matrix{Float64}:
1.0 0.0 0.0
0.0 1.0 0.0
0.0 0.0 0.0
We set up the DAE as an ODE in mass matrix form:
ode_rober = ODEFunction(rober, mass_matrix=M)
(::SciMLBase.ODEFunction{true, typeof(Main.rober), Matrix{Float64}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing}) (generic function with 7 methods)
We have to choose an initial condition which fulfills the constraints:
u0 = [1.0, 0.0, 0.0]
g_rober = constraint_equations(ode_rober)
isapprox(sum(g_rober(u0)), 0.0, atol=1e-8)
true
Using Ambient Forcing we randomly perturb all variables:
Frand = random_force(ode_rober, [0.0, 1], Uniform)
afoprob_rober = ambient_forcing_problem(ode_rober, u0, 2.0, Frand)
z_new_all = ambient_forcing(afoprob_rober, Frand)
isapprox(sum(g_rober(z_new_all)), 0.0, atol=1e-8)
true
Only perturbing the second variable $y_2$ works as well:
h = [0, 1, 0]
z_new_2 = ambient_forcing(afoprob_rober, h)
isapprox(sum(g_rober(z_new_2)), 0.0, atol=1e-8)
true