Skip to content

The @Lie macro ​

@Lie writes brackets as on paper: square brackets for a Lie bracket of vector fields, @Lie [X, Y], which calls ad, and curly braces for a Poisson bracket of Hamiltonians, @Lie {H, G}, which calls Poisson.

julia
using OptimalControl

Lie brackets ​

The fields    and    generate the rotations about the first two axes. Their bracket is   , a rotation about the third axis:

julia
F1 = VectorField(x -> [0, -x[3], x[2]])
F2 = VectorField(x -> [x[3], 0, -x[1]])

F12 = @Lie [F1, F2]
F12([1.0, 2.0, 3.0])
3-element Vector{Float64}:
  2.0
 -1.0
 -0.0

Brackets nest. A linear vector field commutes with the radial field  , so  :

julia
F3 = VectorField(x -> x)

F123 = @Lie [[F1, F2], F3]
F123([1.0, 2.0, 3.0])
3-element Vector{Float64}:
 0.0
 0.0
 0.0

Poisson brackets ​

With    and  ,    and   :

julia
H0(x, p) = p[1] * x[2] - p[2] * x[1]
H1(x, p) = p[2]

H01 = @Lie {H0, H1}
H001 = @Lie {H0, {H0, H1}}

x, p = [1.0, 2.0], [3.0, 4.0]
H01(x, p), H001(x, p)
(-3.0, -4.0)

These iterated brackets give the control on a singular arc (see Poisson bracket).

Keywords ​

On plain functions, give the dependence on time and on the variable with the keywords is_autonomous= and is_variable=, after the brackets. On typed operands, the traits are read from the operands. With     and  ,     , which is at  ,  :

julia
X(t, x) = [t + x[2], -x[1]]
Y(t, x) = [x[1], t * x[2]]

Z = @Lie [X, Y] is_autonomous=false
Z(1.0, [1.0, 2.0])
2-element Vector{Float64}:
 1.0
 0.0

The keyword ad_backend= chooses the AD backend (see AD backend). Any other keyword, such as autonomous=false, raises an IncorrectArgument that lists the accepted ones.

Evaluating a bracket in an expression ​

Inside a bracket expression, [F1, F2](x) evaluates the bracket at x, and the result combines with ordinary arithmetic:

julia
y = [1.0, 2.0, 3.0]
@Lie [F1, F2](y) + 4 * [F1, F2](y)
3-element Vector{Float64}:
 10.0
 -5.0
 -0.0

The macro takes everything that follows it as its argument, commas included. Inside a function call, put it in parentheses: isapprox((@Lie [F1, F2])(y), [2, -1, 0]). Without them, isapprox(@Lie [F1, F2](y), [2, -1, 0]) passes both arguments to the macro, and returns a function instead of a Boolean, without an error.

using OptimalControl is needed ​

The expansion of @Lie refers to the modules CTLie and CTBase by name, which using OptimalControl brings into scope. With import OptimalControl or using OptimalControl: @Lie only, the expanded code fails with an UndefVarError (CTLie#40).

See also ​