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 environment. 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             1          1        0       
   u0s     ├────────────┼──────────────┼──────────────┼────────┼──────────┤  
             
             
           ├────────────┼──────────────┼──────────────┼────────┼──────────┤  
             states_2        1             1          1        0       
           ╰────────────┴──────────────┴──────────────┴────────┴──────────╯  
├─────────┼────────────────────────────────────────────────────────────────────┤
            ╭──────────┬──────────────┬──────────────┬────────┬──────────╮   
              Labels    LowerBound    UpperBound    Mean    StdDev     
            ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
                α           2             2          2        0        
   ps       ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
               
               
            ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
                δ           2             2          2        0        
            ╰──────────┴──────────────┴──────────────┴────────┴──────────╯   
╰─────────┴────────────────────────────────────────────────────────────────────╯
 Basic Statistics for Given Dynamical System's Continuous Fields 
  Number of states in the ExperimentData: 2 
 ╭──────────┬─────────────────────────────────────────────────────────────────...
───────╮...
  Field   ...
            ...
├──────────┼─────────────────────────────────────────────────────────────────...
───────┤...
            ╭────────────┬──────────────┬──────────────┬────────────┬──────...
               Labels     LowerBound    UpperBound      Mean    ...
            ├────────────┼──────────────┼──────────────┼────────────┼──────...
              states_1     0.951337      1.30017      1.09613   ...
  states    ├────────────┼──────────────┼──────────────┼────────────┼──────...
            ...
            ...
            ├────────────┼──────────────┼──────────────┼────────────┼──────...
              states_2     0.745919       1.0482      0.889332  ...
            ╰────────────┴──────────────┴──────────────┴────────────┴──────...
╰──────────┴─────────────────────────────────────────────────────────────────...
───────╯...

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 
 With controls : x₁, x₂ 
╭──────────────┬──────────────────────────────────────────────┬──────────────...
─────╮...
  Space Type                    Statistics                    Number...
Samples  ...
├──────────────┼──────────────────────────────────────────────┼──────────────...
─────┤...
                ╭──────────┬──────────────┬──────────────╮  ...
                  Labels    LowerBound    UpperBound    ...
                ├──────────┼──────────────┼──────────────┤  ...
                   x_1          0            0.1        ...
  CtrlSpace     ├──────────┼──────────────┼──────────────┤  ...
                  ...
                  ...
                ├──────────┼──────────────┼──────────────┤  ...
                   x_2          0            0.1        ...
                ╰──────────┴──────────────┴──────────────╯  ...
╰──────────────┴──────────────────────────────────────────────┴──────────────...
─────╯...
 4 dimensional ParameterSpace with 10 samples 
 ╭──────────────────┬──────────────────────────────────────────────┬──────────...
─────────╮...
    Space Type                      Statistics                    Number...
of Samples  ...
├──────────────────┼──────────────────────────────────────────────┼──────────...
─────────┤...
                    ╭──────────┬──────────────┬──────────────╮  ...
                      Labels    LowerBound    UpperBound    ...
                    ├──────────┼──────────────┼──────────────┤  ...
                        α           2             2         ...
  ParameterSpace    ├──────────┼──────────────┼──────────────┤  ...
                      ...
                      ...
                    ├──────────┼──────────────┼──────────────┤  ...
                        δ           2             2         ...
                    ╰──────────┴──────────────┴──────────────╯  ...
╰──────────────────┴──────────────────────────────────────────────┴──────────...
─────────╯...

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             1          1        0       
   u0s     ├────────────┼──────────────┼──────────────┼────────┼──────────┤  
             
             
           ├────────────┼──────────────┼──────────────┼────────┼──────────┤  
             states_2        1             1          1        0       
           ╰────────────┴──────────────┴──────────────┴────────┴──────────╯  
├─────────┼────────────────────────────────────────────────────────────────────┤
            ╭──────────┬──────────────┬──────────────┬────────┬──────────╮   
              Labels    LowerBound    UpperBound    Mean    StdDev     
            ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
                α           2             2          2        0        
   ps       ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
               
               
            ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
                δ           2             2          2        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.887627      1.42643       1.0959...
   states     ├────────────┼──────────────┼──────────────┼────────────┼────...
              ...
              ...
              ├────────────┼──────────────┼──────────────┼────────────┼────...
                states_2     0.709326      1.13012      0.889302...
              ╰────────────┴──────────────┴──────────────┴────────────┴────...
├────────────┼───────────────────────────────────────────────────────────────...
──────────┤...
              ╭──────────┬──────────────┬──────────────┬──────────────┬────...
                Labels    LowerBound    UpperBound       Mean...
              ├──────────┼──────────────┼──────────────┼──────────────┼────...
                  x₁      -0.0929809    0.0949977     0.00341274...
  controls    ├──────────┼──────────────┼──────────────┼──────────────┼────...
              ...
              ...
              ├──────────┼──────────────┼──────────────┼──────────────┼────...
                  x₂      -0.0930931    0.0949977     0.00331477...
              ╰──────────┴──────────────┴──────────────┴──────────────┴────...
╰────────────┴───────────────────────────────────────────────────────────────...
──────────╯...

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             1          1        0       
   u0s     ├────────────┼──────────────┼──────────────┼────────┼──────────┤  
             
             
           ├────────────┼──────────────┼──────────────┼────────┼──────────┤  
             states_2        1             1          1        0       
           ╰────────────┴──────────────┴──────────────┴────────┴──────────╯  
├─────────┼────────────────────────────────────────────────────────────────────┤
            ╭──────────┬──────────────┬──────────────┬────────┬──────────╮   
              Labels    LowerBound    UpperBound    Mean    StdDev     
            ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
                α           2             2          2        0        
   ps       ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
               
               
            ├──────────┼──────────────┼──────────────┼────────┼──────────┤   
                δ           2             2          2        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.887627      1.42643       1.0959...
   states     ├────────────┼──────────────┼──────────────┼────────────┼────...
              ...
              ...
              ├────────────┼──────────────┼──────────────┼────────────┼────...
                states_2     0.709326      1.13012      0.889302...
              ╰────────────┴──────────────┴──────────────┴────────────┴────...
├────────────┼───────────────────────────────────────────────────────────────...
──────────┤...
              ╭──────────┬──────────────┬──────────────┬──────────────┬────...
                Labels    LowerBound    UpperBound       Mean...
              ├──────────┼──────────────┼──────────────┼──────────────┼────...
                  x₁      -0.0929809    0.0949977     0.00341274...
  controls    ├──────────┼──────────────┼──────────────┼──────────────┼────...
              ...
              ...
              ├──────────┼──────────────┼──────────────┼──────────────┼────...
                  x₂      -0.0930931    0.0949977     0.00331477...
              ╰──────────┴──────────────┴──────────────┴──────────────┴────...
╰────────────┴───────────────────────────────────────────────────────────────...
──────────╯...