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.

Beware!

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)
4

Exported functions and types

OptimalControl.OptimalControlModule
OptimalControl

High-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

See Also

  • solve: Main entry point for solving optimal control problems
  • methods: List available solving methods
  • CTBase: Core types and abstractions
  • CTDirect: Direct methods for discretization
  • CTSolvers: NLP solvers and orchestration

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 F to G at t_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_switch and a switch from F to G.

Example

julia> F * (1.0, η, G)
CTFlows.FlowFunction
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 using CTModels.
  • u::CTFlows.ControlLaw: A feedback control law generated by ControlLaw(...) 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 from t0 to tf.
  • 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 ocp is autonomous: u(x, p)
    • If non-autonomous: u(t, x, p)
  • 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)
Warning

All input functions must match the autonomous/non-autonomous nature of the problem.

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 of autonomous and variable.
  • autonomous: Whether the dynamics are time-independent (false by default).
  • variable: Whether the dynamics depend on a control or parameter v.
  • alg, abstol, reltol, saveat, internalnorm: Solver settings passed to OrdinaryDiffEq.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.@LieMacro

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 variable v.

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 variable v (default: false).

Bracket type detection

  • Square brackets [...] denote Lie brackets between VectorField objects.
  • Curly brackets {...} denote Poisson brackets between Hamiltonian objects or between raw functions.
  • The macro automatically dispatches to Lie or Poisson depending 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.0
julia> 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.0
julia> 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.0
CTFlows.LieFunction

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])
10

Lie 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])
10

Lie 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.LiftFunction
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 HamiltonianLift callable object representing the Hamiltonian lift of X.

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 2
Lift(
    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) if autonomous=true and variable=false
  • (x, p, v) if autonomous=true and variable=true
  • (t, x, p) if autonomous=false and variable=false
  • (t, x, p, v) if autonomous=false and variable=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 2
CTFlows.PoissonFunction
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])     # -20
Poisson(
    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])     # -76
Poisson(
    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])     # 100
Poisson(
    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])     # -76
Poisson(
    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])     # -76
Poisson(
    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])     # -76
CTModels.OCP.boundary_constraints_dualFunction
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_nlFunction
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.bypassFunction
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_to for strategy-specific bypassing
  • force is an alias for bypass - they are identical functions

See also: BypassValue, route_to, force

CTModels.OCP.componentsFunction
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.

Missing docstring.

Missing docstring for constraint. Check Documenter's build log for details.

CTModels.OCP.constraintsFunction
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.controlFunction
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 time
control(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_componentsFunction
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_boxFunction
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_dualFunction
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_dualFunction
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_dimensionFunction
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_nameFunction
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.costateFunction
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 time
CTModels.OCP.criterionFunction
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.@defMacro

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 log
CTModels.OCP.definitionFunction
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 or nothing if not set.
CTSolvers.Strategies.describeFunction

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 mode

See also: metadata, id, options

CTModels.OCP.dim_boundary_constraints_nlFunction
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_boxFunction
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_nlFunction
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_boxFunction
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_boxFunction
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.dimensionFunction
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.

Missing docstring.

Missing docstring for discretize. Check Documenter's build log for details.

CTModels.OCP.dualFunction
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.dynamicsFunction
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_solutionFunction
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 :JLD or :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 .json extension 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 .jld2 extension 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_timeFunction
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_nameFunction
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_examodelFunction
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_timeFunction
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_timeFunction
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_timeFunction
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_timeFunction
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_costFunction
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_costFunction
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_optionFunction
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 instance
  • key::Symbol: The option name

Returns

  • Bool: true if 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)
false

See also: option_value, option_source

CTSolvers.Strategies.idFunction

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)
:mystrategy
CTModels.Serialization.import_ocp_solutionFunction
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 :JLD or :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 .json extension 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 .jld2 extension 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.indexFunction
index(model::CTModels.OCP.FreeTimeModel) -> Int64

Get the index of the time variable from the free time model.

CTModels.OCP.infosFunction
infos(sol::CTModels.OCP.Solution) -> Dict{Symbol, Any}

Return a dictionary of additional infos depending on the solver or nothing.

CTParser.@initMacro
@init ocp begin
    ...
end

Build 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 above

The 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 = true

When 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 (default false) enabling textual logging of the parsed specification.

Returns

  • AbstractInitialGuess: backend-specific initial guess object produced by the current backend (par défaut CTModels).

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
true
CTModels.OCP.initial_timeFunction
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_nameFunction
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_autonomousFunction
is_autonomous(
    ocp::CTModels.OCP.PreModel
) -> Union{Nothing, Bool}

Check whether the system is autonomous.

Arguments

  • ocp::PreModel: The optimal control problem.

Returns

  • Bool: true if the system is autonomous (i.e., does not explicitly depend on time), false otherwise.

Example

julia> is_autonomous(ocp)  # returns true or false
is_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_computedFunction
is_computed(opt::CTSolvers.Options.OptionValue) -> Bool

Check if this option value was computed from other options.

Returns

  • Bool: true if the source is :computed

Example

opt = OptionValue(100, :computed)
is_computed(opt)  # true

See 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: true if 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)
true

See 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 options
  • key::Symbol: Option name

Returns

  • Bool: true if the option was computed

Example

julia> Options.is_computed(opts, :step)
true

See also: Options.source, Options.is_user, Options.is_default

CTSolvers.Options.is_defaultFunction
is_default(opt::CTSolvers.Options.OptionValue) -> Bool

Check if this option value is using its default.

Returns

  • Bool: true if the source is :default

Example

opt = OptionValue(100, :default)
is_default(opt)  # true

See 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 options
  • key::Symbol: Option name

Returns

  • Bool: true if the option is using its default value

Example

julia> Options.is_default(opts, :tol)
true

See also: Options.source, Options.is_user, Options.is_computed

CTModels.OCP.is_emptyFunction
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: Always true for empty time grid models

Example

julia> etg = CTModels.EmptyTimeGridModel()
julia> CTModels.is_empty(etg)
true
is_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: Always false for non-empty time grid models

Example

julia> T = LinRange(0, 1, 101)
julia> utg = CTModels.UnifiedTimeGridModel(T)
julia> CTModels.is_empty(utg)
false
CTModels.OCP.is_final_time_fixedFunction

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_freeFunction

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_fixedFunction

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_freeFunction

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_definedFunction

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_definedFunction

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_userFunction
is_user(opt::CTSolvers.Options.OptionValue) -> Bool

Check if this option value was explicitly provided by the user.

Returns

  • Bool: true if the source is :user

Example

opt = OptionValue(100, :user)
is_user(opt)  # true

See 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 options
  • key::Symbol: Option name

Returns

  • Bool: true if the option was provided by the user

Example

julia> Options.is_user(opts, :max_iter)
true

See also: Options.source, Options.is_default, Options.is_computed

CTModels.OCP.iterationsFunction
iterations(sol::CTModels.OCP.Solution) -> Int64

Return the number of iterations (if solved by an iterative method).

CTModels.OCP.lagrangeFunction
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.mayerFunction
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.messageFunction
message(sol::CTModels.OCP.Solution) -> String

Return the message associated to the status criterion.

CTSolvers.Strategies.metadataFunction

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.methodsFunction
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.

Julia 1.4

At least Julia 1.4 is required for specifying a module.

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 (:cpu or :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 :collocation discretization
  • 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.complete to complete partial method descriptions

See also: solve, CTBase.Descriptions.complete, get_strategy_registry

CTModels.OCP.modelFunction
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.nameFunction
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_modelFunction
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 OCP
  • initial_guess: Initial guess for the NLP solver
  • modeler: 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

Missing docstring.

Missing docstring for objective. Check Documenter's build log for details.

CTSolvers.DOCP.ocp_modelFunction
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_solutionFunction
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 OCP
  • model_solution::SolverCore.AbstractExecutionStats: NLP solver output
  • modeler: 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_defaultFunction
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 type
  • key::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-6

Throws

  • 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_defaultsFunction
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
100

Notes

  • 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_descriptionFunction
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 type
  • key::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_namesFunction
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: backend

Notes

  • 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_sourceFunction
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 instance
  • key::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)
:default

Throws

  • KeyError: If the option name does not exist

See also: option_value, is_user, is_default

CTSolvers.Strategies.option_typeFunction
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 type
  • key::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)
Float64

Throws

  • 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_valueFunction
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 instance
  • key::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-6

Throws

  • KeyError: If the option name does not exist

See also: option_source, options

CTSolvers.Strategies.optionsFunction

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_dualFunction
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_nlFunction
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.plotFunction

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 plot
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,
    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.
    • :normalize or :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.Plot object, 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_toFunction
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.solveMethod
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 problem
  • initial_guess: Initial guess for the solution
  • modeler::Modelers.AbstractNLPModeler: Modeler to build NLP
  • solver::AbstractNLPSolver: Solver to use
  • display::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.solveMethod
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:

  1. Detecting the resolution mode (explicit vs descriptive) from arguments
  2. Extracting or creating the strategy registry for component completion
  3. Dispatching to the appropriate Layer 2 solver based on the detected mode

Arguments

  • ocp::CTModels.AbstractModel: The optimal control problem to solve
  • description::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. A registry keyword 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

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.solveMethod
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 solve
  • initial_guess::CTModels.AbstractInitialGuess: Normalized initial guess for the solution
  • discretizer::CTDirect.AbstractDiscretizer: Concrete discretization strategy
  • modeler::CTSolvers.AbstractNLPModeler: Concrete NLP modeling strategy
  • solver::CTSolvers.AbstractNLPSolver: Concrete NLP solver strategy
  • display::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.stateFunction
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 time
state(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_componentsFunction
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_boxFunction
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_dualFunction
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_dualFunction
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_dimensionFunction
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_nameFunction
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.statusFunction
status(sol::CTModels.OCP.Solution) -> Symbol

Return the status criterion (a Symbol).

Base.successFunction
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.

Base.Libc.timeFunction
time() -> Float64

Get the system time in seconds since the epoch, with fairly high (typically, microsecond) resolution.

See also time_ns.

time(t::TmStruct) -> Float64

Converts 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_gridFunction
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 grid
time_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 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

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 grid
time_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 usage
CTModels.OCP.time_nameFunction
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.timesFunction
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.

Missing docstring.

Missing docstring for variable. Check Documenter's build log for details.

CTModels.OCP.variable_componentsFunction
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_boxFunction
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_dualFunction
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_dualFunction
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_dimensionFunction
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_nameFunction
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])
0

Lie 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])
10

Lie 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