Repository for optimal experimental design for differential equations using optimal control.
DynamicOED.jl
uses multiple packages of Julia's SciML ecosystem, especially ModelingToolkit.jl, DifferentialEquations.jl and Optimization.jl to define optimal experimental design problems using optimal control.
- Currently we support Ordinary Differential Equations and Differential Algebraic Equations.
- Relaxed and Integer formulations of the underlying problem
- Unknown initial conditions
- Continuous and discrete controls (in terms of the variable)
- Variable (measurement) rates for observed and control variables
- Custom constraints
using DynamicOED
using ModelingToolkit
using Optimization, OptimizationMOI, Ipopt
# Define the differential equations
@variables t
@variables x(t)=1.0 [description = "State"]
@parameters p[1:1]=-2.0 [description = "Fixed parameter", tunable = true]
@variables obs(t) [description = "Observed", measurement_rate = 10]
D = Differential(t)
@named simple_system = ODESystem([
D(x) ~ p[1] * x,
], tspan = (0.0, 1.0),
observed = obs .~ [x.^2])
@named oed = OEDSystem(simple_system)
oed = structural_simplify(oed)
# Augment the original problem to an OED problem
oed_problem = OEDProblem(structural_simplify(oed), FisherACriterion())
# Define an MTK Constraint system over the grid variables
optimization_variables = states(oed_problem)
constraint_equations = [
sum(optimization_variables.measurements.w₁) ≲ 3,
]
@named constraint_set = ConstraintsSystem(constraint_equations, optimization_variables, Num[])
# Initialize the optimization problem
optimization_problem = OptimizationProblem(oed_problem, AutoForwardDiff(),
constraints = constraint_set,
integer_constraints = false)
# Solven for the optimal values of the observed variables
solve(optimization_problem, Ipopt.Optimizer())