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,504 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-groups
|
|
2
|
+
r"""
|
|
3
|
+
Semidirect product of groups
|
|
4
|
+
|
|
5
|
+
AUTHORS:
|
|
6
|
+
|
|
7
|
+
- Mark Shimozono (2013) initial version
|
|
8
|
+
"""
|
|
9
|
+
# ****************************************************************************
|
|
10
|
+
# Copyright (C) 2013 Mark Shimozono <mshimo at math.vt.edu>
|
|
11
|
+
#
|
|
12
|
+
# This program is free software: you can redistribute it and/or modify
|
|
13
|
+
# it under the terms of the GNU General Public License as published by
|
|
14
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
15
|
+
# (at your option) any later version.
|
|
16
|
+
# https://www.gnu.org/licenses/
|
|
17
|
+
# ****************************************************************************
|
|
18
|
+
from sage.categories.commutative_additive_groups import CommutativeAdditiveGroups
|
|
19
|
+
from sage.categories.groups import Groups
|
|
20
|
+
from sage.sets.cartesian_product import CartesianProduct
|
|
21
|
+
from sage.misc.cachefunc import cached_method
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class GroupSemidirectProductElement(CartesianProduct.Element):
|
|
25
|
+
r"""
|
|
26
|
+
Element class for :class:`GroupSemidirectProduct`.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def _repr_(self):
|
|
30
|
+
r"""
|
|
31
|
+
A string representing the semidirect product group.
|
|
32
|
+
|
|
33
|
+
EXAMPLES::
|
|
34
|
+
|
|
35
|
+
sage: def twist(x, y):
|
|
36
|
+
....: return y
|
|
37
|
+
sage: GroupSemidirectProduct(WeylGroup(['A',2],prefix='s'), # indirect doctest
|
|
38
|
+
....: WeylGroup(['A',3],prefix='t'), twist)
|
|
39
|
+
Semidirect product of Weyl Group of type ['A', 2]
|
|
40
|
+
(as a matrix group acting on the ambient space) acting on
|
|
41
|
+
Weyl Group of type ['A', 3]
|
|
42
|
+
(as a matrix group acting on the ambient space)
|
|
43
|
+
"""
|
|
44
|
+
def wrapper(prefix, s):
|
|
45
|
+
if prefix is None:
|
|
46
|
+
return s
|
|
47
|
+
return "%s[%s]" % (prefix, s)
|
|
48
|
+
|
|
49
|
+
par = self.parent()
|
|
50
|
+
|
|
51
|
+
g = self.cartesian_projection(0)
|
|
52
|
+
h = self.cartesian_projection(1)
|
|
53
|
+
gstr = wrapper(par._prefix0, repr(g))
|
|
54
|
+
hstr = wrapper(par._prefix1, repr(h))
|
|
55
|
+
if par._print_tuple:
|
|
56
|
+
return "(%s, %s)" % (gstr, hstr)
|
|
57
|
+
|
|
58
|
+
if self == par.one():
|
|
59
|
+
return "1"
|
|
60
|
+
if g == g.parent().one():
|
|
61
|
+
return hstr
|
|
62
|
+
if h == h.parent().one():
|
|
63
|
+
return gstr
|
|
64
|
+
return gstr + " * " + hstr
|
|
65
|
+
|
|
66
|
+
def __invert__(self):
|
|
67
|
+
r"""
|
|
68
|
+
Return the inverse of ``self``.
|
|
69
|
+
|
|
70
|
+
EXAMPLES::
|
|
71
|
+
|
|
72
|
+
sage: # needs sage.rings.number_field
|
|
73
|
+
sage: L = RootSystem(['A',2]).root_lattice()
|
|
74
|
+
sage: from sage.groups.group_exp import GroupExp
|
|
75
|
+
sage: EL = GroupExp()(L)
|
|
76
|
+
sage: W = L.weyl_group(prefix='s')
|
|
77
|
+
sage: def twist(w, v):
|
|
78
|
+
....: return EL(w.action(v.value))
|
|
79
|
+
sage: G = GroupSemidirectProduct(W, EL, twist, prefix1='t')
|
|
80
|
+
sage: g = G.an_element(); g
|
|
81
|
+
s1*s2 * t[2*alpha[1] + 2*alpha[2]]
|
|
82
|
+
sage: g.inverse()
|
|
83
|
+
s2*s1 * t[2*alpha[1]]
|
|
84
|
+
"""
|
|
85
|
+
par = self.parent()
|
|
86
|
+
g = self.cartesian_projection(0)
|
|
87
|
+
h = self.cartesian_projection(1)
|
|
88
|
+
|
|
89
|
+
if par.act_to_right():
|
|
90
|
+
return self.__class__(par, (~g, par._twist(g, ~h)))
|
|
91
|
+
else:
|
|
92
|
+
hi = ~h
|
|
93
|
+
return self.__class__(par, (par._twist(hi, ~g), hi))
|
|
94
|
+
|
|
95
|
+
def to_opposite(self):
|
|
96
|
+
r"""
|
|
97
|
+
Send an element to its image in the opposite semidirect product.
|
|
98
|
+
|
|
99
|
+
EXAMPLES::
|
|
100
|
+
|
|
101
|
+
sage: # needs sage.rings.number_field
|
|
102
|
+
sage: L = RootSystem(['A',2]).root_lattice(); L
|
|
103
|
+
Root lattice of the Root system of type ['A', 2]
|
|
104
|
+
sage: from sage.groups.group_exp import GroupExp
|
|
105
|
+
sage: EL = GroupExp()(L)
|
|
106
|
+
sage: W = L.weyl_group(prefix='s'); W
|
|
107
|
+
Weyl Group of type ['A', 2]
|
|
108
|
+
(as a matrix group acting on the root lattice)
|
|
109
|
+
sage: def twist(w, v):
|
|
110
|
+
....: return EL(w.action(v.value))
|
|
111
|
+
sage: G = GroupSemidirectProduct(W, EL, twist, prefix1='t'); G
|
|
112
|
+
Semidirect product of Weyl Group of type ['A', 2] (as a matrix
|
|
113
|
+
group acting on the root lattice) acting on Multiplicative form of
|
|
114
|
+
Root lattice of the Root system of type ['A', 2]
|
|
115
|
+
sage: mu = L.an_element(); mu
|
|
116
|
+
2*alpha[1] + 2*alpha[2]
|
|
117
|
+
sage: w = W.an_element(); w
|
|
118
|
+
s1*s2
|
|
119
|
+
sage: g = G((w,EL(mu))); g
|
|
120
|
+
s1*s2 * t[2*alpha[1] + 2*alpha[2]]
|
|
121
|
+
sage: g.to_opposite()
|
|
122
|
+
t[-2*alpha[1]] * s1*s2
|
|
123
|
+
sage: g.to_opposite().parent()
|
|
124
|
+
Semidirect product of
|
|
125
|
+
Multiplicative form of Root lattice of the Root system of type ['A', 2]
|
|
126
|
+
acted upon by Weyl Group of type ['A', 2]
|
|
127
|
+
(as a matrix group acting on the root lattice)
|
|
128
|
+
"""
|
|
129
|
+
par = self.parent()
|
|
130
|
+
Gop = par.opposite_semidirect_product()
|
|
131
|
+
g = self.cartesian_projection(0)
|
|
132
|
+
h = self.cartesian_projection(1)
|
|
133
|
+
if par.act_to_right():
|
|
134
|
+
return Gop((par._twist(g, h), g))
|
|
135
|
+
return Gop((h, par._twist(~h, g)))
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class GroupSemidirectProduct(CartesianProduct):
|
|
139
|
+
r"""
|
|
140
|
+
Return the semidirect product of the groups ``G`` and ``H`` using the
|
|
141
|
+
homomorphism ``twist``.
|
|
142
|
+
|
|
143
|
+
INPUT:
|
|
144
|
+
|
|
145
|
+
- ``G``, ``H`` -- multiplicative groups
|
|
146
|
+
- ``twist`` -- (default: ``None``) a function defining
|
|
147
|
+
a homomorphism (see below)
|
|
148
|
+
- ``act_to_right`` -- boolean (default: ``True``)
|
|
149
|
+
- ``prefix0`` -- string (default: ``None``)
|
|
150
|
+
- ``prefix1`` -- string (default: ``None``)
|
|
151
|
+
- ``print_tuple`` -- boolean (default: ``False``)
|
|
152
|
+
- ``category`` -- a category (default: ``Groups()``)
|
|
153
|
+
|
|
154
|
+
A semidirect product of groups `G` and `H` is a group structure on
|
|
155
|
+
the Cartesian product `G \times H` whose product agrees with that
|
|
156
|
+
of `G` on `G \times 1_H` and with that of `H` on `1_G \times H`,
|
|
157
|
+
such that either `1_G \times H` or `G \times 1_H` is a normal
|
|
158
|
+
subgroup. In the former case, the group is denoted `G \ltimes H`
|
|
159
|
+
and in the latter, `G \rtimes H`.
|
|
160
|
+
|
|
161
|
+
If ``act_to_right`` is ``True``, this indicates the group `G \ltimes H`
|
|
162
|
+
in which `G` acts on `H` by automorphisms. In this case there is a
|
|
163
|
+
group homomorphism `\phi \in \mathrm{Hom}(G, \mathrm{Aut}(H))` such that
|
|
164
|
+
|
|
165
|
+
.. MATH::
|
|
166
|
+
|
|
167
|
+
g h g^{-1} = \phi(g)(h).
|
|
168
|
+
|
|
169
|
+
The homomorphism `\phi` is specified by the input ``twist``, which
|
|
170
|
+
syntactically is the function `G\times H\to H` defined by
|
|
171
|
+
|
|
172
|
+
.. MATH::
|
|
173
|
+
|
|
174
|
+
twist(g,h) = \phi(g)(h).
|
|
175
|
+
|
|
176
|
+
The product on `G \ltimes H` is defined by
|
|
177
|
+
|
|
178
|
+
.. MATH::
|
|
179
|
+
|
|
180
|
+
\begin{aligned}
|
|
181
|
+
(g_1,h_1)(g_2,h_2) &= g_1 h_1 g_2 h_2 \\
|
|
182
|
+
&= g_1 g_2 g_2^{-1} h_1 g_2 h_2 \\
|
|
183
|
+
&= (g_1g_2, twist(g_2^{-1}, h_1) h_2)
|
|
184
|
+
\end{aligned}
|
|
185
|
+
|
|
186
|
+
If ``act_to_right`` is ``False``, the group `G \rtimes H` is specified by
|
|
187
|
+
a homomorphism `\psi\in \mathrm{Hom}(H,\mathrm{Aut}(G))` such that
|
|
188
|
+
|
|
189
|
+
.. MATH::
|
|
190
|
+
|
|
191
|
+
h g h^{-1} = \psi(h)(g)
|
|
192
|
+
|
|
193
|
+
Then ``twist`` is the function `H\times G\to G` defined by
|
|
194
|
+
|
|
195
|
+
.. MATH::
|
|
196
|
+
|
|
197
|
+
twist(h,g) = \psi(h)(g).
|
|
198
|
+
|
|
199
|
+
so that the product in `G \rtimes H` is defined by
|
|
200
|
+
|
|
201
|
+
.. MATH::
|
|
202
|
+
|
|
203
|
+
\begin{aligned}
|
|
204
|
+
(g_1,h_1)(g_2,h_2) &= g_1 h_1 g_2 h_2 \\
|
|
205
|
+
&= g_1 h_1 g_2 h_1^{-1} h_1 h_2 \\
|
|
206
|
+
&= (g_1 twist(h_1,g_2), h_1 h_2)
|
|
207
|
+
\end{aligned}
|
|
208
|
+
|
|
209
|
+
If ``prefix0`` (resp. ``prefixl``) is not ``None`` then it is used
|
|
210
|
+
as a wrapper for printing elements of ``G`` (resp. ``H``). If
|
|
211
|
+
``print_tuple`` is ``True`` then elements are printed in the style
|
|
212
|
+
`(g,h)` and otherwise in the style `g * h`.
|
|
213
|
+
|
|
214
|
+
EXAMPLES::
|
|
215
|
+
|
|
216
|
+
sage: G = GL(2,QQ)
|
|
217
|
+
sage: V = QQ^2
|
|
218
|
+
sage: EV = GroupExp()(V) # make a multiplicative version of V
|
|
219
|
+
sage: def twist(g, v):
|
|
220
|
+
....: return EV(g*v.value)
|
|
221
|
+
sage: H = GroupSemidirectProduct(G, EV, twist=twist, prefix1='t'); H
|
|
222
|
+
Semidirect product of General Linear Group of degree 2
|
|
223
|
+
over Rational Field acting on Multiplicative form of Vector space
|
|
224
|
+
of dimension 2 over Rational Field
|
|
225
|
+
sage: x = H.an_element(); x
|
|
226
|
+
t[(1, 0)]
|
|
227
|
+
sage: x^2
|
|
228
|
+
t[(2, 0)]
|
|
229
|
+
|
|
230
|
+
sage: # needs sage.rings.number_field
|
|
231
|
+
sage: cartan_type = CartanType(['A',2])
|
|
232
|
+
sage: W = WeylGroup(cartan_type, prefix='s')
|
|
233
|
+
sage: def twist(w, v):
|
|
234
|
+
....: return w*v*(~w)
|
|
235
|
+
sage: WW = GroupSemidirectProduct(W, W, twist=twist, print_tuple=True)
|
|
236
|
+
sage: s = Family(cartan_type.index_set(), lambda i: W.simple_reflection(i))
|
|
237
|
+
sage: y = WW((s[1],s[2])); y
|
|
238
|
+
(s1, s2)
|
|
239
|
+
sage: y^2
|
|
240
|
+
(1, s2*s1)
|
|
241
|
+
sage: y.inverse()
|
|
242
|
+
(s1, s1*s2*s1)
|
|
243
|
+
|
|
244
|
+
.. TODO::
|
|
245
|
+
|
|
246
|
+
- Functorial constructor for semidirect products for various categories
|
|
247
|
+
- Twofold Direct product as a special case of semidirect product
|
|
248
|
+
"""
|
|
249
|
+
|
|
250
|
+
def __init__(self, G, H, twist=None, act_to_right=True, prefix0=None,
|
|
251
|
+
prefix1=None, print_tuple=False, category=Groups()):
|
|
252
|
+
r"""
|
|
253
|
+
|
|
254
|
+
EXAMPLES::
|
|
255
|
+
|
|
256
|
+
sage: def twist(x, y):
|
|
257
|
+
....: return y
|
|
258
|
+
sage: import __main__
|
|
259
|
+
sage: __main__.twist = twist
|
|
260
|
+
sage: G = GroupSemidirectProduct(WeylGroup(['A',2],prefix='s'),
|
|
261
|
+
....: WeylGroup(['A',3],prefix='t'), twist)
|
|
262
|
+
sage: TestSuite(G).run()
|
|
263
|
+
|
|
264
|
+
The ``__main__`` business is a trick to pass the pickling test.
|
|
265
|
+
"""
|
|
266
|
+
|
|
267
|
+
self._act_to_right = act_to_right
|
|
268
|
+
|
|
269
|
+
def check_implemented_group(x):
|
|
270
|
+
if x in Groups():
|
|
271
|
+
return
|
|
272
|
+
error = ("The semidirect product construction for groups "
|
|
273
|
+
"is implemented only for multiplicative groups")
|
|
274
|
+
if x in CommutativeAdditiveGroups():
|
|
275
|
+
error += (f". Please change the commutative additive group {x}"
|
|
276
|
+
" into a multiplicative group "
|
|
277
|
+
"using the functor sage.groups.group_exp.GroupExp")
|
|
278
|
+
raise TypeError(error)
|
|
279
|
+
|
|
280
|
+
check_implemented_group(G)
|
|
281
|
+
check_implemented_group(H)
|
|
282
|
+
|
|
283
|
+
if twist is None:
|
|
284
|
+
self._twist = lambda g, h: h # use the trivial twist
|
|
285
|
+
else:
|
|
286
|
+
self._twist = twist
|
|
287
|
+
|
|
288
|
+
self._prefix0 = prefix0
|
|
289
|
+
self._prefix1 = prefix1
|
|
290
|
+
self._print_tuple = print_tuple
|
|
291
|
+
self._category = category
|
|
292
|
+
CartesianProduct.__init__(self, (G, H), category=category)
|
|
293
|
+
|
|
294
|
+
def act_to_right(self):
|
|
295
|
+
r"""
|
|
296
|
+
Return ``True`` if the left factor acts on the right factor and
|
|
297
|
+
``False`` if the right factor acts on the left factor.
|
|
298
|
+
|
|
299
|
+
EXAMPLES::
|
|
300
|
+
|
|
301
|
+
sage: def twist(x, y):
|
|
302
|
+
....: return y
|
|
303
|
+
sage: GroupSemidirectProduct(WeylGroup(['A',2],prefix='s'),
|
|
304
|
+
....: WeylGroup(['A',3],prefix='t'), twist).act_to_right()
|
|
305
|
+
True
|
|
306
|
+
"""
|
|
307
|
+
return self._act_to_right
|
|
308
|
+
|
|
309
|
+
def _repr_(self):
|
|
310
|
+
r"""
|
|
311
|
+
A string representing the semidirect product group.
|
|
312
|
+
|
|
313
|
+
EXAMPLES::
|
|
314
|
+
|
|
315
|
+
sage: def twist(x, y):
|
|
316
|
+
....: return y
|
|
317
|
+
sage: GroupSemidirectProduct(WeylGroup(['A',2],prefix='s'), # indirect doctest
|
|
318
|
+
....: WeylGroup(['A',3],prefix='t'), twist)
|
|
319
|
+
Semidirect product of Weyl Group of type ['A', 2] (as a matrix
|
|
320
|
+
group acting on the ambient space) acting on Weyl Group
|
|
321
|
+
of type ['A', 3] (as a matrix group acting on the ambient space)
|
|
322
|
+
"""
|
|
323
|
+
cartesian_factors = self.cartesian_factors()
|
|
324
|
+
if self.act_to_right():
|
|
325
|
+
act_string = "acting on"
|
|
326
|
+
else:
|
|
327
|
+
act_string = "acted upon by"
|
|
328
|
+
return "Semidirect product of %s %s %s" % (cartesian_factors[0],
|
|
329
|
+
act_string,
|
|
330
|
+
cartesian_factors[1])
|
|
331
|
+
|
|
332
|
+
def _element_constructor_(self, x):
|
|
333
|
+
r"""
|
|
334
|
+
EXAMPLES::
|
|
335
|
+
|
|
336
|
+
sage: def twist(x, y):
|
|
337
|
+
....: return y
|
|
338
|
+
sage: import __main__
|
|
339
|
+
sage: __main__.twist = twist
|
|
340
|
+
sage: g = GroupSemidirectProduct(WeylGroup(['A',2],prefix='s'),
|
|
341
|
+
....: WeylGroup(['A',3],prefix='t'), twist).an_element()
|
|
342
|
+
sage: TestSuite(g).run()
|
|
343
|
+
"""
|
|
344
|
+
def type_error():
|
|
345
|
+
raise TypeError(f"{x} cannot be converted into an element of {self}")
|
|
346
|
+
|
|
347
|
+
if isinstance(x, self.element_class) and x.parent() == self:
|
|
348
|
+
return x
|
|
349
|
+
if not isinstance(x, GroupSemidirectProductElement):
|
|
350
|
+
if not isinstance(x, tuple):
|
|
351
|
+
type_error()
|
|
352
|
+
if len(x) != 2:
|
|
353
|
+
type_error()
|
|
354
|
+
g, h = x
|
|
355
|
+
else:
|
|
356
|
+
g = x.cartesian_projection(0)
|
|
357
|
+
h = x.cartesian_projection(1)
|
|
358
|
+
gg = self.cartesian_factors()[0](g)
|
|
359
|
+
hh = self.cartesian_factors()[1](h)
|
|
360
|
+
return self.element_class(self, (gg, hh))
|
|
361
|
+
|
|
362
|
+
@cached_method
|
|
363
|
+
def one(self):
|
|
364
|
+
r"""
|
|
365
|
+
The identity element of the semidirect product group.
|
|
366
|
+
|
|
367
|
+
EXAMPLES::
|
|
368
|
+
|
|
369
|
+
sage: G = GL(2,QQ)
|
|
370
|
+
sage: V = QQ^2
|
|
371
|
+
sage: EV = GroupExp()(V) # make a multiplicative version of V
|
|
372
|
+
sage: def twist(g, v):
|
|
373
|
+
....: return EV(g*v.value)
|
|
374
|
+
sage: one = GroupSemidirectProduct(G, EV, twist=twist, prefix1='t').one(); one
|
|
375
|
+
1
|
|
376
|
+
sage: one.cartesian_projection(0)
|
|
377
|
+
[1 0]
|
|
378
|
+
[0 1]
|
|
379
|
+
sage: one.cartesian_projection(1)
|
|
380
|
+
(0, 0)
|
|
381
|
+
"""
|
|
382
|
+
return self((self.cartesian_factors()[0].one(),
|
|
383
|
+
self.cartesian_factors()[1].one()))
|
|
384
|
+
|
|
385
|
+
def group_generators(self):
|
|
386
|
+
r"""
|
|
387
|
+
Return generators of ``self``.
|
|
388
|
+
|
|
389
|
+
EXAMPLES::
|
|
390
|
+
|
|
391
|
+
sage: twist = lambda x,y: y
|
|
392
|
+
sage: import __main__
|
|
393
|
+
sage: __main__.twist = twist
|
|
394
|
+
sage: EZ = GroupExp()(ZZ)
|
|
395
|
+
sage: GroupSemidirectProduct(EZ, EZ, twist, print_tuple=True).group_generators()
|
|
396
|
+
((1, 0), (0, 1))
|
|
397
|
+
"""
|
|
398
|
+
def has_gens(G):
|
|
399
|
+
if not hasattr(G, 'group_generators'):
|
|
400
|
+
return False
|
|
401
|
+
return G.group_generators()
|
|
402
|
+
|
|
403
|
+
factors = self.cartesian_factors()
|
|
404
|
+
g0 = has_gens(factors[0])
|
|
405
|
+
if g0 is not False:
|
|
406
|
+
g1 = has_gens(factors[1])
|
|
407
|
+
if g1 is not False:
|
|
408
|
+
return tuple([self((x, factors[1].one())) for x in g0] +
|
|
409
|
+
[self((factors[0].one(), x)) for x in g1])
|
|
410
|
+
raise NotImplementedError("one of the factors does not "
|
|
411
|
+
"implement 'group_generators'")
|
|
412
|
+
|
|
413
|
+
def product(self, x, y):
|
|
414
|
+
r"""
|
|
415
|
+
The product of elements `x` and `y` in the semidirect product group.
|
|
416
|
+
|
|
417
|
+
EXAMPLES::
|
|
418
|
+
|
|
419
|
+
sage: G = GL(2,QQ)
|
|
420
|
+
sage: V = QQ^2
|
|
421
|
+
sage: EV = GroupExp()(V) # make a multiplicative version of V
|
|
422
|
+
sage: def twist(g, v):
|
|
423
|
+
....: return EV(g*v.value)
|
|
424
|
+
sage: S = GroupSemidirectProduct(G, EV, twist=twist, prefix1='t')
|
|
425
|
+
sage: g = G([[2,1],[3,1]]); g
|
|
426
|
+
[2 1]
|
|
427
|
+
[3 1]
|
|
428
|
+
sage: v = EV.an_element(); v
|
|
429
|
+
(1, 0)
|
|
430
|
+
sage: x = S((g,v)); x
|
|
431
|
+
[2 1]
|
|
432
|
+
[3 1] * t[(1, 0)]
|
|
433
|
+
sage: x*x # indirect doctest
|
|
434
|
+
[7 3]
|
|
435
|
+
[9 4] * t[(0, 3)]
|
|
436
|
+
"""
|
|
437
|
+
xg = x.cartesian_projection(0)
|
|
438
|
+
xh = x.cartesian_projection(1)
|
|
439
|
+
yg = y.cartesian_projection(0)
|
|
440
|
+
yh = y.cartesian_projection(1)
|
|
441
|
+
if self.act_to_right():
|
|
442
|
+
g = xg * yg
|
|
443
|
+
h = self._twist(~yg, xh) * yh
|
|
444
|
+
else:
|
|
445
|
+
h = xh * yh
|
|
446
|
+
g = xg * self._twist(xh, yg)
|
|
447
|
+
return self((g, h))
|
|
448
|
+
|
|
449
|
+
@cached_method
|
|
450
|
+
def opposite_semidirect_product(self):
|
|
451
|
+
r"""
|
|
452
|
+
Create the same semidirect product but with the positions of the groups exchanged.
|
|
453
|
+
|
|
454
|
+
EXAMPLES::
|
|
455
|
+
|
|
456
|
+
sage: G = GL(2,QQ)
|
|
457
|
+
sage: L = QQ^2
|
|
458
|
+
sage: EL = GroupExp()(L)
|
|
459
|
+
sage: H = GroupSemidirectProduct(G, EL, prefix1='t',
|
|
460
|
+
....: twist=lambda g,v: EL(g*v.value)); H
|
|
461
|
+
Semidirect product of General Linear Group of degree 2
|
|
462
|
+
over Rational Field acting on Multiplicative form of Vector space
|
|
463
|
+
of dimension 2 over Rational Field
|
|
464
|
+
sage: h = H((Matrix([[0,1],[1,0]]), EL.an_element())); h
|
|
465
|
+
[0 1]
|
|
466
|
+
[1 0] * t[(1, 0)]
|
|
467
|
+
sage: Hop = H.opposite_semidirect_product(); Hop
|
|
468
|
+
Semidirect product of Multiplicative form of Vector space
|
|
469
|
+
of dimension 2 over Rational Field acted upon by
|
|
470
|
+
General Linear Group of degree 2 over Rational Field
|
|
471
|
+
sage: hop = h.to_opposite(); hop
|
|
472
|
+
t[(0, 1)] * [0 1]
|
|
473
|
+
[1 0]
|
|
474
|
+
sage: hop in Hop
|
|
475
|
+
True
|
|
476
|
+
"""
|
|
477
|
+
return GroupSemidirectProduct(self.cartesian_factors()[1],
|
|
478
|
+
self.cartesian_factors()[0],
|
|
479
|
+
twist=self._twist,
|
|
480
|
+
act_to_right=not self.act_to_right(),
|
|
481
|
+
prefix0=self._prefix1,
|
|
482
|
+
prefix1=self._prefix0,
|
|
483
|
+
print_tuple=self._print_tuple,
|
|
484
|
+
category=self._category)
|
|
485
|
+
|
|
486
|
+
def construction(self):
|
|
487
|
+
r"""
|
|
488
|
+
Return ``None``.
|
|
489
|
+
|
|
490
|
+
This overrides the construction functor inherited from
|
|
491
|
+
``CartesianProduct``.
|
|
492
|
+
|
|
493
|
+
EXAMPLES::
|
|
494
|
+
|
|
495
|
+
sage: def twist(x, y):
|
|
496
|
+
....: return y
|
|
497
|
+
sage: H = GroupSemidirectProduct(WeylGroup(['A',2],prefix='s'),
|
|
498
|
+
....: WeylGroup(['A',3],prefix='t'), twist)
|
|
499
|
+
sage: H.construction()
|
|
500
|
+
"""
|
|
501
|
+
return None
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
GroupSemidirectProduct.Element = GroupSemidirectProductElement
|