Skip to content

Commit d12a623

Browse files
committed
Add VectorField examples for Lie derivative with keyword arguments
1 parent 7da9e59 commit d12a623

1 file changed

Lines changed: 92 additions & 66 deletions

File tree

docs/src/manual-differential-geometry.md

Lines changed: 92 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ The simplest way to compute a Hamiltonian lift is from a plain Julia function. B
3333
X(x) = [x[2], -x[1]]
3434
3535
# Compute its Hamiltonian lift
36-
H = Lift(X)
36+
HX = Lift(X)
3737
3838
# Evaluate at a point (x, p)
39-
x = [1.0, 2.0]
40-
p = [3.0, 4.0]
41-
H(x, p)
39+
x = [1, 2]
40+
p = [3, 4]
41+
HX(x, p)
4242
```
4343

4444
The result is $H(x, p) = p_1 x_2 + p_2 (-x_1) = 3 \times 2 + 4 \times (-1) = 2$.
@@ -50,11 +50,11 @@ You can also use the `OptimalControl.VectorField` type, which allows more contro
5050
```@example main-1
5151
using OptimalControl # hide
5252
# Wrap in VectorField (autonomous, non-variable by default)
53-
X_vf = OptimalControl.VectorField(x -> [x[2], -x[1]])
54-
H_vf = Lift(X_vf)
53+
X = OptimalControl.VectorField(x -> [x[2], -x[1]])
54+
HX = Lift(X)
5555
5656
# This returns a HamiltonianLift object
57-
H_vf([1.0, 2.0], [3.0, 4.0])
57+
HX([1, 2], [3, 4])
5858
```
5959

6060
### Non-autonomous case
@@ -64,11 +64,11 @@ For time-dependent vector fields, use `autonomous=false`:
6464
```@example main-2
6565
using OptimalControl # hide
6666
# Non-autonomous vector field: X(t, x) = [t*x[2], -x[1]]
67-
X_na(t, x) = [t * x[2], -x[1]]
68-
H_na = Lift(X_na; autonomous=false)
67+
X(t, x) = [t * x[2], -x[1]]
68+
HX = Lift(X; autonomous=false)
6969
7070
# Signature is now H(t, x, p)
71-
H_na(2.0, [1.0, 2.0], [3.0, 4.0])
71+
HX(2, [1, 2], [3, 4])
7272
```
7373

7474
### Variable case
@@ -78,11 +78,11 @@ For vector fields depending on an additional parameter $v$, use `variable=true`:
7878
```@example main-3
7979
using OptimalControl # hide
8080
# Variable vector field: X(x, v) = [x[2] + v, -x[1]]
81-
X_var(x, v) = [x[2] + v, -x[1]]
82-
H_var = Lift(X_var; variable=true)
81+
X(x, v) = [x[2] + v, -x[1]]
82+
HX = Lift(X; variable=true)
8383
8484
# Signature is now H(x, p, v)
85-
H_var([1.0, 2.0], [3.0, 4.0], 1.0)
85+
HX([1, 2], [3, 4], 1)
8686
```
8787

8888
## Lie derivative
@@ -102,14 +102,14 @@ When using plain Julia functions, they are treated as autonomous and non-variabl
102102
```@example main-4
103103
using OptimalControl # hide
104104
# Vector field and scalar function
105-
φ(x) = [x[2], -x[1]]
105+
X(x) = [x[2], -x[1]]
106106
f(x) = x[1]^2 + x[2]^2
107107
108108
# Lie derivative (using dot operator)
109-
Xf = φ ⋅ f
109+
Xf = X ⋅ f
110110
111111
# Evaluate at a point
112-
Xf([1.0, 2.0])
112+
Xf([1, 2])
113113
```
114114

115115
For the harmonic oscillator with $X(x) = (x_2, -x_1)$ and energy $f(x) = x_1^2 + x_2^2$:
@@ -130,7 +130,7 @@ g(x) = x[1]^2 + x[2]^2
130130
131131
# Lie derivative
132132
Xg = X ⋅ g
133-
Xg([1.0, 2.0])
133+
Xg([1, 2])
134134
```
135135

136136
### Alternative syntax
@@ -139,10 +139,10 @@ The `Lie` function is equivalent to the `⋅` operator:
139139

140140
```@example main-5
141141
# These are equivalent
142-
result1 = X ⋅ g
143-
result2 = Lie(X, g)
142+
Xg1 = X ⋅ g
143+
Xg2 = Lie(X, g)
144144
145-
result1([1.0, 2.0]) == result2([1.0, 2.0])
145+
Xg1([1, 2]) == Xg2([1, 2])
146146
```
147147

148148
### With keyword arguments
@@ -152,21 +152,47 @@ For non-autonomous or variable cases, use the `Lie` function with keyword argume
152152
```@example main-6
153153
using OptimalControl # hide
154154
# Non-autonomous case
155-
φ_na(t, x) = [t + x[2], -x[1]]
156-
f_na(t, x) = t + x[1]^2 + x[2]^2
155+
X(t, x) = [t + x[2], -x[1]]
156+
f(t, x) = t + x[1]^2 + x[2]^2
157157
158-
Xf_na = Lie(φ_na, f_na; autonomous=false)
159-
Xf_na(1.0, [1.0, 2.0])
158+
Xf = Lie(X, f; autonomous=false)
159+
Xf(1, [1, 2])
160160
```
161161

162162
```@example main-7
163163
using OptimalControl # hide
164164
# Variable case
165-
φ_var(x, v) = [x[2] + v, -x[1]]
166-
f_var(x, v) = x[1]^2 + x[2]^2 + v
165+
X(x, v) = [x[2] + v, -x[1]]
166+
f(x, v) = x[1]^2 + x[2]^2 + v
167+
168+
Xf = Lie(X, f; variable=true)
169+
Xf([1, 2], 1)
170+
```
171+
172+
### With VectorField type
173+
174+
You can also create the VectorField explicitly with the keywords, then use it without keywords in the Lie function:
175+
176+
```@example main-8
177+
using OptimalControl # hide
178+
# Non-autonomous VectorField created with keywords
179+
X = OptimalControl.VectorField((t, x) -> [t + x[2], -x[1]]; autonomous=false)
180+
f(t, x) = t + x[1]^2 + x[2]^2
181+
182+
# No keywords needed here - the VectorField already knows its properties
183+
Xf = Lie(X, f)
184+
Xf(1, [1, 2])
185+
```
186+
187+
```@example main-9
188+
using OptimalControl # hide
189+
# Variable VectorField created with keywords
190+
X = OptimalControl.VectorField((x, v) -> [x[2] + v, -x[1]]; variable=true)
191+
f(x, v) = x[1]^2 + x[2]^2 + v
167192
168-
Xf_var = Lie(φ_var, f_var; variable=true)
169-
Xf_var([1.0, 2.0], 1.0)
193+
# No keywords needed here
194+
Xf = Lie(X, f)
195+
Xf([1, 2], 1)
170196
```
171197

172198
## Poisson bracket
@@ -195,23 +221,23 @@ f(x, p) = p[1] * x[2] + p[2] * x[1]
195221
g(x, p) = x[1]^2 + p[2]^2
196222
197223
# Compute the Poisson bracket
198-
bracket = Poisson(f, g)
224+
Hfg = Poisson(f, g)
199225
200226
# Evaluate at a point
201-
x = [1.0, 2.0]
202-
p = [3.0, 4.0]
203-
bracket(x, p)
227+
x = [1, 2]
228+
p = [3, 4]
229+
Hfg(x, p)
204230
```
205231

206232
### Verify antisymmetry
207233

208234
```@example main-8
209-
bracket_fg = Poisson(f, g)
210-
bracket_gf = Poisson(g, f)
235+
Hfg = Poisson(f, g)
236+
Hgf = Poisson(g, f)
211237
212-
println("Poisson(f, g) = ", bracket_fg(x, p))
213-
println("Poisson(g, f) = ", bracket_gf(x, p))
214-
println("Sum = ", bracket_fg(x, p) + bracket_gf(x, p))
238+
println("Poisson(f, g) = ", Hfg(x, p))
239+
println("Poisson(g, f) = ", Hgf(x, p))
240+
println("Sum = ", Hfg(x, p) + Hgf(x, p))
215241
```
216242

217243
### From Hamiltonian type
@@ -221,20 +247,20 @@ println("Sum = ", bracket_fg(x, p) + bracket_gf(x, p))
221247
F = OptimalControl.Hamiltonian(f)
222248
G = OptimalControl.Hamiltonian(g)
223249
224-
bracket_HH = Poisson(F, G)
225-
bracket_HH(x, p)
250+
Hfg = Poisson(F, G)
251+
Hfg(x, p)
226252
```
227253

228254
### [With keyword arguments](@id poisson-kwargs)
229255

230256
```@example main-9
231257
using OptimalControl # hide
232258
# Non-autonomous case
233-
f_na(t, x, p) = t + p[1] * x[2] + p[2] * x[1]
234-
g_na(t, x, p) = t^2 + x[1]^2 + p[2]^2
259+
f(t, x, p) = t + p[1] * x[2] + p[2] * x[1]
260+
g(t, x, p) = t^2 + x[1]^2 + p[2]^2
235261
236-
bracket_na = Poisson(f_na, g_na; autonomous=false)
237-
bracket_na(1.0, [1.0, 2.0], [3.0, 4.0])
262+
Hfg = Poisson(f, g; autonomous=false)
263+
Hfg(1, [1, 2], [3, 4])
238264
```
239265

240266
### Relation to Hamiltonian vector fields
@@ -262,8 +288,8 @@ HX = Lift(X)
262288
HY = Lift(Y)
263289
264290
# Poisson bracket of lifts
265-
bracket_lifts = Poisson(HX, HY)
266-
bracket_lifts([1.0, 2.0], [3.0, 4.0])
291+
HXY = Poisson(HX, HY)
292+
HXY([1, 2], [3, 4])
267293
```
268294

269295
This satisfies: $\{H_X, H_Y\} = H_{[X,Y]}$ where $[X,Y]$ is the Lie bracket of vector fields (see next section).
@@ -290,7 +316,7 @@ Y = OptimalControl.VectorField(x -> [x[1], x[2]])
290316
Z = Lie(X, Y)
291317
292318
# Evaluate at a point
293-
Z([1.0, 2.0])
319+
Z([1, 2])
294320
```
295321

296322
### Relation to Poisson brackets
@@ -309,16 +335,16 @@ HX = Lift(x -> X(x))
309335
HY = Lift(x -> Y(x))
310336
311337
# Poisson bracket of the lifts
312-
bracket_XY = Poisson(HX, HY)
338+
HXY = Poisson(HX, HY)
313339
314340
# Lift of the Lie bracket
315341
HZ = Lift(x -> Z(x))
316342
317343
# Compare at a point
318-
x = [1.0, 2.0]
319-
p = [3.0, 4.0]
344+
x = [1, 2]
345+
p = [3, 4]
320346
321-
println("Poisson bracket: ", bracket_XY(x, p))
347+
println("Poisson bracket: ", HXY(x, p))
322348
println("Lift of Lie bracket: ", HZ(x, p))
323349
```
324350

@@ -335,18 +361,18 @@ F1 = OptimalControl.VectorField(x -> [0, -x[3], x[2]])
335361
F2 = OptimalControl.VectorField(x -> [x[3], 0, -x[1]])
336362
337363
# Compute Lie bracket using macro
338-
L = @Lie [F1, F2]
364+
F12 = @Lie [F1, F2]
339365
340366
# Evaluate
341-
L([1.0, 2.0, 3.0])
367+
F12([1, 2, 3])
342368
```
343369

344370
### Nested Lie brackets
345371

346372
```@example main-12
347373
F3 = OptimalControl.VectorField(x -> [x[1], x[2], x[3]])
348-
nested = @Lie [[F1, F2], F3]
349-
nested([1.0, 2.0, 3.0])
374+
F123 = @Lie [[F1, F2], F3]
375+
F123([1, 2, 3])
350376
```
351377

352378
### Poisson brackets from plain functions
@@ -363,7 +389,7 @@ H1(x, p) = p[2]
363389
H01 = @Lie {H0, H1}
364390
365391
# Evaluate
366-
H01([1.0, 2.0], [3.0, 4.0])
392+
H01([1, 2], [3, 4])
367393
```
368394

369395
### Iterated Poisson brackets
@@ -379,8 +405,8 @@ H001 = @Lie {H0, H01}
379405
H101 = @Lie {H1, H01}
380406
381407
# Evaluate
382-
x = [1.0, 2.0]
383-
p = [3.0, 4.0]
408+
x = [1, 2]
409+
p = [3, 4]
384410
385411
println("H01(x, p) = ", H01(x, p))
386412
println("H001(x, p) = ", H001(x, p))
@@ -402,27 +428,27 @@ For non-autonomous functions, specify `autonomous=false`:
402428
```@example main-14
403429
using OptimalControl # hide
404430
# Non-autonomous Hamiltonians
405-
H0_na(t, x, p) = t + p[1] * x[2] + p[2] * (-x[1])
406-
H1_na(t, x, p) = p[2]
431+
H0(t, x, p) = t + p[1] * x[2] + p[2] * (-x[1])
432+
H1(t, x, p) = p[2]
407433
408434
# Poisson bracket with keyword
409-
H01_na = @Lie {H0_na, H1_na} autonomous=false
435+
H01 = @Lie {H0, H1} autonomous=false
410436
411437
# Evaluate
412-
H01_na(1.0, [1.0, 2.0], [3.0, 4.0])
438+
H01(1, [1, 2], [3, 4])
413439
```
414440

415441
### Poisson brackets from Hamiltonian type
416442

417443
```@example main-15
418444
using OptimalControl # hide
419445
# Using Hamiltonian type
420-
H1_ham = OptimalControl.Hamiltonian((x, p) -> x[1]^2 + p[2]^2)
421-
H2_ham = OptimalControl.Hamiltonian((x, p) -> x[2]^2 + p[1]^2)
446+
H1 = OptimalControl.Hamiltonian((x, p) -> x[1]^2 + p[2]^2)
447+
H2 = OptimalControl.Hamiltonian((x, p) -> x[2]^2 + p[1]^2)
422448
423449
# Macro works with Hamiltonian objects too
424-
P = @Lie {H1_ham, H2_ham}
425-
P([1.0, 1.0], [3.0, 2.0])
450+
H12 = @Lie {H1, H2}
451+
H12([1, 1], [3, 2])
426452
```
427453

428454
## Partial time derivative
@@ -462,7 +488,7 @@ g(t, x, p) = t^2 + x[1] * p[1] + x[2] * p[2]
462488
dg = ∂ₜ(g)
463489
464490
# At t=3, ∂g/∂t = 2t = 6
465-
dg(3, [1.0, 2.0], [4.0, 5.0])
491+
dg(3, [1, 2], [4, 5])
466492
```
467493

468494
### Relation to total time derivative

0 commit comments

Comments
 (0)