Lie derivative and Lie bracket
ad(X, foo) is one function with two meanings, chosen by what foo returns.
using OptimalControlOne function, two meanings
fooscalar-valued → the Lie derivative offooalongX.foovector-valued → the Lie bracket ofXandfoo.
Lie derivative
For a vector field
X(x) = [x[2], -x[1]]
f(x) = x[1]^2 + x[2]^2 # energy of the harmonic oscillator
Xf = ad(X, f)
Xf([1.0, 2.0])0.0Energy is conserved along
Lie bracket
For two vector fields
where
Y(x) = [x[1]^2, x[2]^2]
Z = ad(X, Y)
Z([1.0, 2.0])2-element Vector{Float64}:
0.0
-3.0Typed operands
Wrapping the inputs as VectorFields makes ad return a VectorField too — so it nests:
XV = VectorField(x -> [x[2], -x[1]])
YV = VectorField(x -> [x[1]^2, x[2]^2])
ZV = ad(XV, YV)
typeof(ZV)VectorField{CTLie.Ad{VectorField{Main.var"#2#3", CTBase.Traits.Autonomous, CTBase.Traits.Fixed, CTBase.Traits.OutOfPlace}, VectorField{Main.var"#5#6", CTBase.Traits.Autonomous, CTBase.Traits.Fixed, CTBase.Traits.OutOfPlace}, CTBase.Differentiation.DifferentiationInterface{CPU, CTBase.Strategies.StrategyOptions{@NamedTuple{ad_backend::CTBase.Options.OptionValue{AutoForwardDiff{nothing, Nothing}}}}}, CTBase.Traits.Autonomous, CTBase.Traits.Fixed}, CTBase.Traits.Autonomous, CTBase.Traits.Fixed, CTBase.Traits.OutOfPlace}ZZV = ad(ZV, YV) # ad(ad(X, Y), Y) — a second-order bracket
ZZV([1.0, 2.0])2-element Vector{Float64}:
4.0
-2.0Non-autonomous and variable fields
is_autonomous= and is_variable= work exactly as on Lift; both operands must agree, or you get a PreconditionError naming both traits:
julia> Xa = VectorField(x -> [x[2], -x[1]]);
julia> Xb = VectorField((t, x) -> [t + x[2], -x[1]]; is_autonomous=false);
julia> ad(Xa, Xb)
PreconditionError → top-level scope, REPL[3]:2
│
│ ad: TD/VD mismatch between X and Y
│
│ Reason X: CTBase.Traits.Autonomous/CTBase.Traits.Fixed ≠ Y: CTBase.Traits.NonAutonomous/CTBase.Traits.Fixed — both arguments must share the same TimeDependence and VariableDependence
│
│ Context ad on AbstractVectorField
│ Hint Ensure both vector fields have the same time and variable dependence traits
└─Partial time derivative
∂ₜ computes f, VectorField, or Hamiltonian — its result is always NonAutonomous, regardless of whether the input already was:
g(t, x) = t^2 + x[1] * x[2]
dg = ∂ₜ(g)
dg(3.0, [1.0, 2.0]) # ∂g/∂t = 2t = 66.0dXV = ∂ₜ(XV) # XV::VectorField, defined above — still comes back NonAutonomous
typeof(dXV)VectorField{CTLie.TimeDeriv_VF{VectorField{Main.var"#2#3", CTBase.Traits.Autonomous, CTBase.Traits.Fixed, CTBase.Traits.OutOfPlace}, CTBase.Differentiation.DifferentiationInterface{CPU, CTBase.Strategies.StrategyOptions{@NamedTuple{ad_backend::CTBase.Options.OptionValue{AutoForwardDiff{nothing, Nothing}}}}}, CTBase.Traits.Autonomous, CTBase.Traits.Fixed}, CTBase.Traits.NonAutonomous, CTBase.Traits.Fixed, CTBase.Traits.OutOfPlace}Errors you will meet
| Situation | Exception |
|---|---|
ad given an AbstractHamiltonian | IncorrectArgument — points at Poisson |
| time/variable dependence mismatch between operands | PreconditionError |
an InPlace operand | NotImplemented |
a HamiltonianVectorField passed to ad | NotImplemented |
julia> H = Hamiltonian((x, p) -> x[1] + p[1]);
julia> ad(H, x -> x)
IncorrectArgument → top-level scope, REPL[2]:2
│
│ ad is not defined for AbstractHamiltonian operands
│
│ Context ad on AbstractHamiltonian
│ Hint Use Poisson(H, G) for the Poisson bracket of Hamiltonians
└─ad also refuses an InPlace operand:
julia> Xip = VectorField((dx, x) -> (dx .= [x[2], -x[1]]); is_inplace=true);
julia> ad(Xip, x -> x[1]^2)
NotImplemented → top-level scope, REPL[2]:2
│
│ ad is not implemented for InPlace vector fields
│
│ Method Use an OutOfPlace VectorField
│
│ Context ad on AbstractVectorField
│ Hint Reconstruct the VectorField without in-place flag
└─Coming from v2.0
| v2.0 | v2.1 |
|---|---|
Lie(X, f) | ad(X, f) |
X ⋅ f | ad(X, f) — no operator replacement, ⋅ is gone |
See Migrating to v2.1 for the throwing shim on Lie.
See also
Poisson bracket — the Hamiltonian-side counterpart, linked by
Poisson(Lift(X), Lift(Y)) ≈ Lift(ad(X, Y)).The
@Liemacro —ad/Poissonwith bracket notation.