Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/Data/Data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ include(joinpath(@__DIR__, "control_law.jl"))
include(joinpath(@__DIR__, "abstract_pseudo_hamiltonian.jl"))
include(joinpath(@__DIR__, "pseudo_hamiltonian.jl"))
include(joinpath(@__DIR__, "composed_hamiltonian.jl"))
include(joinpath(@__DIR__, "abstract_controlled_vector_field.jl"))
include(joinpath(@__DIR__, "controlled_vector_field.jl"))
include(joinpath(@__DIR__, "composed_vector_field.jl"))
include(joinpath(@__DIR__, "abstract_hamiltonian_vector_field.jl"))
include(joinpath(@__DIR__, "hamiltonian_vector_field.jl"))

Expand All @@ -51,5 +54,9 @@ export PseudoHamiltonian
export ComposedHamiltonian
export pseudo_hamiltonian
export control_law
export AbstractControlledVectorField
export ControlledVectorField
export ComposedVectorField
export controlled_vector_field

end # module Data
93 changes: 93 additions & 0 deletions src/Data/abstract_controlled_vector_field.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# =============================================================================
# AbstractControlledVectorField — abstract supertype for controlled vector fields
# =============================================================================

"""
$(TYPEDEF)

Abstract supertype for **controlled** vector-field functions together with their
time-dependence and variable-dependence traits.

A controlled vector field is a function `fc(t, x, u[, v])` returning the state
derivative, with an **explicit control argument** `u`. It is the state-space analogue
of [`CTBase.Data.AbstractPseudoHamiltonian`](@ref): where a pseudo-Hamiltonian carries
the control alongside the costate, a controlled vector field carries the control
alongside the state. It is always **out-of-place** (returns the derivative), so unlike
[`CTBase.Data.AbstractVectorField`](@ref) it has no mutability trait.

Composing a controlled vector field with an open-loop or closed-loop control law
eliminates the control and yields a plain [`CTBase.Data.ComposedVectorField`](@ref).

# Type Parameters
- `TD <: TimeDependence`: `Autonomous` or `NonAutonomous`.
- `VD <: VariableDependence`: `Fixed` or `NonFixed`.

# Notes
- All controlled vector fields support both natural and uniform call signatures.
- The uniform signature `(t, x, u, v)` is used internally by composition.
- The dynamics trait is always `StateDynamics`.

See also: [`CTBase.Data.ControlledVectorField`](@ref), [`CTBase.Data.ComposedVectorField`](@ref),
[`CTBase.Data.AbstractPseudoHamiltonian`](@ref).
"""
abstract type AbstractControlledVectorField{
TD<:Traits.TimeDependence,VD<:Traits.VariableDependence
} end

# =============================================================================
# Trait accessors
# =============================================================================

"""
$(TYPEDSIGNATURES)

Indicate that all `AbstractControlledVectorField` types support time-dependence queries.

See also: [`CTBase.Traits.time_dependence`](@ref).
"""
Traits.has_time_dependence_trait(::AbstractControlledVectorField) = true

"""
$(TYPEDSIGNATURES)

Indicate that all `AbstractControlledVectorField` types support variable-dependence queries.

See also: [`CTBase.Traits.variable_dependence`](@ref).
"""
Traits.has_variable_dependence_trait(::AbstractControlledVectorField) = true

"""
$(TYPEDSIGNATURES)

Return the time-dependence trait of a controlled vector field.

See also: [`CTBase.Traits.time_dependence`](@ref).
"""
function Traits.time_dependence(
::AbstractControlledVectorField{TD,<:Traits.VariableDependence}
) where {TD<:Traits.TimeDependence}
return TD
end

"""
$(TYPEDSIGNATURES)

Return the variable-dependence trait of a controlled vector field.

See also: [`CTBase.Traits.variable_dependence`](@ref).
"""
function Traits.variable_dependence(
::AbstractControlledVectorField{<:Traits.TimeDependence,VD}
) where {VD<:Traits.VariableDependence}
return VD
end

"""
$(TYPEDSIGNATURES)

Return the dynamics trait of an `AbstractControlledVectorField`, namely
[`CTBase.Traits.StateDynamics`](@ref).

See also: [`CTBase.Traits.dynamics_trait`](@ref).
"""
Traits.dynamics_trait(::AbstractControlledVectorField) = Traits.StateDynamics
161 changes: 161 additions & 0 deletions src/Data/composed_vector_field.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# =============================================================================
# ComposedVectorField — vector field obtained by composing a controlled vector
# field with an open-loop or closed-loop control law
# =============================================================================

"""
$(TYPEDEF)

Vector field obtained by eliminating the control from a
[`CTBase.Data.ControlledVectorField`](@ref) with an **open-loop** or **closed-loop**
[`CTBase.Data.ControlLaw`](@ref):

```math
g(t, x, v) = fc(t, x, u(...), v),
```

where the control is `u(t, v)` for an open-loop law and `u(t, x, v)` for a closed-loop
law. It is the state-space analogue of [`CTBase.Data.ComposedHamiltonian`](@ref).

It is a **functor** (not a closure), out-of-place, and subtypes
[`CTBase.Data.AbstractVectorField`](@ref) with `OutOfPlace` mutability — so it *is* a
vector field usable anywhere one is expected.

# Type Parameters
- `TD <: TimeDependence`, `VD <: VariableDependence`: the **join** of the controlled
vector field's and the control law's dependences.
- `CVF <: ControlledVectorField`: concrete controlled vector-field type.
- `L <: ControlLaw`: concrete control-law type (must carry `OpenLoopFeedback` or
`ClosedLoopFeedback`).

# Fields
- `fc::CVF`: the controlled vector field `fc(t, x, u, v)`.
- `law::L`: the open-loop or closed-loop control law.

See also: [`CTBase.Data.ControlledVectorField`](@ref), [`CTBase.Data.ControlLaw`](@ref),
[`CTBase.Data.OpenLoop`](@ref), [`CTBase.Data.ClosedLoop`](@ref),
[`CTBase.Data.ComposedHamiltonian`](@ref).
"""
struct ComposedVectorField{
TD<:Traits.TimeDependence,
VD<:Traits.VariableDependence,
CVF<:ControlledVectorField,
L<:ControlLaw{<:Function,<:Union{Traits.OpenLoopFeedback,Traits.ClosedLoopFeedback}},
} <: AbstractVectorField{TD,VD,Traits.OutOfPlace}
fc::CVF
law::L
end

# =============================================================================
# Constructor — composed traits are the join of the two inputs
# =============================================================================

"""
$(TYPEDSIGNATURES)

Construct a [`CTBase.Data.ComposedVectorField`](@ref) from a controlled vector field and
an open-loop or closed-loop control law, computing the composed time/variable
dependences as the join of the two inputs.

See also: [`CTBase.Data.ComposedVectorField`](@ref).
"""
function ComposedVectorField(
fc::ControlledVectorField,
law::ControlLaw{<:Function,<:Union{Traits.OpenLoopFeedback,Traits.ClosedLoopFeedback}},
)
TD = _join_td(Traits.time_dependence(fc), Traits.time_dependence(law))
VD = _join_vd(Traits.variable_dependence(fc), Traits.variable_dependence(law))
return ComposedVectorField{TD,VD,typeof(fc),typeof(law)}(fc, law)
end

# =============================================================================
# Getters
# =============================================================================

"""
$(TYPEDSIGNATURES)

Return the underlying controlled vector field of a [`CTBase.Data.ComposedVectorField`](@ref).

See also: [`CTBase.Data.ComposedVectorField`](@ref), [`CTBase.Data.control_law`](@ref).
"""
controlled_vector_field(g::ComposedVectorField) = g.fc

"""
$(TYPEDSIGNATURES)

Return the control law of a [`CTBase.Data.ComposedVectorField`](@ref).

See also: [`CTBase.Data.ComposedVectorField`](@ref), [`CTBase.Data.controlled_vector_field`](@ref).
"""
control_law(g::ComposedVectorField) = g.law

# =============================================================================
# Core computation and call signatures
# =============================================================================

# Evaluate the control from the law — the uniform call arity depends on the feedback:
# open-loop u(t, v) ignores the state, closed-loop u(t, x, v) uses it.
_law_control(law::ControlLaw{<:Function,Traits.OpenLoopFeedback}, t, x, v) = law(t, v)
_law_control(law::ControlLaw{<:Function,Traits.ClosedLoopFeedback}, t, x, v) = law(t, x, v)

"""
$(TYPEDSIGNATURES)

Core computation `g(t, x, v) = fc(t, x, u(...), v)` using the uniform call signatures of
the controlled vector field and the control law (open-loop `u(t,v)` or closed-loop
`u(t,x,v)`).

See also: [`CTBase.Data.ComposedVectorField`](@ref).
"""
function _composed_vf(g::ComposedVectorField, t, x, v)
u = _law_control(g.law, t, x, v)
return g.fc(t, x, u, v) # ControlledVectorField uniform call (t, x, u, v)
end

# Natural call signatures (OutOfPlace) — one per composed (TD, VD)
function (g::ComposedVectorField{Traits.Autonomous,Traits.Fixed})(x)
_composed_vf(g, 0.0, x, nothing)
end
function (g::ComposedVectorField{Traits.NonAutonomous,Traits.Fixed})(t, x)
_composed_vf(g, t, x, nothing)
end
function (g::ComposedVectorField{Traits.Autonomous,Traits.NonFixed})(x, v)
_composed_vf(g, 0.0, x, v)
end
function (g::ComposedVectorField{Traits.NonAutonomous,Traits.NonFixed})(t, x, v)
return _composed_vf(g, t, x, v)
end

# Uniform (t, x, v) call — used by VectorFieldSystem.
# (NonAutonomous, NonFixed) is already covered by the natural signature above.
(g::ComposedVectorField{Traits.Autonomous,Traits.Fixed})(t, x, v) = _composed_vf(g, t, x, v)
function (g::ComposedVectorField{Traits.NonAutonomous,Traits.Fixed})(t, x, v)
_composed_vf(g, t, x, v)
end
function (g::ComposedVectorField{Traits.Autonomous,Traits.NonFixed})(t, x, v)
_composed_vf(g, t, x, v)
end

# =============================================================================
# Base.show
# =============================================================================

"""
$(TYPEDSIGNATURES)

Display a compact representation of a [`CTBase.Data.ComposedVectorField`](@ref).

See also: [`CTBase.Data.ComposedVectorField`](@ref).
"""
function Base.show(io::IO, ::ComposedVectorField{TD,VD}) where {TD,VD}
natural = _natural_sig_vf(TD, VD, Traits.OutOfPlace)
uniform = _uniform_sig_vf(Traits.OutOfPlace)
println(io, "ComposedVectorField: $(_td_label(TD)), $(_vd_label(VD)), out-of-place")
println(io, " natural call: ", natural)
return print(io, " uniform call: ", uniform)
end

function Base.show(io::IO, ::MIME"text/plain", g::ComposedVectorField)
return show(io, g)
end
Loading
Loading