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.
- passagemath_groups/.dylibs/libgap.10.dylib +0 -0
- passagemath_groups/.dylibs/libgmp.10.dylib +0 -0
- passagemath_groups/.dylibs/libreadline.8.2.dylib +0 -0
- passagemath_groups/.dylibs/libz.1.3.1.dylib +0 -0
- passagemath_groups/__init__.py +3 -0
- passagemath_groups-10.6.45.dist-info/METADATA +113 -0
- passagemath_groups-10.6.45.dist-info/RECORD +40 -0
- passagemath_groups-10.6.45.dist-info/WHEEL +6 -0
- passagemath_groups-10.6.45.dist-info/top_level.txt +3 -0
- sage/all__sagemath_groups.py +21 -0
- sage/geometry/all__sagemath_groups.py +1 -0
- sage/geometry/palp_normal_form.cpython-314-darwin.so +0 -0
- sage/geometry/palp_normal_form.pyx +401 -0
- sage/groups/abelian_gps/all.py +25 -0
- sage/groups/all.py +5 -0
- sage/groups/all__sagemath_groups.py +32 -0
- sage/groups/artin.py +1074 -0
- sage/groups/braid.py +3806 -0
- sage/groups/cactus_group.py +1001 -0
- sage/groups/cubic_braid.py +2052 -0
- sage/groups/finitely_presented.py +1896 -0
- sage/groups/finitely_presented_catalog.py +27 -0
- sage/groups/finitely_presented_named.py +592 -0
- sage/groups/fqf_orthogonal.py +579 -0
- sage/groups/free_group.py +944 -0
- sage/groups/group_exp.py +360 -0
- sage/groups/group_semidirect_product.py +504 -0
- sage/groups/kernel_subgroup.py +231 -0
- sage/groups/lie_gps/all.py +1 -0
- sage/groups/lie_gps/catalog.py +8 -0
- sage/groups/lie_gps/nilpotent_lie_group.py +945 -0
- sage/groups/misc_gps/all.py +1 -0
- sage/groups/misc_gps/misc_groups.py +11 -0
- sage/groups/misc_gps/misc_groups_catalog.py +33 -0
- sage/groups/raag.py +866 -0
- sage/groups/semimonomial_transformations/all.py +1 -0
- sage/groups/semimonomial_transformations/semimonomial_transformation.cpython-314-darwin.so +0 -0
- sage/groups/semimonomial_transformations/semimonomial_transformation.pxd +9 -0
- sage/groups/semimonomial_transformations/semimonomial_transformation.pyx +346 -0
- 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
|