OptimalControl.jl
OptimalControl.jl is the core package of the control-toolbox ecosystem. Below, we group together the documentation of all the functions and types exported by OptimalControl.
Even if the following functions are prefixed by another package, such as CTFlows.Lift, they can all be used with OptimalControl. In fact, all functions prefixed with another package are simply reexported. For example, Lift is defined in CTFlows but accessible from OptimalControl.
julia> using OptimalControl
julia> F(x) = 2x
julia> H = Lift(F)
julia> x = 1
julia> p = 2
julia> H(x, p)
4Exported functions and types
OptimalControl.OptimalControl — Module
OptimalControlHigh-level interface for solving optimal control problems.
This package provides a unified, user-friendly API for defining and solving optimal control problems using various discretization methods, NLP modelers, and solvers. It orchestrates the complete workflow from problem definition to solution.
Main Features
- Flexible solve interface: Descriptive (symbolic) or explicit (typed components) modes
- Multiple discretization methods: Collocation and other schemes via CTDirect
- Multiple NLP modelers: ADNLP, ExaModels with CPU/GPU support
- Multiple solvers: Ipopt, MadNLP, MadNCL, Knitro with CPU/GPU support
- Automatic component completion: Partial specifications are completed intelligently
- Option routing: Strategy-specific options are routed to the appropriate components
Usage
using OptimalControl
# Define your optimal control problem
ocp = Model(...)
# ... problem definition ...
# Solve using descriptive mode (symbolic description)
sol = solve(ocp, :collocation, :adnlp, :ipopt)
# Or solve using explicit mode (typed components)
sol = solve(ocp;
discretizer=CTDirect.Collocation(),
modeler=CTSolvers.ADNLP(),
solver=CTSolvers.Ipopt()
)Exported Names
*CTBaseCTModelsExaModelsFlow@LieLieLiftPoissonboundary_constraints_dualboundary_constraints_nlbypasscomponentsconstraintconstraintsconstraints_violationcontrolcontrol_componentscontrol_constraints_boxcontrol_constraints_lb_dualcontrol_constraints_ub_dualcontrol_dimensioncontrol_namecostatecriterion@defdefinitiondescribedim_boundary_constraints_nldim_control_constraints_boxdim_path_constraints_nldim_state_constraints_boxdim_variable_constraints_boxdimensiondiscretizedualdynamicsexport_ocp_solutionfinal_timefinal_time_nameget_build_examodelhas_fixed_final_timehas_fixed_initial_timehas_free_final_timehas_free_initial_timehas_lagrange_costhas_mayer_costhas_optionidimport_ocp_solutionindexinfos@initinitial_timeinitial_time_nameis_autonomousis_computedis_defaultis_emptyis_empty_time_gridis_final_time_fixedis_final_time_freeis_initial_time_fixedis_initial_time_freeis_lagrange_cost_definedis_mayer_cost_definedis_useriterationslagrangemayermessagemetadatamethodsmodelnamenlp_modelobjectiveocp_modelocp_solutionoption_defaultoption_defaultsoption_descriptionoption_namesoption_sourceoption_typeoption_valueoptionspath_constraints_dualpath_constraints_nlplotplot!route_tosolvestatestate_componentsstate_constraints_boxstate_constraints_lb_dualstate_constraints_ub_dualstate_dimensionstate_namestatussuccesssuccessfultimetime_gridtime_nametimesvariablevariable_componentsvariable_constraints_boxvariable_constraints_lb_dualvariable_constraints_ub_dualvariable_dimensionvariable_name⋅
See Also
Documentation
Base.:* — Method
*(x, y...)Multiplication operator.
Infix x*y*z*... calls this function with all arguments, i.e. *(x, y, z, ...), which by default then calls (x*y) * z * ... starting from the left.
Juxtaposition such as 2pi also calls *(2, pi). Note that this operation has higher precedence than a literal *. Note also that juxtaposition "0x..." (integer zero times a variable whose name starts with x) is forbidden as it clashes with unsigned integer literals: 0x01 isa UInt8.
Note that overflow is possible for most integer types, including the default Int, when multiplying large numbers.
Examples
julia> 2 * 7 * 8
112
julia> *(2, 7, 8)
112
julia> [2 0; 0 3] * [1, 10] # matrix * vector
2-element Vector{Int64}:
2
30
julia> 1/2pi, 1/2*pi # juxtaposition has higher precedence
(0.15915494309189535, 1.5707963267948966)
julia> x = [1, 2]; x'x # adjoint vector * vector
5*(
F::CTFlowsODE.AbstractFlow,
g::Tuple{Real, TF<:CTFlowsODE.AbstractFlow}
) -> Any
Shorthand for concatenate(F, g) when g is a tuple (t_switch, G).
Arguments
F::AbstractFlow: The first flow.g::Tuple{ctNumber, AbstractFlow}: Tuple containing the switching time and second flow.
Returns
- A new flow that switches from
FtoGatt_switch.
Example
julia> F * (1.0, G)*(
F::CTFlowsODE.AbstractFlow,
g::Tuple{Real, Any, TF<:CTFlowsODE.AbstractFlow}
) -> Any
Shorthand for concatenate(F, g) when g is a tuple (t_switch, η_switch, G) including a jump.
Arguments
F::AbstractFlow: The first flow.g::Tuple{ctNumber, Any, AbstractFlow}: Tuple with switching time, jump value, and second flow.
Returns
- A flow with a jump at
t_switchand a switch fromFtoG.
Example
julia> F * (1.0, η, G)CTFlows.Flow — Function
Flow(
vf::CTFlows.VectorField;
alg,
abstol,
reltol,
saveat,
internalnorm,
kwargs_Flow...
) -> CTFlowsODE.VectorFieldFlow
Constructs a flow object for a classical (non-Hamiltonian) vector field.
This creates a VectorFieldFlow that integrates the ODE system dx/dt = vf(t, x, v) using DifferentialEquations.jl. It handles both fixed and parametric dynamics, as well as jump discontinuities and event stopping.
Keyword Arguments
alg,abstol,reltol,saveat,internalnorm: Solver options.kwargs_Flow...: Additional arguments passed to the solver configuration.
Example
julia> vf(t, x, v) = -v * x
julia> flow = CTFlows.Flow(CTFlows.VectorField(vf))
julia> x1 = flow(0.0, 1.0, 1.0)Flow(
h::CTFlows.AbstractHamiltonian;
alg,
abstol,
reltol,
saveat,
internalnorm,
kwargs_Flow...
) -> CTFlowsODE.HamiltonianFlow
Constructs a Hamiltonian flow from a scalar Hamiltonian.
This method builds a numerical integrator that simulates the evolution of a Hamiltonian system given a Hamiltonian function h(t, x, p, l) or h(x, p).
Internally, it computes the right-hand side of Hamilton’s equations via automatic differentiation and returns a HamiltonianFlow object.
Keyword Arguments
alg,abstol,reltol,saveat,internalnorm: solver options.kwargs_Flow...: forwarded to the solver.
Example
julia> H(x, p) = dot(p, p) + dot(x, x)
julia> flow = CTFlows.Flow(CTFlows.Hamiltonian(H))
julia> xf, pf = flow(0.0, x0, p0, 1.0)Flow(
hv::CTFlows.HamiltonianVectorField;
alg,
abstol,
reltol,
saveat,
internalnorm,
kwargs_Flow...
) -> CTFlowsODE.HamiltonianFlow
Constructs a Hamiltonian flow from a precomputed Hamiltonian vector field.
This method assumes you already provide the Hamiltonian vector field (dx/dt, dp/dt) instead of deriving it from a scalar Hamiltonian.
Returns a HamiltonianFlow object that integrates the given system.
Keyword Arguments
alg,abstol,reltol,saveat,internalnorm: solver options.kwargs_Flow...: forwarded to the solver.
Example
julia> hv(t, x, p, l) = (∇ₚH, -∇ₓH)
julia> flow = CTFlows.Flow(CTFlows.HamiltonianVectorField(hv))
julia> xf, pf = flow(0.0, x0, p0, 1.0, l)Flow(
ocp::CTModels.OCP.Model,
u::CTFlows.ControlLaw;
alg,
abstol,
reltol,
saveat,
internalnorm,
kwargs_Flow...
) -> Union{CTFlowsODE.OptimalControlFlow{CTFlows.Fixed}, CTFlowsODE.OptimalControlFlow{CTFlows.NonFixed}}
Construct a flow for an optimal control problem using a given control law.
This method builds the Hamiltonian system associated with the optimal control problem (ocp) and integrates the corresponding state–costate dynamics using the specified control law u.
Arguments
ocp::CTModels.Model: An optimal control problem defined usingCTModels.u::CTFlows.ControlLaw: A feedback control law generated byControlLaw(...)or similar.alg: Integration algorithm (default inferred).abstol: Absolute tolerance for the ODE solver.reltol: Relative tolerance for the ODE solver.saveat: Time points at which to save the solution.internalnorm: Optional norm function used by the integrator.kwargs_Flow: Additional keyword arguments passed to the solver.
Returns
A flow object f such that:
f(t0, x0, p0, tf)integrates the state and costate fromt0totf.f((t0, tf), x0, p0)returns the full trajectory over the interval.
Example
julia> u = (x, p) -> p
julia> f = Flow(ocp, ControlLaw(u))Flow(
ocp::CTModels.OCP.Model,
u::Function;
autonomous,
variable,
alg,
abstol,
reltol,
saveat,
internalnorm,
kwargs_Flow...
) -> Union{CTFlowsODE.OptimalControlFlow{CTFlows.Fixed}, CTFlowsODE.OptimalControlFlow{CTFlows.NonFixed}}
Construct a flow for an optimal control problem using a control function in feedback form.
This method constructs the Hamiltonian and integrates the associated state–costate dynamics using a raw function u. It automatically wraps u as a control law.
Arguments
ocp::CTModels.Model: The optimal control problem.u::Function: A feedback control function:- If
ocpis autonomous:u(x, p) - If non-autonomous:
u(t, x, p)
- If
autonomous::Bool: Whether the control law depends on time.variable::Bool: Whether the OCP involves variable time (e.g., free final time).alg,abstol,reltol,saveat,internalnorm: ODE solver parameters.kwargs_Flow: Additional options.
Returns
A Flow object compatible with function call interfaces for state propagation.
Example
julia> u = (t, x, p) -> t + p
julia> f = Flow(ocp, u)Flow(
ocp::CTModels.OCP.Model,
u::Union{CTFlows.ControlLaw{<:Function, T, V}, CTFlows.FeedbackControl{<:Function, T, V}},
g::Union{CTFlows.MixedConstraint{<:Function, T, V}, CTFlows.StateConstraint{<:Function, T, V}},
μ::CTFlows.Multiplier{<:Function, T, V};
alg,
abstol,
reltol,
saveat,
internalnorm,
kwargs_Flow...
) -> Union{CTFlowsODE.OptimalControlFlow{CTFlows.Fixed}, CTFlowsODE.OptimalControlFlow{CTFlows.NonFixed}}
Construct a flow for an optimal control problem with control and constraint multipliers in feedback form.
This variant constructs a Hamiltonian system incorporating both the control law and a multiplier law (e.g., for enforcing state or mixed constraints). All inputs must be consistent in time dependence.
Arguments
ocp::CTModels.Model: The optimal control problem.u::ControlLaw or FeedbackControl: Feedback control.g::StateConstraint or MixedConstraint: Constraint function.μ::Multiplier: Multiplier function.alg,abstol,reltol,saveat,internalnorm: Solver settings.kwargs_Flow: Additional options.
Returns
A Flow object that integrates the constrained Hamiltonian dynamics.
Example
julia> f = Flow(ocp, (x, p) -> p[1], (x, u) -> x[1] - 1, (x, p) -> x[1]+p[1])For non-autonomous cases:
julia> f = Flow(ocp, (t, x, p) -> t + p, (t, x, u) -> x - 1, (t, x, p) -> x+p)Flow(
ocp::CTModels.OCP.Model,
u::Function,
g::Function,
μ::Function;
autonomous,
variable,
alg,
abstol,
reltol,
saveat,
internalnorm,
kwargs_Flow...
) -> Union{CTFlowsODE.OptimalControlFlow{CTFlows.Fixed}, CTFlowsODE.OptimalControlFlow{CTFlows.NonFixed}}
Construct a flow from a raw feedback control, constraint, and multiplier.
This version is for defining flows directly from user functions without wrapping them into ControlLaw, Constraint, or Multiplier types. Automatically wraps and adapts them based on time dependence.
Arguments
ocp::CTModels.Model: The optimal control problem.u::Function: Control law.g::Function: Constraint.μ::Function: Multiplier.autonomous::Bool: Whether the system is autonomous.variable::Bool: Whether time is a free variable.alg,abstol,reltol,saveat,internalnorm: Solver parameters.kwargs_Flow: Additional options.
Returns
A Flow object ready for trajectory integration.
Flow(
dyn::Function;
autonomous,
variable,
alg,
abstol,
reltol,
saveat,
internalnorm,
kwargs_Flow...
) -> CTFlowsODE.ODEFlow
Constructs a Flow from a user-defined dynamical system given as a Julia function.
This high-level interface handles:
- autonomous and non-autonomous systems,
- presence or absence of additional variables (
v), - selection of ODE solvers and tolerances,
- and integrates with the CTFlows event system (e.g., jumps, callbacks).
Arguments
dyn: A function defining the vector field. Its signature must match the values ofautonomousandvariable.autonomous: Whether the dynamics are time-independent (falseby default).variable: Whether the dynamics depend on a control or parameterv.alg,abstol,reltol,saveat,internalnorm: Solver settings passed toOrdinaryDiffEq.solve.kwargs_Flow: Additional keyword arguments passed to the solver.
Returns
An ODEFlow object, wrapping both the full solver and its right-hand side (RHS).
Supported Function Signatures for dyn
Depending on the (autonomous, variable) flags:
(false, false):dyn(x)(false, true):dyn(x, v)(true, false):dyn(t, x)(true, true):dyn(t, x, v)
Example
julia> dyn(t, x, v) = [-x[1] + v[1] * sin(t)]
julia> flow = CTFlows.Flow(dyn; autonomous=true, variable=true)
julia> xT = flow((0.0, 1.0), [1.0], [0.1])CTFlows.@Lie — Macro
Compute Lie or Poisson brackets.
This macro provides a unified notation to define recursively nested Lie brackets (for vector fields) or Poisson brackets (for Hamiltonians).
Syntax
@Lie [F, G]: computes the Lie bracket[F, G]of two vector fields.@Lie [[F, G], H]: supports arbitrarily nested Lie brackets.@Lie {H, K}: computes the Poisson bracket{H, K}of two Hamiltonians.@Lie {{H, K}, L}: supports arbitrarily nested Poisson brackets.@Lie expr autonomous = false: specifies a non-autonomous system.@Lie expr variable = true: indicates presence of an auxiliary variablev.
Keyword-like arguments can be provided to control the evaluation context for Poisson brackets with raw functions:
autonomous = Bool: whether the system is time-independent (default:true).variable = Bool: whether the system depends on an extra variablev(default:false).
Bracket type detection
- Square brackets
[...]denote Lie brackets betweenVectorFieldobjects. - Curly brackets
{...}denote Poisson brackets betweenHamiltonianobjects or between raw functions. - The macro automatically dispatches to
LieorPoissondepending on the input pattern.
Return
A callable object representing the specified Lie or Poisson bracket expression. The returned function can be evaluated like any other vector field or Hamiltonian.
Examples
■ Lie brackets with VectorField (autonomous)
julia> F1 = VectorField(x -> [0, -x[3], x[2]])
julia> F2 = VectorField(x -> [x[3], 0, -x[1]])
julia> L = @Lie [F1, F2]
julia> L([1.0, 2.0, 3.0])
3-element Vector{Float64}:
2.0
-1.0
0.0■ Lie brackets with VectorField (non-autonomous, with auxiliary variable)
julia> F1 = VectorField((t, x, v) -> [0, -x[3], x[2]]; autonomous=false, variable=true)
julia> F2 = VectorField((t, x, v) -> [x[3], 0, -x[1]]; autonomous=false, variable=true)
julia> L = @Lie [F1, F2]
julia> L(0.0, [1.0, 2.0, 3.0], 1.0)
3-element Vector{Float64}:
2.0
-1.0
0.0■ Poisson brackets with Hamiltonian (autonomous)
julia> H1 = Hamiltonian((x, p) -> x[1]^2 + p[2]^2)
julia> H2 = Hamiltonian((x, p) -> x[2]^2 + p[1]^2)
julia> P = @Lie {H1, H2}
julia> P([1.0, 1.0], [3.0, 2.0])
-4.0■ Poisson brackets with Hamiltonian (non-autonomous, with variable)
julia> H1 = Hamiltonian((t, x, p, v) -> x[1]^2 + p[2]^2 + v; autonomous=false, variable=true)
julia> H2 = Hamiltonian((t, x, p, v) -> x[2]^2 + p[1]^2 + v; autonomous=false, variable=true)
julia> P = @Lie {H1, H2}
julia> P(1.0, [1.0, 3.0], [4.0, 2.0], 3.0)
8.0■ Poisson brackets from raw functions
julia> H1 = (x, p) -> x[1]^2 + p[2]^2
julia> H2 = (x, p) -> x[2]^2 + p[1]^2
julia> P = @Lie {H1, H2}
julia> P([1.0, 1.0], [3.0, 2.0])
-4.0■ Poisson bracket with non-autonomous raw functions
julia> H1 = (t, x, p) -> x[1]^2 + p[2]^2 + t
julia> H2 = (t, x, p) -> x[2]^2 + p[1]^2 + t
julia> P = @Lie {H1, H2} autonomous = false
julia> P(3.0, [1.0, 2.0], [4.0, 1.0])
-8.0■ Nested brackets
julia> F = VectorField(x -> [-x[1], x[2], x[3]])
julia> G = VectorField(x -> [x[3], -x[2], 0])
julia> H = VectorField(x -> [0, 0, -x[1]])
julia> nested = @Lie [[F, G], H]
julia> nested([1.0, 2.0, 3.0])
3-element Vector{Float64}:
2.0
0.0
-6.0julia> H1 = (x, p) -> x[2]*x[1]^2 + p[1]^2
julia> H2 = (x, p) -> x[1]*p[2]^2
julia> H3 = (x, p) -> x[1]*p[2] + x[2]*p[1]
julia> nested_poisson = @Lie {{H1, H2}, H3}
julia> nested_poisson([1.0, 2.0], [0.5, 1.0])
14.0■ Mixed expressions with arithmetic
julia> F1 = VectorField(x -> [0, -x[3], x[2]])
julia> F2 = VectorField(x -> [x[3], 0, -x[1]])
julia> x = [1.0, 2.0, 3.0]
julia> @Lie [F1, F2](x) + 3 * [F1, F2](x)
3-element Vector{Float64}:
8.0
-4.0
0.0julia> H1 = (x, p) -> x[1]^2
julia> H2 = (x, p) -> p[1]^2
julia> H3 = (x, p) -> x[1]*p[1]
julia> x = [1.0, 2.0, 3.0]
julia> p = [3.0, 2.0, 1.0]
julia> @Lie {H1, H2}(x, p) + 2 * {H2, H3}(x, p)
24.0CTFlows.Lie — Function
Lie derivative of a scalar function along a vector field.
Example:
julia> φ = x -> [x[2], -x[1]]
julia> X = VectorField(φ)
julia> f = x -> x[1]^2 + x[2]^2
julia> Lie(X,f)([1, 2])
0
julia> φ = (t, x, v) -> [t + x[2] + v[1], -x[1] + v[2]]
julia> X = VectorField(φ, NonAutonomous, NonFixed)
julia> f = (t, x, v) -> t + x[1]^2 + x[2]^2
julia> Lie(X, f)(1, [1, 2], [2, 1])
10Lie derivative of a scalar function along a function with specified dependencies.
Example:
julia> φ = x -> [x[2], -x[1]]
julia> f = x -> x[1]^2 + x[2]^2
julia> Lie(φ,f)([1, 2])
0
julia> φ = (t, x, v) -> [t + x[2] + v[1], -x[1] + v[2]]
julia> f = (t, x, v) -> t + x[1]^2 + x[2]^2
julia> Lie(φ, f, autonomous=false, variable=true)(1, [1, 2], [2, 1])
10Lie bracket of two vector fields in the autonomous case.
Example:
julia> f = x -> [x[2], 2x[1]]
julia> g = x -> [3x[2], -x[1]]
julia> X = VectorField(f)
julia> Y = VectorField(g)
julia> Lie(X, Y)([1, 2])
[7, -14]Lie bracket of two vector fields in the nonautonomous case.
Example:
julia> f = (t, x, v) -> [t + x[2] + v, -2x[1] - v]
julia> g = (t, x, v) -> [t + 3x[2] + v, -x[1] - v]
julia> X = VectorField(f, NonAutonomous, NonFixed)
julia> Y = VectorField(g, NonAutonomous, NonFixed)
julia> Lie(X, Y)(1, [1, 2], 1)
[-7, 12]CTFlows.Lift — Function
Lift(
X::CTFlows.VectorField
) -> CTFlows.HamiltonianLift{CTFlows.VectorField{TF, TD, VD}} where {TF<:Function, TD<:CTFlows.TimeDependence, VD<:CTFlows.VariableDependence}
Construct the Hamiltonian lift of a VectorField.
Arguments
X::VectorField: The vector field to lift. Its signature determines if it is autonomous and/or variable.
Returns
- A
HamiltonianLiftcallable object representing the Hamiltonian lift ofX.
Examples
julia> HL = Lift(VectorField(x -> [x[1]^2, x[2]^2], autonomous=true, variable=false))
julia> HL([1, 0], [0, 1]) # returns 0
julia> HL2 = Lift(VectorField((t, x, v) -> [t + x[1]^2, x[2]^2 + v], autonomous=false, variable=true))
julia> HL2(1, [1, 0], [0, 1], 1) # returns 1
julia> H = Lift(x -> 2x)
julia> H(1, 1) # returns 2
julia> H2 = Lift((t, x, v) -> 2x + t - v, autonomous=false, variable=true)
julia> H2(1, 1, 1, 1) # returns 2
# Alternative syntax using symbols for autonomy and variability
julia> H3 = Lift((t, x, v) -> 2x + t - v, NonAutonomous, NonFixed)
julia> H3(1, 1, 1, 1) # returns 2Lift(
X::Function;
autonomous,
variable
) -> CTFlows.var"#21#22"{<:Function}
Construct the Hamiltonian lift of a function.
Arguments
X::Function: The function representing the vector field.autonomous::Bool=true: Whether the function is autonomous (time-independent).variable::Bool=false: Whether the function depends on an additional variable argument.
Returns
- A callable function computing the Hamiltonian lift,
(and variants depending on autonomous and variable).
Details
Depending on the autonomous and variable flags, the returned function has one of the following call signatures:
(x, p)ifautonomous=trueandvariable=false(x, p, v)ifautonomous=trueandvariable=true(t, x, p)ifautonomous=falseandvariable=false(t, x, p, v)ifautonomous=falseandvariable=true
Examples
julia> H = Lift(x -> 2x)
julia> H(1, 1) # returns 2
julia> H2 = Lift((t, x, v) -> 2x + t - v, autonomous=false, variable=true)
julia> H2(1, 1, 1, 1) # returns 2CTFlows.Poisson — Function
Poisson(
f::CTFlows.AbstractHamiltonian{CTFlows.Autonomous, V<:CTFlows.VariableDependence},
g::CTFlows.AbstractHamiltonian{CTFlows.Autonomous, V<:CTFlows.VariableDependence}
) -> Any
Poisson bracket of two Hamiltonian functions (subtype of AbstractHamiltonian). Autonomous case.
Returns a Hamiltonian representing the Poisson bracket {f, g} of two autonomous Hamiltonian functions f and g.
Example
julia> f = (x, p) -> x[2]^2 + 2x[1]^2 + p[1]^2
julia> g = (x, p) -> 3x[2]^2 - x[1]^2 + p[2]^2 + p[1]
julia> F = Hamiltonian(f)
julia> G = Hamiltonian(g)
julia> Poisson(f, g)([1, 2], [2, 1]) # -20
julia> Poisson(f, G)([1, 2], [2, 1]) # -20
julia> Poisson(F, g)([1, 2], [2, 1]) # -20Poisson(
f::CTFlows.AbstractHamiltonian{CTFlows.NonAutonomous, V<:CTFlows.VariableDependence},
g::CTFlows.AbstractHamiltonian{CTFlows.NonAutonomous, V<:CTFlows.VariableDependence}
) -> Any
Poisson bracket of two Hamiltonian functions. Non-autonomous case.
Returns a Hamiltonian representing {f, g} where f and g are time-dependent.
Example
julia> f = (t, x, p, v) -> t*v[1]*x[2]^2 + 2x[1]^2 + p[1]^2 + v[2]
julia> g = (t, x, p, v) -> 3x[2]^2 - x[1]^2 + p[2]^2 + p[1] + t - v[2]
julia> F = Hamiltonian(f, autonomous=false, variable=true)
julia> G = Hamiltonian(g, autonomous=false, variable=true)
julia> Poisson(F, G)(2, [1, 2], [2, 1], [4, 4]) # -76
julia> Poisson(f, g, NonAutonomous, NonFixed)(2, [1, 2], [2, 1], [4, 4]) # -76Poisson(
f::CTFlows.HamiltonianLift{T<:CTFlows.TimeDependence, V<:CTFlows.VariableDependence},
g::CTFlows.HamiltonianLift{T<:CTFlows.TimeDependence, V<:CTFlows.VariableDependence}
)
Poisson bracket of two HamiltonianLift vector fields.
Returns the HamiltonianLift corresponding to the Lie bracket of vector fields f.X and g.X.
Example
julia> f = x -> [x[1]^2 + x[2]^2, 2x[1]^2]
julia> g = x -> [3x[2]^2, x[2] - x[1]^2]
julia> F = Lift(f)
julia> G = Lift(g)
julia> Poisson(F, G)([1, 2], [2, 1]) # -64
julia> f = (t, x, v) -> [t*v[1]*x[2]^2, 2x[1]^2 + v[2]]
julia> g = (t, x, v) -> [3x[2]^2 - x[1]^2, t - v[2]]
julia> F = Lift(f, NonAutonomous, NonFixed)
julia> G = Lift(g, NonAutonomous, NonFixed)
julia> Poisson(F, G)(2, [1, 2], [2, 1], [4, 4]) # 100Poisson(
f::Function,
g::Function;
autonomous,
variable
) -> CTFlows.Hamiltonian
Poisson bracket of two functions. The time and variable dependence are specified with keyword arguments.
Returns a Hamiltonian computed from the functions promoted as Hamiltonians.
Example
julia> f = (x, p) -> x[2]^2 + 2x[1]^2 + p[1]^2
julia> g = (x, p) -> 3x[2]^2 - x[1]^2 + p[2]^2 + p[1]
julia> Poisson(f, g)([1, 2], [2, 1]) # -20
julia> f = (t, x, p, v) -> t*v[1]*x[2]^2 + 2x[1]^2 + p[1]^2 + v[2]
julia> g = (t, x, p, v) -> 3x[2]^2 - x[1]^2 + p[2]^2 + p[1] + t - v[2]
julia> Poisson(f, g, autonomous=false, variable=true)(2, [1, 2], [2, 1], [4, 4]) # -76Poisson(
f::Function,
g::CTFlows.AbstractHamiltonian{TD<:CTFlows.TimeDependence, VD<:CTFlows.VariableDependence}
) -> CTFlows.Hamiltonian
Poisson bracket of a function and a Hamiltonian.
Returns a Hamiltonian representing {f, g} where g is already a Hamiltonian.
Example
julia> f = (x, p) -> x[2]^2 + 2x[1]^2 + p[1]^2
julia> g = (x, p) -> 3x[2]^2 - x[1]^2 + p[2]^2 + p[1]
julia> G = Hamiltonian(g)
julia> Poisson(f, G)([1, 2], [2, 1]) # -20
julia> f = (t, x, p, v) -> t*v[1]*x[2]^2 + 2x[1]^2 + p[1]^2 + v[2]
julia> g = (t, x, p, v) -> 3x[2]^2 - x[1]^2 + p[2]^2 + p[1] + t - v[2]
julia> G = Hamiltonian(g, autonomous=false, variable=true)
julia> Poisson(f, G)(2, [1, 2], [2, 1], [4, 4]) # -76Poisson(
f::CTFlows.AbstractHamiltonian{TD<:CTFlows.TimeDependence, VD<:CTFlows.VariableDependence},
g::Function
) -> CTFlows.Hamiltonian
Poisson bracket of a Hamiltonian and a function.
Returns a Hamiltonian representing {f, g} where f is already a Hamiltonian.
Example
julia> f = (x, p) -> x[2]^2 + 2x[1]^2 + p[1]^2
julia> g = (x, p) -> 3x[2]^2 - x[1]^2 + p[2]^2 + p[1]
julia> F = Hamiltonian(f)
julia> Poisson(F, g)([1, 2], [2, 1]) # -20
julia> f = (t, x, p, v) -> t*v[1]*x[2]^2 + 2x[1]^2 + p[1]^2 + v[2]
julia> g = (t, x, p, v) -> 3x[2]^2 - x[1]^2 + p[2]^2 + p[1] + t - v[2]
julia> F = Hamiltonian(f, autonomous=false, variable=true)
julia> Poisson(F, g)(2, [1, 2], [2, 1], [4, 4]) # -76CTModels.OCP.boundary_constraints_dual — Function
boundary_constraints_dual(
model::CTModels.OCP.DualModel{<:Union{Nothing, Function}, BC_Dual<:Union{Nothing, AbstractVector{<:Real}}}
) -> Union{Nothing, AbstractVector{<:Real}}
Return the dual vector associated with the boundary constraints.
Arguments
model::DualModel: A model including dual variables for boundary constraints.
Returns
A vector of dual values, or nothing if not set.
boundary_constraints_dual(
sol::CTModels.OCP.Solution
) -> Union{Nothing, AbstractVector{<:Real}}
Return the dual of the boundary constraints.
CTModels.OCP.boundary_constraints_nl — Function
boundary_constraints_nl(
model::CTModels.OCP.ConstraintsModel{<:Tuple, TB}
) -> Any
Get the nonlinear boundary constraints from the model.
Arguments
model: The constraints model from which to retrieve the boundary constraints.
Returns
- The nonlinear boundary constraints.
Example
# Example of retrieving nonlinear boundary constraints
julia> model = ConstraintsModel(...)
julia> boundary_constraints = boundary_constraints_nl(model)boundary_constraints_nl(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.TimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.AbstractControlModel, <:CTModels.OCP.AbstractVariableModel, <:Function, <:CTModels.OCP.AbstractObjectiveModel, <:CTModels.OCP.ConstraintsModel{<:Tuple, TB<:Tuple}}
) -> Any
Return the nonlinear boundary constraints.
CTSolvers.Strategies.bypass — Function
bypass(val) -> CTSolvers.Strategies.BypassValue
Mark an option value to bypass validation.
This function creates a BypassValue wrapper around the provided value. When passed to a strategy constructor, this value will be accepted even if the option name is unknown (not in metadata) or if validation would otherwise fail.
This can be combined with route_to to bypass validation for specific strategies when routing ambiguous options.
Arguments
val: The option value to wrap
Returns
BypassValue: The wrapped value
Example
julia> using CTSolvers.Strategies
julia> # Pass an unknown option directly to strategy
julia> solver = Ipopt(
max_iter=100,
custom_backend_option=bypass(42) # Bypasses validation
)
Ipopt(options=StrategyOptions{...})
julia> # Alternative syntax using force alias
julia> solver = Ipopt(
max_iter=100,
custom_backend_option=force(42) # Same as bypass(42)
)
Ipopt(options=StrategyOptions{...})
julia> # Combine with routing for ambiguous options
julia> solve(ocp, method;
backend = route_to(ipopt=bypass(42)) # Route to ipopt AND bypass validation
)Notes
- Use with caution! Bypassed options are passed directly to the backend.
- Typos in option names will not be caught by validation.
- Invalid values for the backend will cause backend-level errors.
- Can be combined with
route_tofor strategy-specific bypassing forceis an alias forbypass- they are identical functions
See also: BypassValue, route_to, force
CTModels.OCP.components — Function
components(model::CTModels.OCP.StateModel) -> Vector{String}
Get the components names of the state from the state model.
components(
model::CTModels.OCP.StateModelSolution
) -> Vector{String}
Get the components names of the state from the state model solution.
components(
model::CTModels.OCP.ControlModel
) -> Vector{String}
Get the names of the control components.
Arguments
model::ControlModel: The control model.
Returns
Vector{String}: A list of control component names.
Example
julia> components(controlmodel)
["u₁", "u₂"]components(
model::CTModels.OCP.ControlModelSolution
) -> Vector{String}
Get the names of the control components from the solution.
Arguments
model::ControlModelSolution: The control model solution.
Returns
Vector{String}: A list of control component names.
components(
_::CTModels.OCP.EmptyControlModel
) -> Vector{String}
Return an empty vector since there are no control components defined.
components(
model::CTModels.OCP.VariableModel
) -> Vector{String}
Return the names of the components of the variable.
components(
model::CTModels.OCP.VariableModelSolution
) -> Vector{String}
Return the names of the components from the variable solution.
components(
_::CTModels.OCP.EmptyVariableModel
) -> Vector{String}
Return an empty vector since there are no variable components defined.
CTModels.OCP.constraints — Function
constraints(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.AbstractTimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.AbstractControlModel, <:CTModels.OCP.AbstractVariableModel, <:Function, <:CTModels.OCP.AbstractObjectiveModel, C<:CTModels.OCP.AbstractConstraintsModel}
) -> CTModels.OCP.AbstractConstraintsModel
Return the constraints struct.
CTModels.OCP.constraints_violation — Function
constraints_violation(sol::CTModels.OCP.Solution) -> Float64
Return the constraints violation.
CTModels.OCP.control — Function
control(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.TimesModel, <:CTModels.OCP.AbstractStateModel, T<:CTModels.OCP.AbstractControlModel}
) -> CTModels.OCP.AbstractControlModel
Return the control struct.
control(
sol::CTModels.OCP.Solution{<:CTModels.OCP.AbstractTimeGridModel, <:CTModels.OCP.AbstractTimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.ControlModelSolution{TS<:Function}}
) -> Function
Return the control as a function of time.
julia> u = control(sol)
julia> t0 = time_grid(sol)[1]
julia> u0 = u(t0) # control at the initial timecontrol(init::CTModels.Init.AbstractInitialGuess) -> Any
Return the control trajectory from an initial guess.
control(sol::CTModels.OCP.AbstractSolution) -> Function
Return the control trajectory from a solution.
CTModels.OCP.control_components — Function
control_components(
ocp::CTModels.OCP.Model
) -> Vector{String}
Return the names of the components of the control.
control_components(
sol::CTModels.OCP.Solution
) -> Vector{String}
Return the names of the components of the control.
CTModels.OCP.control_constraints_box — Function
control_constraints_box(
model::CTModels.OCP.ConstraintsModel{<:Tuple, <:Tuple, <:Tuple, TC}
) -> Any
Get the control box constraints from the model.
Arguments
model: The constraints model from which to retrieve the control box constraints.
Returns
- The control box constraints.
Example
# Example of retrieving control box constraints
julia> model = ConstraintsModel(...)
julia> control_constraints = control_constraints_box(model)control_constraints_box(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.TimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.AbstractControlModel, <:CTModels.OCP.AbstractVariableModel, <:Function, <:CTModels.OCP.AbstractObjectiveModel, <:CTModels.OCP.ConstraintsModel{<:Tuple, <:Tuple, <:Tuple, TC<:Tuple}}
) -> Any
Return the box constraints on control.
CTModels.OCP.control_constraints_lb_dual — Function
control_constraints_lb_dual(
model::CTModels.OCP.DualModel{<:Union{Nothing, Function}, <:Union{Nothing, AbstractVector{<:Real}}, <:Union{Nothing, Function}, <:Union{Nothing, Function}, CC_LB_Dual<:Union{Nothing, Function}}
) -> Union{Nothing, Function}
Return the dual function associated with the lower bounds of control constraints.
Arguments
model::DualModel: A model including dual variables for control lower bounds.
Returns
A function mapping time t to a vector of dual values, or nothing if not set.
control_constraints_lb_dual(
sol::CTModels.OCP.Solution
) -> Union{Nothing, Function}
Return the lower bound dual of the control constraints.
CTModels.OCP.control_constraints_ub_dual — Function
control_constraints_ub_dual(
model::CTModels.OCP.DualModel{<:Union{Nothing, Function}, <:Union{Nothing, AbstractVector{<:Real}}, <:Union{Nothing, Function}, <:Union{Nothing, Function}, <:Union{Nothing, Function}, CC_UB_Dual<:Union{Nothing, Function}}
) -> Union{Nothing, Function}
Return the dual function associated with the upper bounds of control constraints.
Arguments
model::DualModel: A model including dual variables for control upper bounds.
Returns
A function mapping time t to a vector of dual values, or nothing if not set.
control_constraints_ub_dual(
sol::CTModels.OCP.Solution
) -> Union{Nothing, Function}
Return the upper bound dual of the control constraints.
CTModels.OCP.control_dimension — Function
control_dimension(ocp::CTModels.OCP.Model) -> Int64
Return the control dimension.
control_dimension(sol::CTModels.OCP.Solution) -> Int64
Return the dimension of the control.
CTModels.OCP.control_name — Function
control_name(ocp::CTModels.OCP.Model) -> String
Return the name of the control.
control_name(sol::CTModels.OCP.Solution) -> String
Return the name of the control.
CTModels.OCP.costate — Function
costate(
sol::CTModels.OCP.Solution{<:CTModels.OCP.AbstractTimeGridModel, <:CTModels.OCP.AbstractTimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.AbstractControlModel, <:CTModels.OCP.AbstractVariableModel, <:CTModels.OCP.AbstractModel, Co<:Function}
) -> Function
Return the costate as a function of time.
julia> p = costate(sol)
julia> t0 = time_grid(sol)[1]
julia> p0 = p(t0) # costate at the initial timeCTModels.OCP.criterion — Function
criterion(model::CTModels.OCP.MayerObjectiveModel) -> Symbol
Return the criterion (:min or :max).
criterion(
model::CTModels.OCP.LagrangeObjectiveModel
) -> Symbol
Return the criterion (:min or :max).
criterion(model::CTModels.OCP.BolzaObjectiveModel) -> Symbol
Return the criterion (:min or :max).
criterion(ocp::CTModels.OCP.Model) -> Symbol
Return the type of criterion (:min or :max).
CTParser.@def — Macro
Define an optimal control problem. One pass parsing of the definition. Can be used writing either ocp = @def begin ... end or @def ocp begin ... end. In the second case, setting log to true will display the parsing steps.
Example
ocp = @def begin
tf ∈ R, variable
t ∈ [ 0, tf ], time
x ∈ R², state
u ∈ R, control
tf ≥ 0
-1 ≤ u(t) ≤ 1
q = x₁
v = x₂
q(0) == 1
v(0) == 2
q(tf) == 0
v(tf) == 0
0 ≤ q(t) ≤ 5, (1)
-2 ≤ v(t) ≤ 3, (2)
ẋ(t) == [ v(t), u(t) ]
tf → min
end
@def ocp begin
tf ∈ R, variable
t ∈ [ 0, tf ], time
x ∈ R², state
u ∈ R, control
tf ≥ 0
-1 ≤ u(t) ≤ 1
q = x₁
v = x₂
q(0) == 1
v(0) == 2
q(tf) == 0
v(tf) == 0
0 ≤ q(t) ≤ 5, (1)
-2 ≤ v(t) ≤ 3, (2)
ẋ(t) == [ v(t), u(t) ]
tf → min
end true # final boolean to show parsing logCTModels.OCP.definition — Function
definition(ocp::CTModels.OCP.Model) -> Expr
Return the model definition of the optimal control problem.
Arguments
ocp::Model: The built optimal control problem model.
Returns
Expr: The symbolic expression defining the problem.
definition(
ocp::CTModels.OCP.PreModel
) -> Union{Nothing, Expr}
Return the model definition of the optimal control problem or nothing.
Arguments
ocp::PreModel: The pre-model (may not have a definition set).
Returns
Union{Expr, Nothing}: The symbolic expression ornothingif not set.
CTSolvers.Strategies.describe — Function
Display detailed information about a strategy type, including its id, supertype, and full metadata with all available option definitions.
This function is useful for discovering what options a strategy accepts before constructing an instance.
Arguments
strategy_type::Type{<:AbstractStrategy}: The strategy type to describe
Example
julia> describe(Modelers.ADNLP)
Modelers.ADNLP (strategy type)
├─ id: :adnlp
├─ supertype: AbstractNLPModeler
└─ metadata: 4 options defined
├─ show_time :: Bool (default: false)
│ description: Whether to show timing information
├─ backend :: Symbol (default: optimized)
│ description: AD backend used by ADNLPModels
└─ matrix_free :: Bool (default: false)
description: Enable matrix-free modeSee also: metadata, id, options
CTModels.OCP.dim_boundary_constraints_nl — Function
dim_boundary_constraints_nl(
model::CTModels.OCP.ConstraintsModel
) -> Int64
Return the dimension of nonlinear boundary constraints.
Arguments
model: The constraints model from which to retrieve the dimension of boundary constraints.
Returns
Dimension: The dimension of the nonlinear boundary constraints.
Example
# Example of getting the dimension of nonlinear boundary constraints
julia> model = ConstraintsModel(...)
julia> dim_boundary = dim_boundary_constraints_nl(model)dim_boundary_constraints_nl(
ocp::CTModels.OCP.Model
) -> Int64
Return the dimension of the boundary constraints.
dim_boundary_constraints_nl(
sol::CTModels.OCP.Solution
) -> Int64
Return the dimension of the boundary constraints.
CTModels.OCP.dim_control_constraints_box — Function
dim_control_constraints_box(
model::CTModels.OCP.ConstraintsModel
) -> Int64
Return the dimension of control box constraints.
Arguments
model: The constraints model from which to retrieve the dimension of control box constraints.
Returns
Dimension: The dimension of the control box constraints.
Example
julia> # Example of getting the dimension of control box constraints
julia> model = ConstraintsModel(...)
julia> dim_control = dim_control_constraints_box(model)dim_control_constraints_box(
ocp::CTModels.OCP.Model
) -> Int64
Return the dimension of box constraints on control.
dim_control_constraints_box(
sol::CTModels.OCP.Solution
) -> Int64
Return the dimension of box constraints on control.
CTModels.OCP.dim_path_constraints_nl — Function
dim_path_constraints_nl(
model::CTModels.OCP.ConstraintsModel
) -> Int64
Return the dimension of nonlinear path constraints.
Arguments
model: The constraints model from which to retrieve the dimension of path constraints.
Returns
Dimension: The dimension of the nonlinear path constraints.
Example
# Example of getting the dimension of nonlinear path constraints
julia> model = ConstraintsModel(...)
julia> dim_path = dim_path_constraints_nl(model)dim_path_constraints_nl(ocp::CTModels.OCP.Model) -> Int64
Return the dimension of nonlinear path constraints.
dim_path_constraints_nl(sol::CTModels.OCP.Solution) -> Int64
Return the dimension of the path constraints.
CTModels.OCP.dim_state_constraints_box — Function
dim_state_constraints_box(
model::CTModels.OCP.ConstraintsModel
) -> Int64
Return the dimension of state box constraints.
Arguments
model: The constraints model from which to retrieve the dimension of state box constraints.
Returns
Dimension: The dimension of the state box constraints.
Example
julia> # Example of getting the dimension of state box constraints
julia> model = ConstraintsModel(...)
julia> dim_state = dim_state_constraints_box(model)dim_state_constraints_box(ocp::CTModels.OCP.Model) -> Int64
Return the dimension of box constraints on state.
dim_state_constraints_box(
sol::CTModels.OCP.Solution
) -> Int64
Return the dimension of box constraints on state.
CTModels.OCP.dim_variable_constraints_box — Function
dim_variable_constraints_box(
model::CTModels.OCP.ConstraintsModel
) -> Int64
Return the dimension of variable box constraints.
Arguments
model: The constraints model from which to retrieve the dimension of variable box constraints.
Returns
Dimension: The dimension of the variable box constraints.
Example
julia> # Example of getting the dimension of variable box constraints
julia> model = ConstraintsModel(...)
julia> dim_variable = dim_variable_constraints_box(model)dim_variable_constraints_box(
ocp::CTModels.OCP.Model
) -> Int64
Return the dimension of box constraints on variable.
dim_variable_constraints_box(
sol::CTModels.OCP.Solution
) -> Int64
Return the dimension of the variable box constraints.
CTModels.OCP.dimension — Function
dimension(model::CTModels.OCP.StateModel) -> Int64
Get the dimension of the state from the state model.
dimension(model::CTModels.OCP.StateModelSolution) -> Int64
Get the dimension of the state from the state model solution.
dimension(model::CTModels.OCP.ControlModel) -> Int64
Get the control input dimension.
Arguments
model::ControlModel: The control model.
Returns
Dimension: The number of control components.
dimension(model::CTModels.OCP.ControlModelSolution) -> Int64
Get the control input dimension from the solution.
Arguments
model::ControlModelSolution: The control model solution.
Returns
Dimension: The number of control components.
dimension(_::CTModels.OCP.EmptyControlModel) -> Int64
Return 0 since no control is defined.
dimension(model::CTModels.OCP.VariableModel) -> Int64
Return the dimension (number of components) of the variable.
dimension(
model::CTModels.OCP.VariableModelSolution
) -> Int64
Return the number of components in the variable solution.
dimension(_::CTModels.OCP.EmptyVariableModel) -> Int64
Return 0 since no variable is defined.
CTModels.OCP.dual — Function
dual(
sol::CTModels.OCP.Solution,
model::CTModels.OCP.Model,
label::Symbol
) -> Any
Return the dual variable associated with a constraint identified by its label.
Searches through all constraint types (path, boundary, state, control, and variable constraints) defined in the model and returns the corresponding dual value from the solution.
Arguments
sol::Solution: Solution object containing dual variables.model::Model: Model containing constraint definitions.label::Symbol: Symbol corresponding to a constraint label.
Returns
A function of time t for time-dependent constraints, or a scalar/vector for time-invariant duals. If the label is not found, throws an IncorrectArgument exception.
CTModels.OCP.dynamics — Function
dynamics(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.AbstractTimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.AbstractControlModel, <:CTModels.OCP.AbstractVariableModel, D<:Function}
) -> Function
Return the dynamics.
CTModels.Serialization.export_ocp_solution — Function
export_ocp_solution(sol; format=:JLD, filename="solution")Export an optimal control solution to a file.
Arguments
sol::AbstractSolution: The solution to export.
Keyword Arguments
format::Symbol=:JLD: Export format, either:JLDor:JSON.filename::String="solution": Base filename (extension added automatically).
Notes
Requires loading the appropriate package (JLD2 or JSON3) before use.
See also: import_ocp_solution
export_ocp_solution(
::CTModels.Serialization.JSON3Tag,
sol::CTModels.OCP.Solution;
filename
)
Export an optimal control solution to a .json file using the JSON3 format.
This function serializes a CTModels.Solution into a structured JSON dictionary, including all primal and dual information, which can be read by external tools.
Arguments
::CTModels.JSON3Tag: A tag used to dispatch the export method for JSON3.sol::CTModels.Solution: The solution to be saved.
Keyword Arguments
filename::String = "solution": Base filename. The.jsonextension is automatically appended.
Notes
The exported JSON includes the time grid, state, control, costate, objective, solver info, and all constraint duals (if available).
Example
julia> using JSON3
julia> export_ocp_solution(JSON3Tag(), sol; filename="mysolution")
# → creates "mysolution.json"export_ocp_solution(
::CTModels.Serialization.JLD2Tag,
sol::CTModels.OCP.Solution;
filename
)
Export an optimal control solution to a .jld2 file using the JLD2 format.
This function serializes and saves a CTModels.Solution object to disk, allowing it to be reloaded later. The solution is discretized to avoid serialization warnings for function objects.
Arguments
::CTModels.JLD2Tag: A tag used to dispatch the export method for JLD2.sol::CTModels.Solution: The optimal control solution to be saved.
Keyword Arguments
filename::String = "solution": Base name of the file. The.jld2extension is automatically appended.
Example
julia> using JLD2
julia> export_ocp_solution(JLD2Tag(), sol; filename="mysolution")
# → creates "mysolution.jld2"Notes
- Functions are discretized on the time grid to avoid JLD2 serialization warnings
- The solution can be perfectly reconstructed via
import_ocp_solution - Uses the same discretization logic as JSON export for consistency
CTModels.OCP.final_time — Function
final_time(
model::CTModels.OCP.TimesModel{<:CTModels.OCP.AbstractTimeModel, <:CTModels.OCP.FixedTimeModel{T<:Real}}
) -> Real
Get the final time from the times model, from a fixed final time model.
final_time(
model::CTModels.OCP.TimesModel{<:CTModels.OCP.AbstractTimeModel, CTModels.OCP.FreeTimeModel},
variable::AbstractArray{T<:Real, 1}
) -> Any
Get the final time from the times model, from a free final time model.
final_time(ocp::CTModels.OCP.AbstractModel) -> Any
Throw an error for unsupported final time access.
final_time(
ocp::CTModels.OCP.AbstractModel,
variable::AbstractVector
) -> Any
Throw an error for unsupported final time access with variable.
final_time(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.TimesModel{<:CTModels.OCP.AbstractTimeModel, CTModels.OCP.FixedTimeModel{T<:Real}}}
) -> Any
Return the final time, for a fixed final time.
final_time(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.TimesModel{<:CTModels.OCP.AbstractTimeModel, CTModels.OCP.FreeTimeModel}},
variable::AbstractArray{T<:Real, 1}
) -> Any
Return the final time, for a free final time.
final_time(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.TimesModel{<:CTModels.OCP.AbstractTimeModel, CTModels.OCP.FreeTimeModel}},
variable::Real
) -> Real
Return the final time, for a free final time.
final_time(sol::CTModels.OCP.Solution) -> Real
Return the final time of the solution.
CTModels.OCP.final_time_name — Function
final_time_name(model::CTModels.OCP.TimesModel) -> String
Get the name of the final time from the times model.
final_time_name(ocp::CTModels.OCP.Model) -> String
Return the name of the final time.
final_time_name(sol::CTModels.OCP.Solution) -> String
Return the name of the final time.
CTModels.OCP.get_build_examodel — Function
get_build_examodel(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.AbstractTimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.AbstractControlModel, <:CTModels.OCP.AbstractVariableModel, <:Function, <:CTModels.OCP.AbstractObjectiveModel, <:CTModels.OCP.AbstractConstraintsModel, BE<:Function}
) -> Function
Return the build_examodel.
get_build_examodel(
_::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.AbstractTimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.AbstractControlModel, <:CTModels.OCP.AbstractVariableModel, <:Function, <:CTModels.OCP.AbstractObjectiveModel, <:CTModels.OCP.AbstractConstraintsModel, <:Nothing}
)
Return an error (PreconditionError) since the model is not built with the :exa backend.
CTModels.OCP.has_fixed_final_time — Function
has_fixed_final_time(
times::CTModels.OCP.TimesModel{<:CTModels.OCP.AbstractTimeModel, <:CTModels.OCP.FixedTimeModel{T<:Real}}
) -> Bool
Check if the final time is fixed. Return true.
has_fixed_final_time(
times::CTModels.OCP.TimesModel{<:CTModels.OCP.AbstractTimeModel, CTModels.OCP.FreeTimeModel}
) -> Bool
Check if the final time is free. Return false.
has_fixed_final_time(ocp::CTModels.OCP.Model) -> Bool
Check if the final time is fixed.
has_fixed_final_time(sol::CTModels.OCP.Solution) -> Bool
Check if the final time is fixed.
CTModels.OCP.has_fixed_initial_time — Function
has_fixed_initial_time(
times::CTModels.OCP.TimesModel{<:CTModels.OCP.FixedTimeModel{T<:Real}}
) -> Bool
Check if the initial time is fixed. Return true.
has_fixed_initial_time(
times::CTModels.OCP.TimesModel{CTModels.OCP.FreeTimeModel}
) -> Bool
Check if the initial time is free. Return false.
has_fixed_initial_time(ocp::CTModels.OCP.Model) -> Bool
Check if the initial time is fixed.
has_fixed_initial_time(sol::CTModels.OCP.Solution) -> Bool
Check if the initial time is fixed.
CTModels.OCP.has_free_final_time — Function
has_free_final_time(times::CTModels.OCP.TimesModel) -> Bool
Check if the final time is free.
has_free_final_time(ocp::CTModels.OCP.Model) -> Bool
Check if the final time is free.
has_free_final_time(sol::CTModels.OCP.Solution) -> Bool
Check if the final time is free.
CTModels.OCP.has_free_initial_time — Function
has_free_initial_time(
times::CTModels.OCP.TimesModel
) -> Bool
Check if the final time is free.
has_free_initial_time(ocp::CTModels.OCP.Model) -> Bool
Check if the initial time is free.
has_free_initial_time(sol::CTModels.OCP.Solution) -> Bool
Check if the initial time is free.
CTModels.OCP.has_lagrange_cost — Function
has_lagrange_cost(
_::CTModels.OCP.MayerObjectiveModel
) -> Bool
Return false.
has_lagrange_cost(
_::CTModels.OCP.LagrangeObjectiveModel
) -> Bool
Return true.
has_lagrange_cost(
_::CTModels.OCP.BolzaObjectiveModel
) -> Bool
Return true.
has_lagrange_cost(ocp::CTModels.OCP.Model) -> Bool
Check if the model has a Lagrange cost.
CTModels.OCP.has_mayer_cost — Function
has_mayer_cost(_::CTModels.OCP.MayerObjectiveModel) -> Bool
Return true.
has_mayer_cost(
_::CTModels.OCP.LagrangeObjectiveModel
) -> Bool
Return false.
has_mayer_cost(_::CTModels.OCP.BolzaObjectiveModel) -> Bool
Return true.
has_mayer_cost(ocp::CTModels.OCP.Model) -> Bool
Check if the model has a Mayer cost.
CTSolvers.Strategies.has_option — Function
has_option(
strategy::CTSolvers.Strategies.AbstractStrategy,
key::Symbol
) -> Any
Check if an option exists in a strategy instance.
Returns true if the option is present in the strategy's options, false otherwise. This is useful for checking if unknown options were stored in permissive mode.
Arguments
strategy::AbstractStrategy: The strategy instancekey::Symbol: The option name
Returns
Bool:trueif the option exists
Example
julia> using CTSolvers.Strategies
julia> strategy = MyStrategy(max_iter=200; mode=:permissive, custom_opt=123)
julia> has_option(strategy, :max_iter)
true
julia> has_option(strategy, :custom_opt)
true
julia> has_option(strategy, :nonexistent)
falseSee also: option_value, option_source
CTSolvers.Strategies.id — Function
Return the unique identifier for this strategy type.
Arguments
strategy_type::Type{<:AbstractStrategy}: The strategy type
Returns
Symbol: Unique identifier for the strategy
Example
# For a concrete strategy type MyStrategy:
julia> id(MyStrategy)
:mystrategyCTModels.Serialization.import_ocp_solution — Function
import_ocp_solution(ocp; format=:JLD, filename="solution")Import an optimal control solution from a file.
Arguments
ocp::AbstractModel: The model associated with the solution.
Keyword Arguments
format::Symbol=:JLD: Import format, either:JLDor:JSON.filename::String="solution": Base filename (extension added automatically).
Returns
Solution: The imported solution.
Notes
Requires loading the appropriate package (JLD2 or JSON3) before use.
See also: export_ocp_solution
import_ocp_solution(
::CTModels.Serialization.JSON3Tag,
ocp::CTModels.OCP.Model;
filename
)
Import an optimal control solution from a .json file exported with export_ocp_solution.
This function reads the JSON contents and reconstructs a CTModels.Solution object, including the discretized primal and dual trajectories.
Arguments
::CTModels.JSON3Tag: A tag used to dispatch the import method for JSON3.ocp::CTModels.Model: The model associated with the optimal control problem. Used to rebuild the full solution.
Keyword Arguments
filename::String = "solution": Base filename. The.jsonextension is automatically appended.
Returns
CTModels.Solution: A reconstructed solution instance.
Notes
Handles both vector and matrix encodings of signals. If dual fields are missing or null, the corresponding attributes are set to nothing.
Example
julia> using JSON3
julia> sol = import_ocp_solution(JSON3Tag(), model; filename="mysolution")import_ocp_solution(
::CTModels.Serialization.JLD2Tag,
ocp::CTModels.OCP.Model;
filename
)
Import an optimal control solution from a .jld2 file.
This function loads a previously saved CTModels.Solution from disk and reconstructs it using build_solution from the discretized data.
Arguments
::CTModels.JLD2Tag: A tag used to dispatch the import method for JLD2.ocp::CTModels.Model: The associated optimal control problem model.
Keyword Arguments
filename::String = "solution": Base name of the file. The.jld2extension is automatically appended.
Returns
CTModels.Solution: The reconstructed solution object.
Example
julia> using JLD2
julia> sol = import_ocp_solution(JLD2Tag(), model; filename="mysolution")Notes
- The solution is reconstructed from discretized data via
build_solution - This ensures perfect round-trip consistency with the export
- The OCP model from the file is used if the provided one is not compatible
CTModels.OCP.index — Function
index(model::CTModels.OCP.FreeTimeModel) -> Int64
Get the index of the time variable from the free time model.
CTModels.OCP.infos — Function
infos(sol::CTModels.OCP.Solution) -> Dict{Symbol, Any}
Return a dictionary of additional infos depending on the solver or nothing.
CTParser.@init — Macro
@init ocp begin
...
endBuild an initial guess object for an optimal control problem from a small initialisation DSL.
The block following @init is interpreted as a collection of assignment rules for the state, control and variable components of an optimal control problem, using a compact syntax of the form
q(t) := sin(t) # time-dependent function
x(T) := X # time grid and associated samples
u := 0.1 # constant value
a = 1.0 # ordinary Julia alias (not part of the initial guess)
v(t) := a # time-dependent function using the alias aboveThe macro itself only rewrites this DSL into a NamedTuple-based representation. All dimensional checks, interpretation of aliases and construction of the concrete initial guess object are delegated to the backend selected by init_prefix (by défaut :CTModels), via build_initial_guess and validate_initial_guess.
An optional keyword-like trailing argument controls logging:
ig = @init ocp begin
u(t) := t
end log = trueWhen log = true, the macro additionally prints a human-readable NamedTuple-like representation of the specification.
Arguments
ocp: symbolic optimal control problem built with@def.begin ... end: block containing the initialisation DSL.log: optional Boolean keyword (defaultfalse) enabling textual logging of the parsed specification.
Returns
AbstractInitialGuess: backend-specific initial guess object produced by the current backend (par défautCTModels).
Example
julia> using CTParser
julia> ocp = @def begin
t ∈ [0, 1], time
x ∈ R, state
u ∈ R, control
ẋ(t) == u(t)
x(0) == 0
x(1) == 0
∫(0.5u(t)^2) → min
end
julia> ig = @init ocp begin
u(t) := t
end
julia> ig isa CTModels.AbstractInitialGuess
trueCTModels.OCP.initial_time — Function
initial_time(
model::CTModels.OCP.TimesModel{<:CTModels.OCP.FixedTimeModel{T<:Real}}
) -> Real
Get the initial time from the times model, from a fixed initial time model.
initial_time(
model::CTModels.OCP.TimesModel{CTModels.OCP.FreeTimeModel},
variable::AbstractArray{T<:Real, 1}
) -> Any
Get the initial time from the times model, from a free initial time model.
initial_time(ocp::CTModels.OCP.AbstractModel) -> Any
Throw an error for unsupported initial time access.
initial_time(
ocp::CTModels.OCP.AbstractModel,
variable::AbstractVector
) -> Any
Throw an error for unsupported initial time access with variable.
initial_time(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.TimesModel{CTModels.OCP.FixedTimeModel{T<:Real}}}
) -> Any
Return the initial time, for a fixed initial time.
initial_time(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.TimesModel{CTModels.OCP.FreeTimeModel}},
variable::AbstractArray{T<:Real, 1}
) -> Any
Return the initial time, for a free initial time.
initial_time(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.TimesModel{CTModels.OCP.FreeTimeModel}},
variable::Real
) -> Real
Return the initial time, for a free initial time.
initial_time(sol::CTModels.OCP.Solution) -> Real
Return the initial time of the solution.
CTModels.OCP.initial_time_name — Function
initial_time_name(model::CTModels.OCP.TimesModel) -> String
Get the name of the initial time from the times model.
initial_time_name(ocp::CTModels.OCP.Model) -> String
Return the name of the initial time.
initial_time_name(sol::CTModels.OCP.Solution) -> String
Return the name of the initial time.
CTModels.OCP.is_autonomous — Function
is_autonomous(
ocp::CTModels.OCP.PreModel
) -> Union{Nothing, Bool}
Check whether the system is autonomous.
Arguments
ocp::PreModel: The optimal control problem.
Returns
Bool:trueif the system is autonomous (i.e., does not explicitly depend on time),falseotherwise.
Example
julia> is_autonomous(ocp) # returns true or falseis_autonomous(
_::CTModels.OCP.Model{CTModels.OCP.Autonomous, <:CTModels.OCP.TimesModel}
) -> Bool
Return true for an autonomous model.
is_autonomous(
_::CTModels.OCP.Model{CTModels.OCP.NonAutonomous, <:CTModels.OCP.TimesModel}
) -> Bool
Return false for a non-autonomous model.
CTSolvers.Options.is_computed — Function
is_computed(opt::CTSolvers.Options.OptionValue) -> Bool
Check if this option value was computed from other options.
Returns
Bool:trueif the source is:computed
Example
opt = OptionValue(100, :computed)
is_computed(opt) # trueSee also: is_user, is_default, source
is_computed(def::CTSolvers.Options.OptionDefinition) -> Bool
Check if this option definition has a computed default value.
Returns true when the default value is computed from strategy parameters (e.g., backend in Exa{GPU} which depends on the GPU parameter).
Returns
Bool:trueif the default is computed from parameters
Example
julia> using CTSolvers.Options
julia> # Static default
julia> def1 = OptionDefinition(name=:max_iter, type=Int, default=100,
description="Maximum iterations")
OptionDefinition{Int}(...)
julia> is_computed(def1)
false
julia> # Computed default
julia> def2 = OptionDefinition(name=:backend, type=Any, default=compute_backend(),
description="Backend", computed=true)
OptionDefinition{...}(...)
julia> is_computed(def2)
trueSee also: has_default, is_required, OptionDefinition
is_computed(
opts::CTSolvers.Strategies.StrategyOptions,
key::Symbol
) -> Bool
Check if an option was computed.
Arguments
opts::StrategyOptions: Strategy optionskey::Symbol: Option name
Returns
Bool:trueif the option was computed
Example
julia> Options.is_computed(opts, :step)
trueSee also: Options.source, Options.is_user, Options.is_default
CTSolvers.Options.is_default — Function
is_default(opt::CTSolvers.Options.OptionValue) -> Bool
Check if this option value is using its default.
Returns
Bool:trueif the source is:default
Example
opt = OptionValue(100, :default)
is_default(opt) # trueSee also: is_user, is_computed, source
is_default(
opts::CTSolvers.Strategies.StrategyOptions,
key::Symbol
) -> Bool
Check if an option is using its default value.
Arguments
opts::StrategyOptions: Strategy optionskey::Symbol: Option name
Returns
Bool:trueif the option is using its default value
Example
julia> Options.is_default(opts, :tol)
trueSee also: Options.source, Options.is_user, Options.is_computed
CTModels.OCP.is_empty — Function
is_empty(model::CTModels.OCP.EmptyTimeGridModel) -> Bool
Return true if the time grid model is empty.
Arguments
model::EmptyTimeGridModel: An empty time grid model
Returns
Bool: Alwaystruefor empty time grid models
Example
julia> etg = CTModels.EmptyTimeGridModel()
julia> CTModels.is_empty(etg)
trueis_empty(model::CTModels.OCP.AbstractTimeGridModel) -> Bool
Return false for non-empty time grid models.
Arguments
model::AbstractTimeGridModel: Any non-empty time grid model
Returns
Bool: Alwaysfalsefor non-empty time grid models
Example
julia> T = LinRange(0, 1, 101)
julia> utg = CTModels.UnifiedTimeGridModel(T)
julia> CTModels.is_empty(utg)
falseCTModels.OCP.is_empty_time_grid — Function
is_empty_time_grid(sol::CTModels.OCP.Solution) -> Bool
Check if the time grid is empty from the solution.
CTModels.OCP.is_final_time_fixed — Function
Alias for has_fixed_final_time. Check if the final time is fixed.
Example
julia> is_final_time_fixed(times) # equivalent to has_fixed_final_time(times)See also: has_fixed_final_time, is_final_time_free.
CTModels.OCP.is_final_time_free — Function
Alias for has_free_final_time. Check if the final time is free.
Example
julia> is_final_time_free(times) # equivalent to has_free_final_time(times)See also: has_free_final_time, is_final_time_fixed.
CTModels.OCP.is_initial_time_fixed — Function
Alias for has_fixed_initial_time. Check if the initial time is fixed.
Example
julia> is_initial_time_fixed(times) # equivalent to has_fixed_initial_time(times)See also: has_fixed_initial_time, is_initial_time_free.
CTModels.OCP.is_initial_time_free — Function
Alias for has_free_initial_time. Check if the initial time is free.
Example
julia> is_initial_time_free(times) # equivalent to has_free_initial_time(times)See also: has_free_initial_time, is_initial_time_fixed.
CTModels.OCP.is_lagrange_cost_defined — Function
Alias for has_lagrange_cost. Check if the objective has a Lagrange (integral) cost defined.
Example
julia> is_lagrange_cost_defined(obj) # equivalent to has_lagrange_cost(obj)See also: has_lagrange_cost, is_mayer_cost_defined.
CTModels.OCP.is_mayer_cost_defined — Function
Alias for has_mayer_cost. Check if the objective has a Mayer (terminal) cost defined.
Example
julia> is_mayer_cost_defined(obj) # equivalent to has_mayer_cost(obj)See also: has_mayer_cost, is_lagrange_cost_defined.
CTSolvers.Options.is_user — Function
is_user(opt::CTSolvers.Options.OptionValue) -> Bool
Check if this option value was explicitly provided by the user.
Returns
Bool:trueif the source is:user
Example
opt = OptionValue(100, :user)
is_user(opt) # trueSee also: is_default, is_computed, source
is_user(
opts::CTSolvers.Strategies.StrategyOptions,
key::Symbol
) -> Bool
Check if an option was provided by the user.
Arguments
opts::StrategyOptions: Strategy optionskey::Symbol: Option name
Returns
Bool:trueif the option was provided by the user
Example
julia> Options.is_user(opts, :max_iter)
trueSee also: Options.source, Options.is_default, Options.is_computed
CTModels.OCP.iterations — Function
iterations(sol::CTModels.OCP.Solution) -> Int64
Return the number of iterations (if solved by an iterative method).
CTModels.OCP.lagrange — Function
lagrange(
model::CTModels.OCP.LagrangeObjectiveModel{L<:Function}
) -> Function
Return the Lagrange function.
lagrange(
model::CTModels.OCP.BolzaObjectiveModel{<:Function, L<:Function}
) -> Function
Return the Lagrange function.
lagrange(ocp::CTModels.OCP.AbstractModel) -> Function
Throw an error when accessing Lagrange cost on a model without one.
lagrange(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.AbstractTimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.AbstractControlModel, <:CTModels.OCP.AbstractVariableModel, <:Function, CTModels.OCP.LagrangeObjectiveModel{L<:Function}}
) -> Function
Return the Lagrange cost.
lagrange(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.AbstractTimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.AbstractControlModel, <:CTModels.OCP.AbstractVariableModel, <:Function, <:CTModels.OCP.BolzaObjectiveModel{<:Function, L<:Function}}
) -> Any
Return the Lagrange cost.
CTModels.OCP.mayer — Function
mayer(
model::CTModels.OCP.MayerObjectiveModel{M<:Function}
) -> Function
Return the Mayer function.
mayer(
model::CTModels.OCP.BolzaObjectiveModel{M<:Function}
) -> Function
Return the Mayer function.
mayer(ocp::CTModels.OCP.AbstractModel) -> Any
Throw an error when accessing Mayer cost on a model without one.
mayer(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.AbstractTimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.AbstractControlModel, <:CTModels.OCP.AbstractVariableModel, <:Function, <:CTModels.OCP.MayerObjectiveModel{M<:Function}}
) -> Any
Return the Mayer cost.
mayer(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.AbstractTimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.AbstractControlModel, <:CTModels.OCP.AbstractVariableModel, <:Function, <:CTModels.OCP.BolzaObjectiveModel{M<:Function}}
) -> Any
Return the Mayer cost.
CTModels.OCP.message — Function
message(sol::CTModels.OCP.Solution) -> String
Return the message associated to the status criterion.
CTSolvers.Strategies.metadata — Function
Return metadata about a strategy type.
Arguments
strategy_type::Type{<:AbstractStrategy}: The strategy type
Returns
StrategyMetadata: Option specifications and validation rules
Example
# For a concrete strategy type MyStrategy:
julia> meta = metadata(MyStrategy)
julia> meta
StrategyMetadata with option definitions for max_iter, etc.Base.methods — Function
methods(f, [types], [module])Return the method table for f.
If types is specified, return an array of methods whose types match. If module is specified, return an array of methods defined in that module. A list of modules can also be specified as an array or set.
See also: which, @which and methodswith.
methods() -> NTuple{10, NTuple{4, Symbol}}
Return the tuple of available method quadruplets for solving optimal control problems.
Each quadruplet consists of (discretizer_id, modeler_id, solver_id, parameter) where:
discretizer_id::Symbol: Discretization strategy identifier (e.g.,:collocation)modeler_id::Symbol: NLP modeling strategy identifier (e.g.,:adnlp,:exa)solver_id::Symbol: NLP solver identifier (e.g.,:ipopt,:madnlp,:madncl,:knitro)parameter::Symbol: Execution parameter (:cpuor:gpu)
Returns
Tuple{Vararg{Tuple{Symbol, Symbol, Symbol, Symbol}}}: Available method combinations
Examples
julia> m = methods()
((:collocation, :adnlp, :ipopt, :cpu), (:collocation, :adnlp, :madnlp, :cpu), ...)
julia> length(m)
10 # 8 CPU methods + 2 GPU methods
julia> # CPU methods
julia> methods()[1]
(:collocation, :adnlp, :ipopt, :cpu)
julia> # GPU methods
julia> methods()[9]
(:collocation, :exa, :madnlp, :gpu)Notes
- Returns a precomputed constant tuple (allocation-free, type-stable)
- All methods currently use
:collocationdiscretization - CPU methods (8 total): All combinations of
{adnlp, exa}×{ipopt, madnlp, madncl, knitro} - GPU methods (2 total): Only GPU-capable combinations
exa×{madnlp, madncl} - GPU-capable strategies use parameterized types with automatic defaults
- Used by
CTBase.Descriptions.completeto complete partial method descriptions
See also: solve, CTBase.Descriptions.complete, get_strategy_registry
CTModels.OCP.model — Function
model(
sol::CTModels.OCP.Solution{<:CTModels.OCP.AbstractTimeGridModel, <:CTModels.OCP.AbstractTimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.AbstractControlModel, <:CTModels.OCP.AbstractVariableModel, M<:CTModels.OCP.AbstractModel}
) -> CTModels.OCP.AbstractModel
Return the model of the optimal control problem.
CTModels.OCP.name — Function
name(model::CTModels.OCP.StateModel) -> String
Get the name of the state from the state model.
name(model::CTModels.OCP.StateModelSolution) -> String
Get the name of the state from the state model solution.
name(model::CTModels.OCP.ControlModel) -> String
Get the name of the control variable.
Arguments
model::ControlModel: The control model.
Returns
String: The name of the control.
Example
julia> name(controlmodel)
"u"name(model::CTModels.OCP.ControlModelSolution) -> String
Get the name of the control variable from the solution.
Arguments
model::ControlModelSolution: The control model solution.
Returns
String: The name of the control.
name(_::CTModels.OCP.EmptyControlModel) -> String
Return an empty string, since no control is defined.
name(model::CTModels.OCP.VariableModel) -> String
Return the name of the variable stored in the model.
name(model::CTModels.OCP.VariableModelSolution) -> String
Return the name of the variable stored in the model solution.
name(_::CTModels.OCP.EmptyVariableModel) -> String
Return an empty string, since no variable is defined.
name(model::CTModels.OCP.FixedTimeModel) -> String
Get the name of the time from the fixed time model.
name(model::CTModels.OCP.FreeTimeModel) -> String
Get the name of the time from the free time model.
CTSolvers.DOCP.nlp_model — Function
nlp_model(
prob::CTSolvers.DOCP.DiscretizedModel,
initial_guess,
modeler::CTSolvers.Modelers.AbstractNLPModeler
) -> NLPModels.AbstractNLPModel
Build an NLP model from a discretized optimal control problem.
This is a convenience wrapper around build_model that provides explicit typing for DiscretizedModel.
Arguments
prob::DiscretizedModel: The discretized OCPinitial_guess: Initial guess for the NLP solvermodeler: The modeler to use (e.g., Modelers.ADNLP, Modelers.Exa)
Returns
NLPModels.AbstractNLPModel: The NLP model
Example
nlp = nlp_model(docp, initial_guess, modeler)See also: ocp_solution, Optimization.build_model
CTSolvers.DOCP.ocp_model — Function
ocp_model(
docp::CTSolvers.DOCP.DiscretizedModel
) -> CTModels.OCP.AbstractModel
Extract the original optimal control problem from a discretized problem.
Arguments
docp::DiscretizedModel: The discretized optimal control problem
Returns
- The original optimal control problem
Example
ocp = ocp_model(docp)See also: DiscretizedModel
CTSolvers.DOCP.ocp_solution — Function
ocp_solution(
docp::CTSolvers.DOCP.DiscretizedModel,
model_solution::SolverCore.AbstractExecutionStats,
modeler::CTSolvers.Modelers.AbstractNLPModeler
) -> Any
Build an optimal control solution from NLP execution statistics.
This is a convenience wrapper around build_solution that provides explicit typing for DiscretizedModel and ensures the return type is an optimal control solution.
Arguments
docp::DiscretizedModel: The discretized OCPmodel_solution::SolverCore.AbstractExecutionStats: NLP solver outputmodeler: The modeler used for building
Returns
AbstractSolution: The OCP solution
Example
sol = ocp_solution(docp, nlp_stats, modeler)See also: nlp_model, Optimization.build_solution
CTSolvers.Strategies.option_default — Function
option_default(
strategy_type::Type{<:CTSolvers.Strategies.AbstractStrategy},
key::Symbol
) -> Any
Get the default value for a specific option.
Returns the value that will be used if the option is not explicitly provided by the user during strategy construction.
Arguments
strategy_type::Type{<:AbstractStrategy}: The strategy typekey::Symbol: The option name
Returns
- The default value for the option (type depends on the option)
Example
julia> using CTSolvers.Strategies
julia> option_default(MyStrategy, :max_iter)
100
julia> option_default(MyStrategy, :tol)
1.0e-6Throws
KeyError: If the option name does not exist
Notes
- This function operates on types, not instances
- If you have an instance, use
option_default(typeof(strategy), key)
See also: option_defaults, option_type
CTSolvers.Strategies.option_defaults — Function
option_defaults(
strategy_type::Type{<:CTSolvers.Strategies.AbstractStrategy}
) -> NamedTuple
Get all default values as a NamedTuple.
Returns a NamedTuple containing the default value for every option defined in the strategy's metadata. This is useful for resetting configurations or understanding the baseline behavior.
Arguments
strategy_type::Type{<:AbstractStrategy}: The strategy type
Returns
NamedTuple: All default values keyed by option name
Example
julia> using CTSolvers.Strategies
julia> option_defaults(MyStrategy)
(max_iter = 100, tol = 1.0e-6)
julia> defaults = option_defaults(MyStrategy)
julia> defaults.max_iter
100Notes
- This function operates on types, not instances
- If you have an instance, use
option_defaults(typeof(strategy))
See also: option_default, option_names
CTSolvers.Strategies.option_description — Function
option_description(
strategy_type::Type{<:CTSolvers.Strategies.AbstractStrategy},
key::Symbol
) -> String
Get the human-readable description for a specific option.
Returns the documentation string that explains what the option controls. This is useful for generating help messages and documentation.
Arguments
strategy_type::Type{<:AbstractStrategy}: The strategy typekey::Symbol: The option name
Returns
String: The option description
Example
julia> using CTSolvers.Strategies
julia> option_description(MyStrategy, :max_iter)
"Maximum number of iterations"
julia> option_description(MyStrategy, :tol)
"Convergence tolerance"Throws
KeyError: If the option name does not exist
Notes
- This function operates on types, not instances
- If you have an instance, use
option_description(typeof(strategy), key)
See also: option_type, option_default
CTSolvers.Strategies.option_names — Function
option_names(
strategy_type::Type{<:CTSolvers.Strategies.AbstractStrategy}
) -> Tuple
Get all option names for a strategy type.
Returns a tuple of all option names defined in the strategy's metadata. This is useful for discovering what options are available without needing to instantiate the strategy.
Arguments
strategy_type::Type{<:AbstractStrategy}: The strategy type to introspect
Returns
Tuple{Vararg{Symbol}}: Tuple of option names
Example
julia> using CTSolvers.Strategies
julia> option_names(MyStrategy)
(:max_iter, :tol, :backend)
julia> for name in option_names(MyStrategy)
println("Available option: ", name)
end
Available option: max_iter
Available option: tol
Available option: backendNotes
- This function operates on types, not instances
- If you have an instance, use
option_names(typeof(strategy))
See also: option_type, option_description, option_default
CTSolvers.Strategies.option_source — Function
option_source(
strategy::CTSolvers.Strategies.AbstractStrategy,
key::Symbol
) -> Symbol
Get the source provenance of an option value.
Returns a symbol indicating where the option value came from:
:user- Explicitly provided by the user:default- Using the default value from metadata:computed- Calculated from other options
Arguments
strategy::AbstractStrategy: The strategy instancekey::Symbol: The option name
Returns
Symbol: The source provenance (:user,:default, or:computed)
Example
julia> using CTSolvers.Strategies
julia> strategy = MyStrategy(max_iter=200)
julia> option_source(strategy, :max_iter)
:user
julia> option_source(strategy, :tol)
:defaultThrows
KeyError: If the option name does not exist
See also: option_value, is_user, is_default
CTSolvers.Strategies.option_type — Function
option_type(
strategy_type::Type{<:CTSolvers.Strategies.AbstractStrategy},
key::Symbol
) -> Type
Get the expected type for a specific option.
Returns the Julia type that the option value must satisfy. This is useful for validation and documentation purposes.
Arguments
strategy_type::Type{<:AbstractStrategy}: The strategy typekey::Symbol: The option name
Returns
Type: The expected type for the option value
Example
julia> using CTSolvers.Strategies
julia> option_type(MyStrategy, :max_iter)
Int64
julia> option_type(MyStrategy, :tol)
Float64Throws
KeyError: If the option name does not exist
Notes
- This function operates on types, not instances
- If you have an instance, use
option_type(typeof(strategy), key)
See also: option_description, option_default
CTSolvers.Strategies.option_value — Function
option_value(
strategy::CTSolvers.Strategies.AbstractStrategy,
key::Symbol
) -> Any
Get the current value of an option from a strategy instance.
Returns the effective value that the strategy is using for the specified option. This may be a user-provided value or the default value.
Arguments
strategy::AbstractStrategy: The strategy instancekey::Symbol: The option name
Returns
- The current option value (type depends on the option)
Example
julia> using CTSolvers.Strategies
julia> strategy = MyStrategy(max_iter=200)
julia> option_value(strategy, :max_iter)
200
julia> option_value(strategy, :tol) # Uses default
1.0e-6Throws
KeyError: If the option name does not exist
See also: option_source, options
CTSolvers.Strategies.options — Function
Return the current options of a strategy as a StrategyOptions.
Arguments
strategy::AbstractStrategy: The strategy instance
Returns
StrategyOptions: Current option values with provenance tracking
Example
# For a concrete strategy instance:
julia> strategy = MyStrategy(backend=:sparse)
julia> opts = options(strategy)
julia> opts
StrategyOptions with values=(backend=:sparse), sources=(backend=:user)CTModels.OCP.path_constraints_dual — Function
path_constraints_dual(
model::CTModels.OCP.DualModel{PC_Dual<:Union{Nothing, Function}}
) -> Union{Nothing, Function}
Return the dual function associated with the nonlinear path constraints.
Arguments
model::DualModel: A model including dual variables for path constraints.
Returns
A function mapping time t to the vector of dual values, or nothing if not set.
path_constraints_dual(
sol::CTModels.OCP.Solution
) -> Union{Nothing, Function}
Return the dual of the path constraints.
CTModels.OCP.path_constraints_nl — Function
path_constraints_nl(
model::CTModels.OCP.ConstraintsModel{TP}
) -> Any
Get the nonlinear path constraints from the model.
Arguments
model: The constraints model from which to retrieve the path constraints.
Returns
- The nonlinear path constraints.
Example
# Example of retrieving nonlinear path constraints
julia> model = ConstraintsModel(...)
julia> path_constraints = path_constraints_nl(model)path_constraints_nl(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.TimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.AbstractControlModel, <:CTModels.OCP.AbstractVariableModel, <:Function, <:CTModels.OCP.AbstractObjectiveModel, <:CTModels.OCP.ConstraintsModel{TP<:Tuple}}
) -> Any
Return the nonlinear path constraints.
RecipesBase.plot — Function
The main plot command. Use plot to create a new plot object, and plot! to add to an existing one:
plot(args...; kw...) # creates a new plot window, and sets it to be the current
plot!(args...; kw...) # adds to the `current`
plot!(plotobj, args...; kw...) # adds to the plot `plotobj`There are lots of ways to pass in data, and lots of keyword arguments... just try it and it will likely work as expected. When you pass in matrices, it splits by columns. To see the list of available attributes, use the plotattr(attr) function, where attr is the symbol :Series, :Subplot, :Plot, or :Axis. Pass any attribute to plotattr as a String to look up its docstring, e.g., plotattr("seriestype").
Extended help
Series attributes
- arrow
- bar_edges
- bar_position
- bar_width
- bins
- colorbar_entry
- connections
- contour_labels
- contours
- extra_kwargs
- fill
- fill_z
- fillalpha
- fillcolor
- fillrange
- fillstyle
- group
- hover
- label
- levels
- line
- line_z
- linealpha
- linecolor
- linestyle
- linewidth
- marker
- marker_z
- markeralpha
- markercolor
- markershape
- markersize
- markerstrokealpha
- markerstrokecolor
- markerstrokestyle
- markerstrokewidth
- normalize
- orientation
- permute
- primary
- quiver
- ribbon
- series_annotations
- seriesalpha
- seriescolor
- seriestype
- show_empty_bins
- smooth
- stride
- subplot
- weights
- x
- xerror
- y
- yerror
- z
- z_order
- zerror
Axis attributes
Prepend these with the axis letter (x, y or z)
- axis
- discrete_values
- draw_arrow
- flip
- foreground_color_axis
- foreground_color_border
- foreground_color_grid
- foreground_color_guide
- foreground_color_minor_grid
- foreground_color_text
- formatter
- grid
- gridalpha
- gridlinewidth
- gridstyle
- guide
- guide_position
- guidefont
- guidefontcolor
- guidefontfamily
- guidefonthalign
- guidefontrotation
- guidefontsize
- guidefontvalign
- lims
- link
- minorgrid
- minorgridalpha
- minorgridlinewidth
- minorgridstyle
- minorticks
- mirror
- rotation
- scale
- showaxis
- tick_direction
- tickfont
- tickfontcolor
- tickfontfamily
- tickfonthalign
- tickfontrotation
- tickfontsize
- tickfontvalign
- ticks
- unit
- unitformat
- widen
Subplot attributes
- annotationcolor
- annotationfontfamily
- annotationfontsize
- annotationhalign
- annotationrotation
- annotations
- annotationvalign
- aspect_ratio
- background_color_inside
- background_color_subplot
- bottom_margin
- camera
- clims
- color_palette
- colorbar
- colorbar_continuous_values
- colorbar_discrete_values
- colorbar_fontfamily
- colorbar_formatter
- colorbar_scale
- colorbar_tickfontcolor
- colorbar_tickfontfamily
- colorbar_tickfonthalign
- colorbar_tickfontrotation
- colorbar_tickfontsize
- colorbar_tickfontvalign
- colorbar_ticks
- colorbar_title
- colorbar_title_location
- colorbar_titlefont
- colorbar_titlefontcolor
- colorbar_titlefontfamily
- colorbar_titlefonthalign
- colorbar_titlefontrotation
- colorbar_titlefontsize
- colorbar_titlefontvalign
- extra_kwargs
- fontfamily_subplot
- foreground_color_subplot
- foreground_color_title
- framestyle
- left_margin
- legend_background_color
- legend_column
- legend_font
- legend_font_color
- legend_font_family
- legend_font_halign
- legend_font_pointsize
- legend_font_rotation
- legend_font_valign
- legend_foreground_color
- legend_position
- legend_title
- legend_title_font
- legend_title_font_color
- legend_title_font_family
- legend_title_font_halign
- legend_title_font_pointsize
- legend_title_font_rotation
- legend_title_font_valign
- margin
- plot_title_font
- projection
- projection_type
- right_margin
- subplot_index
- title
- title_font
- titlefontcolor
- titlefontfamily
- titlefonthalign
- titlefontrotation
- titlefontsize
- titlefontvalign
- titlelocation
- top_margin
Plot attributes
- background_color
- background_color_outside
- display_type
- dpi
- extra_kwargs
- extra_plot_kwargs
- fontfamily
- foreground_color
- html_output_format
- inset_subplots
- layout
- link
- overwrite_figure
- plot_title
- plot_titlefontcolor
- plot_titlefontfamily
- plot_titlefonthalign
- plot_titlefontrotation
- plot_titlefontsize
- plot_titlefontvalign
- plot_titleindex
- plot_titlelocation
- plot_titlevspan
- pos
- show
- size
- tex_output_standalone
- thickness_scaling
- warn_on_unsupported
- window_title
Extract a subplot from an existing plot.
Examples
julia> p1, p2 = plot(1:2), plot(10:20)
julia> pl = plot(p1, p2) # plot containing 2 subplots
julia> plot(pl.subplots[1]) # extract 1st subplot as a standalone plot
julia> plot(pl.subplots[2]) # extract 2nd subplot as a standalone plotplot(
sol::CTModels.OCP.Solution,
description::Symbol...;
layout,
control,
time,
state_style,
state_bounds_style,
control_style,
control_bounds_style,
costate_style,
time_style,
path_style,
path_bounds_style,
dual_style,
size,
color,
kwargs...
) -> Plots.Plot
Plot the components of an optimal control solution.
This is the main user-facing function to visualise the solution of an optimal control problem solved with the control-toolbox ecosystem.
It generates a set of subplots showing the evolution of the state, control, costate, path constraints, and dual variables over time, depending on the problem and the user’s choices.
Arguments
sol::CTModels.Solution: The optimal control solution to visualise.description::Symbol...: A variable number of symbols indicating which components to include in the plot. Common values include::state– plot the state.:costate– plot the costate (adjoint).:control– plot the control.:path– plot the path constraints.:dual– plot the dual variables (or Lagrange multipliers) associated with path constraints.
If no symbols are provided, a default set is used based on the problem and styles.
Keyword Arguments (Optional)
layout::Symbol = :group: Specifies how to arrange plots.:group: Fewer plots, grouping similar variables together (e.g., all states in one subplot).:split: One plot per variable component, stacked in a layout.
control::Symbol = :components: Defines how to represent control inputs.:components: One curve per control component.:norm: Single curve showing the Euclidean norm ‖u(t)‖.:all: Plot both components and norm.
time::Symbol = :default: Time normalisation for plots.:default: Real time scale.:normalizeor:normalise: Normalised to the interval [0, 1].
color: set the color of the all the graphs.
Style Options (Optional)
All style-related keyword arguments can be either a NamedTuple of plotting attributes or the Symbol :none referring to not plot the associated element. These allow you to customise color, line style, markers, etc.
time_style: Style for vertical lines at initial and final times.state_style: Style for state components.costate_style: Style for costate components.control_style: Style for control components.path_style: Style for path constraint values.dual_style: Style for dual variables.
Bounds Decorations (Optional)
Use these options to customise bounds on the plots if applicable and defined in the model. Set to :none to hide.
state_bounds_style: Style for state bounds.control_bounds_style: Style for control bounds.path_bounds_style: Style for path constraint bounds.
Returns
- A
Plots.Plotobject, which can be displayed, saved, or further customised.
Example
# basic plot
julia> plot(sol)
# plot only the state and control
julia> plot(sol, :state, :control)
# customise layout and styles, no costate
julia> plot(sol;
layout = :group,
control = :all,
state_style = (color=:blue, linestyle=:solid),
control_style = (color=:red, linestyle=:dash),
costate_style = :none) RecipesBase.plot! — Function
plot!(
p::Plots.Plot,
sol::CTModels.OCP.Solution,
description::Symbol...;
layout,
control,
time,
state_style,
state_bounds_style,
control_style,
control_bounds_style,
costate_style,
time_style,
path_style,
path_bounds_style,
dual_style,
color,
kwargs...
) -> Plots.Plot
Modify Plot p with the optimal control solution sol.
See plot for full behavior and keyword arguments.
plot!(
sol::CTModels.OCP.Solution,
description::Symbol...;
layout,
control,
time,
state_style,
state_bounds_style,
control_style,
control_bounds_style,
costate_style,
time_style,
path_style,
path_bounds_style,
dual_style,
color,
kwargs...
) -> Any
Modify Plot current() with the optimal control solution sol.
See plot for full behavior and keyword arguments.
CTSolvers.Strategies.route_to — Function
route_to(; kwargs...)
Create a disambiguated option value by explicitly routing it to specific strategies.
This function resolves ambiguity when the same option name exists in multiple strategies (e.g., both modeler and solver have max_iter). It creates a RoutedOption that tells the orchestration layer exactly which strategy should receive which value.
Arguments
kwargs...: Named arguments where keys are strategy identifiers (:solver,:modeler, etc.) and values are the option values to route to those strategies
Returns
RoutedOption: A routed option containing the strategy => value mappings
Throws
Exceptions.PreconditionError: If no strategies are provided
Example
julia> using CTSolvers.Strategies
julia> # Single strategy
julia> route_to(solver=100)
RoutedOption((solver = 100,))
julia> # Multiple strategies with different values
julia> route_to(solver=100, modeler=50)
RoutedOption((solver = 100, modeler = 50))Usage in solve()
# Without disambiguation - error if max_iter exists in multiple strategies
solve(ocp, method; max_iter=100) # ❌ Ambiguous!
# With disambiguation - explicit routing
solve(ocp, method;
max_iter = route_to(solver=100) # Only solver gets 100
)
solve(ocp, method;
max_iter = route_to(solver=100, modeler=50) # Different values for each
)Notes
- Strategy identifiers must match the actual strategy IDs in your method tuple
- You can route to one or multiple strategies in a single call
- This is the recommended way to disambiguate options
- The orchestration layer will validate that the strategy IDs exist
See also: RoutedOption, route_all_options
CommonSolve.solve — Method
solve(
problem::CTSolvers.Optimization.AbstractOptimizationProblem,
initial_guess,
modeler::CTSolvers.Modelers.AbstractNLPModeler,
solver::CTSolvers.Solvers.AbstractNLPSolver;
display
) -> Any
High-level solve: Build NLP model, solve it, and build solution.
Arguments
problem::Optimization.AbstractOptimizationProblem: The optimization probleminitial_guess: Initial guess for the solutionmodeler::Modelers.AbstractNLPModeler: Modeler to build NLPsolver::AbstractNLPSolver: Solver to usedisplay::Bool: Whether to show solver output (default: true)
Returns
- Solution object from the optimization problem
Example
# Conceptual usage pattern
# problem = ...
# x0 = ...
# modeler = Modelers.ADNLP()
# solver = Solvers.Ipopt(max_iter=1000)
# solution = solve(problem, x0, modeler, solver, display=true)See also: Optimization.build_model, Optimization.build_solution
CommonSolve.solve — Method
solve(
ocp::CTModels.OCP.AbstractModel,
description::Symbol...;
kwargs...
) -> Union{CTModels.OCP.Solution{TimeGridModelType, TimesModelType, StateModelType, ControlModelType, VariableModelType, ModelType, CostateModelType, Float64, DualModelType, CTModels.OCP.SolverInfos{Any, Dict{Symbol, Any}}} where {TimeGridModelType<:Union{CTModels.OCP.MultipleTimeGridModel, CTModels.OCP.UnifiedTimeGridModel{Vector{Float64}}}, TimesModelType<:CTModels.OCP.TimesModel, StateModelType<:Union{CTModels.OCP.StateModelSolution{TS} where TS<:CTModels.OCP.var"#_wrap_scalar_and_deepcopy##0#_wrap_scalar_and_deepcopy##1", CTModels.OCP.StateModelSolution{TS} where TS<:CTModels.OCP.var"#_wrap_scalar_and_deepcopy##2#_wrap_scalar_and_deepcopy##3"}, ControlModelType<:Union{CTModels.OCP.ControlModelSolution{TS} where TS<:CTModels.OCP.var"#_wrap_scalar_and_deepcopy##0#_wrap_scalar_and_deepcopy##1", CTModels.OCP.ControlModelSolution{TS} where TS<:CTModels.OCP.var"#_wrap_scalar_and_deepcopy##2#_wrap_scalar_and_deepcopy##3"}, VariableModelType<:Union{CTModels.OCP.VariableModelSolution{Vector{Float64}}, CTModels.OCP.VariableModelSolution{Float64}}, ModelType<:(CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, T} where T<:CTModels.OCP.TimesModel), CostateModelType<:Union{CTModels.OCP.var"#_wrap_scalar_and_deepcopy##0#_wrap_scalar_and_deepcopy##1", CTModels.OCP.var"#_wrap_scalar_and_deepcopy##2#_wrap_scalar_and_deepcopy##3"}, DualModelType<:(CTModels.OCP.DualModel{PC_Dual, Nothing, SC_LB_Dual, SC_UB_Dual, CC_LB_Dual, CC_UB_Dual, Vector{Float64}, Vector{Float64}} where {PC_Dual<:Union{CTModels.OCP.var"#_wrap_scalar_and_deepcopy##0#_wrap_scalar_and_deepcopy##1", CTModels.OCP.var"#_wrap_scalar_and_deepcopy##2#_wrap_scalar_and_deepcopy##3"}, SC_LB_Dual<:Union{CTModels.OCP.var"#_wrap_scalar_and_deepcopy##0#_wrap_scalar_and_deepcopy##1", CTModels.OCP.var"#_wrap_scalar_and_deepcopy##2#_wrap_scalar_and_deepcopy##3"}, SC_UB_Dual<:Union{CTModels.OCP.var"#_wrap_scalar_and_deepcopy##0#_wrap_scalar_and_deepcopy##1", CTModels.OCP.var"#_wrap_scalar_and_deepcopy##2#_wrap_scalar_and_deepcopy##3"}, CC_LB_Dual<:Union{CTModels.OCP.var"#_wrap_scalar_and_deepcopy##0#_wrap_scalar_and_deepcopy##1", CTModels.OCP.var"#_wrap_scalar_and_deepcopy##2#_wrap_scalar_and_deepcopy##3"}, CC_UB_Dual<:Union{CTModels.OCP.var"#_wrap_scalar_and_deepcopy##0#_wrap_scalar_and_deepcopy##1", CTModels.OCP.var"#_wrap_scalar_and_deepcopy##2#_wrap_scalar_and_deepcopy##3"}})}, CTModels.OCP.Solution{TimeGridModelType, TimesModelType, StateModelType, ControlModelType, VariableModelType, ModelType, CostateModelType, Float64, DualModelType, CTModels.OCP.SolverInfos{Any, Dict{Symbol, Any}}} where {TimeGridModelType<:Union{CTModels.OCP.MultipleTimeGridModel, CTModels.OCP.UnifiedTimeGridModel{Vector{Float64}}}, TimesModelType<:CTModels.OCP.TimesModel, StateModelType<:Union{CTModels.OCP.StateModelSolution{TS} where TS<:CTModels.OCP.var"#_wrap_scalar_and_deepcopy##0#_wrap_scalar_and_deepcopy##1", CTModels.OCP.StateModelSolution{TS} where TS<:CTModels.OCP.var"#_wrap_scalar_and_deepcopy##2#_wrap_scalar_and_deepcopy##3"}, ControlModelType<:Union{CTModels.OCP.ControlModelSolution{TS} where TS<:CTModels.OCP.var"#_wrap_scalar_and_deepcopy##0#_wrap_scalar_and_deepcopy##1", CTModels.OCP.ControlModelSolution{TS} where TS<:CTModels.OCP.var"#_wrap_scalar_and_deepcopy##2#_wrap_scalar_and_deepcopy##3"}, VariableModelType<:Union{CTModels.OCP.VariableModelSolution{Vector{Float64}}, CTModels.OCP.VariableModelSolution{Float64}}, ModelType<:(CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, T} where T<:CTModels.OCP.TimesModel), CostateModelType<:Union{CTModels.OCP.var"#_wrap_scalar_and_deepcopy##0#_wrap_scalar_and_deepcopy##1", CTModels.OCP.var"#_wrap_scalar_and_deepcopy##2#_wrap_scalar_and_deepcopy##3"}, DualModelType<:(CTModels.OCP.DualModel{PC_Dual, Vector{Float64}, SC_LB_Dual, SC_UB_Dual, CC_LB_Dual, CC_UB_Dual, Vector{Float64}, Vector{Float64}} where {PC_Dual<:Union{CTModels.OCP.var"#_wrap_scalar_and_deepcopy##0#_wrap_scalar_and_deepcopy##1", CTModels.OCP.var"#_wrap_scalar_and_deepcopy##2#_wrap_scalar_and_deepcopy##3"}, SC_LB_Dual<:Union{CTModels.OCP.var"#_wrap_scalar_and_deepcopy##0#_wrap_scalar_and_deepcopy##1", CTModels.OCP.var"#_wrap_scalar_and_deepcopy##2#_wrap_scalar_and_deepcopy##3"}, SC_UB_Dual<:Union{CTModels.OCP.var"#_wrap_scalar_and_deepcopy##0#_wrap_scalar_and_deepcopy##1", CTModels.OCP.var"#_wrap_scalar_and_deepcopy##2#_wrap_scalar_and_deepcopy##3"}, CC_LB_Dual<:Union{CTModels.OCP.var"#_wrap_scalar_and_deepcopy##0#_wrap_scalar_and_deepcopy##1", CTModels.OCP.var"#_wrap_scalar_and_deepcopy##2#_wrap_scalar_and_deepcopy##3"}, CC_UB_Dual<:Union{CTModels.OCP.var"#_wrap_scalar_and_deepcopy##0#_wrap_scalar_and_deepcopy##1", CTModels.OCP.var"#_wrap_scalar_and_deepcopy##2#_wrap_scalar_and_deepcopy##3"}})}}
Main entry point for optimal control problem resolution.
This function orchestrates the complete solve workflow by:
- Detecting the resolution mode (explicit vs descriptive) from arguments
- Extracting or creating the strategy registry for component completion
- Dispatching to the appropriate Layer 2 solver based on the detected mode
Arguments
ocp::CTModels.AbstractModel: The optimal control problem to solvedescription::Symbol...: Symbolic description tokens (e.g.,:collocation,:adnlp,:ipopt)kwargs...: All keyword arguments. Action options (initial_guess/init,display) are extracted by the appropriate Layer 2 function. Explicit components (discretizer,modeler,solver) are identified by abstract type. Aregistrykeyword can be provided to override the default strategy registry.
Returns
CTModels.AbstractSolution: Solution to the optimal control problem
Examples
# Descriptive mode (symbolic description)
solve(ocp, :collocation, :adnlp, :ipopt)
# With initial guess alias
solve(ocp, :collocation; init=x0, display=false)
# Explicit mode (typed components)
solve(ocp; discretizer=CTDirect.Collocation(),
modeler=CTSolvers.ADNLP(), solver=CTSolvers.Ipopt())Throws
CTBase.Exceptions.IncorrectArgument: If explicit components and symbolic description are mixed
Notes
- This is the main entry point (Layer 1) of the solve architecture
- Mode detection determines whether to use explicit or descriptive resolution path
- The registry can be injected for testing or customization purposes
- Action options and strategy-specific options are handled by Layer 2 functions
See also: _explicit_or_descriptive, solve_explicit, solve_descriptive, get_strategy_registry
CommonSolve.solve — Method
solve(
ocp::CTModels.OCP.AbstractModel,
initial_guess::CTModels.Init.AbstractInitialGuess,
discretizer::CTDirect.AbstractDiscretizer,
modeler::CTSolvers.Modelers.AbstractNLPModeler,
solver::CTSolvers.Solvers.AbstractNLPSolver;
display
)
Resolve an optimal control problem using fully specified, concrete components (Layer 3).
This is the lowest-level execution layer for solving an optimal control problem. It expects all components (initial guess, discretizer, modeler, and solver) to be fully instantiated and normalized. It discretizes the problem and passes it to the underlying solve pipeline.
Arguments
ocp::CTModels.AbstractModel: The optimal control problem to solveinitial_guess::CTModels.AbstractInitialGuess: Normalized initial guess for the solutiondiscretizer::CTDirect.AbstractDiscretizer: Concrete discretization strategymodeler::CTSolvers.AbstractNLPModeler: Concrete NLP modeling strategysolver::CTSolvers.AbstractNLPSolver: Concrete NLP solver strategydisplay::Bool: Whether to display the OCP configuration before solving
Returns
CTModels.AbstractSolution: The solution to the optimal control problem
Example
# Conceptual usage pattern for Layer 3 solve
ocp = Model(time=:final)
# ... define OCP ...
init = CTModels.build_initial_guess(ocp, nothing)
disc = CTDirect.Collocation(grid_size=100)
mod = CTSolvers.ADNLP()
sol = CTSolvers.Ipopt()
solution = solve(ocp, init, disc, mod, sol; display=true)Notes
- This is Layer 3 of the solve architecture - all inputs must be concrete, fully specified types
- No defaults, no normalization, no component completion occurs at this level
- The function performs: (1) optional configuration display, (2) problem discretization, (3) NLP solving
- This function is typically called by higher-level solvers (
solve_explicit,solve_descriptive)
See also: solve_explicit, solve_descriptive
CTModels.OCP.state — Function
state(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.TimesModel, T<:CTModels.OCP.AbstractStateModel}
) -> CTModels.OCP.AbstractStateModel
Return the state struct.
state(
sol::CTModels.OCP.Solution{<:CTModels.OCP.AbstractTimeGridModel, <:CTModels.OCP.AbstractTimesModel, <:CTModels.OCP.StateModelSolution{TS<:Function}}
) -> Function
Return the state as a function of time.
julia> x = state(sol)
julia> t0 = time_grid(sol)[1]
julia> x0 = x(t0) # state at the initial timestate(init::CTModels.Init.AbstractInitialGuess) -> Any
Return the state trajectory from an initial guess.
state(sol::CTModels.OCP.AbstractSolution) -> Function
Return the state trajectory from a solution.
CTModels.OCP.state_components — Function
state_components(ocp::CTModels.OCP.Model) -> Vector{String}
Return the names of the components of the state.
state_components(
sol::CTModels.OCP.Solution
) -> Vector{String}
Return the names of the components of the state.
CTModels.OCP.state_constraints_box — Function
state_constraints_box(
model::CTModels.OCP.ConstraintsModel{<:Tuple, <:Tuple, TS}
) -> Any
Get the state box constraints from the model.
Arguments
model: The constraints model from which to retrieve the state box constraints.
Returns
- The state box constraints.
Example
# Example of retrieving state box constraints
julia> model = ConstraintsModel(...)
julia> state_constraints = state_constraints_box(model)state_constraints_box(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.TimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.AbstractControlModel, <:CTModels.OCP.AbstractVariableModel, <:Function, <:CTModels.OCP.AbstractObjectiveModel, <:CTModels.OCP.ConstraintsModel{<:Tuple, <:Tuple, TS<:Tuple}}
) -> Any
Return the box constraints on state.
CTModels.OCP.state_constraints_lb_dual — Function
state_constraints_lb_dual(
model::CTModels.OCP.DualModel{<:Union{Nothing, Function}, <:Union{Nothing, AbstractVector{<:Real}}, SC_LB_Dual<:Union{Nothing, Function}}
) -> Union{Nothing, Function}
Return the dual function associated with the lower bounds of state constraints.
Arguments
model::DualModel: A model including dual variables for state lower bounds.
Returns
A function mapping time t to a vector of dual values, or nothing if not set.
state_constraints_lb_dual(
sol::CTModels.OCP.Solution
) -> Union{Nothing, Function}
Return the lower bound dual of the state constraints.
CTModels.OCP.state_constraints_ub_dual — Function
state_constraints_ub_dual(
model::CTModels.OCP.DualModel{<:Union{Nothing, Function}, <:Union{Nothing, AbstractVector{<:Real}}, <:Union{Nothing, Function}, SC_UB_Dual<:Union{Nothing, Function}}
) -> Union{Nothing, Function}
Return the dual function associated with the upper bounds of state constraints.
Arguments
model::DualModel: A model including dual variables for state upper bounds.
Returns
A function mapping time t to a vector of dual values, or nothing if not set.
state_constraints_ub_dual(
sol::CTModels.OCP.Solution
) -> Union{Nothing, Function}
Return the upper bound dual of the state constraints.
CTModels.OCP.state_dimension — Function
state_dimension(ocp::CTModels.OCP.PreModel) -> Int64
Return the state dimension of the PreModel.
Throws Exceptions.PreconditionError if state has not been set.
state_dimension(ocp::CTModels.OCP.Model) -> Int64
Return the state dimension.
state_dimension(sol::CTModels.OCP.Solution) -> Int64
Return the dimension of the state.
CTModels.OCP.state_name — Function
state_name(ocp::CTModels.OCP.Model) -> String
Return the name of the state.
state_name(sol::CTModels.OCP.Solution) -> String
Return the name of the state.
CTModels.OCP.status — Function
status(sol::CTModels.OCP.Solution) -> Symbol
Return the status criterion (a Symbol).
Base.success — Function
success(command)Run a command object, constructed with backticks (see the Running External Programs section in the manual), and tell whether it was successful (exited with a code of 0). An exception is raised if the process cannot be started.
CTModels.OCP.successful — Function
successful(sol::CTModels.OCP.Solution) -> Bool
Return the successful status.
Base.Libc.time — Function
time() -> Float64Get the system time in seconds since the epoch, with fairly high (typically, microsecond) resolution.
See also time_ns.
time(t::TmStruct) -> Float64Converts a TmStruct struct to a number of seconds since the epoch.
time(model::CTModels.OCP.FixedTimeModel{T<:Real}) -> Real
Get the time from the fixed time model.
time(
model::CTModels.OCP.FreeTimeModel,
variable::AbstractArray{T<:Real, 1}
) -> Any
Get the time from the free time model.
Exceptions
- If the index of the time variable is not in [1, length(variable)], throw an error.
CTModels.OCP.time_grid — Function
time_grid(
sol::CTModels.OCP.Solution{<:CTModels.OCP.UnifiedTimeGridModel{T<:Union{StepRangeLen, AbstractVector{<:Real}}}}
) -> Union{StepRangeLen, AbstractVector{<:Real}}
Return the time grid for solutions with unified time grid.
time_grid(
sol::CTModels.OCP.Solution{<:CTModels.OCP.UnifiedTimeGridModel{T<:Union{StepRangeLen, AbstractVector{<:Real}}}},
component::Symbol
) -> Union{StepRangeLen, AbstractVector{<:Real}}
Return the time grid for a specific component.
Arguments
sol::Solution: The solution (unified or multiple time grids)component::Symbol: The component (:state, :control, :path) Also accepted: :costate/:costates (→ :state), :dual/:duals (→ :path), :stateboxconstraint(s) (→ :state), :controlboxconstraint(s) (→ :control), plural forms (:states, :controls)
Returns
TimesDisc: The time grid for the specified component
Behavior
- For
UnifiedTimeGridModel: Returns the unique time grid for any component - For
MultipleTimeGridModel: Returns the specific time grid for the component
Throws
IncorrectArgument: If component is not one of the valid symbols
Examples
julia> time_grid(sol, :state) # Works for both unified and multiple grids
julia> time_grid(sol, :control) # Works for both unified and multiple grids
julia> time_grid(sol, :costate) # Maps to :state grid
julia> time_grid(sol, :dual) # Maps to :path gridtime_grid(
sol::CTModels.OCP.Solution{<:CTModels.OCP.MultipleTimeGridModel},
component::Symbol
) -> Union{StepRangeLen, AbstractVector{<:Real}}
Return the time grid for a specific component in solutions with multiple time grids.
Arguments
sol::Solution: The solution with multiple time gridscomponent::Symbol: The component (:state, :control, :path) Also accepted: :costate/:costates (→ :state), :dual/:duals (→ :path), :stateboxconstraint(s) (→ :state), :controlboxconstraint(s) (→ :control), plural forms (:states, :controls)
Returns
TimesDisc: The time grid for the specified component
Throws
IncorrectArgument: If component is not one of the valid symbols
Examples
julia> time_grid(sol, :state) # Get state time grid
julia> time_grid(sol, :control) # Get control time grid
julia> time_grid(sol, :costate) # Maps to state time grid
julia> time_grid(sol, :dual) # Maps to path time gridtime_grid(
sol::CTModels.OCP.Solution{<:CTModels.OCP.MultipleTimeGridModel}
)
Return the time grid for solutions with multiple time grids (component must be specified).
Throws
IncorrectArgument: Always thrown for MultipleTimeGridModel without component specification
Notes
This method enforces explicit component specification for solutions with multiple time grids to avoid ambiguity about which grid is being accessed.
Examples
julia> time_grid(sol) # ❌ Error for MultipleTimeGridModel
julia> time_grid(sol, :state) # ✅ Correct usageCTModels.OCP.time_name — Function
time_name(model::CTModels.OCP.TimesModel) -> String
Get the name of the time variable from the times model.
time_name(ocp::CTModels.OCP.Model) -> String
Return the name of the time.
time_name(sol::CTModels.OCP.Solution) -> String
Return the name of the time component.
CTModels.OCP.times — Function
times(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, T<:CTModels.OCP.TimesModel}
) -> CTModels.OCP.TimesModel
Return the times struct.
times(
sol::CTModels.OCP.Solution{<:CTModels.OCP.AbstractTimeGridModel, TM<:CTModels.OCP.AbstractTimesModel}
) -> CTModels.OCP.AbstractTimesModel
Return the times model.
CTModels.OCP.variable_components — Function
variable_components(
ocp::CTModels.OCP.Model
) -> Vector{String}
Return the names of the components of the variable.
variable_components(
sol::CTModels.OCP.Solution
) -> Vector{String}
Return the names of the components of the variable.
CTModels.OCP.variable_constraints_box — Function
variable_constraints_box(
model::CTModels.OCP.ConstraintsModel{<:Tuple, <:Tuple, <:Tuple, <:Tuple, TV}
) -> Any
Get the variable box constraints from the model.
Arguments
model: The constraints model from which to retrieve the variable box constraints.
Returns
- The variable box constraints.
Example
# Example of retrieving variable box constraints
julia> model = ConstraintsModel(...)
julia> variable_constraints = variable_constraints_box(model)variable_constraints_box(
ocp::CTModels.OCP.Model{<:CTModels.OCP.TimeDependence, <:CTModels.OCP.TimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.AbstractControlModel, <:CTModels.OCP.AbstractVariableModel, <:Function, <:CTModels.OCP.AbstractObjectiveModel, <:CTModels.OCP.ConstraintsModel{<:Tuple, <:Tuple, <:Tuple, <:Tuple, TV<:Tuple}}
) -> Any
Return the box constraints on variable.
CTModels.OCP.variable_constraints_lb_dual — Function
variable_constraints_lb_dual(
model::CTModels.OCP.DualModel{<:Union{Nothing, Function}, <:Union{Nothing, AbstractVector{<:Real}}, <:Union{Nothing, Function}, <:Union{Nothing, Function}, <:Union{Nothing, Function}, <:Union{Nothing, Function}, VC_LB_Dual<:Union{Nothing, AbstractVector{<:Real}}}
) -> Union{Nothing, AbstractVector{<:Real}}
Return the dual vector associated with the lower bounds of variable constraints.
Arguments
model::DualModel: A model including dual variables for variable lower bounds.
Returns
A vector of dual values, or nothing if not set.
variable_constraints_lb_dual(
sol::CTModels.OCP.Solution
) -> Union{Nothing, AbstractVector{<:Real}}
Return the lower bound dual of the variable constraints.
CTModels.OCP.variable_constraints_ub_dual — Function
variable_constraints_ub_dual(
model::CTModels.OCP.DualModel{<:Union{Nothing, Function}, <:Union{Nothing, AbstractVector{<:Real}}, <:Union{Nothing, Function}, <:Union{Nothing, Function}, <:Union{Nothing, Function}, <:Union{Nothing, Function}, <:Union{Nothing, AbstractVector{<:Real}}, VC_UB_Dual<:Union{Nothing, AbstractVector{<:Real}}}
) -> Union{Nothing, AbstractVector{<:Real}}
Return the dual vector associated with the upper bounds of variable constraints.
Arguments
model::DualModel: A model including dual variables for variable upper bounds.
Returns
A vector of dual values, or nothing if not set.
variable_constraints_ub_dual(
sol::CTModels.OCP.Solution
) -> Union{Nothing, AbstractVector{<:Real}}
Return the upper bound dual of the variable constraints.
CTModels.OCP.variable_dimension — Function
variable_dimension(ocp::CTModels.OCP.Model) -> Int64
Return the variable dimension.
variable_dimension(sol::CTModels.OCP.Solution) -> Int64
Return the dimension of the variable.
CTModels.OCP.variable_name — Function
variable_name(ocp::CTModels.OCP.Model) -> String
Return the name of the variable.
variable_name(sol::CTModels.OCP.Solution) -> String
Return the name of the variable.
CTFlows.:⋅ — Function
Lie derivative of a scalar function along a vector field in the autonomous case.
Example:
julia> φ = x -> [x[2], -x[1]]
julia> X = VectorField(φ)
julia> f = x -> x[1]^2 + x[2]^2
julia> (X⋅f)([1, 2])
0Lie derivative of a scalar function along a vector field in the nonautonomous case.
Example:
julia> φ = (t, x, v) -> [t + x[2] + v[1], -x[1] + v[2]]
julia> X = VectorField(φ, NonAutonomous, NonFixed)
julia> f = (t, x, v) -> t + x[1]^2 + x[2]^2
julia> (X⋅f)(1, [1, 2], [2, 1])
10Lie derivative of a scalar function along a function (considered autonomous and non-variable).
Example:
julia> φ = x -> [x[2], -x[1]]
julia> f = x -> x[1]^2 + x[2]^2
julia> (φ⋅f)([1, 2])
0
julia> φ = (t, x, v) -> [t + x[2] + v[1], -x[1] + v[2]]
julia> f = (t, x, v) -> t + x[1]^2 + x[2]^2
julia> (φ⋅f)(1, [1, 2], [2, 1])
MethodError