Public API
This page lists exported symbols of CTBase.Differentiation.
From CTBase.Differentiation
CTBase.Differentiation [Module]
CTBase.Differentiation Module
Module CTBase.Differentiation provides automatic differentiation backend strategies for computing gradients of scalar Hamiltonian functions.
Architecture
The module defines an abstract contract AbstractADBackend with the following methods:
ad_backend(backend)→ the wrapped ADTypes backend (resolved in core)hamiltonian_gradient(backend, h, t, x, p, v)→ (∂H/∂x, ∂H/∂p)variable_gradient(backend, h, t, x, p, v)→ ∂H/∂vpseudo_hamiltonian_gradient(backend, h̃, t, x, p, u, v)→ (∂H̃/∂x, ∂H̃/∂p)pseudo_hamiltonian_control_gradient(backend, h̃, t, x, p, u, v)→ ∂H̃/∂upseudo_variable_gradient(backend, h̃, t, x, p, u, v)→ ∂H̃/∂v (control u held constant)gradient(backend, f, x)→ ∇f (extension contract)derivative(backend, g, t)→ dg/dt (extension contract)differentiate(backend, f, ::Val{Slot}, active, consts...)→ partial derivative at slotpushforward(backend, f, ::Val{Slot}, x, dx, consts...)→ JVP along direction dx
The concrete strategy DifferentiationInterface wraps DifferentiationInterface.jl backends (e.g., AutoForwardDiff()) and stores them in its :ad_backend option.
Dependencies
ADTypes.jl(hard dependency) — providesAutoForwardDifftypeCTBase.Data—AbstractHamiltonianin the gradient contract signaturesCTBase.Strategies— strategy contractCTBase.Exceptions—NotImplementedfor stub methods
Extension
Gradient computation requires the CTBaseDifferentiationInterface extension, which implements the contract methods using DifferentiationInterface.gradient and friends. It is loaded automatically when DifferentiationInterface is loaded together with CTBase.
Exports
AbstractADBackendDifferentiationInterfacebuild_ad_backendad_backendhamiltonian_gradientvariable_gradientgradientderivativedifferentiatepushforward
AbstractADBackend [Abstract Type]
CTBase.Differentiation.AbstractADBackend Type
abstract type AbstractADBackend <: CTBase.Strategies.AbstractStrategyAbstract base type for automatic differentiation backends.
An AbstractADBackend is a strategy that defines how to compute gradients of a scalar Hamiltonian function. Concrete backends (e.g., DifferentiationInterface) implement the contract methods to provide actual gradient computation.
Notes
AbstractADBackendsubtypesCTBase.Strategies.AbstractStrategy— they are first-class strategies in the CTBase.Strategies ecosystem.The contract comprises
ad_backend(the wrapped ADTypes backend), the domain methodshamiltonian_gradient,variable_gradient,pseudo_hamiltonian_gradient,pseudo_hamiltonian_control_gradient,pseudo_variable_gradient, and the generic primitivesgradient,derivative,differentiateandpushforward. All butad_backendare supplied by theCTBaseDifferentiationInterfaceextension.Gradient methods return non-negated partial derivatives; the RHS closures apply the signs (ṗ = -∂H/∂x, ṽ = -∂H/∂v).
See also: CTBase.Differentiation.DifferentiationInterface, CTBase.Differentiation.hamiltonian_gradient, CTBase.Differentiation.variable_gradient.
DifferentiationInterface [Struct]
CTBase.Differentiation.DifferentiationInterface Type
struct DifferentiationInterface{O<:CTBase.Strategies.StrategyOptions} <: CTBase.Differentiation.AbstractADBackendConcrete AD backend strategy wrapping DifferentiationInterface.jl backends.
DifferentiationInterface stores a :ad_backend option (e.g., AutoForwardDiff(), AutoZygote()) and uses it to compute gradients via the DifferentiationInterface.jl ecosystem.
Arguments
backend=AutoForwardDiff(): The DifferentiationInterface.jl backend to use. Defaults toAutoForwardDiff()fromADTypes.jl(a hard dependency).kwargs...: Additional options passed toStrategyOptions.
Notes
ADTypes.jlis a hard dependency, soAutoForwardDiff()is always available in core.Gradient computation requires the
CTBaseDifferentiationInterfaceextension.Without the extension, the gradient methods throw
NotImplementedwith a helpful message.
See also: CTBase.Differentiation.AbstractADBackend, CTBase.Differentiation.hamiltonian_gradient, CTBase.Differentiation.variable_gradient.
ad_backend [Function]
CTBase.Differentiation.ad_backend Function
ad_backend(
backend::CTBase.Differentiation.AbstractADBackend
) -> AnyExtract the AD backend from a backend strategy.
Arguments
backend::AbstractADBackend: The AD backend.
Returns
ADTypes.AbstractADType: The concrete AD backend (e.g.,AutoForwardDiff()).
Throws
CTBase.Exceptions.NotImplemented: If the concrete backend does not implement this method.
Notes
This method is used by Hamiltonian vector-field getters to extract the AD backend from a Hamiltonian system's backend.
For
DifferentiationInterface, this extracts the:ad_backendoption.
See also: CTBase.Differentiation.DifferentiationInterface.
ad_backend(
backend::CTBase.Differentiation.DifferentiationInterface
) -> AnyExtract the AD backend from a DifferentiationInterface strategy.
Arguments
backend::DifferentiationInterface: The AD backend.
Returns
ADTypes.AbstractADType: The concrete AD backend from the:ad_backendoption.
Notes
This extracts the
:ad_backendoption from the strategy's options.Used by Hamiltonian vector-field getters to delegate to the AD-backed getter.
See also: CTBase.Differentiation.ad_backend.
build_ad_backend [Function]
CTBase.Differentiation.build_ad_backend Function
build_ad_backend(
;
kwargs...
) -> CTBase.Differentiation.DifferentiationInterface{CTBase.Strategies.StrategyOptions{NT}} where NT<:NamedTupleFactory function to build an AD backend with default options.
Arguments
kwargs...: Options passed toDifferentiationInterfaceconstructor.
Returns
DifferentiationInterface: A new AD backend strategy instance.
Notes
- This is a convenience factory that always returns a
DifferentiationInterfaceinstance with the provided options.
derivative [Function]
CTBase.Differentiation.derivative Function
derivative(
backend::CTBase.Differentiation.AbstractADBackend,
g::Function,
t::Real
) -> AnyCompute the derivative of a scalar function using the backend.
Arguments
backend::AbstractADBackend: The AD backend.g: The scalar function to differentiate.t::Real: The input scalar.
Returns
dg/dt: The derivative ofgatt.
Throws
CTBase.Exceptions.NotImplemented: If the concrete backend does not implement this method.
Notes
- This method is provided for extensions that implement derivative computation via DifferentiationInterface.jl.
See also: CTBase.Differentiation.gradient, CTBase.Differentiation.variable_gradient.
derivative(
backend::CTBase.Differentiation.DifferentiationInterface,
g::Function,
t::Real
) -> AnyCompute the derivative of a scalar function using DifferentiationInterface.jl.
Arguments
backend::Differentiation.DifferentiationInterface: The AD backend.g::Function: The scalar function to differentiate.t::Real: The input scalar.
Returns
dg/dt: The derivative ofgatt.
See also
differentiate [Function]
CTBase.Differentiation.differentiate Function
differentiate(
backend::CTBase.Differentiation.AbstractADBackend,
f,
_::Val{Slot},
active,
consts...
) -> AnyCompute the partial derivative or gradient of f with respect to the argument at slot Slot, holding all other arguments fixed.
f is called as f(arg₁, …, argₙ). The active argument is active (placed at position Slot); the remaining n-1 arguments are supplied as consts... in slot order (skipping Slot).
Arguments
backend::AbstractADBackend: The AD backend.f: The function to differentiate (any callable).::Val{Slot}: Compile-time slot index of the active argument.active: The point at which to differentiate.consts...: The fixed arguments, in order of their slot positions (excludingSlot).
Returns
- Gradient vector if
active isa AbstractArray, scalar derivative ifactive isa Real.
Throws
CTBase.Exceptions.NotImplemented: If the concrete backend does not implement this method.
See also: CTBase.Differentiation.pushforward.
differentiate(
backend::CTBase.Differentiation.DifferentiationInterface,
f,
_::Val{Slot},
active,
consts...
) -> AnyCompute the partial derivative or gradient of f with respect to the argument at slot Slot, using DifferentiationInterface.jl.
An anonymous closure captures the constant arguments and places active_ at Slot via ntuple — same rationale as CTBase.Differentiation.hamiltonian_gradient (ForwardDiff tag ordering). _derivator dispatches to DI.gradient for array active and DI.derivative for scalar.
See also: CTBase.Differentiation.pushforward.
gradient [Function]
CTBase.Differentiation.gradient Function
gradient(
backend::CTBase.Differentiation.AbstractADBackend,
f::Function,
x
) -> AnyCompute the gradient of a scalar function using the backend.
Arguments
backend::AbstractADBackend: The AD backend.f: The scalar function to differentiate.x: The input vector.
Returns
∇f: The gradient offatx.
Throws
CTBase.Exceptions.NotImplemented: If the concrete backend does not implement this method.
Notes
- This method is provided for extensions that implement gradient computation via DifferentiationInterface.jl.
See also: CTBase.Differentiation.derivative, CTBase.Differentiation.hamiltonian_gradient.
gradient(
backend::CTBase.Differentiation.DifferentiationInterface,
f::Function,
x::AbstractArray
) -> AnyCompute the gradient of a scalar function using DifferentiationInterface.jl.
Arguments
backend::Differentiation.DifferentiationInterface: The AD backend.f::Function: The scalar function to differentiate.x::AbstractArray: The input vector.
Returns
∇f: The gradient offatx.
See also
gradient(
backend::CTBase.Differentiation.DifferentiationInterface,
f::Function,
x::Real
) -> AnyCompute the gradient of a scalar function using DifferentiationInterface.jl (scalar case).
Arguments
backend::Differentiation.DifferentiationInterface: The AD backend.f::Function: The scalar function to differentiate.x::Real: The input scalar.
Returns
df/dx: The derivative offatx.
See also
hamiltonian_gradient [Function]
CTBase.Differentiation.hamiltonian_gradient Function
hamiltonian_gradient(
backend::CTBase.Differentiation.AbstractADBackend,
h::CTBase.Data.AbstractHamiltonian,
t,
x,
p,
v
) -> Tuple{Any, Any}Compute the Hamiltonian gradient (∂H/∂x, ∂H/∂p) using the backend.
Arguments
backend::AbstractADBackend: The AD backend.h: The Hamiltonian function or type.t: Time (scalar).x: State vector.p: Costate vector.v: Variable (scalar ornothingfor Fixed problems).
Returns
(∂H_∂x, ∂H_∂p): Tuple of partial derivatives, non-negated. The RHS closure is responsible for applying the signs (ṗ = -∂H/∂x).
Throws
CTBase.Exceptions.NotImplemented: If the concrete backend does not implement this method.
See also: CTBase.Differentiation.variable_gradient.
hamiltonian_gradient(
backend::CTBase.Differentiation.DifferentiationInterface,
h::CTBase.Data.AbstractHamiltonian,
t,
x,
p,
v
) -> Tuple{Any, Any}Compute Hamiltonian gradients (∂H/∂x, ∂H/∂p) via DifferentiationInterface.jl.
Anonymous closures are used deliberately so that ForwardDiff tagcount values are assigned at runtime in the correct left-to-right order inside ForwardDiff.≺, avoiding silent zero-gradient bugs in nested-AD contexts (e.g. inside NonlinearSolve).
Returns
- Tuple
(grad_x, grad_p)wheregrad_x= ∂H/∂x,grad_p= ∂H/∂p.
pseudo_hamiltonian_control_gradient [Function]
CTBase.Differentiation.pseudo_hamiltonian_control_gradient Function
pseudo_hamiltonian_control_gradient(
backend::CTBase.Differentiation.AbstractADBackend,
h̃::CTBase.Data.AbstractPseudoHamiltonian,
t,
x,
p,
u,
v
) -> AnyCompute the pseudo-Hamiltonian control gradient ∂H̃/∂u using the backend.
This is typically used to check the PMP stationarity condition ∂H̃/∂u = 0, not for the Hamiltonian flow itself (which only needs ∂H̃/∂x and ∂H̃/∂p; see CTBase.Differentiation.pseudo_hamiltonian_gradient).
Arguments
backend::AbstractADBackend: The AD backend.h̃: The pseudo-Hamiltonian function or type.t: Time (scalar).x: State vector.p: Costate vector.u: Control (scalar or vector).v: Variable (scalar ornothingfor Fixed problems).
Returns
∂H̃_∂u: The partial derivative with respect to the control.
Throws
CTBase.Exceptions.NotImplemented: If the concrete backend does not implement this method.
See also: CTBase.Differentiation.pseudo_hamiltonian_gradient, CTBase.Differentiation.variable_gradient.
pseudo_hamiltonian_control_gradient(
backend::CTBase.Differentiation.DifferentiationInterface,
h̃::CTBase.Data.AbstractPseudoHamiltonian,
t,
x,
p,
u,
v
) -> AnyCompute the pseudo-Hamiltonian control gradient ∂H̃/∂u via DifferentiationInterface.jl.
This is typically used to check the PMP stationarity condition ∂H̃/∂u = 0, not for the Hamiltonian flow itself.
Arguments
backend::Differentiation.DifferentiationInterface: The DI backend strategy.h̃::Data.AbstractPseudoHamiltonian: The pseudo-Hamiltonian.t: Time (scalar).x: State vector.p: Costate vector.u: Control (scalar or vector).v: Variable (scalar ornothingfor Fixed problems).
Returns
grad_u: ∂H̃/∂u.
See also: CTBase.Differentiation.pseudo_hamiltonian_gradient.
pseudo_hamiltonian_gradient [Function]
CTBase.Differentiation.pseudo_hamiltonian_gradient Function
pseudo_hamiltonian_gradient(
backend::CTBase.Differentiation.AbstractADBackend,
h̃::CTBase.Data.AbstractPseudoHamiltonian,
t,
x,
p,
u,
v
) -> Tuple{Any, Any}Compute the pseudo-Hamiltonian gradient (∂H̃/∂x, ∂H̃/∂p) using the backend.
Along a PMP solution, the stationarity condition ∂H̃/∂u = 0 holds, so the Hamiltonian flow only requires ∂H̃/∂x and ∂H̃/∂p. Use CTBase.Differentiation.pseudo_hamiltonian_control_gradient to compute ∂H̃/∂u separately (e.g. for checking the stationarity condition).
Arguments
backend::AbstractADBackend: The AD backend.h̃: The pseudo-Hamiltonian function or type.t: Time (scalar).x: State vector.p: Costate vector.u: Control (scalar or vector).v: Variable (scalar ornothingfor Fixed problems).
Returns
(∂H̃_∂x, ∂H̃_∂p): Tuple of partial derivatives, non-negated. The RHS closure is responsible for applying the signs (ṗ = -∂H̃/∂x).
Throws
CTBase.Exceptions.NotImplemented: If the concrete backend does not implement this method.
See also: CTBase.Differentiation.pseudo_hamiltonian_control_gradient, CTBase.Differentiation.hamiltonian_gradient, CTBase.Differentiation.variable_gradient.
pseudo_hamiltonian_gradient(
backend::CTBase.Differentiation.DifferentiationInterface,
h̃::CTBase.Data.AbstractPseudoHamiltonian,
t,
x,
p,
u,
v
) -> Tuple{Any, Any}Compute pseudo-Hamiltonian gradients (∂H̃/∂x, ∂H̃/∂p) via DifferentiationInterface.jl.
Along a PMP solution, the stationarity condition ∂H̃/∂u = 0 holds, so the Hamiltonian flow only requires ∂H̃/∂x and ∂H̃/∂p. Use CTBase.Differentiation.pseudo_hamiltonian_control_gradient for ∂H̃/∂u.
Anonymous closures are used deliberately so that ForwardDiff tagcount values are assigned at runtime in the correct left-to-right order inside ForwardDiff.≺, avoiding silent zero-gradient bugs in nested-AD contexts (e.g. inside NonlinearSolve).
Arguments
backend::Differentiation.DifferentiationInterface: The DI backend strategy.h̃::Data.AbstractPseudoHamiltonian: The pseudo-Hamiltonian.t: Time (scalar).x: State vector.p: Costate vector.u: Control (scalar or vector).v: Variable (scalar ornothingfor Fixed problems).
Returns
- Tuple
(grad_x, grad_p)wheregrad_x= ∂H̃/∂x,grad_p= ∂H̃/∂p.
See also: CTBase.Differentiation.pseudo_hamiltonian_control_gradient, CTBase.Differentiation.hamiltonian_gradient.
pseudo_variable_gradient [Function]
CTBase.Differentiation.pseudo_variable_gradient Function
pseudo_variable_gradient(
backend::CTBase.Differentiation.AbstractADBackend,
h̃::CTBase.Data.AbstractPseudoHamiltonian,
t,
x,
p,
u,
v
) -> AnyCompute the pseudo-Hamiltonian variable gradient ∂H̃/∂v using the backend, with the control u held constant.
This is the pseudo-Hamiltonian analogue of CTBase.Differentiation.variable_gradient, used by the augmented (variable-costate) right-hand side of a PseudoHamiltonianSystem where the control is fixed at the feedback value u = u(t, x, p, v). Because u is held constant, this is a partial derivative; it differs from the total derivative ∂/∂v[H̃(t, x, p, u(t,x,p,v), v)] whenever the feedback is not stationary (∂H̃/∂u ≠ 0).
Arguments
backend::AbstractADBackend: The AD backend.h̃: The pseudo-Hamiltonian function or type.t: Time (scalar).x: State vector.p: Costate vector.u: Control (scalar or vector), held constant during differentiation.v: Variable (scalar ornothingfor Fixed problems).
Returns
∂H̃_∂v: Partial derivative with respect to the variable, non-negated. The RHS closure is responsible for applying the sign (ṗv = -∂H̃/∂v).
Throws
CTBase.Exceptions.NotImplemented: If the concrete backend does not implement this method.
See also: CTBase.Differentiation.variable_gradient, CTBase.Differentiation.pseudo_hamiltonian_gradient.
pseudo_variable_gradient(
backend::CTBase.Differentiation.DifferentiationInterface,
h̃::CTBase.Data.AbstractPseudoHamiltonian,
t,
x,
p,
u,
v
) -> AnyCompute the pseudo-Hamiltonian variable gradient ∂H̃/∂v via DifferentiationInterface.jl, with the control u held constant.
See the note in CTBase.Differentiation.hamiltonian_gradient on why anonymous closures are used, and CTBase.Differentiation.pseudo_variable_gradient on the partial-vs-total distinction.
Returns
grad_v= ∂H̃/∂v (withufixed).
pushforward [Function]
CTBase.Differentiation.pushforward Function
pushforward(
backend::CTBase.Differentiation.AbstractADBackend,
f,
_::Val{Slot},
x,
dx,
consts...
) -> AnyCompute the pushforward (Jacobian-vector product) of f at x in direction dx, holding fixed arguments consts... at the slots other than Slot.
Returns d/ds f(x + s·dx, consts…)|_{s=0} — the directional derivative of f at x along dx, with all other arguments frozen.
Arguments
backend::AbstractADBackend: The AD backend.f: The function to differentiate (any callable).::Val{Slot}: Compile-time slot index of the active (differentiated) argument.x: The point at which to differentiate.dx: The direction (tangent vector, same shape asx).consts...: The fixed arguments, in slot order (excludingSlot).
Returns
- The directional derivative
J_f(x) · dx, same shape asf(x, …).
Throws
CTBase.Exceptions.NotImplemented: If the concrete backend does not implement this method.
See also: CTBase.Differentiation.differentiate.
pushforward(
backend::CTBase.Differentiation.DifferentiationInterface,
f,
_::Val{Slot},
x,
dx,
consts...
) -> AnyCompute the pushforward (Jacobian-vector product) of f at x in direction dx, using DifferentiationInterface.jl.
An anonymous closure captures consts and reconstructs the full argument tuple via ntuple, placing x_ at slot Slot. The single tangent is extracted with only.
See also: CTBase.Differentiation.differentiate.
variable_gradient [Function]
CTBase.Differentiation.variable_gradient Function
variable_gradient(
backend::CTBase.Differentiation.AbstractADBackend,
h::CTBase.Data.AbstractHamiltonian,
t,
x,
p,
v
) -> AnyCompute the variable gradient ∂H/∂v using the backend.
Arguments
backend::AbstractADBackend: The AD backend.h: The Hamiltonian function or type.t: Time (scalar).x: State vector.p: Costate vector.v: Variable (scalar ornothingfor Fixed problems).
Returns
∂H_∂v: Partial derivative with respect to the variable, non-negated. The RHS closure is responsible for applying the sign (ṽ = -∂H/∂v).
Throws
CTBase.Exceptions.NotImplemented: If the concrete backend does not implement this method.
See also: CTBase.Differentiation.hamiltonian_gradient.
variable_gradient(
backend::CTBase.Differentiation.DifferentiationInterface,
h::CTBase.Data.AbstractHamiltonian,
t,
x,
p,
v
) -> AnyCompute variable gradient ∂H/∂v via DifferentiationInterface.jl.
See the note in CTBase.Differentiation.hamiltonian_gradient on why anonymous closures are used.
Returns
grad_v= ∂H/∂v.