Private API
This page lists non-exported (internal) symbols of CTModels.Display, CTModelsPlots, CTModels.Solutions, CTModelsJSON, CTModelsJLD, CTModels.Components, CTModels.Building, CTModels.Init, CTModels.Models, CTModels.Serialization.
From CTModels.Display
__print [Function]
CTModels.Display.__print Function
__print(e::Expr, io::IO, l::Int64)Print an expression with indentation.
Arguments
e::Expr: The expression to print.io::IO: The output stream.l::Int: The indentation level (number of spaces).
Returns
Nothing: Prints toioand returns nothing.
__print_mathematical_definition [Function]
CTModels.Display.__print_mathematical_definition Function
__print_mathematical_definition(
io::IO,
some_printing::Bool,
x_dim::Int64,
u_dim::Int64,
v_dim::Int64,
t_name::String,
t0_name::String,
tf_name::String,
x_name::String,
u_name::String,
v_name::String,
xi_names::Vector{String},
ui_names::Vector{String},
vi_names::Vector{String},
is_variable_dependent::Bool,
is_time_dependent::Bool,
is_control_free_ocp::Bool,
has_a_lagrange_cost::Bool,
has_a_mayer_cost::Bool,
dim_path_cons_nl::Int64,
dim_boundary_cons_nl::Int64,
dim_state_cons_box::Int64,
dim_control_cons_box::Int64,
dim_variable_cons_box::Int64
) -> BoolPrint the mathematical definition of an optimal control problem.
Displays the problem in standard mathematical notation with objective, dynamics, and constraints.
When u_dim == 0 (no control input), all control-dependent parts of the output are suppressed:
The objective is rendered as
J(x, v)instead ofJ(x, u, v).Dynamics arguments omit the control:
f(t, x, v)instead off(t, x, u, v).The "where" clause lists only
x(andvif variable-dependent).Box constraints on control are not listed.
Arguments
io::IO: The output stream.some_printing::Bool: Whether content has already been printed.x_dim::Int: State dimension.u_dim::Int: Control dimension.v_dim::Int: Variable dimension.t_name::String: Time variable name.t0_name::String: Initial time name.tf_name::String: Final time name.x_name::String: State variable name.u_name::String: Control variable name.v_name::String: Variable name.xi_names::Vector{String}: State component names.ui_names::Vector{String}: Control component names.vi_names::Vector{String}: Variable component names.is_variable_dependent::Bool: Whether the problem depends on variables.is_time_dependent::Bool: Whether the problem is non-autonomous.is_control_free_ocp::Bool: Whether the problem has no control input.has_a_lagrange_cost::Bool: Whether the problem has a Lagrange cost.has_a_mayer_cost::Bool: Whether the problem has a Mayer cost.dim_path_cons_nl::Int: Dimension of nonlinear path constraints.dim_boundary_cons_nl::Int: Dimension of nonlinear boundary constraints.dim_state_cons_box::Int: Dimension of state box constraints.dim_control_cons_box::Int: Dimension of control box constraints.dim_variable_cons_box::Int: Dimension of variable box constraints.
Returns
Bool:trueif something was printed.
See also: CTModels.Display._print_abstract_definition.
_print_abstract_definition [Function]
CTModels.Display._print_abstract_definition Function
_print_abstract_definition(
_::IO,
_::CTModels.Components.EmptyDefinition
) -> BoolPrint a CTModels.Components.EmptyDefinition: no output is produced.
Returns
Bool:falseto indicate that nothing was printed.
_print_abstract_definition(
io::IO,
d::CTModels.Components.Definition
) -> BoolPrint a CTModels.Components.Definition under an "Abstract definition:" header.
Block expressions are unfolded line-by-line; other expression heads are printed as a single indented entry.
Arguments
io::IO: The output stream.d::Definition: The symbolic definition to display.
Returns
Bool:trueto indicate that output was produced.
See also: CTModels.Display.__print.
From CTModelsPlots
_BOUND_STYLE [Constant]
CTModelsPlots._BOUND_STYLE Constant
Default style for box-bound and path-bound horizontal reference lines.
_TIME_STYLE [Constant]
CTModelsPlots._TIME_STYLE Constant
Default style for initial/final time vertical reference lines.
__control_layout [Function]
CTModelsPlots.__control_layout Function
__control_layout() -> SymbolReturn the default control representation (:components).
__description [Function]
CTModelsPlots.__description Function
__description() -> NTuple{12, Symbol}Return the default description tuple used when the user gives none.
Aliases are included so that clean collapses them to the canonical set.
__plot_label_suffix [Function]
CTModelsPlots.__plot_label_suffix Function
__plot_label_suffix() -> StringReturn the default suffix appended to plot labels (empty string).
__plot_layout [Function]
CTModelsPlots.__plot_layout Function
__plot_layout() -> SymbolReturn the default plot layout (:split).
__plot_style [Function]
CTModelsPlots.__plot_style Function
__plot_style() -> @NamedTuple{}Return the default plotting style (empty NamedTuple).
__time_normalization [Function]
CTModelsPlots.__time_normalization Function
__time_normalization() -> SymbolReturn the default time-axis normalization (:default).
_assemble_group [Function]
CTModelsPlots._assemble_group Function
_assemble_group(
cells::AbstractVector{<:CTBase.Plotting.AbstractLayoutNode}
) -> AnyAssemble group cells horizontally (:group layout).
Exactly four cells (state, costate, control, control-norm) fold into a 2×2 grid.
_assemble_split [Function]
CTModelsPlots._assemble_split Function
_assemble_split(
;
state,
costate,
control,
path,
dual
) -> Union{Nothing, CTBase.Plotting.AbstractLayoutNode}Assemble stacked columns (:split layout).
The layout is (state | costate) over control over (path | dual). Returns nothing when there is nothing to draw.
_base_style [Function]
CTModelsPlots._base_style Function
_base_style(style::NamedTuple) -> NamedTupleReturn the default per-series style, merged with any user-supplied group style.
_box_hlines [Function]
CTModelsPlots._box_hlines Function
_box_hlines(
box,
ncomp::Int64,
style::NamedTuple
) -> Vector{Vector{CTBase.Plotting.HLine}}Build per-component horizontal bound lines from a box constraint tuple.
For a panel with ncomp components, hlines[i] holds the lines for component i.
_build_root [Function]
CTModelsPlots._build_root Function
_build_root(
sol,
description::Symbol...;
layout,
control,
time,
state_style,
costate_style,
control_style,
path_style,
dual_style,
time_style,
state_bounds_style,
control_bounds_style,
path_bounds_style
)Build the CTBase.Plotting layout tree for a CTModels solution.
Returns nothing if there is nothing to draw. Decorations (bounds, initial/final time lines) are added according to the user-supplied style keywords.
_control_panels [Function]
CTModelsPlots._control_panels Function
_control_panels(
sol,
control::Symbol,
style::NamedTuple,
layout::Symbol
) -> Vector{CTBase.Plotting.Panel}Build one or more CTBase.Plotting.Panel objects for the control trajectory.
control = :components: one panel with a curve per control component.control = :norm: one panel with the Euclidean norm of the control.control = :all: both panels (in:group) or a single panel with components and norm (in:split).
Returns
Vector{Plotting.Panel}: The panels to be assembled into the layout.
_costate_panel [Function]
CTModelsPlots._costate_panel Function
_costate_panel(sol, style::NamedTuple; layout, state_shown)Build a CTBase.Plotting.Panel for the costate trajectory.
Labels depend on layout and whether the state panel is shown alongside.
_dual_panel [Function]
CTModelsPlots._dual_panel Function
_dual_panel(sol, model, style::NamedTuple; path_shown)Build a CTBase.Plotting.Panel for the dual variables of the path constraints.
_pair [Function]
CTModelsPlots._pair Function
_pair(a, b) -> AnyPair two layout columns side by side, tolerating a missing one.
If both are present, returns a Plotting.Paired; otherwise returns the non-nothing one.
_path_hlines [Function]
CTModelsPlots._path_hlines Function
_path_hlines(model, style::NamedTuple) -> AnyBuild bound lines for nonlinear path constraints.
Each of the nc components carries lower and upper bound lines.
_path_panel [Function]
CTModelsPlots._path_panel Function
_path_panel(
sol,
model,
style::NamedTuple
) -> CTBase.Plotting.PanelBuild a CTBase.Plotting.Panel for the nonlinear path constraints.
_plot [Function]
CTModelsPlots._plot Function
_plot(
sol::CTModels.Solutions.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...
) -> AnyInternal implementation of Plots.plot(::CTModels.Solution).
Builds the layout tree and renders it via CTBase.Plotting.
_plot! [Function]
CTModelsPlots._plot! Function
_plot!(
p::Plots.Plot,
sol::CTModels.Solutions.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.PlotInternal implementation of Plots.plot!(::Plots.Plot, ::CTModels.Solution).
Builds the layout tree and overlays it onto the existing plot p via CTBase.Plotting.
_rownorm [Function]
_sample [Function]
CTModelsPlots._sample Function
_sample(f, T) -> AnySample a callable f over grid T into an (n_times, n_components) matrix.
Uniform for scalar and vector-valued f.
_state_panel [Function]
CTModelsPlots._state_panel Function
_state_panel(
sol,
style::NamedTuple
) -> CTBase.Plotting.PanelBuild a CTBase.Plotting.Panel for the state trajectory.
_time_name [Function]
CTModelsPlots._time_name Function
_time_name(sol, time::Symbol) -> StringReturn the time-axis label, with the historical "(normalized)" suffix when time is rescaled.
_time_vlines [Function]
CTModelsPlots._time_vlines Function
_time_vlines(
sol,
model,
time::Symbol,
style::NamedTuple
) -> Vector{CTBase.Plotting.VLine}Build initial/final time vertical lines shared by every cell.
Positions are [0, 1] under time normalisation, otherwise read from the model (variable-dependent for free time).
clean [Function]
CTModelsPlots.clean Function
clean(description) -> TupleCollapse plural/alias forms to canonical singular symbols and drop duplicates.
For example, (:states, :controls, :cons, :duals) becomes (:state, :control, :path, :dual).
Arguments
description: A tuple of symbols from the caller.
Returns
Tuple{Symbol...}: Cleaned, unique, canonical symbols.
do_decorate [Function]
CTModelsPlots.do_decorate Function
do_decorate(
;
model,
time_style,
state_bounds_style,
control_bounds_style,
path_bounds_style
)Decide which decorations to draw (bounds lines and initial/final time lines).
Each decoration needs a non-:none style and a model to read the bounds/times from.
Returns
NTuple{4, Bool}: flags for(time, state_bounds, control_bounds, path_bounds).
do_plot [Function]
CTModelsPlots.do_plot Function
do_plot(
sol::CTModels.Solutions.AbstractSolution,
description::Symbol...;
state_style,
control_style,
costate_style,
path_style,
dual_style
)Decide which signal groups to draw for the given solution and description.
A group is drawn when it is requested, its style is not :none, and it actually exists in the solution:
control needs
control_dimension(sol) > 0,path needs
dim_path_constraints_nl(ocp) > 0,dual needs
path_constraints_dual(sol)to be present.
Returns
NTuple{5, Bool}: flags for(state, costate, control, path, dual).
From CTModels.Solutions
BoxDualDiff [Struct]
CTModels.Solutions.BoxDualDiff Type
BoxDualDiff{DL,DU,I} <: FunctionCallable struct computing the net dual of a box constraint: f(t) = lb(t)[idx] - ub(t)[idx].
I = Int gives a scalar; I = Vector{Int} gives a vector.
Replaces anonymous closures t -> duals_lb(t)[i] - duals_ub(t)[i] (and the vector variant) produced by dual(sol, model, label) for state and control box constraints.
DualSlice [Struct]
CTModels.Solutions.DualSlice Type
DualSlice{D,I} <: FunctionCallable struct extracting a slice of a time-dependent dual vector: f(t) = duals(t)[idx].
I = Int gives a scalar; I = Vector{Int} gives a vector. The scalar/vector distinction is encoded in the type parameter so the call method is fully specialised (no runtime branch).
Replaces anonymous closures t -> duals(t)[indices[1]] and t -> duals(t)[indices] produced by dual(sol, model, label).
_discretize_all_components [Function]
CTModels.Solutions._discretize_all_components Function
_discretize_all_components(
sol::CTModels.Solutions.Solution,
T_state::Vector{Float64},
T_control::Vector{Float64},
T_costate::Vector{Float64},
T_path::Vector{Float64},
dim_x::Int64,
dim_u::Int64
) -> Dict{String, Any}Discretize all solution components on their respective time grids for serialization.
This internal helper function extracts the common discretization logic shared by both UnifiedTimeGridModel and MultipleTimeGridModel serialization. It evaluates all trajectory functions on their associated time grids and assembles them into a dictionary.
Grid-Component Association
Each component is discretized on its semantically correct time grid:
State trajectory →
T_stategridControl trajectory →
T_controlgridCostate trajectory →
T_costategridPath constraint duals →
T_pathgridState box constraint duals (lb/ub) →
T_stategridControl box constraint duals (lb/ub) →
T_controlgridBoundary/variable duals → Time-independent (vectors, not discretized)
Arguments
sol::Solution: Solution object containing trajectory functionsT_state::Vector{Float64}: Time grid for state discretizationT_control::Vector{Float64}: Time grid for control discretizationT_costate::Vector{Float64}: Time grid for costate discretizationT_path::Vector{Float64}: Time grid for path constraint dual discretizationdim_x::Int: State dimension (for validation)dim_u::Int: Control dimension (for validation)
Returns
Dict{String, Any}: Dictionary with all discretized components (grids not included)
Notes
This function does NOT include time grid data in the returned dictionary. The calling function (_serialize_solution for UnifiedTimeGridModel or MultipleTimeGridModel) is responsible for adding the appropriate grid keys.
See also: _serialize_solution, _discretize_function, _discretize_dual
_discretize_dual [Function]
CTModels.Solutions._discretize_dual Function
_discretize_dual(
dual_func::Union{Nothing, Function},
T
) -> Union{Nothing, Matrix{Float64}}
_discretize_dual(
dual_func::Union{Nothing, Function},
T,
dim::Int64
) -> Union{Nothing, Matrix{Float64}}Discretize a dual function, returning nothing if the input is nothing.
Arguments
dual_func::Union{Function,Nothing}: Dual function ornothing.T: Time grid.dim::Int: Dimension (auto-detected if -1).
Returns
Matrix{Float64}ifdual_funcis a function.nothingifdual_funcisnothing.
See also: CTModels.Solutions._discretize_function.
_discretize_function [Function]
CTModels.Solutions._discretize_function Function
_discretize_function(
f::Function,
T::AbstractVector
) -> Matrix{Float64}
_discretize_function(
f::Function,
T::AbstractVector,
dim::Int64
) -> Matrix{Float64}Discretize a function on a time grid.
Evaluates f at each point in T and collects the results into a matrix. If dim is -1, the output dimension is auto-detected from the first evaluation of f.
Arguments
f::Function: Function to discretize (can return a scalar or a vector).T::AbstractVector: Time grid.dim::Int: Expected dimension of the result. If -1, auto-detected from first evaluation.
Returns
Matrix{Float64}: n×dim matrix where n = length(T).
Examples
# Scalar function
f_scalar = t -> 2.0 * t
result = _discretize_function(f_scalar, [0.0, 0.5, 1.0], 1)
# result = [0.0; 1.0; 2.0]
# Vector function
f_vec = t -> [t, 2*t]
result = _discretize_function(f_vec, [0.0, 0.5, 1.0], 2)
# result = [0.0 0.0; 0.5 1.0; 1.0 2.0]
# Auto-detect dimension
result = _discretize_function(f_vec, [0.0, 0.5, 1.0])
# result = [0.0 0.0; 0.5 1.0; 1.0 2.0]See also: CTModels.Solutions._discretize_dual.
_discretize_function(
f::Function,
T::CTModels.Solutions.UnifiedTimeGridModel
) -> Matrix{Float64}
_discretize_function(
f::Function,
T::CTModels.Solutions.UnifiedTimeGridModel,
dim::Int64
) -> Matrix{Float64}Discretize a function on a TimeGridModel by extracting the underlying time grid.
See also: CTModels.Solutions._discretize_function.
_dual_dimension [Function]
CTModels.Solutions._dual_dimension Function
_dual_dimension(
_::Nothing,
_::CTModels.Solutions.Solution
) -> Int64Return the dimension of a dual value, evaluating at initial time.
Arguments
dual::Union{Nothing, Function}: The dual function or nothing.sol::Solution: The optimal control solution.
Returns
Dimension: The dual dimension (0 if dual is nothing).
See also: CTModels.Solutions.dim_dual_state_constraints_box, CTModels.Solutions.dim_dual_control_constraints_box.
_extend_grid_to_match [Function]
CTModels.Solutions._extend_grid_to_match Function
_extend_grid_to_match(
T_target::Vector{Float64},
T_reference::Vector{Float64},
component_name::String
) -> Vector{Float64}Extend a target time grid to match a reference grid if the target is a strict prefix.
This function checks if T_target is missing only the last element of T_reference (i.e., T_target == T_reference[1:end-1]). If so, it returns T_reference to enable grid unification. Otherwise, it returns T_target unchanged.
Arguments
T_target::Vector{Float64}: Time grid to potentially extendT_reference::Vector{Float64}: Reference time grid (typically the longest grid)component_name::String: Name of the component for logging purposes
Returns
Vector{Float64}: Extended grid if extension condition met, otherwise originalT_target
Notes
Extension condition:
length(T_target) == length(T_reference) - 1ANDT_target == T_reference[1:end-1]Emits
@infolog when extension is performed for transparencyDoes not modify trajectory data matrices (interpolation handles this via
T[1:N])
See also: _validate_and_fix_time_grid, build_solution
_interpolate_from_data [Function]
CTModels.Solutions._interpolate_from_data Function
_interpolate_from_data(data, T, dim, type_param; allow_nothing=false,
constant_if_two_points=false, expected_dim=nothing,
interpolation=:linear)Internal helper to create an interpolated function from discrete data.
Arguments
data: Matrix{Float64}, Function, or Nothing (if allow_nothing=true)T: Time grid vectordim: Dimension to extract from matrix (nothing = take full matrix)type_param: Type parameter for dispatch (Matrix, Function, or Nothing)allow_nothing: If false, throws IncorrectArgument when data is nothingconstant_if_two_points: If true and length(T)==2, return constant functionexpected_dim: If provided, validates matrix dimension matches (via @ensure)interpolation: Interpolation type (:linearor:constant)
Returns
- Interpolated function (or nothing if data=nothing and allow_nothing=true)
Throws
IncorrectArgument: If data is nothing and allow_nothing=falseAssertionError: If expected_dim provided and doesn't match (via @ensure)
Notes
This is a low-level helper. Use build_interpolated_function for the complete workflow.
See also: CTModels.Solutions.build_interpolated_function, CTModels.Solutions._wrap_scalar_and_deepcopy.
_serialize_solution [Function]
CTModels.Solutions._serialize_solution Function
_serialize_solution(
sol::CTModels.Solutions.Solution
) -> Dict{String, Any}Serialize a solution into discrete data for export to persistent storage (JLD2, JSON, etc.).
This function converts a Solution object (which may contain interpolated functions) into a fully discrete, serializable representation. All trajectory functions are evaluated on their respective time grids and stored as matrices. The serialization format automatically adapts based on whether the solution uses unified or multiple time grids.
Serialization Formats
The function produces two different formats depending on the solution's time grid model:
Unified Time Grid Format (Legacy)
When all grids are identical (UnifiedTimeGridModel), produces:
Dict(
"time_grid" => T, # Single grid for all components
"state" => Matrix, # Discretized on T
"control" => Matrix, # Discretized on T
"costate" => Matrix, # Discretized on T
"path_constraints_dual" => Matrix, # Discretized on T
# ... other fields
)Multiple Time Grids Format
When grids differ (MultipleTimeGridModel), produces:
Dict(
"time_grid_state" => T_state, # State-specific grid
"time_grid_control" => T_control, # Control-specific grid
"time_grid_costate" => T_costate, # Costate-specific grid
"time_grid_path" => T_path, # Path constraints grid
"state" => Matrix, # Discretized on T_state
"control" => Matrix, # Discretized on T_control
"costate" => Matrix, # Discretized on T_costate
"path_constraints_dual" => Matrix, # Discretized on T_path
# ... other fields
)Arguments
sol::Solution: Solution object to serialize (may contain functions or matrices)
Returns
Dict{String, Any}: Complete serializable dictionary containing:Time grids: Either single
"time_grid"or four separate gridsTrajectories:
"state","control","costate"asMatrix{Float64}Variable:
"variable"asVector{Float64}(time-independent)Objective:
"objective"asFloat64Dual variables: All constraint duals (can be
nothingif not present)"path_constraints_dual": Path constraint duals on path grid"state_constraints_lb_dual","state_constraints_ub_dual": State box duals on state grid"control_constraints_lb_dual","control_constraints_ub_dual": Control box duals on control grid"boundary_constraints_dual": Boundary duals (time-independent vector)"variable_constraints_lb_dual","variable_constraints_ub_dual": Variable duals (vectors)
Solver info:
"iterations","message","status","successful","constraints_violation","infos"
Discretization Behavior
Function trajectories: Evaluated at each point of their associated time grid
Matrix trajectories: Copied as-is (already discrete)
Nothing duals: Preserved as
nothingin the dictionaryGrid association: Each component is discretized on its correct grid:
State and state box duals →
T_stateControl and control box duals →
T_controlCostate →
T_costatePath constraint duals →
T_path
Example
using CTModels
# Solve OCP with multiple grids
sol = solve(ocp, strategy=MyStrategy())
# Serialize to dictionary
data = _serialize_solution(sol)
# Check format
if haskey(data, "time_grid_state")
# Multiple grids format
println("State grid: ", length(data["time_grid_state"]), " points")
println("Control grid: ", length(data["time_grid_control"]), " points")
println("Costate grid: ", length(data["time_grid_costate"]), " points")
else
# Unified grid format
println("Unified grid: ", length(data["time_grid"]), " points")
end
# Export to file (handled by extensions)
export_ocp_solution(sol; filename="solution", format=:JLD)
# Reconstruct from data
sol_reconstructed = _reconstruct_solution_from_data(ocp, data)Notes
Backward Compatibility
The serialization format is designed for backward compatibility:
Old files with single
"time_grid"can be read (costate defaults to state grid)New files with four grids are forward-compatible with updated readers
The
_reconstruct_solution_from_datafunction handles both formats automatically
Memory Efficiency
When all grids are identical, the unified format avoids storing redundant grid data, reducing file size and memory usage.
Round-Trip Guarantee
The serialized data is fully compatible with build_solution for exact reconstruction:
data = _serialize_solution(sol)
sol_new = build_solution(ocp, data["time_grid_state"], ...; objective=data["objective"], ...)See also: CTModels.Solutions.build_solution, CTModels.Serialization._reconstruct_solution_from_data, CTModels.Serialization.export_ocp_solution, CTModels.Serialization.import_ocp_solution
_serialize_solution(
_::CTModels.Solutions.UnifiedTimeGridModel,
sol::CTModels.Solutions.Solution,
dim_x::Int64,
dim_u::Int64
) -> Dict{String, Any}Serialize solution with unified time grid (legacy single-grid format).
This method handles solutions where all components share the same time grid. It produces the legacy format with a single "time_grid" key, which is backward-compatible with older versions of the package.
Format Produced
Dict(
"time_grid" => T, # Single unified grid
"state" => Matrix, # All components discretized on T
"control" => Matrix,
"costate" => Matrix,
# ... all other fields
)Arguments
::UnifiedTimeGridModel: Time grid model type (dispatch parameter)sol::Solution: Solution to serializedim_x::Int: State dimensiondim_u::Int: Control dimension
Returns
Dict{String, Any}: Serialized data with single time grid
Notes
This format is used when build_solution is called with identical grids for all components, or when using the legacy single-grid signature. It ensures backward compatibility with files created before the multi-grid feature was introduced.
See also: CTModels.Solutions._serialize_solution
_serialize_solution(
_::CTModels.Solutions.MultipleTimeGridModel,
sol::CTModels.Solutions.Solution,
dim_x::Int64,
dim_u::Int64
) -> Dict{String, Any}Serialize solution with multiple independent time grids (modern format).
This method handles solutions where different components use different time grids. It produces the modern format with four separate grid keys (time_grid_state, time_grid_control, time_grid_costate, time_grid_path), preserving the independent discretizations.
Format Produced
Dict(
"time_grid_state" => T_state, # State-specific grid
"time_grid_control" => T_control, # Control-specific grid
"time_grid_costate" => T_costate, # Costate-specific grid
"time_grid_path" => T_path, # Path constraints grid
"state" => Matrix, # Discretized on T_state
"control" => Matrix, # Discretized on T_control
"costate" => Matrix, # Discretized on T_costate
"path_constraints_dual" => Matrix, # Discretized on T_path
# ... all other fields
)Arguments
::MultipleTimeGridModel: Time grid model type (dispatch parameter)sol::Solution: Solution to serializedim_x::Int: State dimensiondim_u::Int: Control dimension
Returns
Dict{String, Any}: Serialized data with four independent time grids
Notes
This format is used when build_solution is called with different grids for different components. It allows numerical schemes to use optimal discretizations for each component (e.g., finer grid for state, coarser for control, custom for costate).
The reconstruction function _reconstruct_solution_from_data detects this format by checking for the presence of "time_grid_state" key and handles it appropriately.
See also: CTModels.Solutions._serialize_solution, CTModels.Solutions.build_solution
_validate_and_fix_time_grid [Function]
CTModels.Solutions._validate_and_fix_time_grid Function
_validate_and_fix_time_grid(
T::Vector{Float64},
component_name::String
) -> Vector{Float64}Validate and fix a time grid by ensuring it is strictly increasing.
Arguments
T::Vector{Float64}: Time grid to validatecomponent_name::String: Name of the component for error messages
Returns
Vector{Float64}: Validated and potentially reordered time grid
Notes
If the grid is not strictly increasing, it is reordered and a warning is emitted.
_wrap_scalar_and_deepcopy [Function]
CTModels.Solutions._wrap_scalar_and_deepcopy Function
_wrap_scalar_and_deepcopy(func, dim)Internal helper to wrap a function with scalar extraction and deepcopy, returning a CTModels.Components.CoercedTrajectory.
Arguments
func: Function or callable to wrap (or nothing)dim: Dimension of output (1 = scalar extraction viaonly, otherwiseidentity)
Returns
Components.CoercedTrajectory(deepcopy(func), coerce)wherecoerceisonly(dim==1) oridentity(otherwise)nothingif func is nothing
Notes
deepcopy is applied to func before storing it in the struct. This is essential for closures supplied by the user: Julia closures capture variable REFERENCES, not values, so without deepcopy, modifying external variables after solution creation would affect the solution.
Example:
param_x = 1.0
X_func = t -> [param_x * t]
sol = build_solution(...)
param_x = 999.0
# Without deepcopy: sol.state(0.5) would return [499.5] (uses new param_x)
# With deepcopy: sol.state(0.5) returns [0.5] (uses original param_x value)See also: CTModels.Solutions._interpolate_from_data, CTModels.Solutions.build_interpolated_function.
build_interpolated_function [Function]
CTModels.Solutions.build_interpolated_function Function
build_interpolated_function(data, T, dim, type_param; allow_nothing=false,
constant_if_two_points=false, expected_dim=nothing,
interpolation=:linear)Unified function to build an interpolated function with deepcopy and scalar wrapping.
This is the main entry point that combines interpolation and wrapping in one call.
Arguments
data: Matrix{Float64}, Function, or Nothing (if allow_nothing=true)T: Time grid vectordim: Dimension to extract (nothing = take full matrix)type_param: Type parameter for dispatchallow_nothing: Allow data=nothing (for optional duals)constant_if_two_points: Return constant function if length(T)==2 (for costate)expected_dim: Validate matrix has this dimension (for robustness)interpolation: Interpolation type (:linearor:constant)
Returns
Wrapped interpolated function ready for use in Solution
nothing if data=nothing and allow_nothing=true
Throws
IncorrectArgument: If data is nothing and allow_nothing=falseAssertionError: If expected_dim doesn't match actual dimension
Examples
# State interpolation (required, with validation)
fx = build_interpolated_function(X, T, dim_x, TX; expected_dim=dim_x)
# Control with piecewise-constant interpolation
fu = build_interpolated_function(U, T, dim_u, TU; expected_dim=dim_u, interpolation=:constant)
# Costate with special 2-point handling
fp = build_interpolated_function(P, T, dim_x, TP;
constant_if_two_points=true, expected_dim=dim_x)
# Optional dual (can be nothing)
fscbd = build_interpolated_function(state_constraints_lb_dual, T, dim_x,
Union{Matrix{Float64},Nothing};
allow_nothing=true)See also: CTModels.Solutions._interpolate_from_data, CTModels.Solutions._wrap_scalar_and_deepcopy.
dual_model [Function]
CTModels.Solutions.dual_model Function
dual_model(
sol::CTModels.Solutions.Solution{<:CTModels.Solutions.AbstractTimeGridModel, <:CTModels.Components.AbstractTimesModel, <:CTModels.Components.AbstractStateModel, <:CTModels.Components.AbstractControlModel, <:CTModels.Components.AbstractVariableModel, <:CTModels.Models.AbstractModel, <:Function, <:Real, DM<:CTModels.Solutions.AbstractDualModel}
) -> CTModels.Solutions.AbstractDualModelReturn the dual model containing all constraint multipliers.
From CTModelsJSON
_MATRIX_FIELDS [Constant]
CTModelsJSON._MATRIX_FIELDS Constant
Solution fields that are always serialized as Matrix{Float64} and must be converted to Vector{Vector} for JSON3.
_OPTIONAL_MATRIX_FIELDS [Constant]
CTModelsJSON._OPTIONAL_MATRIX_FIELDS Constant
Solution fields that may be present (non-empty duals) and require the same Matrix → Vector{Vector} conversion.
_apply_over_grid [Function]
CTModelsJSON._apply_over_grid Function
Apply a function over a grid (broadcast), or return nothing if input is nothing.
_convert_matrices_for_json! [Function]
CTModelsJSON._convert_matrices_for_json! Function
Convert Matrix fields to Vector{Vector} for JSON3 export.
JSON3 flattens Matrix{Float64} into 1D arrays, losing the 2D structure. This function converts all matrix fields to Vector{Vector} format to preserve dimensions.
_deserialize_infos [Function]
CTModelsJSON._deserialize_infos Function
Convert Dict{String,Any} back to Dict{Symbol,Any} after JSON deserialization. Uses symbol_keys metadata to restore Symbol types where they were originally present.
_deserialize_value [Function]
CTModelsJSON._deserialize_value Function
Deserialize a single value from JSON format. Uses symbol_keys to restore Symbol types at the correct paths.
_json_to_matrix [Function]
CTModelsJSON._json_to_matrix Function
Convert a JSON field (Vector{Vector} via stack) to Matrix{Float64}.
JSON exports matrices as Vector{Vector}. After stack(blob[field]; dims=1), we get either a Matrix (multi-D) or Vector (1D). This normalizes to Matrix.
Arguments
blob_field: JSON array field (Vector of Vectors)
Returns
Matrix{Float64}: (n_time_points, n_dim)
_json_to_optional_matrix [Function]
CTModelsJSON._json_to_optional_matrix Function
Convert an optional JSON field to Matrix{Float64} or nothing.
Arguments
blob_field: JSON array field or nothing
Returns
Matrix{Float64}ornothing
_serialize_infos [Function]
CTModelsJSON._serialize_infos Function
Convert Dict{Symbol,Any} to Dict{String,Any} for JSON serialization. Only serializes JSON-compatible types (numbers, strings, bools, arrays, dicts). Returns a tuple: (serialized_dict, symbol_keys) where symbol_keys tracks which values were Symbols.
_serialize_value [Function]
CTModelsJSON._serialize_value Function
Serialize a single value to JSON-compatible format. Returns a tuple: (serialized_value, symbol_paths) where symbol_paths tracks Symbol locations.
From CTModels.Components
CoercedTrajectory [Struct]
CTModels.Components.CoercedTrajectory Type
CoercedTrajectory{F,C} <: FunctionA callable struct decorating a time function inner with a coercion coerce: f(t) = coerce(inner(t)).
Replaces anonymous closures t -> func(t)[1] (coerce = only, scalar extraction) and t -> func(t) (coerce = identity, pass-through). Since C is a concrete singleton type (typeof(only) or typeof(identity)), the call method is fully specialised — no type instability.
Satisfies <: Function so it can be stored in containers parameterised by F <: Function (e.g. StateModelSolution{TS<:Function}).
Examples
f = CoercedTrajectory(t -> [2t], only)
f(0.5) # returns 1.0 (scalar extraction, validates length == 1)
g = CoercedTrajectory(t -> [t, 2t], identity)
g(0.5) # returns [0.5, 1.0]ConstantInTime [Struct]
CTModels.Components.ConstantInTime Type
ConstantInTime{V} <: FunctionA callable struct representing a constant function of time: f(t) = value for all t.
Replaces anonymous closures t -> value to gain named type, type stability, value capture (no deepcopy needed), and testability.
Satisfies <: Function so it can be stored in containers parameterised by F <: Function (e.g. InitialGuess{X<:Function, U<:Function, V}).
Examples
f = ConstantInTime(1.0)
f(0.5) # returns 1.0
g = ConstantInTime([1.0, 2.0])
g(3.7) # returns [1.0, 2.0]From CTModels.Building
CompositeConstraint [Struct]
CTModels.Building.CompositeConstraint Type
struct CompositeConstraint{Sig, CS} <: FunctionIn-place callable struct concatenating n nonlinear constraints into a single composite constraint. Sig = :path selects the call method (val, t, x, u, v); Sig = :boundary selects (val, x0, xf, v). Both the signature and the concrete tuple type CS are encoded in type parameters, so each call method is fully specialised with no runtime branch.
Storing n, dims, and funs as fields (Pattern 7) eliminates the capture-by-reference fragility present in the previous make_boundary_cons_nl closure (where constraints_number and constraints_dimensions were outside the let block).
Replaces the anonymous closures path_cons_nl! and boundary_cons_nl! produced inside CTModels.Building.build in build.jl.
Fields
n::Int: Number of individual constraints.dims::Vector{Int}: Dimension of each individual constraint.funs::CS: Concrete tuple of the N constraint functions.
Examples
using CTModels.Building
f1!(r, t, x, u, v) = (r[1] = x[1] + u[1])
f2!(r, t, x, u, v) = (r[1] = x[2])
fc = CompositeConstraint{:path}(2, [1, 1], (f1!, f2!))
val = zeros(2)
fc(val, 0.0, [1.0, 2.0], [3.0], nothing)
# val == [4.0, 2.0]__build_dynamics_from_parts [Function]
CTModels.Building.__build_dynamics_from_parts Function
__build_dynamics_from_parts(
parts::Vector{<:Tuple{var"#s48", var"#s47"} where {var"#s48"<:(AbstractRange{<:Int64}), var"#s47"<:Function}}
) -> CTModels.Building.var"#dyn!#__build_dynamics_from_parts##0"{Vector{var"#s46"}} where var"#s46"<:(Tuple{var"#s45", var"#s44"} where {var"#s45"<:(AbstractRange{<:Int64}), var"#s44"<:Function})Build a single combined in-place dynamics function from ordered partial parts.
Used internally by CTModels.Building.build after all partial dynamics calls have been collected. Each part function updates its assigned slice of the output vector via a @view, avoiding copies.
Arguments
parts::Vector{<:Tuple{<:AbstractRange{<:Int},<:Function}}: Ordered vector of(range, f!)pairs; eachf!(r, t, x, u, v)fillsr=view(val, range).
Returns
Function: Combineddyn!(val, t, x, u, v)that applies all parts in order.
__collect_used_names [Function]
CTModels.Building.__collect_used_names Function
__collect_used_names(
ocp::CTModels.Building.PreModel
) -> Vector{String}Collect all names already used in the PreModel across all components.
Returns a vector containing:
Time name (if set)
State name and components (if set)
Control name and components (if set)
Variable name and components (if set and non-empty)
Example
julia> using CTModels
julia> ocp = CTModels.PreModel(); CTModels.state!(ocp, 2, "x", ["x₁", "x₂"]); CTModels.control!(ocp, 1, "u");
julia> CTModels.Building.__collect_used_names(ocp)
4-element Vector{String}:
"x"
"x₁"
"x₂"
"u"See also: CTModels.Building.__has_name_conflict, CTModels.Building.__validate_name_uniqueness.
__constraint! [Function]
CTModels.Building.__constraint! Function
__constraint!(
ocp_constraints::OrderedCollections.OrderedDict{Symbol, Tuple{Symbol, Union{Function, OrdinalRange{<:Int64}}, AbstractVector{<:Real}, AbstractVector{<:Real}}},
type::Symbol,
n::Int64,
m::Int64,
q::Int64;
rg,
f,
lb,
ub,
label,
codim_f
)Add a constraint to a dictionary of constraints.
Arguments
ocp_constraints: The dictionary of constraints to which the constraint will be added.type: The type of the constraint. It can be:state,:control,:variable,:boundary, or:path.n: The dimension of the state.m: The dimension of the control.q: The dimension of the variable.rg: The range of the constraint. It can be an integer or a range of integers.f: The function that defines the constraint. It must return a vector of the same dimension as the constraint.lb: The lower bound of the constraint. It can be a number or a vector.ub: The upper bound of the constraint. It can be a number or a vector.label: The label of the constraint. It must be unique in the dictionary of constraints.
Requirements
The constraint must not be set before.
The lower bound
lband the upper boundubcannot be bothnothing.The lower bound
lband the upper boundubmust have the same length, if both provided.
If rg and f are not provided then,
typemust be:state,:control, or:variable.lbandubmust be of dimensionn,m, orqrespectively, when provided.
If rg is provided, then:
fmust not be provided.typemust be:state,:control, or:variable.rgmust be a range of integers, and must be contained in1:n,1:m, or1:qrespectively.
If f is provided, then:
rgmust not be provided.typemust be:boundaryor:path.fmust be a function that returns a vector of the same dimension as the constraint.lbandubmust be of the same dimension as the output off, when provided.
Example
julia> using CTModels
julia> ocp_constraints = CTModels.Components.ConstraintsDictType()
julia> CTModels.Building.__constraint!(ocp_constraints, :state, 3, 2, 1; rg=1:2, lb=[-1.0, -1.0], ub=[1.0, 1.0], label=:x_box);__constraint_label [Function]
CTModels.Building.__constraint_label Function
__constraint_label() -> SymbolReturn a unique label for a constraint using gensym with prefix :unnamed.
Returns
Symbol: A unique constraint label.
__constraints [Function]
CTModels.Building.__constraints Function
__constraints()Return the default value for the constraints.
Returns
Nothing
__control_components [Function]
CTModels.Building.__control_components Function
__control_components(
m::Int64,
name::String
) -> Vector{String}Return the default component names for a control variable of dimension m.
Arguments
m::Dimension: The control dimension.name::String: The base name for components.
Returns
Vector{String}: Component names (single element for m=1, subscripted for m>1).
__control_interpolation [Function]
CTModels.Building.__control_interpolation Function
__control_interpolation() -> SymbolReturn the default control interpolation type.
Returns
Symbol: The interpolation type (:constantfor piecewise constant,:linearfor piecewise linear).
__control_name [Function]
CTModels.Building.__control_name Function
__control_name() -> StringReturn the default name of the control variable.
Returns
String: The default control name ("u").
__criterion_type [Function]
CTModels.Building.__criterion_type Function
__criterion_type() -> SymbolReturn the default optimization criterion type.
Returns
Symbol: The criterion type (:minfor minimization).
__filename_export_import [Function]
CTModels.Building.__filename_export_import Function
__filename_export_import() -> StringReturn the default filename (without extension) for exporting and importing solutions.
Returns
String: The default filename ("solution").
__format [Function]
CTModels.Building.__format Function
__format() -> SymbolReturn the default format of the file to be used for export and import.
Returns
Symbol: The format symbol (:JLD).
__has_name_conflict [Function]
CTModels.Building.__has_name_conflict Function
__has_name_conflict(
ocp::CTModels.Building.PreModel,
new_name::String
) -> Bool
__has_name_conflict(
ocp::CTModels.Building.PreModel,
new_name::String,
exclude_component::Symbol
) -> BoolCheck if a name conflicts with existing names in the PreModel.
Arguments
ocp::PreModel: The model to check againstnew_name::String: The new name to checkexclude_component::Symbol: Component type to exclude from check (:state,:control,:variable,:time,:none)
The exclude_component parameter allows checking for conflicts while updating a component, excluding the component's own current names from the check.
Returns
Bool:trueif conflict exists,falseotherwise
Example
julia> using CTModels
julia> ocp = CTModels.PreModel(); CTModels.state!(ocp, 2, "x", ["x₁", "x₂"]);
julia> CTModels.Building.__has_name_conflict(ocp, "x", :none)
true
julia> CTModels.Building.__has_name_conflict(ocp, "y", :none)
falseSee also: CTModels.Building.__collect_used_names, CTModels.Building.__validate_name_uniqueness.
__is_autonomous_set [Function]
CTModels.Building.__is_autonomous_set Function
__is_autonomous_set(ocp::CTModels.Building.PreModel) -> BoolReturn true if the autonomous flag has been set in the PreModel.
Returns
Bool
__is_consistent [Function]
CTModels.Building.__is_consistent Function
__is_consistent(ocp::CTModels.Building.PreModel) -> BoolReturn true if all the required fields are set in the PreModel.
Arguments
ocp::PreModel: The pre-model to check.
Returns
Bool
__is_control_empty [Function]
CTModels.Building.__is_control_empty Function
__is_control_empty(c) -> BoolReturn true if c is an EmptyControlModel.
Returns
Bool
__is_control_empty(ocp::CTModels.Building.PreModel) -> BoolReturn true if the control field of the PreModel is an EmptyControlModel.
Returns
Bool
__is_definition_empty [Function]
CTModels.Building.__is_definition_empty Function
__is_definition_empty(d) -> BoolReturn true if d is an CTModels.Components.EmptyDefinition.
Returns
Bool
__is_definition_empty(
ocp::CTModels.Building.PreModel
) -> BoolReturn true if the definition field of the PreModel is an CTModels.Components.EmptyDefinition.
Returns
Bool
__is_dynamics_complete [Function]
CTModels.Building.__is_dynamics_complete Function
__is_dynamics_complete(
ocp::CTModels.Building.PreModel
) -> BoolReturn true if dynamics cover all state components in the PreModel.
For component-wise dynamics, checks that all state indices are covered.
Arguments
ocp::PreModel: The pre-model to check.
Returns
Bool
__is_dynamics_set [Function]
CTModels.Building.__is_dynamics_set Function
__is_dynamics_set(ocp::CTModels.Building.PreModel) -> BoolReturn true if dynamics have been set in the PreModel.
Returns
Bool
__is_empty [Function]
CTModels.Building.__is_empty Function
__is_empty(ocp::CTModels.Building.PreModel) -> BoolReturn true if nothing has been set.
Arguments
ocp::PreModel: The pre-model to check.
Returns
Bool
__is_objective_set [Function]
CTModels.Building.__is_objective_set Function
__is_objective_set(ocp::CTModels.Building.PreModel) -> BoolReturn true if objective has been set in the PreModel.
Returns
Bool
__is_set [Function]
CTModels.Building.__is_set Function
__is_set(x) -> BoolReturn true if x is not nothing.
Returns
Bool
__is_state_set [Function]
CTModels.Building.__is_state_set Function
__is_state_set(ocp::CTModels.Building.PreModel) -> BoolReturn true if state has been set in the PreModel.
Returns
Bool
__is_times_set [Function]
CTModels.Building.__is_times_set Function
__is_times_set(ocp::CTModels.Building.PreModel) -> BoolReturn true if times have been set in the PreModel.
Returns
Bool
__is_variable_empty [Function]
CTModels.Building.__is_variable_empty Function
__is_variable_empty(v) -> BoolReturn true if v is an EmptyVariableModel.
Returns
Bool
__is_variable_empty(ocp::CTModels.Building.PreModel) -> BoolReturn true if the variable field of the PreModel is an EmptyVariableModel.
Returns
Bool
__state_components [Function]
CTModels.Building.__state_components Function
__state_components(n::Int64, name::String) -> Vector{String}Return the default component names for a state variable of dimension n.
Arguments
n::Dimension: The state dimension.name::String: The base name for components.
Returns
Vector{String}: Component names (single element for n=1, subscripted for n>1).
__state_name [Function]
CTModels.Building.__state_name Function
__state_name() -> StringReturn the default name of the state variable.
Returns
String: The default state name ("x").
__time_grid_default_component [Function]
CTModels.Building.__time_grid_default_component Function
__time_grid_default_component() -> SymbolReturn the default component for time grid access in multiple time grid solutions.
Returns
Symbol: The default component (:state).
__time_name [Function]
CTModels.Building.__time_name Function
__time_name() -> StringReturn the default name of the time variable.
Returns
String: The default time name ("t").
__validate_name_uniqueness [Function]
CTModels.Building.__validate_name_uniqueness Function
__validate_name_uniqueness(
ocp::CTModels.Building.PreModel,
name::String,
components::Vector{String},
component_type::Symbol
)Validate that a name and its components don't conflict with existing names.
Performs comprehensive validation:
Name is not empty
Components are not empty
Name not in components (internal conflict)
No duplicates in components
No conflicts with existing names in other components (global uniqueness)
Arguments
ocp::PreModel: The model to validate againstname::String: The component namecomponents::Vector{String}: The component namescomponent_type::Symbol: Type of component (:state,:control,:variable,:time)
Throws
Exceptions.IncorrectArgument: If any validation fails
Example
julia> using CTModels
julia> ocp = CTModels.PreModel(); CTModels.state!(ocp, 2, "x", ["x₁", "x₂"]);
julia> CTModels.Building.__validate_name_uniqueness(ocp, "y", ["u"], :control) # "y" is unique: succeedsSee also: CTModels.Building.__has_name_conflict, CTModels.Building.__collect_used_names.
__variable_components [Function]
CTModels.Building.__variable_components Function
__variable_components(
q::Int64,
name::String
) -> Vector{String}Return the default component names for a variable of dimension q.
Arguments
q::Dimension: The variable dimension.name::String: The base name for components.
Returns
Vector{String}: Component names (empty for q=0, single element for q=1, subscripted for q>1).
__variable_name [Function]
CTModels.Building.__variable_name Function
__variable_name(q::Int64) -> StringReturn the default name for optimization variables.
Arguments
q::Dimension: The variable dimension.
Returns
String: The variable name ("v"for q>0, empty string for q=0).
_dedup_box_constraints! [Function]
CTModels.Building._dedup_box_constraints! Function
_dedup_box_constraints!(
inds::Vector{Int64},
lbs::Array{T<:Real, 1},
ubs::Array{T<:Real, 1},
labels::Vector{Symbol},
aliases::Vector{Vector{Symbol}},
kind::String
)Deduplicate box-constraint declarations by component, applying the intersection of all declared bounds for each repeated component. Produces an aliases vector recording every label that targeted each component.
After this function returns, the vectors satisfy the invariant:
allunique(inds)— each component appears at most once.lbs[k]=maxof all declared lower bounds for componentinds[k].ubs[k]=minof all declared upper bounds for componentinds[k].labels[k]= the first label that declared componentinds[k](stable order).aliases[k]= all distinct labels that declared componentinds[k], in first-seen order (always starts withlabels[k]).Vectors are sorted by
inds.
A @warn is emitted once for each duplicated component, listing all contributing labels. If the intersection is empty (i.e. max(lbs_k) > min(ubs_k)), an CTBase.Exceptions.IncorrectArgument is thrown.
Arguments
inds,lbs,ubs,labels: in-place flat vectors produced by successive calls toCTModels.Building.append_box_constraints!.aliases: in-place emptyVector{Vector{Symbol}}to be populated with the per-component list of all declaring labels.kind::String: human-readable descriptor (e.g. "state", "control", "variable") used in diagnostic messages.
Throws
CTBase.Exceptions.IncorrectArgumentif the intersection of declared bounds is empty for some component.
Returns
Nothing
as_range [Function]
CTModels.Building.as_range Function
as_range(::Nothing) -> NothingReturn nothing unchanged.
Returns
Nothing
as_range(r::Int) -> UnitRange{Int}Convert a scalar integer to a single-element range r:r.
Arguments
r::Int: An integer index.
Returns
UnitRange{Int}: A range containing onlyr.
Example
julia> as_range(3)
3:3as_range(r::OrdinalRange{Int}) -> OrdinalRange{Int}Return an ordinal range unchanged.
Arguments
r::OrdinalRange{Int}: A range of integers.
Returns
OrdinalRange{Int}: The input range unchanged.
Example
julia> as_range(1:5)
1:5as_vector [Function]
CTModels.Building.as_vector Function
as_vector(::Nothing) -> NothingReturn nothing unchanged.
Returns
Nothing
as_vector(x::T) -> Vector{T} where {T<:ctNumber}Wrap a scalar number into a single-element vector.
Arguments
x::T: A scalar number.
Returns
Vector{T}: A single-element vector containingx.
Example
julia> as_vector(1.0)
1-element Vector{Float64}:
1.0as_vector(x::AbstractVector{T}) -> AbstractVector{T} where {T<:ctNumber}Return a vector unchanged.
Arguments
x::AbstractVector{T}: A vector of numbers.
Returns
AbstractVector{T}: The input vector unchanged.
Example
julia> as_vector([1.0, 2.0, 3.0])
3-element Vector{Float64}:
1.0
2.0
3.0From CTModels.Init
MergedTrajectory [Struct]
CTModels.Init.MergedTrajectory Type
struct MergedTrajectory{F, C<:(AbstractDict{Int64, <:Function})} <: FunctionCallable struct merging a block-level trajectory base with sparse component-level overrides comps: f(t) evaluates base(t), normalises to a vector, applies each component override, and returns a scalar (dim == 1) or a vector.
base::F is a concrete type parameter, replacing the former base_fun::Function abstract capture. comps::C stores the Dict{Int,Function} override map.
Component index bounds are validated at construction, not at call time, so the call method stays allocation-free beyond what base and the component functions allocate.
Replaces the anonymous closure t -> begin … end (57 lines) produced inside CTModels.Init._build_block_with_components in builders.jl.
Fields
base::F: Block-level trajectory function.comps::C: Component-level override map (Dict{Int,Function}).dim::Int: Total dimension.role::Symbol: Component role (:stateor:control).
Examples
using CTModels.Init
base = t -> [0.0, 0.0]
comps = Dict{Int,Function}(2 => t -> sin(t))
f = MergedTrajectory(base, comps, 2, :state)
f(0.5) # returns [0.0, sin(0.5)]_build_block_with_components [Function]
CTModels.Init._build_block_with_components Function
_build_block_with_components(
ocp::CTModels.Models.AbstractModel,
role::Symbol,
block_data,
comp_data::Dict{Int64, Any}
) -> AnyBuild an initialisation function combining block-level and component-level data.
Arguments
ocp::CTModels.Models.AbstractModel: The optimal control problem.role::Symbol: The component role (:stateor:control).block_data: Block-level initialisation data.comp_data::Dict{Int,Any}: Component-level initialisation data indexed by component.
Returns
Function: A combined initialisation function that merges block and component data.
Throws
CTBase.Exceptions.IncorrectArgument: If dimensions are incompatible or component indices are out of bounds.
See also: CTModels.Init.MergedTrajectory, CTModels.Init.initial_state, CTModels.Init.initial_control
_build_component_function [Function]
CTModels.Init._build_component_function Function
_build_component_function(data) -> FunctionBuild a component-level initialisation function from data.
Arguments
data: The component data (time-dependent tuple or time-independent data).
Returns
Function: A component initialisation function.
See also: CTModels.Init._build_component_function_without_time, CTModels.Init._build_component_function_with_time
_build_component_function_with_time [Function]
CTModels.Init._build_component_function_with_time Function
_build_component_function_with_time(
data,
time::AbstractVector
) -> FunctionBuild a component function from data with an associated time grid.
Arguments
data: The component data (function, scalar, or vector).time::AbstractVector: The time grid for interpolation.
Returns
Function: A component initialisation function with time interpolation.
Throws
CTBase.Exceptions.IncorrectArgument: If the data type is unsupported or time-grid mismatch occurs.
See also: CTModels.Components.ConstantInTime, CTBase.Interpolation.ctinterpolate
_build_component_function_without_time [Function]
CTModels.Init._build_component_function_without_time Function
_build_component_function_without_time(data) -> FunctionBuild a component function from time-independent data (scalar, vector, or function).
Arguments
data: The time-independent data (function, scalar, or vector).
Returns
Function: A component initialisation function.
Throws
CTBase.Exceptions.IncorrectArgument: If the data type is unsupported or vector length is invalid.
See also: CTModels.Components.ConstantInTime
_build_time_dependent_init [Function]
CTModels.Init._build_time_dependent_init Function
_build_time_dependent_init(
ocp::CTModels.Models.AbstractModel,
role::Symbol,
data,
time::AbstractVector
) -> Union{Nothing, Function}Build a time-dependent initialisation function from data and a time grid.
Arguments
ocp::CTModels.Models.AbstractModel: The optimal control problem.role::Symbol: The component role (:stateor:control).data: The data to interpolate (function, vector, or vector-of-vectors).time::AbstractVector: The time grid.
Returns
Function: An interpolated initialisation functiont -> value(t).
Throws
CTBase.Exceptions.IncorrectArgument: If data type is unsupported or dimensions/time-grid mismatch occurs.
See also: CTBase.Interpolation.ctinterpolate, CTModels.Init.initial_state, CTModels.Init.initial_control
_coerce_base [Function]
CTModels.Init._coerce_base Function
_coerce_base(
v::AbstractVector,
dim::Int64,
role::Symbol
) -> AnyValidate and collect the base trajectory output for a component with dim > 1.
Throws if v is not an AbstractVector of the expected length, or if v is a scalar.
Arguments
v: raw output of the base trajectory function.dim::Int: expected component dimension.role::Symbol: component role (e.g.:state,:control) used in the error message.
Returns
Vector: a freshly collected copy ofv.
Throws
CTBase.Exceptions.IncorrectArgument: ifvis a scalar or has incorrect length.
See also: CTModels.Init._wrap_1d
_format_init_data_for_grid [Function]
CTModels.Init._format_init_data_for_grid Function
_format_init_data_for_grid(data) -> AnyConvert matrix data to vector-of-vectors format for time-grid interpolation.
Arguments
data: The data to format (matrix or other format).
Returns
Union{AbstractVector, Any}: The formatted data as vector-of-vectors, or the original data.
_format_time_grid [Function]
CTModels.Init._format_time_grid Function
_format_time_grid(time_data) -> AnyNormalise time grid data to a vector format.
Arguments
time_data: The time grid data (vector, array, ornothing).
Returns
Union{Nothing, AbstractVector}: The normalised time grid as a vector, ornothing.
Throws
Exceptions.IncorrectArgument: If the time grid type is invalid.
_initial_guess_from_namedtuple [Function]
CTModels.Init._initial_guess_from_namedtuple Function
_initial_guess_from_namedtuple(
ocp::CTModels.Models.AbstractModel,
init_data::NamedTuple
) -> CTModels.Init.InitialGuessBuild an initial guess from a NamedTuple.
Arguments
ocp::Models.AbstractModel: The optimal control problem.init_data::NamedTuple: The initial guess data with named fields.
Returns
InitialGuess: An initial guess constructed from the NamedTuple.
Throws
Exceptions.IncorrectArgument: If keys are invalid, dimensions mismatch, or specifications are duplicated.
_initial_guess_from_preinit [Function]
CTModels.Init._initial_guess_from_preinit Function
_initial_guess_from_preinit(
ocp::CTModels.Models.AbstractModel,
pre::CTModels.Init.PreInitialGuess
) -> CTModels.Init.InitialGuessBuild an initial guess from a pre-initialisation object.
Arguments
ocp::Models.AbstractModel: The optimal control problem.pre::PreInitialGuess: The pre-initialisation container.
Returns
InitialGuess: An initial guess constructed from the pre-initialisation data.
_initial_guess_from_solution [Function]
CTModels.Init._initial_guess_from_solution Function
_initial_guess_from_solution(
ocp::CTModels.Models.AbstractModel,
sol::CTModels.Solutions.AbstractSolution
) -> Union{CTModels.Init.InitialGuess{X, U, V} where {X<:Function, U<:Function, V<:Real}, CTModels.Init.InitialGuess{X, U, V} where {X<:Function, U<:Function, V<:(AbstractVector{<:Real})}}Build an initial guess from a previous solution (warm start).
Arguments
ocp::Models.AbstractModel: The optimal control problem.sol::Solutions.AbstractSolution: The previous solution.
Returns
InitialGuess: An initial guess constructed from the solution.
Throws
Exceptions.IncorrectArgument: If dimensions do not match between the problem and solution.
_validate_initial_guess [Function]
CTModels.Init._validate_initial_guess Function
_validate_initial_guess(
ocp::CTModels.Models.AbstractModel,
init::CTModels.Init.InitialGuess
) -> CTModels.Init.InitialGuessInternal validation of an InitialGuess.
Arguments
ocp::Models.AbstractModel: The optimal control problem.init::InitialGuess: The initial guess to validate.
Returns
InitialGuess: The validated initial guess.
Throws
Exceptions.IncorrectArgument: If dimensions or types are incompatible.
_wrap_1d [Function]
CTModels.Init._wrap_1d Function
_wrap_1d(v::AbstractVector) -> AnyNormalise a scalar or vector base value to a Vector of length 1 for dim-1 components.
Dispatched overloads replace isa AbstractVector runtime checks with static dispatch, letting the compiler specialise on the return type of the base trajectory.
Arguments
v: raw output of a base trajectory function for a 1-dimensional component.
Returns
Vector: a length-1 vector containing or wrappingv.
See also: CTModels.Init._coerce_base
From CTModels.Models
BoxProjection [Struct]
CTModels.Models.BoxProjection Type
BoxProjection{Slot,CIDX} <: FunctionCallable struct projecting a box constraint onto selected components.
Slot ∈ (:state, :control, :variable) selects which argument is projected; CIDX = Int gives a scalar, CIDX = Vector{Int} gives a vector. Both the slot and the scalar/vector distinction are encoded in type parameters so the call method is fully specialised (no runtime branch).
Replaces three anonymous closures in constraint(model, label):
(_, x, _, _) -> x[cidxs](state box)(_, _, u, _) -> u[cidxs](control box)(_, _, v) -> v[cidxs](variable box, arity 3)
SubBoundaryConstraint [Struct]
CTModels.Models.SubBoundaryConstraint Type
SubBoundaryConstraint{CP,I} <: FunctionIn-place callable struct extracting a sub-vector of a nonlinear boundary constraint: evaluates the full boundary constraint vector then copies r .= r_[indices].
I = Int or I = Vector{Int}. Intended to be wrapped by Core.to_out_of_place.
Replaces the anonymous in-place closure produced inside constraint(model, label): fc! = (r, x0, xf, v) -> begin r_ = zeros(...); cp[2](r_, x0, xf, v); r .= r_[indices] end.
SubPathConstraint [Struct]
CTModels.Models.SubPathConstraint Type
SubPathConstraint{CP,I} <: FunctionIn-place callable struct extracting a sub-vector of a nonlinear path constraint: evaluates the full path constraint vector then copies r .= r_[indices].
I = Int or I = Vector{Int}. Intended to be wrapped by Core.to_out_of_place.
Replaces the anonymous in-place closure produced inside constraint(model, label): fc! = (r, t, x, u, v) -> begin r_ = zeros(...); cp[2](r_, t, x, u, v); r .= r_[indices] end.
_control_dependence [Function]
CTModels.Models._control_dependence Function
_control_dependence(
_::CTModels.Components.EmptyControlModel
) -> Type{CTBase.Traits.ControlFree}Resolve the control-dependence trait value from the control model type.
Returns Traits.ControlFree when the model carries no control input (CTModels.Components.EmptyControlModel), and Traits.WithControl otherwise.
Arguments
model: anCTModels.Components.AbstractControlModelinstance.
Returns
- trait value:
Traits.ControlFreeorTraits.WithControl.
See also: CTModels.Models._variable_dependence
_variable_dependence [Function]
CTModels.Models._variable_dependence Function
_variable_dependence(
_::CTModels.Components.EmptyVariableModel
) -> Type{CTBase.Traits.Fixed}Resolve the variable-dependence trait value from the variable model type.
Returns Traits.Fixed when the model carries no optimisation variable (CTModels.Components.EmptyVariableModel), and Traits.NonFixed otherwise.
Arguments
model: anCTModels.Components.AbstractVariableModelinstance.
Returns
- trait value:
Traits.FixedorTraits.NonFixed.
See also: CTModels.Models._control_dependence
From CTModels.Serialization
_extract_time_vector [Function]
CTModels.Serialization._extract_time_vector Function
_extract_time_vector(time_data) -> AnyExtract time vector from various data formats.
Arguments
time_data: Time data in various formats (Vector, Matrix, etc.)
Returns
Vector{Float64}: Time vector
Notes
Handles both Vector{Float64} and Matrix{Float64} (single column) formats
Used by JSON and JLD2 importers to normalize time grid data
See also: CTModels.Serialization._reconstruct_solution_from_data.
_reconstruct_solution_from_data [Function]
CTModels.Serialization._reconstruct_solution_from_data Function
_reconstruct_solution_from_data(
ocp,
data;
infos
) -> CTModels.Solutions.Solution{TimeGridModelType, TimesModelType, StateModelType, ControlModelType, VariableModelType, ModelType, CostateModelType, Float64, DualModelType, CTModels.Solutions.SolverInfos{Any, Dict{Symbol, Any}}} where {TimeGridModelType<:Union{CTModels.Solutions.MultipleTimeGridModel, CTModels.Solutions.UnifiedTimeGridModel{Vector{Float64}}}, TimesModelType<:CTModels.Components.TimesModel, StateModelType<:(CTModels.Components.StateModelSolution{TS} where TS<:CTModels.Components.CoercedTrajectory), ControlModelType<:(CTModels.Components.ControlModelSolution{TS} where TS<:CTModels.Components.CoercedTrajectory), VariableModelType<:Union{CTModels.Components.VariableModelSolution{Vector{Float64}}, CTModels.Components.VariableModelSolution{Float64}}, ModelType<:(CTModels.Models.Model{<:CTBase.Traits.TimeDependence, T} where T<:CTModels.Components.TimesModel), CostateModelType<:CTModels.Components.CoercedTrajectory, DualModelType<:Union{CTModels.Solutions.EmptyDualModel, CTModels.Solutions.DualModel{PC_Dual, BC_Dual, SC_LB_Dual, SC_UB_Dual, CC_LB_Dual, CC_UB_Dual, VC_LB_Dual, VC_UB_Dual} where {PC_Dual<:Union{Nothing, CTModels.Components.CoercedTrajectory}, BC_Dual<:Union{Nothing, Vector{Float64}}, SC_LB_Dual<:Union{Nothing, CTModels.Components.CoercedTrajectory}, SC_UB_Dual<:Union{Nothing, CTModels.Components.CoercedTrajectory}, CC_LB_Dual<:Union{Nothing, CTModels.Components.CoercedTrajectory}, CC_UB_Dual<:Union{Nothing, CTModels.Components.CoercedTrajectory}, VC_LB_Dual<:Union{Nothing, Vector{Float64}}, VC_UB_Dual<:Union{Nothing, Vector{Float64}}}}}Reconstruct a solution from imported data, detecting the format (single vs multiple time grids).
Duals and control_interpolation are read from data. Only infos is accepted as a keyword argument because its deserialization is format-specific (JSON restores Symbol types).
Arguments
ocp: The optimal control problem modeldata: Dictionary containing the imported solution data, including all dual fields andcontrol_interpolation
Keyword Arguments
infos: Solver information dictionary (Dict{Symbol,Any}). Passed explicitly because JSON deserialization must restoreSymboltypes before calling this helper.
Returns
Solution: Reconstructed solution with appropriate time grid model
Notes
If
time_grid_statekey exists, assumes multiple time grid formatOtherwise, uses the current unified format (single
time_gridkey)
Example
julia> sol = _reconstruct_solution_from_data(ocp, data; infos=infos)See also: CTModels.Serialization._extract_time_vector.