Surrogatize ODEProblem

JuliaSim Surrogates can help users generate surrogate models from their ODE code in just a few short steps:

  1. Problem Definition
  2. Data Generation
  3. Pre-processing
  4. Surrogatization
  5. Visualisation

Julia Environment

First we prepare the environment by listing the packages we are using within the example. Each package below (except for OrdinaryDiffEq) represents a module of JuliaSimSurrogates.

using OrdinaryDiffEq
using DataGeneration
using PreProcessing
using Surrogatize
using Visualisations
using LoggingUtils

Model Setup

This example builds upon the well-documented rober model. First, we define the classic system with an out-of-place form (non-mutating). This form will be useful at the end when we want to make inferences on our trained model.

function rober(u, p, t)
    y₁, y₂, y₃ = u
    k₁, k₂, k₃ = p
    [-k₁ * y₁ + k₃ * y₂ * y₃;
     k₁ * y₁ - k₂ * y₂^2 - k₃ * y₂ * y₃;
     k₂ * y₂^2]
end
rober (generic function with 1 method)

Then we define another version of the system, this time accounting for control sampling with an in-place form.

function rober(u, x, p, t)
    y₁, y₂, y₃ = u
    k₁, k₂, k₃ = p
    x₁, x₂, x₃ = x
    [-k₁ * y₁ + k₃ * y₂ * y₃ + x₁;
     k₁ * y₁ - k₂ * y₂^2 - k₃ * y₂ * y₃ + x₂;
     k₂ * y₂^2 + x₃]
end
rober (generic function with 2 methods)

Finally, in order to declare our ODEProblem, we provide initial conditions, time span and paramter values.

tstop = 1e4
p = [0.04, 3e7, 1e4]
u0 = [1.0, 0.0, 0.0]
tspan = (0.0, tstop)
prob = ODEProblem{false}(rober, u0, tspan, p)
ODEProblem with uType Vector{Float64} and tType Float64. In-place: false
timespan: (0.0, 10000.0)
u0: 3-element Vector{Float64}:
 1.0
 0.0
 0.0

Generating Data

Now that we have a working model we want to generate many samples. A collection of samples can then be used to train a surrogate model. JuliaSim's DataGeneration.jl will help us generate the data.

Parameter Space

For simplicity, this example will only define a ParameterSpace wherein we define the desired number of samples, bounds of the space, and values in order to produce our final parameter space.

nsamples = 100
param_space = [(0.036, 0.044), (2.7e7, 3.3e7), (0.9e4, 1.1e4)]
p_lb = first.(param_space)
p_ub = last.(param_space)
param_space = ParameterSpace(p_lb, p_ub, nsamples)
ParameterSpace{Matrix{Float64}}
3 dimension space with 100 samples)
Samples : [0.0361875 0.0401875 … 0.0424687 0.0384687; 2.93906e7 3.23906e7 … 2.88984e7 3.18984e7; 10640.6 9640.62 … 10492.2 9492.19]

Producing Simulations

In order to generate the data we now define a simulator configuration and run the simulations! Define a Simulator configuration which holds information about all the sampling spaces and apply this Simulator to the problem definition.

sim_config = SimulatorConfig(param_space)
exp_data = sim_config(prob; alg = Rosenbrock23(), abstol = 1e-12, reltol = 1e-12);
[ Info: #Processes = 1
[ Info: Simulating samples from worker processes

Surrogatization

All that's left to create a surrogate from our SimulationResults is to declare the model for surrogatization. Options include CTESN, ELM, and Augmented ELM. This example will employ the ELM (Extreme Learning Machine) model with 3 input dimensions and 50 hidden features.

elm = ELM(3, 250)
surr = surrogatize(exp_data, elm);

We can now make inferences on this surr object!

surr([1.1, 0.1, 0.1], [0.04, 3e7, 1e4], (0.0, 1e4))

This page was generated using Literate.jl.