Dynamics
Index
In the examples in the documentation below, the methods are not prefixed by the module name even if they are private.
julia> using CTModels
julia> x = 1
julia> private_fun(x) # throw an error
must be replaced by
julia> using CTModels
julia> x = 1
julia> CTModels.private_fun(x)
However, if the method is reexported by another package, then, there is no need of prefixing.
julia> module OptimalControl
import CTModels: private_fun
export private_fun
end
julia> using OptimalControl
julia> x = 1
julia> private_fun(x)
Documentation
CTModels.__build_dynamics_from_parts
— Method__build_dynamics_from_parts(
parts::Vector{<:Tuple{var"#s53", var"#s52"} where {var"#s53"<:(AbstractRange{<:Int64}), var"#s52"<:Function}}
) -> CTModels.var"#dyn!#64"{Vector{var"#s54"}} where var"#s54"<:(Tuple{var"#s53", var"#s52"} where {var"#s53"<:(AbstractRange{<:Int64}), var"#s52"<:Function})
Build a combined dynamics function from multiple parts.
This function constructs an in-place dynamics function dyn!
by composing several sub-functions, each responsible for updating a specific segment of the output vector.
Arguments
parts::Vector{<:Tuple{<:AbstractRange{<:Int}, <:Function}}
: A vector of tuples, where each tuple contains:- A range specifying the indices in the output vector
val
that the corresponding function updates. - A function
f
with the signature(output_segment, t, x, u, v)
, which updates the slice ofval
indicated by the range.
- A range specifying the indices in the output vector
Returns
dyn!
: A function with signature(val, t, x, u, v)
that updates the full output vectorval
in-place by applying each part function to its assigned segment.
Details
- The returned
dyn!
function calls each part function with a view ofval
restricted to the assigned range. This avoids unnecessary copying and allows efficient updates of sub-vectors. - Each part function is expected to modify its output segment in-place.
Example
# Define two sub-dynamics functions
julia> f1(out, t, x, u, v) = out .= x[1:2] .+ u[1:2]
julia> f2(out, t, x, u, v) = out .= x[3] * v
# Combine them into one dynamics function affecting different parts of the output vector
julia> parts = [(1:2, f1), (3:3, f2)]
julia> dyn! = __build_dynamics_from_parts(parts)
val = zeros(3)
julia> dyn!(val, 0.0, [1.0, 2.0, 3.0], [0.5, 0.5], 2.0)
julia> println(val) # prints [1.5, 2.5, 6.0]
CTModels.dynamics!
— Methoddynamics!(
ocp::CTModels.PreModel,
rg::AbstractRange{<:Int64},
f::Function
)
Add a partial dynamics function f
to the optimal control problem ocp
, applying to the subset of state indices specified by the range rg
.
Arguments
ocp::PreModel
: The optimal control problem being defined.rg::AbstractRange{<:Int}
: Range of state indices to whichf
applies.f::Function
: A function describing the dynamics over the specified state indices.
Preconditions
- The state, control, and times must be set before calling this function.
- The full dynamics must not yet be complete.
- No overlap is allowed between
rg
and existing dynamics index ranges.
Behavior
This function appends the tuple (rg, f)
to the list of partial dynamics. It ensures that the specified indices are not already covered and that the system is in a valid configuration for adding partial dynamics.
Errors
Throws CTBase.UnauthorizedCall
if:
- The state, control, or times are not yet set.
- The dynamics are already defined completely.
- Any index in
rg
overlaps with an existing dynamics range.
Example
julia> dynamics!(ocp, 1:2, (out, t, x, u, v) -> out .= x[1:2] .+ u[1:2])
julia> dynamics!(ocp, 3:3, (out, t, x, u, v) -> out .= x[3] * v[1])
CTModels.dynamics!
— Methoddynamics!(ocp::CTModels.PreModel, f::Function)
Set the full dynamics of the optimal control problem ocp
using the function f
.
Arguments
ocp::PreModel
: The optimal control problem being defined.f::Function
: A function that defines the complete system dynamics.
Preconditions
- The state, control, and times must be set before calling this function.
- No dynamics must have been set previously.
Behavior
This function assigns f
as the complete dynamics of the system. It throws an error if any of the required fields (state
, control
, times
) are not yet set, or if dynamics have already been set.
Errors
Throws CTBase.UnauthorizedCall
if called out of order or in an invalid state.
CTModels.dynamics!
— Methoddynamics!(ocp::CTModels.PreModel, i::Integer, f::Function)
Define partial dynamics for a single state variable index in an optimal control problem.
This is a convenience method for defining dynamics affecting only one element of the state vector. It wraps the scalar index i
into a range i:i
and delegates to the general partial dynamics method.
Arguments
ocp::PreModel
: The optimal control problem being defined.i::Integer
: The index of the state variable to which the functionf
applies.f::Function
: A function of the form(out, t, x, u, v) -> ...
, which updates the scalar outputout[1]
in-place.
Behavior
This is equivalent to calling:
julia> dynamics!(ocp, i:i, f)
Errors
Throws the same errors as the range-based method if:
- The model is not properly initialized.
- The index
i
overlaps with existing dynamics. - A full dynamics function is already defined.
Example
julia> dynamics!(ocp, 3, (out, t, x, u, v) -> out[1] = x[3]^2 + u[1])