Generating Data for an ODEProblem

To train a DigitalEcho we need to generate the training data. To generate this data, we simulate the system which can be an ODEProblem or a FMU. In this section, we will demonstrate how to generate data using an ODEProblem for training a DigitalEcho.

We start by setting up our enviornment. We load DataGeneration and OrdinaryDiffEq for defining an ODEProblem.

using DataGeneration
using OrdinaryDiffEq

For this demonstration, we choose a simple Lotka Volterra system. This system is a pair of non-linear differential equations used to describe the dynamics of a biological system. The system has a set of parameters α, β, γ, δ.

\[\frac{du₁}{dt} = \alpha u₁ - \beta u₁u₂\]

\[\frac{du₂}{dt} = \delta u₁u₂ - \gamma u₂\]

ODEProblem with parameters

We define the dynamics in the above equations in a function lotka_volterra.

function lotka_volterra(u, p, t)
    u₁, u₂ = u
    α, β, γ, δ = p
    dx = α * u₁ - β * u₁ * u₂
    dy = δ * u₁ * u₂ - γ * u₂
    [dx, dy]
end
lotka_volterra (generic function with 1 method)

Next we define the initial condition for the states : u₁ and u₂, and the timespan : tspan.

u0 = [1.0, 1.0]
tspan = (0, 12.5)
(0, 12.5)

We define the ODEProblem as:

lv_ode_problem = ODEProblem{false}(lotka_volterra, u0, tspan)
ODEProblem with uType Vector{Float64} and tType Float64. In-place: false
timespan: (0.0, 12.5)
u0: 2-element Vector{Float64}:
 1.0
 1.0

For more detailed examples on defining ODEProblem see: OrdinaryDiffEq.jl. Note one needs to define it with the {false} flag. For generating data, we need to define a ParameterSpace for sampling parameters: α, β, γ, δ. We start by defining the lower bound and upper bound.

param_lb = [1.5, 1.75, 1.5, 1.75]
param_lb = [2.0, 2.25, 2.25, 2.0]
n_samples = 10
10

And then we define the ParameterSpace:

param_space = ParameterSpace(param_lb, param_lb, n_samples; labels = ["α", "β", "γ", "δ"]);

We define the SimulatorConfig with this parameter space:

simconfig = SimulatorConfig(param_space);

And finally to generate the data, we call this SimulatorConfig on our problem. This returns an ExperimentData object that is consumed by DigitalEcho for training.

ed = simconfig(lv_ode_problem);
[ Info: #Processes = 1
[ Info: Simulating samples from worker processes

Additionally we can provide keyword arguments such as alg to the SimulatorConfig object call.

ed = simconfig(lv_ode_problem; alg = Tsit5())
 Number of Trajectories in ExperimentData: 10 
  Basic Statistics for Given Dynamical System's Specifications 
  Number of u0s in the ExperimentData: 2 
  Number of ps in the ExperimentData: 4 
 ╭─────────┬────────────────────────────────────────────────────────────────────╮
  Field                                                                      
├─────────┼────────────────────────────────────────────────────────────────────┤
           ╭────────────┬──────────────┬──────────────┬────────┬──────────╮  
              Labels     LowerBound    UpperBound    Mean    StdDev    
           ├────────────┼──────────────┼──────────────┼────────┼──────────┤  
             states_1       1.0           1.0        1.0      0.0      
   u0s     ├────────────┼──────────────┼──────────────┼────────┼──────────┤  
             
             
           ├────────────┼──────────────┼──────────────┼────────┼──────────┤  
             states_2       1.0           1.0        1.0      0.0      
           ╰────────────┴──────────────┴──────────────┴────────┴──────────╯  
├─────────┼────────────────────────────────────────────────────────────────────┤
            ╭──────────┬──────────────┬──────────────┬────────┬──────────╮   
              Labels    LowerBound    UpperBound    Mean    StdDev     
            ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
                α          2.0           2.0        2.0      0.0       
   ps       ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
               
               
            ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
                δ          2.0           2.0        2.0      0.0       
            ╰──────────┴──────────────┴──────────────┴────────┴──────────╯   
╰─────────┴────────────────────────────────────────────────────────────────────╯
 Basic Statistics for Given Dynamical System's Continuous Fields 
  Number of states in the ExperimentData: 2 
 ╭──────────┬─────────────────────────────────────────────────────────────────...
──╮...
  Field   ...
       ...
├──────────┼─────────────────────────────────────────────────────────────────...
──┤...
            ╭────────────┬──────────────┬──────────────┬─────────┬─────────...
               Labels     LowerBound    UpperBound    Mean     StdDev...
            ├────────────┼──────────────┼──────────────┼─────────┼─────────...
              states_1      0.951          1.3        1.096    0.129...
  states    ├────────────┼──────────────┼──────────────┼─────────┼─────────...
            ...
            ...
            ├────────────┼──────────────┼──────────────┼─────────┼─────────...
              states_2      0.746         1.048       0.889    0.104...
            ╰────────────┴──────────────┴──────────────┴─────────┴─────────...
╰──────────┴─────────────────────────────────────────────────────────────────...
──╯...

ODEProblem with parameters and inputs

The above system of equations can be modified to use control inputs as:

\[\frac{du₁}{dt} = \alpha u₁ - \beta u₁u₂ + x₁ \]

\[\frac{du₂}{dt} = \delta u₁u₂ - \gamma u₂ - x₂\]

And thus our new function would be:

function lotka_volterra_ctrl(u, x, p, t)
    u₁, u₂ = u
    α, β, γ, δ = p
    x₁, x₂ = x
    dx = α * u₁ - β * u₁ * u₂ + x₁
    dy = δ * u₁ * u₂ - γ * u₂ - x₂
    [dx, dy]
end
lotka_volterra_ctrl (generic function with 1 method)

Now we can define a new ODEProblem for this controlled lotka-volterra system as:

controlled_lv_ode_problem = ODEProblem{false}(lotka_volterra_ctrl, u0, tspan)
ODEProblem with uType Vector{Float64} and tType Float64. In-place: false
timespan: (0.0, 12.5)
u0: 2-element Vector{Float64}:
 1.0
 1.0

Since we have introduced control inputs in this system, lets define a CtrlSpace to sample control functions.

nsamples_ctrl = 10
ctrl_lb = [0.0, 0.0]
ctrl_ub = [0.1, 0.1]
ctrl_func(u, p, t) = [p[1] * sin(t), p[2] * sin(t)]
ctrl_space = CtrlSpace(ctrl_lb, ctrl_ub, ctrl_func, nsamples_ctrl; labels = ["x₁", "x₂"]);

We have previously defined a ParameterSpace, which we will reuse for data generation in this case. So we can define a SimulatorConfig with ParameterSpace as well as CtrlSpace.

simconfig = SimulatorConfig(param_space, ctrl_space)
 Simulator Config with :   CtrlSpace  ParameterSpace
  Statistics for all Spaces  

  2 dimensional CtrlSpace with 10 samples 
 ╭──────────────┬──────────────────────────────────────────────┬──────────────...
─────╮...
  Space Type                    Statistics                    Number...
Samples  ...
├──────────────┼──────────────────────────────────────────────┼──────────────...
─────┤...
                ╭──────────┬──────────────┬──────────────╮  ...
                  Labels    LowerBound    UpperBound    ...
                ├──────────┼──────────────┼──────────────┤  ...
                    x₁         0.0           0.1        ...
  CtrlSpace     ├──────────┼──────────────┼──────────────┤  ...
                  ...
                  ...
                ├──────────┼──────────────┼──────────────┤  ...
                    x₂         0.0           0.1        ...
                ╰──────────┴──────────────┴──────────────╯  ...
╰──────────────┴──────────────────────────────────────────────┴──────────────...
─────╯...
 4 dimensional ParameterSpace with 10 samples 
 ╭──────────────────┬──────────────────────────────────────────────┬──────────...
─────────╮...
    Space Type                      Statistics                    Number...
of Samples  ...
├──────────────────┼──────────────────────────────────────────────┼──────────...
─────────┤...
                    ╭──────────┬──────────────┬──────────────╮  ...
                      Labels    LowerBound    UpperBound    ...
                    ├──────────┼──────────────┼──────────────┤  ...
                        α          2.0           2.0        ...
  ParameterSpace    ├──────────┼──────────────┼──────────────┤  ...
                      ...
                      ...
                    ├──────────┼──────────────┼──────────────┤  ...
                        δ          2.0           2.0        ...
                    ╰──────────┴──────────────┴──────────────╯  ...
╰──────────────────┴──────────────────────────────────────────────┴──────────...
─────────╯...

Similar to the previous example, we can generate the ExperimentData by calling the SimulatorConfig on our controlled_lv_ode_problem.

ed_ctrl = simconfig(controlled_lv_ode_problem)
 Number of Trajectories in ExperimentData: 100 
  Basic Statistics for Given Dynamical System's Specifications 
  Number of u0s in the ExperimentData: 2 
  Number of ps in the ExperimentData: 4 
 ╭─────────┬────────────────────────────────────────────────────────────────────╮
  Field                                                                      
├─────────┼────────────────────────────────────────────────────────────────────┤
           ╭────────────┬──────────────┬──────────────┬────────┬──────────╮  
              Labels     LowerBound    UpperBound    Mean    StdDev    
           ├────────────┼──────────────┼──────────────┼────────┼──────────┤  
             states_1       1.0           1.0        1.0      0.0      
   u0s     ├────────────┼──────────────┼──────────────┼────────┼──────────┤  
             
             
           ├────────────┼──────────────┼──────────────┼────────┼──────────┤  
             states_2       1.0           1.0        1.0      0.0      
           ╰────────────┴──────────────┴──────────────┴────────┴──────────╯  
├─────────┼────────────────────────────────────────────────────────────────────┤
            ╭──────────┬──────────────┬──────────────┬────────┬──────────╮   
              Labels    LowerBound    UpperBound    Mean    StdDev     
            ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
                α          2.0           2.0        2.0      0.0       
   ps       ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
               
               
            ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
                δ          2.0           2.0        2.0      0.0       
            ╰──────────┴──────────────┴──────────────┴────────┴──────────╯   
╰─────────┴────────────────────────────────────────────────────────────────────╯
 Basic Statistics for Given Dynamical System's Continuous Fields 
  Number of states in the ExperimentData: 2 
  Number of controls in the ExperimentData: 2 
 ╭────────────┬───────────────────────────────────────────────────────────────...
────╮...
   Field    ...
         ...
├────────────┼───────────────────────────────────────────────────────────────...
────┤...
              ╭────────────┬──────────────┬──────────────┬─────────┬───────...
                 Labels     LowerBound    UpperBound    Mean   ...
              ├────────────┼──────────────┼──────────────┼─────────┼───────...
                states_1      0.887          1.43       1.096  ...
   states     ├────────────┼──────────────┼──────────────┼─────────┼───────...
              ...
              ...
              ├────────────┼──────────────┼──────────────┼─────────┼───────...
                states_2      0.705         1.129       0.889  ...
              ╰────────────┴──────────────┴──────────────┴─────────┴───────...
├────────────┼───────────────────────────────────────────────────────────────...
────┤...
               ╭──────────┬──────────────┬──────────────┬─────────┬────────...
                 Labels    LowerBound    UpperBound    Mean     StdDev...
               ├──────────┼──────────────┼──────────────┼─────────┼────────...
                   x₁        -0.093        0.094       0.003    0.036...
  controls     ├──────────┼──────────────┼──────────────┼─────────┼────────...
               ...
               ...
               ├──────────┼──────────────┼──────────────┼─────────┼────────...
                   x₂        -0.095        0.097       0.004    0.041...
               ╰──────────┴──────────────┴──────────────┴─────────┴────────...
╰────────────┴───────────────────────────────────────────────────────────────...
────╯...

Parallelization

The Data Generation supports distributed computing via multiple processes. To enable multi-processing using processes, we need to load Distributed.

using Distributed

We add processes using addprocs. For more detailed understanding about distributed computing see: Distributed.jl.

addprocs(2, exeflags = ["--project=."])

We need to load DataGeneration module of JuliaSimSurrogates on all the processes.

@everywhere using DataGeneration

We need to use @everywhere to define functions on these added processes.

@everywhere function lotka_volterra_ctrl(u, x, p, t)
    u₁, u₂ = u
    α, β, γ, δ = p
    x₁, x₂ = x
    dx = α * u₁ - β * u₁ * u₂ + x₁
    dy = δ * u₁ * u₂ - γ * u₂ - x₂
    [dx, dy]
end

@everywhere ctrl_func(u, p, t) = [p[1] * sin(t), p[2] * sin(t)]

Once we have defined the necessary functions on these processes, we can take advantage of multi-processing for data generation.

ed_ctrl = simconfig(controlled_lv_ode_problem)
 Number of Trajectories in ExperimentData: 100 
  Basic Statistics for Given Dynamical System's Specifications 
  Number of u0s in the ExperimentData: 2 
  Number of ps in the ExperimentData: 4 
 ╭─────────┬────────────────────────────────────────────────────────────────────╮
  Field                                                                      
├─────────┼────────────────────────────────────────────────────────────────────┤
           ╭────────────┬──────────────┬──────────────┬────────┬──────────╮  
              Labels     LowerBound    UpperBound    Mean    StdDev    
           ├────────────┼──────────────┼──────────────┼────────┼──────────┤  
             states_1       1.0           1.0        1.0      0.0      
   u0s     ├────────────┼──────────────┼──────────────┼────────┼──────────┤  
             
             
           ├────────────┼──────────────┼──────────────┼────────┼──────────┤  
             states_2       1.0           1.0        1.0      0.0      
           ╰────────────┴──────────────┴──────────────┴────────┴──────────╯  
├─────────┼────────────────────────────────────────────────────────────────────┤
            ╭──────────┬──────────────┬──────────────┬────────┬──────────╮   
              Labels    LowerBound    UpperBound    Mean    StdDev     
            ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
                α          2.0           2.0        2.0      0.0       
   ps       ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
               
               
            ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
                δ          2.0           2.0        2.0      0.0       
            ╰──────────┴──────────────┴──────────────┴────────┴──────────╯   
╰─────────┴────────────────────────────────────────────────────────────────────╯
 Basic Statistics for Given Dynamical System's Continuous Fields 
  Number of states in the ExperimentData: 2 
  Number of controls in the ExperimentData: 2 
 ╭────────────┬───────────────────────────────────────────────────────────────...
────╮...
   Field    ...
         ...
├────────────┼───────────────────────────────────────────────────────────────...
────┤...
              ╭────────────┬──────────────┬──────────────┬─────────┬───────...
                 Labels     LowerBound    UpperBound    Mean   ...
              ├────────────┼──────────────┼──────────────┼─────────┼───────...
                states_1      0.887          1.43       1.096  ...
   states     ├────────────┼──────────────┼──────────────┼─────────┼───────...
              ...
              ...
              ├────────────┼──────────────┼──────────────┼─────────┼───────...
                states_2      0.705         1.129       0.889  ...
              ╰────────────┴──────────────┴──────────────┴─────────┴───────...
├────────────┼───────────────────────────────────────────────────────────────...
────┤...
               ╭──────────┬──────────────┬──────────────┬─────────┬────────...
                 Labels    LowerBound    UpperBound    Mean     StdDev...
               ├──────────┼──────────────┼──────────────┼─────────┼────────...
                   x₁        -0.093        0.094       0.003    0.036...
  controls     ├──────────┼──────────────┼──────────────┼─────────┼────────...
               ...
               ...
               ├──────────┼──────────────┼──────────────┼─────────┼────────...
                   x₂        -0.095        0.097       0.004    0.041...
               ╰──────────┴──────────────┴──────────────┴─────────┴────────...
╰────────────┴───────────────────────────────────────────────────────────────...
────╯...