passagemath-groups 10.6.45__cp314-cp314-macosx_13_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. passagemath_groups/.dylibs/libgap.10.dylib +0 -0
  2. passagemath_groups/.dylibs/libgmp.10.dylib +0 -0
  3. passagemath_groups/.dylibs/libreadline.8.2.dylib +0 -0
  4. passagemath_groups/.dylibs/libz.1.3.1.dylib +0 -0
  5. passagemath_groups/__init__.py +3 -0
  6. passagemath_groups-10.6.45.dist-info/METADATA +113 -0
  7. passagemath_groups-10.6.45.dist-info/RECORD +40 -0
  8. passagemath_groups-10.6.45.dist-info/WHEEL +6 -0
  9. passagemath_groups-10.6.45.dist-info/top_level.txt +3 -0
  10. sage/all__sagemath_groups.py +21 -0
  11. sage/geometry/all__sagemath_groups.py +1 -0
  12. sage/geometry/palp_normal_form.cpython-314-darwin.so +0 -0
  13. sage/geometry/palp_normal_form.pyx +401 -0
  14. sage/groups/abelian_gps/all.py +25 -0
  15. sage/groups/all.py +5 -0
  16. sage/groups/all__sagemath_groups.py +32 -0
  17. sage/groups/artin.py +1074 -0
  18. sage/groups/braid.py +3806 -0
  19. sage/groups/cactus_group.py +1001 -0
  20. sage/groups/cubic_braid.py +2052 -0
  21. sage/groups/finitely_presented.py +1896 -0
  22. sage/groups/finitely_presented_catalog.py +27 -0
  23. sage/groups/finitely_presented_named.py +592 -0
  24. sage/groups/fqf_orthogonal.py +579 -0
  25. sage/groups/free_group.py +944 -0
  26. sage/groups/group_exp.py +360 -0
  27. sage/groups/group_semidirect_product.py +504 -0
  28. sage/groups/kernel_subgroup.py +231 -0
  29. sage/groups/lie_gps/all.py +1 -0
  30. sage/groups/lie_gps/catalog.py +8 -0
  31. sage/groups/lie_gps/nilpotent_lie_group.py +945 -0
  32. sage/groups/misc_gps/all.py +1 -0
  33. sage/groups/misc_gps/misc_groups.py +11 -0
  34. sage/groups/misc_gps/misc_groups_catalog.py +33 -0
  35. sage/groups/raag.py +866 -0
  36. sage/groups/semimonomial_transformations/all.py +1 -0
  37. sage/groups/semimonomial_transformations/semimonomial_transformation.cpython-314-darwin.so +0 -0
  38. sage/groups/semimonomial_transformations/semimonomial_transformation.pxd +9 -0
  39. sage/groups/semimonomial_transformations/semimonomial_transformation.pyx +346 -0
  40. sage/groups/semimonomial_transformations/semimonomial_transformation_group.py +512 -0
@@ -0,0 +1,945 @@
1
+ # sage_setup: distribution = sagemath-groups
2
+ # sage.doctest: needs sage.symbolic
3
+ r"""
4
+ Nilpotent Lie groups
5
+
6
+ AUTHORS:
7
+
8
+ - Eero Hakavuori (2018-09-25): initial version of nilpotent Lie groups
9
+ """
10
+
11
+ # ****************************************************************************
12
+ # Copyright (C) 2018 Eero Hakavuori <eero.hakavuori@gmail.com>
13
+ #
14
+ # This program is free software: you can redistribute it and/or modify
15
+ # it under the terms of the GNU General Public License as published by
16
+ # the Free Software Foundation, either version 2 of the License, or
17
+ # (at your option) any later version.
18
+ # https://www.gnu.org/licenses/
19
+ # ****************************************************************************
20
+
21
+ from sage.algebras.lie_algebras.structure_coefficients import LieAlgebraWithStructureCoefficients
22
+ from sage.categories.lie_groups import LieGroups
23
+ from sage.categories.lie_algebras import LieAlgebras
24
+ from sage.groups.group import Group
25
+ from sage.manifolds.differentiable.manifold import DifferentiableManifold
26
+ from sage.manifolds.structure import (DifferentialStructure,
27
+ RealDifferentialStructure)
28
+ from sage.misc.cachefunc import cached_method
29
+ from sage.misc.repr import repr_lincomb
30
+ from sage.modules.free_module_element import vector
31
+ import sage.rings.abc
32
+ from sage.structure.element import MultiplicativeGroupElement
33
+ from sage.symbolic.ring import SR
34
+
35
+
36
+ def _symbolic_lie_algebra_copy(L):
37
+ r"""
38
+ Create a copy of the Lie algebra ``L`` admitting symbolic coefficients.
39
+
40
+ This is used internally to compute a symbolic expression for the group law.
41
+
42
+ INPUT:
43
+
44
+ - ``L`` -- a finite dimensional Lie algebra with basis
45
+
46
+ EXAMPLES::
47
+
48
+ sage: from sage.groups.lie_gps.nilpotent_lie_group import _symbolic_lie_algebra_copy
49
+ sage: L = LieAlgebra(QQ, 2, step=2)
50
+ sage: L_SR = _symbolic_lie_algebra_copy(L)
51
+ sage: L.structure_coefficients()
52
+ Finite family {((1,), (2,)): X_12}
53
+ sage: L_SR.structure_coefficients()
54
+ Finite family {((1,), (2,)): L[(1, 2)]}
55
+
56
+ TESTS:
57
+
58
+ Verify that copying works with something that is not an instance of
59
+ :class:`LieAlgebraWithStructureCoefficients`::
60
+
61
+ sage: from sage.groups.lie_gps.nilpotent_lie_group import _symbolic_lie_algebra_copy
62
+ sage: L = lie_algebras.Heisenberg(QQ, 1)
63
+ sage: hasattr(L, 'change_ring')
64
+ False
65
+ sage: L_SR = _symbolic_lie_algebra_copy(L)
66
+ sage: L_SR.structure_coefficients()
67
+ Finite family {('p1', 'q1'): z}
68
+ """
69
+ try:
70
+ return L.change_ring(SR)
71
+ except AttributeError:
72
+ s_coeff = L.structure_coefficients()
73
+ index_set = L.basis().keys()
74
+ names = L.variable_names()
75
+ return LieAlgebraWithStructureCoefficients(SR, s_coeff, names=names,
76
+ index_set=index_set)
77
+
78
+
79
+ class NilpotentLieGroup(Group, DifferentiableManifold):
80
+ r"""
81
+ A nilpotent Lie group.
82
+
83
+ INPUT:
84
+
85
+ - ``L`` -- the Lie algebra of the Lie group; must be a finite
86
+ dimensional nilpotent Lie algebra with basis over a topological
87
+ field, e.g. `\QQ` or `\RR`
88
+ - ``name`` -- string; name (symbol) given to the Lie group
89
+
90
+ Two types of exponential coordinates are defined on any
91
+ nilpotent Lie group using the basis of the Lie algebra,
92
+ see :meth:`chart_exp1` and :meth:`chart_exp2`.
93
+
94
+ EXAMPLES:
95
+
96
+ Creation of a nilpotent Lie group::
97
+
98
+ sage: L = lie_algebras.Heisenberg(QQ, 1)
99
+ sage: G = L.lie_group(); G
100
+ Lie group G of Heisenberg algebra of rank 1 over Rational Field
101
+
102
+ Giving a different name to the group::
103
+
104
+ sage: L.lie_group('H')
105
+ Lie group H of Heisenberg algebra of rank 1 over Rational Field
106
+
107
+ Elements can be created using the exponential map::
108
+
109
+ sage: p,q,z = L.basis()
110
+ sage: g = G.exp(p); g
111
+ exp(p1)
112
+ sage: h = G.exp(q); h
113
+ exp(q1)
114
+
115
+ Lie group multiplication has the usual product syntax::
116
+
117
+ sage: k = g*h; k
118
+ exp(p1 + q1 + 1/2*z)
119
+
120
+ The identity element is given by :meth:`one`::
121
+
122
+ sage: e = G.one(); e
123
+ exp(0)
124
+ sage: e*k == k and k*e == k
125
+ True
126
+
127
+ The default coordinate system is exponential coordinates of the first kind::
128
+
129
+ sage: G.default_chart() == G.chart_exp1()
130
+ True
131
+ sage: G.chart_exp1()
132
+ Chart (G, (x_0, x_1, x_2))
133
+
134
+ Changing the default coordinates to exponential coordinates of the second
135
+ kind will change how elements are printed::
136
+
137
+ sage: G.set_default_chart(G.chart_exp2())
138
+ sage: k
139
+ exp(z)exp(q1)exp(p1)
140
+ sage: G.set_default_chart(G.chart_exp1())
141
+ sage: k
142
+ exp(p1 + q1 + 1/2*z)
143
+
144
+ The frames of left- or right-invariant vector fields are created using
145
+ :meth:`left_invariant_frame` and :meth:`right_invariant_frame`::
146
+
147
+ sage: X = G.left_invariant_frame(); X
148
+ Vector frame (G, (X_0,X_1,X_2))
149
+ sage: X[0]
150
+ Vector field X_0 on the Lie group G of Heisenberg algebra of rank 1 over Rational Field
151
+
152
+ A vector field can be displayed with respect to a coordinate frame::
153
+
154
+ sage: exp1_frame = G.chart_exp1().frame()
155
+ sage: exp2_frame = G.chart_exp2().frame()
156
+ sage: X[0].display(exp1_frame)
157
+ X_0 = ∂/∂x_0 - 1/2*x_1 ∂/∂x_2
158
+ sage: X[0].display(exp2_frame)
159
+ X_0 = ∂/∂y_0
160
+ sage: X[1].display(exp1_frame)
161
+ X_1 = ∂/∂x_1 + 1/2*x_0 ∂/∂x_2
162
+ sage: X[1].display(exp2_frame)
163
+ X_1 = ∂/∂y_1 + x_0 ∂/∂y_2
164
+
165
+ Defining a left translation by a generic point::
166
+
167
+ sage: g = G.point([var('a'), var('b'), var('c')]); g
168
+ exp(a*p1 + b*q1 + c*z)
169
+ sage: L_g = G.left_translation(g); L_g
170
+ Diffeomorphism of the Lie group G of Heisenberg algebra of rank 1 over Rational Field
171
+ sage: L_g.display()
172
+ G → G
173
+ (x_0, x_1, x_2) ↦ (a + x_0, b + x_1, -1/2*b*x_0 + 1/2*a*x_1 + c + x_2)
174
+ (x_0, x_1, x_2) ↦ (y_0, y_1, y_2) = (a + x_0, b + x_1,
175
+ 1/2*a*b + 1/2*(2*a + x_0)*x_1 + c + x_2)
176
+ (y_0, y_1, y_2) ↦ (x_0, x_1, x_2) = (a + y_0, b + y_1,
177
+ -1/2*b*y_0 + 1/2*(a - y_0)*y_1 + c + y_2)
178
+ (y_0, y_1, y_2) ↦ (a + y_0, b + y_1, 1/2*a*b + a*y_1 + c + y_2)
179
+
180
+ Verifying the left-invariance of the left-invariant frame::
181
+
182
+ sage: x = G(G.chart_exp1()[:])
183
+ sage: L_g.differential(x)(X[0].at(x)) == X[0].at(L_g(x))
184
+ True
185
+ sage: L_g.differential(x)(X[1].at(x)) == X[1].at(L_g(x))
186
+ True
187
+ sage: L_g.differential(x)(X[2].at(x)) == X[2].at(L_g(x))
188
+ True
189
+
190
+ An element of the Lie algebra can be extended to a left or right invariant
191
+ vector field::
192
+
193
+ sage: X_L = G.left_invariant_extension(p + 3*q); X_L
194
+ Vector field p1 + 3*q1 on the Lie group G of Heisenberg algebra of rank 1 over Rational Field
195
+ sage: X_L.display(exp1_frame)
196
+ p1 + 3*q1 = ∂/∂x_0 + 3 ∂/∂x_1 + (3/2*x_0 - 1/2*x_1) ∂/∂x_2
197
+ sage: X_R = G.right_invariant_extension(p + 3*q)
198
+ sage: X_R.display(exp1_frame)
199
+ p1 + 3*q1 = ∂/∂x_0 + 3 ∂/∂x_1 + (-3/2*x_0 + 1/2*x_1) ∂/∂x_2
200
+
201
+ The nilpotency step of the Lie group is the nilpotency step of its algebra.
202
+ Nilpotency for Lie groups means that group commutators that are longer than
203
+ the nilpotency step vanish::
204
+
205
+ sage: G.step()
206
+ 2
207
+ sage: g = G.exp(p); h = G.exp(q)
208
+ sage: c = g*h*~g*~h; c
209
+ exp(z)
210
+ sage: g*c*~g*~c
211
+ exp(0)
212
+ """
213
+
214
+ def __init__(self, L, name, **kwds):
215
+ r"""
216
+ Initialize ``self``.
217
+
218
+ TESTS::
219
+
220
+ sage: L = lie_algebras.Heisenberg(QQ, 2)
221
+ sage: G = L.lie_group()
222
+ sage: TestSuite(G).run()
223
+ """
224
+ required_cat = LieAlgebras(L.base_ring()).FiniteDimensional()
225
+ required_cat = required_cat.WithBasis().Nilpotent()
226
+ if L not in required_cat:
227
+ raise TypeError("L needs to be a finite dimensional nilpotent "
228
+ "Lie algebra with basis")
229
+ self._lie_algebra = L
230
+
231
+ R = L.base_ring()
232
+ category = kwds.pop('category', None)
233
+ category = LieGroups(R).or_subcategory(category)
234
+ if isinstance(R, sage.rings.abc.RealField):
235
+ structure = RealDifferentialStructure()
236
+ else:
237
+ structure = DifferentialStructure()
238
+
239
+ DifferentiableManifold.__init__(self, L.dimension(), name, R,
240
+ structure, category=category)
241
+
242
+ # initialize exponential coordinates of the first kind
243
+ basis_strs = [str(X) for X in L.basis()]
244
+ split = list(zip(*[s.split('_') for s in basis_strs]))
245
+ if len(split) == 2 and all(sk == split[0][0] for sk in split[0]):
246
+ self._var_indexing = split[1]
247
+ else:
248
+ self._var_indexing = [str(k) for k in range(L.dimension())]
249
+ variables = ' '.join('x_%s' % k for k in self._var_indexing)
250
+ self._Exp1 = self.chart(variables)
251
+
252
+ # compute a symbolic formula for the group law
253
+ L_SR = _symbolic_lie_algebra_copy(L)
254
+ n = L.dimension()
255
+ a, b = (tuple(SR.var('%s_%d' % (s, j)) for j in range(n))
256
+ for s in ['a', 'b'])
257
+ self._group_law_vars = (a, b)
258
+ bch = L_SR.bch(L_SR.from_vector(a), L_SR.from_vector(b), L.step())
259
+ self._group_law = vector(SR, (zk.expand() for zk in bch.to_vector()))
260
+
261
+ def _repr_(self):
262
+ r"""
263
+ Return a string representation of ``self``.
264
+
265
+ EXAMPLES::
266
+
267
+ sage: L = lie_algebras.Heisenberg(RR, 1)
268
+ sage: L.lie_group()
269
+ Lie group G of Heisenberg algebra of rank 1 over
270
+ Real Field with 53 bits of precision
271
+ """
272
+ return "Lie group %s of %s" % (self._name, self.lie_algebra())
273
+
274
+ def _dLx(self):
275
+ r"""
276
+ Return the matrix of the differential at the identity of a left
277
+ translation by a generic point in the default coordinate system.
278
+
279
+ EXAMPLES::
280
+
281
+ sage: L = LieAlgebra(QQ, 2, step=2)
282
+ sage: G = L.lie_group()
283
+ sage: G._dLx()
284
+ [ 1 0 0]
285
+ [ 0 1 0]
286
+ [-1/2*x_2 1/2*x_1 1]
287
+ """
288
+ a = self._group_law_vars[0]
289
+ x = self.default_chart()[:]
290
+ asubs = dict(zip(a, x))
291
+ L_a = self.left_translation(self.point(a))
292
+ return L_a.differential(self.one()).matrix().subs(asubs)
293
+
294
+ def _dRx(self):
295
+ r"""
296
+ Return the matrix of the differential at the identity of a right
297
+ translation by a generic point in the default coordinate system.
298
+
299
+ EXAMPLES::
300
+
301
+ sage: L = LieAlgebra(QQ, 2, step=2)
302
+ sage: G = L.lie_group()
303
+ sage: G._dRx()
304
+ [ 1 0 0]
305
+ [ 0 1 0]
306
+ [ 1/2*x_2 -1/2*x_1 1]
307
+ """
308
+ a = self._group_law_vars[0]
309
+ x = self.default_chart()[:]
310
+ asubs = dict(zip(a, x))
311
+ R_a = self.right_translation(self.point(a))
312
+ return R_a.differential(self.one()).matrix().subs(asubs)
313
+
314
+ @cached_method
315
+ def gens(self) -> tuple:
316
+ r"""
317
+ Return a tuple of elements whose one-parameter subgroups generate
318
+ the Lie group.
319
+
320
+ EXAMPLES::
321
+
322
+ sage: L = lie_algebras.Heisenberg(QQ, 1)
323
+ sage: G = L.lie_group()
324
+ sage: G.gens()
325
+ (exp(p1), exp(q1), exp(z))
326
+ """
327
+ return tuple(self.exp(X) for X in self.lie_algebra().basis())
328
+
329
+ def lie_algebra(self):
330
+ r"""
331
+ Return the Lie algebra of ``self``.
332
+
333
+ EXAMPLES::
334
+
335
+ sage: L = LieAlgebra(QQ, 2, step=2)
336
+ sage: G = L.lie_group()
337
+ sage: G.lie_algebra() == L
338
+ True
339
+ """
340
+ return self._lie_algebra
341
+
342
+ def step(self):
343
+ r"""
344
+ Return the nilpotency step of ``self``.
345
+
346
+ EXAMPLES::
347
+
348
+ sage: L = LieAlgebra(QQ, 2, step=4)
349
+ sage: G = L.lie_group()
350
+ sage: G.step()
351
+ 4
352
+ """
353
+ return self._lie_algebra.step()
354
+
355
+ def chart_exp1(self):
356
+ r"""
357
+ Return the chart of exponential coordinates of the first kind.
358
+
359
+ Exponential coordinates of the first kind are
360
+
361
+ .. MATH ::
362
+
363
+ \exp(x_1X_1 + \cdots + x_nX_n) \mapsto (x_1, \ldots, x_n).
364
+
365
+ EXAMPLES::
366
+
367
+ sage: L = LieAlgebra(QQ, 2, step=2)
368
+ sage: G = L.lie_group()
369
+ sage: G.chart_exp1()
370
+ Chart (G, (x_1, x_2, x_12))
371
+ """
372
+ return self._Exp1
373
+
374
+ @cached_method
375
+ def chart_exp2(self):
376
+ r"""
377
+ Return the chart of exponential coordinates of the second kind.
378
+
379
+ Exponential coordinates of the second kind are
380
+
381
+ .. MATH ::
382
+
383
+ \exp(x_nX_n) \cdots \exp(x_1X_1) \mapsto (x_1, \ldots, x_n).
384
+
385
+ EXAMPLES::
386
+
387
+ sage: L = LieAlgebra(QQ, 2, step=2)
388
+ sage: G = L.lie_group()
389
+ sage: G.chart_exp2()
390
+ Chart (G, (y_1, y_2, y_12))
391
+ """
392
+ variables = ' '.join('y_%s' % k for k in self._var_indexing)
393
+ ret = self.chart(variables)
394
+
395
+ # compute transitions between exponential coordinates
396
+ # compute exp-2 to exp-1
397
+ n = self.dimension()
398
+ Z = self.one()
399
+ for k, yk in enumerate(ret[:]):
400
+ v = [0] * n
401
+ v[k] = yk
402
+ Z = self.point(v, chart=self._Exp1) * Z
403
+ f = [zk.expand() for zk in Z.coordinates(chart=self._Exp1)]
404
+ ret.transition_map(self._Exp1, f)
405
+
406
+ # compute exp-1 to exp-2 by inverting the previous map
407
+ inv_subs = {}
408
+ for xk, yk, fk in zip(self._Exp1[:], ret[:], f):
409
+ inv_subs[yk] = xk - (fk - yk).subs(inv_subs)
410
+ f_inv = [inv_subs[yk].expand() for yk in ret[:]]
411
+ self._Exp1.transition_map(ret, f_inv)
412
+ return ret
413
+
414
+ def exp(self, X):
415
+ r"""
416
+ Return the group element `exp(X)`.
417
+
418
+ INPUT:
419
+
420
+ - ``X`` -- an element of the Lie algebra of ``self``
421
+
422
+ EXAMPLES::
423
+
424
+ sage: L.<X,Y,Z> = LieAlgebra(QQ, 2, step=2)
425
+ sage: G = L.lie_group()
426
+ sage: G.exp(X)
427
+ exp(X)
428
+ sage: G.exp(Y)
429
+ exp(Y)
430
+ sage: G.exp(X + Y)
431
+ exp(X + Y)
432
+ """
433
+ return self.point(X.to_vector(), chart=self._Exp1)
434
+
435
+ def log(self, x):
436
+ r"""
437
+ Return the logarithm of the element ``x`` of ``self``.
438
+
439
+ INPUT:
440
+
441
+ - ``x`` -- an element of ``self``
442
+
443
+ The logarithm is by definition the inverse of :meth:`exp`.
444
+
445
+ If the Lie algebra of ``self`` does not admit symbolic coefficients,
446
+ the logarithm is not defined for abstract, i.e. symbolic, points.
447
+
448
+ EXAMPLES:
449
+
450
+ The logarithm is the inverse of the exponential::
451
+
452
+ sage: L.<X,Y,Z> = LieAlgebra(QQ, 2, step=2)
453
+ sage: G = L.lie_group()
454
+ sage: G.log(G.exp(X)) == X
455
+ True
456
+ sage: G.log(G.exp(X)*G.exp(Y))
457
+ X + Y + 1/2*Z
458
+
459
+ The logarithm is not defined for abstract (symbolic) points::
460
+
461
+ sage: g = G.point([var('a'), 1, 2]); g
462
+ exp(a*X + Y + 2*Z)
463
+ sage: G.log(g)
464
+ Traceback (most recent call last):
465
+ ...
466
+ TypeError: unable to convert a to a rational
467
+ """
468
+ xvec = x.coordinates(chart=self._Exp1)
469
+ return self.lie_algebra().from_vector(xvec)
470
+
471
+ def one(self):
472
+ r"""
473
+ Return the identity element of ``self``.
474
+
475
+ EXAMPLES::
476
+
477
+ sage: L = LieAlgebra(QQ, 2, step=4)
478
+ sage: G = L.lie_group()
479
+ sage: G.one()
480
+ exp(0)
481
+ """
482
+ return self.exp(self._lie_algebra.zero())
483
+
484
+ def left_translation(self, g):
485
+ r"""
486
+ Return the left translation by ``g`` as an automorphism of ``self``.
487
+
488
+ The left translation by `g` on a Lie group `G` is the map
489
+
490
+ .. MATH::
491
+
492
+ G \to G, \qquad
493
+ h \mapsto gh.
494
+
495
+ INPUT:
496
+
497
+ - ``g`` -- an element of ``self``
498
+
499
+ EXAMPLES:
500
+
501
+ A left translation in the Heisenberg group::
502
+
503
+ sage: H = lie_algebras.Heisenberg(QQ, 1)
504
+ sage: p,q,z = H.basis()
505
+ sage: G = H.lie_group()
506
+ sage: g = G.exp(p)
507
+ sage: L_g = G.left_translation(g); L_g
508
+ Diffeomorphism of the Lie group G of Heisenberg algebra of rank 1 over Rational Field
509
+ sage: L_g.display(chart1=G.chart_exp1(), chart2=G.chart_exp1())
510
+ G → G
511
+ (x_0, x_1, x_2) ↦ (x_0 + 1, x_1, 1/2*x_1 + x_2)
512
+
513
+ Left translation by a generic element::
514
+
515
+ sage: h = G.point([var('a'), var('b'), var('c')])
516
+ sage: L_h = G.left_translation(h)
517
+ sage: L_h.display(chart1=G.chart_exp1(), chart2=G.chart_exp1())
518
+ G → G
519
+ (x_0, x_1, x_2) ↦ (a + x_0, b + x_1, -1/2*b*x_0 + 1/2*a*x_1 + c + x_2)
520
+ """
521
+ chart = self.default_chart()
522
+ x = self.point(chart[:])
523
+ L_g_expr = (g * x).coordinates()
524
+ return self.diffeomorphism(self, coord_functions=L_g_expr)
525
+
526
+ def left_invariant_frame(self, **kwds):
527
+ r"""
528
+ Return the frame of left-invariant vector fields of ``self``.
529
+
530
+ The labeling of the frame and the dual frame can be customized using
531
+ keyword parameters as described in
532
+ :meth:`sage.manifolds.differentiable.manifold.DifferentiableManifold.vector_frame`.
533
+
534
+ EXAMPLES:
535
+
536
+ The default left-invariant frame::
537
+
538
+ sage: L = LieAlgebra(QQ, 2, step=2)
539
+ sage: G = L.lie_group()
540
+ sage: livf = G.left_invariant_frame(); livf
541
+ Vector frame (G, (X_1,X_2,X_12))
542
+ sage: coord_frame = G.chart_exp1().frame()
543
+ sage: livf[0].display(coord_frame)
544
+ X_1 = ∂/∂x_1 - 1/2*x_2 ∂/∂x_12
545
+ sage: livf[1].display(coord_frame)
546
+ X_2 = ∂/∂x_2 + 1/2*x_1 ∂/∂x_12
547
+ sage: livf[2].display(coord_frame)
548
+ X_12 = ∂/∂x_12
549
+
550
+ Examples of custom labeling for the frame::
551
+
552
+ sage: G.left_invariant_frame(symbol='Y')
553
+ Vector frame (G, (Y_1,Y_2,Y_12))
554
+ sage: G.left_invariant_frame(symbol='Z', indices=None)
555
+ Vector frame (G, (Z_0,Z_1,Z_2))
556
+ sage: G.left_invariant_frame(symbol='W', indices=('a','b','c'))
557
+ Vector frame (G, (W_a,W_b,W_c))
558
+ """
559
+ dLx_field = self.automorphism_field()
560
+ dLx_field[:] = self._dLx()
561
+ coord_frame = self._Exp1.frame()
562
+ symbol = kwds.pop('symbol', 'X')
563
+ indices = kwds.pop('indices', self._var_indexing)
564
+ return coord_frame.new_frame(dLx_field, symbol=symbol,
565
+ indices=indices, **kwds)
566
+
567
+ livf = left_invariant_frame
568
+
569
+ def left_invariant_extension(self, X, name=None):
570
+ r"""
571
+ Return the left-invariant vector field that has the value ``X``
572
+ at the identity.
573
+
574
+ INPUT:
575
+
576
+ - ``X`` -- an element of the Lie algebra of ``self``
577
+ - ``name`` -- (optional) a string to use as a name for the vector field;
578
+ if nothing is given, the name of the vector ``X`` is used
579
+
580
+ EXAMPLES:
581
+
582
+ A left-invariant extension in the Heisenberg group::
583
+
584
+ sage: L = lie_algebras.Heisenberg(QQ, 1)
585
+ sage: p, q, z = L.basis()
586
+ sage: H = L.lie_group('H')
587
+ sage: X = H.left_invariant_extension(p); X
588
+ Vector field p1 on the Lie group H of Heisenberg algebra of rank 1 over Rational Field
589
+ sage: X.display(H.chart_exp1().frame())
590
+ p1 = ∂/∂x_0 - 1/2*x_1 ∂/∂x_2
591
+
592
+ Default vs. custom naming for the invariant vector field::
593
+
594
+ sage: Y = H.left_invariant_extension(p + q); Y
595
+ Vector field p1 + q1 on the Lie group H of Heisenberg algebra of rank 1 over Rational Field
596
+ sage: Z = H.left_invariant_extension(p + q, 'Z'); Z
597
+ Vector field Z on the Lie group H of Heisenberg algebra of rank 1 over Rational Field
598
+ """
599
+ if name is None:
600
+ name = str(X)
601
+ X_vf = self.vector_field(name)
602
+ frame = self._Exp1.frame()
603
+ X_vf[frame, :] = self._dLx() * X.to_vector()
604
+ return X_vf
605
+
606
+ def right_translation(self, g):
607
+ r"""
608
+ Return the right translation by ``g`` as an automorphism of ``self``.
609
+
610
+ The right translation by `g` on a Lie group `G` is the map
611
+
612
+ .. MATH::
613
+
614
+ G \to G, \qquad
615
+ h\mapsto hg.
616
+
617
+ INPUT:
618
+
619
+ - ``g`` -- an element of ``self``
620
+
621
+ EXAMPLES:
622
+
623
+ A right translation in the Heisenberg group::
624
+
625
+ sage: H = lie_algebras.Heisenberg(QQ, 1)
626
+ sage: p,q,z = H.basis()
627
+ sage: G = H.lie_group()
628
+ sage: g = G.exp(p)
629
+ sage: R_g = G.right_translation(g); R_g
630
+ Diffeomorphism of the Lie group G of Heisenberg algebra of rank 1 over Rational Field
631
+ sage: R_g.display(chart1=G.chart_exp1(), chart2=G.chart_exp1())
632
+ G → G
633
+ (x_0, x_1, x_2) ↦ (x_0 + 1, x_1, -1/2*x_1 + x_2)
634
+
635
+ Right translation by a generic element::
636
+
637
+ sage: h = G.point([var('a'), var('b'), var('c')])
638
+ sage: R_h = G.right_translation(h)
639
+ sage: R_h.display(chart1=G.chart_exp1(), chart2=G.chart_exp1())
640
+ G → G
641
+ (x_0, x_1, x_2) ↦ (a + x_0, b + x_1, 1/2*b*x_0 - 1/2*a*x_1 + c + x_2)
642
+ """
643
+ chart = self.default_chart()
644
+ x = self.point(chart[:])
645
+ R_g_expr = (x * g).coordinates()
646
+ return self.diffeomorphism(self, coord_functions=R_g_expr)
647
+
648
+ def right_invariant_frame(self, **kwds):
649
+ r"""
650
+ Return the frame of right-invariant vector fields of ``self``.
651
+
652
+ The labeling of the frame and the dual frame can be customized using
653
+ keyword parameters as described in
654
+ :meth:`sage.manifolds.differentiable.manifold.DifferentiableManifold.vector_frame`.
655
+
656
+ EXAMPLES:
657
+
658
+ The default right-invariant frame::
659
+
660
+ sage: L = LieAlgebra(QQ, 2, step=2)
661
+ sage: G = L.lie_group()
662
+ sage: rivf = G.right_invariant_frame(); rivf
663
+ Vector frame (G, (XR_1,XR_2,XR_12))
664
+ sage: coord_frame = G.chart_exp1().frame()
665
+ sage: rivf[0].display(coord_frame)
666
+ XR_1 = ∂/∂x_1 + 1/2*x_2 ∂/∂x_12
667
+ sage: rivf[1].display(coord_frame)
668
+ XR_2 = ∂/∂x_2 - 1/2*x_1 ∂/∂x_12
669
+ sage: rivf[2].display(coord_frame)
670
+ XR_12 = ∂/∂x_12
671
+
672
+ Examples of custom labeling for the frame::
673
+
674
+ sage: G.right_invariant_frame(symbol='Y')
675
+ Vector frame (G, (Y_1,Y_2,Y_12))
676
+ sage: G.right_invariant_frame(symbol='Z', indices=None)
677
+ Vector frame (G, (Z_0,Z_1,Z_2))
678
+ sage: G.right_invariant_frame(symbol='W', indices=('a','b','c'))
679
+ Vector frame (G, (W_a,W_b,W_c))
680
+ """
681
+ dRx_field = self.automorphism_field()
682
+ dRx_field[:] = self._dRx()
683
+ coord_frame = self._Exp1.frame()
684
+ symbol = kwds.pop('symbol', 'XR')
685
+ indices = kwds.pop('indices', self._var_indexing)
686
+ return coord_frame.new_frame(dRx_field, symbol=symbol,
687
+ indices=indices, **kwds)
688
+
689
+ rivf = right_invariant_frame
690
+
691
+ def right_invariant_extension(self, X, name=None):
692
+ r"""
693
+ Return the right-invariant vector field that has the value ``X``
694
+ at the identity.
695
+
696
+ INPUT:
697
+
698
+ - ``X`` -- an element of the Lie algebra of ``self``
699
+ - ``name`` -- (optional) a string to use as a name for the vector field;
700
+ if nothing is given, the name of the vector ``X`` is used
701
+
702
+ EXAMPLES:
703
+
704
+ A right-invariant extension in the Heisenberg group::
705
+
706
+ sage: L = lie_algebras.Heisenberg(QQ, 1)
707
+ sage: p, q, z = L.basis()
708
+ sage: H = L.lie_group('H')
709
+ sage: X = H.right_invariant_extension(p); X
710
+ Vector field p1 on the Lie group H of Heisenberg algebra of rank 1 over Rational Field
711
+ sage: X.display(H.chart_exp1().frame())
712
+ p1 = ∂/∂x_0 + 1/2*x_1 ∂/∂x_2
713
+
714
+ Default vs. custom naming for the invariant vector field::
715
+
716
+ sage: Y = H.right_invariant_extension(p + q); Y
717
+ Vector field p1 + q1 on the Lie group H of Heisenberg algebra of rank 1 over Rational Field
718
+ sage: Z = H.right_invariant_extension(p + q, 'Z'); Z
719
+ Vector field Z on the Lie group H of Heisenberg algebra of rank 1 over Rational Field
720
+ """
721
+ if name is None:
722
+ name = str(X)
723
+ X_vf = self.vector_field(name)
724
+ frame = self._Exp1.frame()
725
+ X_vf[frame, :] = self._dRx() * X.to_vector()
726
+ return X_vf
727
+
728
+ def conjugation(self, g):
729
+ r"""
730
+ Return the conjugation by ``g`` as an automorphism of ``self``.
731
+
732
+ The conjugation by `g` on a Lie group `G` is the map
733
+
734
+ .. MATH::
735
+
736
+ G \to G, \qquad
737
+ h \mapsto ghg^{-1}.
738
+
739
+ INPUT:
740
+
741
+ - ``g`` -- an element of ``self``
742
+
743
+ EXAMPLES:
744
+
745
+ A generic conjugation in the Heisenberg group::
746
+
747
+ sage: H = lie_algebras.Heisenberg(QQ, 1)
748
+ sage: p,q,z = H.basis()
749
+ sage: G = H.lie_group()
750
+ sage: g = G.point([var('a'), var('b'), var('c')])
751
+ sage: C_g = G.conjugation(g); C_g
752
+ Diffeomorphism of the Lie group G of Heisenberg algebra of rank 1 over Rational Field
753
+ sage: C_g.display(chart1=G.chart_exp1(), chart2=G.chart_exp1())
754
+ G → G
755
+ (x_0, x_1, x_2) ↦ (x_0, x_1, -b*x_0 + a*x_1 + x_2)
756
+ """
757
+ chart = self.default_chart()
758
+ x = self.point(chart[:])
759
+ C_g_expr = (g * x * ~g).coordinates()
760
+ return self.diffeomorphism(self, coord_functions=C_g_expr)
761
+
762
+ def adjoint(self, g):
763
+ r"""
764
+ Return the adjoint map as an automorphism
765
+ of the Lie algebra of ``self``.
766
+
767
+ INPUT:
768
+
769
+ - ``g`` -- an element of ``self``
770
+
771
+ For a Lie group element `g`, the adjoint map `\operatorname{Ad}_g` is
772
+ the map on the Lie algebra `\mathfrak{g}` given by the differential
773
+ of the conjugation by `g` at the identity.
774
+
775
+ If the Lie algebra of ``self`` does not admit symbolic coefficients,
776
+ the adjoint is not in general defined for abstract points.
777
+
778
+ EXAMPLES:
779
+
780
+ An example of an adjoint map::
781
+
782
+ sage: L = LieAlgebra(QQ, 2, step=3)
783
+ sage: G = L.lie_group()
784
+ sage: g = G.exp(L.basis().list()[0]); g
785
+ exp(X_1)
786
+ sage: Ad_g = G.adjoint(g); Ad_g
787
+ Lie algebra endomorphism of Free Nilpotent Lie algebra on 5
788
+ generators (X_1, X_2, X_12, X_112, X_122) over Rational Field
789
+ Defn: X_1 |--> X_1
790
+ X_2 |--> X_2 + X_12 + 1/2*X_112
791
+ X_12 |--> X_12 + X_112
792
+ X_112 |--> X_112
793
+ X_122 |--> X_122
794
+
795
+ Usually the adjoint map of a symbolic point is not defined::
796
+
797
+ sage: L = LieAlgebra(QQ, 2, step=2)
798
+ sage: G = L.lie_group()
799
+ sage: g = G.point([var('a'), var('b'), var('c')]); g
800
+ exp(a*X_1 + b*X_2 + c*X_12)
801
+ sage: G.adjoint(g)
802
+ Traceback (most recent call last):
803
+ ...
804
+ TypeError: unable to convert -b to a rational
805
+
806
+ However, if the adjoint map is independent from the symbolic terms,
807
+ the map is still well defined::
808
+
809
+ sage: g = G.point([0, 0, var('a')]); g
810
+ exp(a*X_12)
811
+ sage: G.adjoint(g)
812
+ Lie algebra endomorphism of Free Nilpotent Lie algebra on 3 generators (X_1, X_2, X_12) over Rational Field
813
+ Defn: X_1 |--> X_1
814
+ X_2 |--> X_2
815
+ X_12 |--> X_12
816
+ """
817
+ Adg_mat = self.conjugation(g).differential(self.one()).matrix()
818
+ L = self.lie_algebra()
819
+ basis_images = {X: L.from_vector(Adg_mat * X.to_vector())
820
+ for X in L.basis()}
821
+ return L.morphism(basis_images, codomain=L)
822
+
823
+ class Element(DifferentiableManifold.Element, MultiplicativeGroupElement):
824
+ r"""
825
+ A base class for an element of a Lie group.
826
+
827
+ EXAMPLES:
828
+
829
+ Elements of the group are printed in the default
830
+ exponential coordinates::
831
+
832
+ sage: L.<X,Y,Z> = LieAlgebra(QQ, 2, step=2)
833
+ sage: G = L.lie_group()
834
+ sage: g = G.exp(2*X + 3*Z); g
835
+ exp(2*X + 3*Z)
836
+ sage: h = G.point([ var('a'), var('b'), 0]); h
837
+ exp(a*X + b*Y)
838
+ sage: G.set_default_chart(G.chart_exp2())
839
+ sage: g
840
+ exp(3*Z)exp(2*X)
841
+ sage: h
842
+ exp(1/2*a*b*Z)exp(b*Y)exp(a*X)
843
+
844
+ Multiplication of two elements uses the usual product syntax::
845
+
846
+ sage: G.exp(Y)*G.exp(X)
847
+ exp(Y)exp(X)
848
+ sage: G.exp(X)*G.exp(Y)
849
+ exp(Z)exp(Y)exp(X)
850
+ sage: G.set_default_chart(G.chart_exp1())
851
+ sage: G.exp(X)*G.exp(Y)
852
+ exp(X + Y + 1/2*Z)
853
+ """
854
+
855
+ def __init__(self, parent, **kwds):
856
+ r"""
857
+ Initialize ``self``.
858
+
859
+ TESTS::
860
+
861
+ sage: L.<X,Y,Z> = LieAlgebra(QQ, 2, step=2)
862
+ sage: G = L.lie_group()
863
+ sage: g = G.exp(X)
864
+ sage: TestSuite(g).run()
865
+ """
866
+ MultiplicativeGroupElement.__init__(self, parent)
867
+ DifferentiableManifold.Element.__init__(self, parent, **kwds)
868
+
869
+ def __invert__(self):
870
+ r"""
871
+ Return the inverse of ``self``.
872
+
873
+ EXAMPLES::
874
+
875
+ sage: L.<X,Y,Z> = LieAlgebra(QQ, 2, step=2)
876
+ sage: G = L.lie_group('H')
877
+ sage: g = G.point([var('a'), var('b'), var('c')]); g
878
+ exp(a*X + b*Y + c*Z)
879
+ sage: ~g
880
+ exp((-a)*X + (-b)*Y + (-c)*Z)
881
+ sage: g*~g
882
+ exp(0)
883
+ """
884
+ G = self.parent()
885
+ x = self.coordinates(chart=G._Exp1)
886
+ return G.point(tuple(-xk for xk in x), chart=G._Exp1)
887
+
888
+ def _mul_(self, other):
889
+ r"""
890
+ Return the product ``self`` * ``other``.
891
+
892
+ EXAMPLES::
893
+
894
+ sage: L = LieAlgebra(QQ, 2, step=2)
895
+ sage: G = L.lie_group('H')
896
+ sage: g1 = G.point([2, 0, 0]); g1
897
+ exp(2*X_1)
898
+ sage: g2 = G.point([0, 1/3, 0]); g2
899
+ exp(1/3*X_2)
900
+ sage: g1*g2
901
+ exp(2*X_1 + 1/3*X_2 + 1/3*X_12)
902
+ """
903
+ G = self.parent()
904
+ a, b = G._group_law_vars
905
+ self_c = list(zip(a, self.coordinates(chart=G._Exp1)))
906
+ other_c = list(zip(b, other.coordinates(chart=G._Exp1)))
907
+ sd = dict(self_c + other_c)
908
+ return G.point([gk.expand() for gk in G._group_law.subs(sd)],
909
+ chart=G._Exp1)
910
+
911
+ def _repr_(self):
912
+ r"""
913
+ Return a string representation of ``self``.
914
+
915
+ Supports printing in exponential coordinates of the first and
916
+ second kinds, depending on the default coordinate system.
917
+
918
+ EXAMPLES::
919
+
920
+ sage: L = LieAlgebra(QQ, 2, step=2)
921
+ sage: G = L.lie_group('H')
922
+ sage: g = G.point([1, 2, 3]); g
923
+ exp(X_1 + 2*X_2 + 3*X_12)
924
+ sage: G.set_default_chart(G.chart_exp2())
925
+ sage: g
926
+ exp(4*X_12)exp(2*X_2)exp(X_1)
927
+ """
928
+ G = self.parent()
929
+ chart = G.default_chart()
930
+ if chart != G._Exp1:
931
+ if chart != G.chart_exp2():
932
+ chart = G._Exp1
933
+
934
+ x = self.coordinates(chart=chart)
935
+ B = G.lie_algebra().basis()
936
+ nonzero_pairs = [(Xk, xk) for Xk, xk in zip(B, x) if xk]
937
+
938
+ if chart == G._Exp1:
939
+ s = repr_lincomb(nonzero_pairs)
940
+ else:
941
+ s = ")exp(".join(repr_lincomb([(Xk, xk)])
942
+ for Xk, xk in reversed(nonzero_pairs))
943
+ if not s:
944
+ s = "0"
945
+ return "exp(%s)" % s