Control-free problems
What this is for
Control-free problems are optimal control problems without a control. They are used to optimise constant parameters of a dynamical system, for instance to
identify unknown parameters from observed data (parameter estimation),
find the parameters that are best for a given performance criterion.
This page shows how to declare and solve such problems. For the full story of the two examples below, solved by both the direct and the indirect method, see Parameter estimation without a control.
How to declare it
There is no dedicated syntax: simply never declare a control. Declare a variable (the parameters), a time, a state, the dynamics and a cost, and omit the control line with @def, or never call control! with the functional API. The functional API page builds the parameter-estimation problem below both ways, side by side.
control!(pre, 0) is an error
With the functional API, a control-free problem is obtained by omission only. control!(pre, 0) throws an IncorrectArgument: a dimension must be positive.
using OptimalControl
using NLPModelsIpopt
using PlotsExample: parameter estimation
A system with exponential growth,
The data come from the model with variable:
# observed data (analytical solution with λ = 0.5, plus a perturbation)
λ_true = 0.5
data(t) = 2 * exp(λ_true * t) + 2e-1 * sin(4π * t)
t0 = 0; tf = 2; x0 = 2
ocp = @def begin
λ ∈ R, variable # growth rate to estimate
t ∈ [t0, tf], time
x ∈ R, state
x(t0) == x0
ẋ(t) == λ * x(t)
∫((x(t) - data(t))^2) → min # fit to observed data
endThe model knows it has no control:
is_control_free(ocp)trueIt solves like any other problem. The estimated parameter is the optimal value of the variable:
sol = solve(ocp; grid_size=20, display=false)
println("estimated λ = ", variable(sol), " (true value: ", λ_true, ")")estimated λ = 0.4960778956661449 (true value: 0.5)The fitted state follows the data, up to the perturbation:
plt = plot(sol, :state; size=(800, 400), label="Direct")
tg = time_grid(sol)
plot!(
plt, tg, data.(tg);
subplot=1, line=:dot, lw=2, label="Data", color=:black,
)Example: harmonic oscillator
The same shape with a Mayer cost: minimise the pulsation
ocp = @def begin
ω ∈ R, variable # pulsation to minimise
t ∈ [0, 1], time
x = (q, v) ∈ R², state
q(0) == 1.0
v(0) == 0.0
q(1) == 0.0
ẋ(t) == [v(t), -ω^2 * q(t)]
ω^2 → min
endSolving it recovers
sol = solve(ocp; display=false)
println("ω = ", variable(sol), " (π/2 = ", π / 2, ")")ω = 1.570801494616592 (π/2 = 1.5707963267948966)See also
Formulation — the control-free case,
.Abstract syntax (
@def) — the control-free syntax.Functional API — the control-free functional-API form.
Parameter estimation without a control — both problems above, direct and indirect, in full.
From an OCP — building flows, including
Flow(ocp)for a control-free problem.