Private API

This page lists non-exported (internal) symbols of CTModels.OCP.


From CTModels.OCP

_discretize_all_components

CTModels.OCP._discretize_all_componentsFunction
_discretize_all_components(
    sol::CTModels.OCP.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 trajectoryT_state grid
  • Control trajectoryT_control grid
  • Costate trajectoryT_costate grid
  • Path constraint dualsT_path grid
  • State box constraint duals (lb/ub) → T_state grid
  • Control box constraint duals (lb/ub) → T_control grid
  • Boundary/variable duals → Time-independent (vectors, not discretized)

Arguments

  • sol::Solution: Solution object containing trajectory functions
  • T_state::Vector{Float64}: Time grid for state discretization
  • T_control::Vector{Float64}: Time grid for control discretization
  • T_costate::Vector{Float64}: Time grid for costate discretization
  • T_path::Vector{Float64}: Time grid for path constraint dual discretization
  • dim_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

CTModels.OCP._discretize_dualFunction
_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 or nothing.
  • T: Time grid.
  • dim::Int: Dimension (auto-detected if -1).

Returns

  • Matrix{Float64} if dual_func is a function.
  • nothing if dual_func is nothing.

See also: _discretize_function

_discretize_function

CTModels.OCP._discretize_functionFunction
_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: _discretize_dual

_discretize_function(
    f::Function,
    T::CTModels.OCP.UnifiedTimeGridModel
) -> Matrix{Float64}
_discretize_function(
    f::Function,
    T::CTModels.OCP.UnifiedTimeGridModel,
    dim::Int64
) -> Matrix{Float64}

Discretize a function on a TimeGridModel by extracting the underlying time grid.

See also: _discretize_function

_interpolate_from_data

CTModels.OCP._interpolate_from_dataFunction
_interpolate_from_data(data, T, dim, type_param; allow_nothing=false, 
                       constant_if_two_points=false, expected_dim=nothing)

Internal helper to create an interpolated function from discrete data.

Arguments

  • data: Matrix{Float64}, Function, or Nothing (if allow_nothing=true)
  • T: Time grid vector
  • dim: 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 nothing
  • constant_if_two_points: If true and length(T)==2, return constant function
  • expected_dim: If provided, validates matrix dimension matches (via @ensure)

Returns

  • Interpolated function (or nothing if data=nothing and allow_nothing=true)

Throws

  • IncorrectArgument: If data is nothing and allow_nothing=false
  • AssertionError: 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.

_validate_and_fix_time_grid

CTModels.OCP._validate_and_fix_time_gridFunction
_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 validate
  • component_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

CTModels.OCP._wrap_scalar_and_deepcopyFunction
_wrap_scalar_and_deepcopy(func, dim)

Internal helper to wrap a function with scalar extraction and deepcopy.

Arguments

  • func: Function or callable to wrap (or nothing)
  • dim: Dimension of output (1 = scalar extraction, otherwise vector)

Returns

  • Wrapped function with deepcopy and scalar extraction if dim==1
  • nothing if func is nothing

Notes

Deepcopy is ESSENTIAL because Julia closures capture variable REFERENCES, not values. Without deepcopy, modifications to 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)

build_interpolated_function

CTModels.OCP.build_interpolated_functionFunction
build_interpolated_function(data, T, dim, type_param; allow_nothing=false,
                            constant_if_two_points=false, expected_dim=nothing)

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 vector
  • dim: Dimension to extract (nothing = take full matrix)
  • type_param: Type parameter for dispatch
  • allow_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)

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=false
  • AssertionError: 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)

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

dual_model

CTModels.OCP.dual_modelFunction
dual_model(
    sol::CTModels.OCP.Solution{<:CTModels.OCP.AbstractTimeGridModel, <:CTModels.OCP.AbstractTimesModel, <:CTModels.OCP.AbstractStateModel, <:CTModels.OCP.AbstractControlModel, <:CTModels.OCP.AbstractVariableModel, <:CTModels.OCP.AbstractModel, <:Function, <:Real, DM<:CTModels.OCP.AbstractDualModel}
) -> CTModels.OCP.AbstractDualModel

Return the dual model containing all constraint multipliers.

isempty_constraints