passagemath-groups 10.6.41__cp314-cp314t-musllinux_1_2_x86_64.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/__init__.py +3 -0
- passagemath_groups-10.6.41.dist-info/METADATA +113 -0
- passagemath_groups-10.6.41.dist-info/RECORD +36 -0
- passagemath_groups-10.6.41.dist-info/WHEEL +5 -0
- passagemath_groups-10.6.41.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-314t-x86_64-linux-musl.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-314t-x86_64-linux-musl.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,512 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-groups
|
|
2
|
+
# sage.doctest: needs sage.rings.finite_rings
|
|
3
|
+
r"""
|
|
4
|
+
Semimonomial transformation group
|
|
5
|
+
|
|
6
|
+
The semimonomial transformation group of degree `n` over a ring `R` is
|
|
7
|
+
the semidirect product of the monomial transformation group of degree `n`
|
|
8
|
+
(also known as the complete monomial group over the group of units
|
|
9
|
+
`R^{\times}` of `R`) and the group of ring automorphisms.
|
|
10
|
+
|
|
11
|
+
The multiplication of two elements `(\phi, \pi, \alpha)(\psi, \sigma, \beta)`
|
|
12
|
+
with
|
|
13
|
+
|
|
14
|
+
- `\phi, \psi \in {R^{\times}}^n`
|
|
15
|
+
|
|
16
|
+
- `\pi, \sigma \in S_n` (with the multiplication `\pi\sigma`
|
|
17
|
+
done from left to right (like in GAP) --
|
|
18
|
+
that is, `(\pi\sigma)(i) = \sigma(\pi(i))` for all `i`.)
|
|
19
|
+
|
|
20
|
+
- `\alpha, \beta \in Aut(R)`
|
|
21
|
+
|
|
22
|
+
is defined by
|
|
23
|
+
|
|
24
|
+
.. MATH::
|
|
25
|
+
|
|
26
|
+
(\phi, \pi, \alpha)(\psi, \sigma, \beta) =
|
|
27
|
+
(\phi \cdot \psi^{\pi, \alpha}, \pi\sigma, \alpha \circ \beta)
|
|
28
|
+
|
|
29
|
+
where
|
|
30
|
+
`\psi^{\pi, \alpha} = (\alpha(\psi_{\pi(1)-1}), \ldots, \alpha(\psi_{\pi(n)-1}))`
|
|
31
|
+
and the multiplication of vectors is defined elementwisely. (The indexing
|
|
32
|
+
of vectors is `0`-based here, so `\psi = (\psi_0, \psi_1, \ldots, \psi_{n-1})`.)
|
|
33
|
+
|
|
34
|
+
.. TODO::
|
|
35
|
+
|
|
36
|
+
Up to now, this group is only implemented for finite fields because of
|
|
37
|
+
the limited support of automorphisms for arbitrary rings.
|
|
38
|
+
|
|
39
|
+
AUTHORS:
|
|
40
|
+
|
|
41
|
+
- Thomas Feulner (2012-11-15): initial version
|
|
42
|
+
|
|
43
|
+
EXAMPLES::
|
|
44
|
+
|
|
45
|
+
sage: S = SemimonomialTransformationGroup(GF(4, 'a'), 4)
|
|
46
|
+
sage: G = S.gens()
|
|
47
|
+
sage: G[0]*G[1]
|
|
48
|
+
((a, 1, 1, 1); (1,2,3,4), Ring endomorphism of Finite Field in a of size 2^2
|
|
49
|
+
Defn: a |--> a)
|
|
50
|
+
|
|
51
|
+
TESTS::
|
|
52
|
+
|
|
53
|
+
sage: TestSuite(S).run()
|
|
54
|
+
sage: TestSuite(S.an_element()).run()
|
|
55
|
+
"""
|
|
56
|
+
from __future__ import annotations
|
|
57
|
+
from sage.rings.integer import Integer
|
|
58
|
+
|
|
59
|
+
from sage.groups.group import FiniteGroup
|
|
60
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
61
|
+
from sage.categories.action import Action
|
|
62
|
+
from sage.combinat.permutation import Permutation
|
|
63
|
+
from sage.groups.semimonomial_transformations.semimonomial_transformation import SemimonomialTransformation
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class SemimonomialTransformationGroup(FiniteGroup, UniqueRepresentation):
|
|
67
|
+
r"""
|
|
68
|
+
A semimonomial transformation group over a ring.
|
|
69
|
+
|
|
70
|
+
The semimonomial transformation group of degree `n` over a ring `R` is
|
|
71
|
+
the semidirect product of the monomial transformation group of degree `n`
|
|
72
|
+
(also known as the complete monomial group over the group of units
|
|
73
|
+
`R^{\times}` of `R`) and the group of ring automorphisms.
|
|
74
|
+
|
|
75
|
+
The multiplication of two elements `(\phi, \pi, \alpha)(\psi, \sigma, \beta)`
|
|
76
|
+
with
|
|
77
|
+
|
|
78
|
+
- `\phi, \psi \in {R^{\times}}^n`
|
|
79
|
+
|
|
80
|
+
- `\pi, \sigma \in S_n` (with the multiplication `\pi\sigma`
|
|
81
|
+
done from left to right (like in GAP) --
|
|
82
|
+
that is, `(\pi\sigma)(i) = \sigma(\pi(i))` for all `i`.)
|
|
83
|
+
|
|
84
|
+
- `\alpha, \beta \in Aut(R)`
|
|
85
|
+
|
|
86
|
+
is defined by
|
|
87
|
+
|
|
88
|
+
.. MATH::
|
|
89
|
+
|
|
90
|
+
(\phi, \pi, \alpha)(\psi, \sigma, \beta) =
|
|
91
|
+
(\phi \cdot \psi^{\pi, \alpha}, \pi\sigma, \alpha \circ \beta)
|
|
92
|
+
|
|
93
|
+
where
|
|
94
|
+
`\psi^{\pi, \alpha} = (\alpha(\psi_{\pi(1)-1}), \ldots, \alpha(\psi_{\pi(n)-1}))`
|
|
95
|
+
and the multiplication of vectors is defined elementwisely. (The indexing
|
|
96
|
+
of vectors is `0`-based here, so `\psi = (\psi_0, \psi_1, \ldots, \psi_{n-1})`.)
|
|
97
|
+
|
|
98
|
+
.. TODO::
|
|
99
|
+
|
|
100
|
+
Up to now, this group is only implemented for finite fields because of
|
|
101
|
+
the limited support of automorphisms for arbitrary rings.
|
|
102
|
+
|
|
103
|
+
EXAMPLES::
|
|
104
|
+
|
|
105
|
+
sage: F.<a> = GF(9)
|
|
106
|
+
sage: S = SemimonomialTransformationGroup(F, 4)
|
|
107
|
+
sage: g = S(v = [2, a, 1, 2])
|
|
108
|
+
sage: h = S(perm = Permutation('(1,2,3,4)'), autom=F.hom([a**3]))
|
|
109
|
+
sage: g*h
|
|
110
|
+
((2, a, 1, 2); (1,2,3,4),
|
|
111
|
+
Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> 2*a + 1)
|
|
112
|
+
sage: h*g
|
|
113
|
+
((2*a + 1, 1, 2, 2); (1,2,3,4),
|
|
114
|
+
Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> 2*a + 1)
|
|
115
|
+
sage: S(g)
|
|
116
|
+
((2, a, 1, 2); (),
|
|
117
|
+
Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> a)
|
|
118
|
+
sage: S(1)
|
|
119
|
+
((1, 1, 1, 1); (),
|
|
120
|
+
Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> a)
|
|
121
|
+
"""
|
|
122
|
+
Element = SemimonomialTransformation
|
|
123
|
+
|
|
124
|
+
def __init__(self, R, len):
|
|
125
|
+
r"""
|
|
126
|
+
Initialization.
|
|
127
|
+
|
|
128
|
+
INPUT:
|
|
129
|
+
|
|
130
|
+
- ``R`` -- a ring
|
|
131
|
+
|
|
132
|
+
- ``len`` -- the degree of the monomial group
|
|
133
|
+
|
|
134
|
+
OUTPUT: the complete semimonomial group
|
|
135
|
+
|
|
136
|
+
EXAMPLES::
|
|
137
|
+
|
|
138
|
+
sage: F.<a> = GF(9)
|
|
139
|
+
sage: S = SemimonomialTransformationGroup(F, 4)
|
|
140
|
+
"""
|
|
141
|
+
if not R.is_field():
|
|
142
|
+
raise NotImplementedError('the ring must be a field')
|
|
143
|
+
self._R = R
|
|
144
|
+
self._len = len
|
|
145
|
+
|
|
146
|
+
from sage.categories.finite_groups import FiniteGroups
|
|
147
|
+
super().__init__(category=FiniteGroups())
|
|
148
|
+
|
|
149
|
+
def _element_constructor_(self, arg1, v=None, perm=None, autom=None, check=True):
|
|
150
|
+
r"""
|
|
151
|
+
Coerce ``arg1`` into this permutation group, if ``arg1`` is 0,
|
|
152
|
+
then we will try to coerce ``(v, perm, autom)``.
|
|
153
|
+
|
|
154
|
+
INPUT:
|
|
155
|
+
|
|
156
|
+
- ``arg1`` -- (optional) either the integers 0, 1 or an element of ``self``
|
|
157
|
+
|
|
158
|
+
- ``v`` -- (optional) a vector of length ``self.degree()``
|
|
159
|
+
|
|
160
|
+
- ``perm`` -- (optional) a permutation of degree ``self.degree()``
|
|
161
|
+
|
|
162
|
+
- ``autom`` -- (optional) an automorphism of the ring
|
|
163
|
+
|
|
164
|
+
EXAMPLES::
|
|
165
|
+
|
|
166
|
+
sage: F.<a> = GF(9)
|
|
167
|
+
sage: S = SemimonomialTransformationGroup(F, 4)
|
|
168
|
+
sage: S(1)
|
|
169
|
+
((1, 1, 1, 1); (), Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> a)
|
|
170
|
+
sage: g = S(v=[1,1,1,a])
|
|
171
|
+
sage: S(g)
|
|
172
|
+
((1, 1, 1, a); (), Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> a)
|
|
173
|
+
sage: S(perm=Permutation('(1,2)(3,4)'))
|
|
174
|
+
((1, 1, 1, 1); (1,2)(3,4), Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> a)
|
|
175
|
+
sage: S(autom=F.hom([a**3]))
|
|
176
|
+
((1, 1, 1, 1); (), Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> 2*a + 1)
|
|
177
|
+
"""
|
|
178
|
+
from sage.categories.homset import End
|
|
179
|
+
R = self.base_ring()
|
|
180
|
+
if arg1 == 0:
|
|
181
|
+
if v is None:
|
|
182
|
+
v = [R.one()] * self.degree()
|
|
183
|
+
if perm is None:
|
|
184
|
+
perm = Permutation(range(1, self.degree() + 1))
|
|
185
|
+
if autom is None:
|
|
186
|
+
autom = R.hom(R.gens())
|
|
187
|
+
|
|
188
|
+
if check:
|
|
189
|
+
try:
|
|
190
|
+
v = [R(x) for x in v]
|
|
191
|
+
except TypeError:
|
|
192
|
+
raise TypeError('the vector attribute %s ' % v +
|
|
193
|
+
'should be iterable')
|
|
194
|
+
if len(v) != self.degree():
|
|
195
|
+
raise ValueError('the length of the vector is %s,' % len(v) +
|
|
196
|
+
' should be %s' % self.degree())
|
|
197
|
+
if not all(x.parent() is R and x.is_unit() for x in v):
|
|
198
|
+
raise ValueError('there is at least one element in the ' +
|
|
199
|
+
'list %s not lying in %s ' % (v, R) +
|
|
200
|
+
'or which is not invertible')
|
|
201
|
+
try:
|
|
202
|
+
perm = Permutation(perm)
|
|
203
|
+
except TypeError:
|
|
204
|
+
raise TypeError('the permutation attribute %s ' % perm +
|
|
205
|
+
'could not be converted to a permutation')
|
|
206
|
+
if len(perm) != self.degree():
|
|
207
|
+
txt = 'the permutation length is {}, should be {}'
|
|
208
|
+
raise ValueError(txt.format(len(perm), self.degree()))
|
|
209
|
+
|
|
210
|
+
try:
|
|
211
|
+
if autom.parent() != End(R):
|
|
212
|
+
autom = End(R)(autom)
|
|
213
|
+
except TypeError:
|
|
214
|
+
raise TypeError('%s of type %s' % (autom, type(autom)) +
|
|
215
|
+
' is not coerceable to an automorphism')
|
|
216
|
+
return self.Element(self, v, perm, autom)
|
|
217
|
+
else:
|
|
218
|
+
try:
|
|
219
|
+
if arg1.parent() is self:
|
|
220
|
+
return arg1
|
|
221
|
+
except AttributeError:
|
|
222
|
+
pass
|
|
223
|
+
try:
|
|
224
|
+
from sage.rings.integer import Integer
|
|
225
|
+
if Integer(arg1) == 1:
|
|
226
|
+
return self()
|
|
227
|
+
except TypeError:
|
|
228
|
+
pass
|
|
229
|
+
raise TypeError('the first argument must be an integer' +
|
|
230
|
+
' or an element of this group')
|
|
231
|
+
|
|
232
|
+
def base_ring(self):
|
|
233
|
+
r"""
|
|
234
|
+
Return the underlying ring of ``self``.
|
|
235
|
+
|
|
236
|
+
EXAMPLES::
|
|
237
|
+
|
|
238
|
+
sage: F.<a> = GF(4)
|
|
239
|
+
sage: SemimonomialTransformationGroup(F, 3).base_ring() is F
|
|
240
|
+
True
|
|
241
|
+
"""
|
|
242
|
+
return self._R
|
|
243
|
+
|
|
244
|
+
def degree(self) -> Integer:
|
|
245
|
+
r"""
|
|
246
|
+
Return the degree of ``self``.
|
|
247
|
+
|
|
248
|
+
EXAMPLES::
|
|
249
|
+
|
|
250
|
+
sage: F.<a> = GF(4)
|
|
251
|
+
sage: SemimonomialTransformationGroup(F, 3).degree()
|
|
252
|
+
3
|
|
253
|
+
"""
|
|
254
|
+
return self._len
|
|
255
|
+
|
|
256
|
+
def _an_element_(self):
|
|
257
|
+
r"""
|
|
258
|
+
Return an element of ``self``.
|
|
259
|
+
|
|
260
|
+
EXAMPLES::
|
|
261
|
+
|
|
262
|
+
sage: F.<a> = GF(4)
|
|
263
|
+
sage: SemimonomialTransformationGroup(F, 3).an_element() # indirect doctest
|
|
264
|
+
((a, 1, 1); (1,3,2), Ring endomorphism of Finite Field in a of size 2^2 Defn: a |--> a + 1)
|
|
265
|
+
"""
|
|
266
|
+
R = self.base_ring()
|
|
267
|
+
v = [R.primitive_element()] + [R.one()] * (self.degree() - 1)
|
|
268
|
+
p = Permutation([self.degree()] + list(range(1, self.degree())))
|
|
269
|
+
|
|
270
|
+
if not R.is_prime_field():
|
|
271
|
+
f = R.hom([R.gen()**R.characteristic()])
|
|
272
|
+
else:
|
|
273
|
+
f = R.Hom(R).identity()
|
|
274
|
+
return self(0, v, p, f)
|
|
275
|
+
|
|
276
|
+
def __contains__(self, item) -> bool:
|
|
277
|
+
r"""
|
|
278
|
+
EXAMPLES::
|
|
279
|
+
|
|
280
|
+
sage: F.<a> = GF(4)
|
|
281
|
+
sage: S = SemimonomialTransformationGroup(F, 3)
|
|
282
|
+
sage: 1 in S # indirect doctest
|
|
283
|
+
True
|
|
284
|
+
sage: a in S # indirect doctest
|
|
285
|
+
False
|
|
286
|
+
"""
|
|
287
|
+
try:
|
|
288
|
+
self(item, check=True)
|
|
289
|
+
except TypeError:
|
|
290
|
+
return False
|
|
291
|
+
return True
|
|
292
|
+
|
|
293
|
+
def gens(self) -> tuple:
|
|
294
|
+
r"""
|
|
295
|
+
Return a tuple of generators of ``self``.
|
|
296
|
+
|
|
297
|
+
EXAMPLES::
|
|
298
|
+
|
|
299
|
+
sage: F.<a> = GF(4)
|
|
300
|
+
sage: SemimonomialTransformationGroup(F, 3).gens()
|
|
301
|
+
(((a, 1, 1); (),
|
|
302
|
+
Ring endomorphism of Finite Field in a of size 2^2 Defn: a |--> a),
|
|
303
|
+
((1, 1, 1); (1,2,3),
|
|
304
|
+
Ring endomorphism of Finite Field in a of size 2^2 Defn: a |--> a),
|
|
305
|
+
((1, 1, 1); (1,2),
|
|
306
|
+
Ring endomorphism of Finite Field in a of size 2^2 Defn: a |--> a),
|
|
307
|
+
((1, 1, 1); (),
|
|
308
|
+
Ring endomorphism of Finite Field in a of size 2^2 Defn: a |--> a + 1))
|
|
309
|
+
"""
|
|
310
|
+
from sage.groups.perm_gps.permgroup_named import SymmetricGroup
|
|
311
|
+
R = self.base_ring()
|
|
312
|
+
l = [self(v=([R.primitive_element()] + [R.one()] * (self.degree() - 1)))]
|
|
313
|
+
l.extend(self(perm=Permutation(g))
|
|
314
|
+
for g in SymmetricGroup(self.degree()).gens())
|
|
315
|
+
if R.is_field() and not R.is_prime_field():
|
|
316
|
+
l.append(self(autom=R.hom([R.primitive_element()**R.characteristic()])))
|
|
317
|
+
return tuple(l)
|
|
318
|
+
|
|
319
|
+
def order(self) -> Integer:
|
|
320
|
+
r"""
|
|
321
|
+
Return the number of elements of ``self``.
|
|
322
|
+
|
|
323
|
+
EXAMPLES::
|
|
324
|
+
|
|
325
|
+
sage: F.<a> = GF(4)
|
|
326
|
+
sage: SemimonomialTransformationGroup(F, 5).order() == (4-1)**5 * factorial(5) * 2
|
|
327
|
+
True
|
|
328
|
+
"""
|
|
329
|
+
from sage.arith.misc import factorial
|
|
330
|
+
from sage.categories.homset import End
|
|
331
|
+
n = self.degree()
|
|
332
|
+
R = self.base_ring()
|
|
333
|
+
if R.is_field():
|
|
334
|
+
multgroup_size = len(R) - 1
|
|
335
|
+
autgroup_size = R.degree()
|
|
336
|
+
else:
|
|
337
|
+
multgroup_size = R.unit_group_order()
|
|
338
|
+
autgroup_size = len([x for x in End(R) if x.is_injective()])
|
|
339
|
+
return multgroup_size**n * factorial(n) * autgroup_size
|
|
340
|
+
|
|
341
|
+
def _get_action_(self, X, op, self_on_left):
|
|
342
|
+
r"""
|
|
343
|
+
If ``self`` is the semimonomial group of degree `n` over `R`, then
|
|
344
|
+
there is the natural action on `R^n` and on matrices `R^{m \times n}`
|
|
345
|
+
for arbitrary integers `m` from the left.
|
|
346
|
+
|
|
347
|
+
See also:
|
|
348
|
+
:class:`~sage.groups.semimonomial_transformations.semimonomial_transformation_group.SemimonomialActionVec` and
|
|
349
|
+
:class:`~sage.groups.semimonomial_transformations.semimonomial_transformation_group.SemimonomialActionMat`
|
|
350
|
+
|
|
351
|
+
EXAMPLES::
|
|
352
|
+
|
|
353
|
+
sage: F.<a> = GF(4)
|
|
354
|
+
sage: s = SemimonomialTransformationGroup(F, 3).an_element()
|
|
355
|
+
sage: v = (F**3).0
|
|
356
|
+
sage: s*v # indirect doctest
|
|
357
|
+
(0, 1, 0)
|
|
358
|
+
sage: M = MatrixSpace(F, 3).one()
|
|
359
|
+
sage: s*M # indirect doctest
|
|
360
|
+
[ 0 1 0]
|
|
361
|
+
[ 0 0 1]
|
|
362
|
+
[a + 1 0 0]
|
|
363
|
+
"""
|
|
364
|
+
if self_on_left:
|
|
365
|
+
try:
|
|
366
|
+
A = SemimonomialActionVec(self, X)
|
|
367
|
+
return A
|
|
368
|
+
except ValueError:
|
|
369
|
+
pass
|
|
370
|
+
|
|
371
|
+
try:
|
|
372
|
+
A = SemimonomialActionMat(self, X)
|
|
373
|
+
return A
|
|
374
|
+
except ValueError:
|
|
375
|
+
pass
|
|
376
|
+
|
|
377
|
+
return None
|
|
378
|
+
|
|
379
|
+
def _repr_(self) -> str:
|
|
380
|
+
r"""
|
|
381
|
+
Return a string describing ``self``.
|
|
382
|
+
|
|
383
|
+
EXAMPLES::
|
|
384
|
+
|
|
385
|
+
sage: F.<a> = GF(4)
|
|
386
|
+
sage: SemimonomialTransformationGroup(F, 3) # indirect doctest
|
|
387
|
+
Semimonomial transformation group over Finite Field in a of size 2^2 of degree 3
|
|
388
|
+
"""
|
|
389
|
+
return ('Semimonomial transformation group over %s' % self.base_ring() +
|
|
390
|
+
' of degree %s' % self.degree())
|
|
391
|
+
|
|
392
|
+
def _latex_(self) -> str:
|
|
393
|
+
r"""
|
|
394
|
+
Method for describing ``self`` in LaTeX.
|
|
395
|
+
|
|
396
|
+
EXAMPLES::
|
|
397
|
+
|
|
398
|
+
sage: F.<a> = GF(4)
|
|
399
|
+
sage: latex(SemimonomialTransformationGroup(F, 3)) # indirect doctest
|
|
400
|
+
\left(\Bold{F}_{2^{2}}^3\wr\langle (1,2,3), (1,2) \rangle \right) \rtimes \operatorname{Aut}(\Bold{F}_{2^{2}})
|
|
401
|
+
"""
|
|
402
|
+
from sage.groups.perm_gps.permgroup_named import SymmetricGroup
|
|
403
|
+
ring_latex = self.base_ring()._latex_()
|
|
404
|
+
return ('\\left(' + ring_latex + '^' + str(self.degree()) + '\\wr' +
|
|
405
|
+
SymmetricGroup(self.degree())._latex_() +
|
|
406
|
+
' \\right) \\rtimes \\operatorname{Aut}(' + ring_latex + ')')
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
class SemimonomialActionVec(Action):
|
|
410
|
+
r"""
|
|
411
|
+
The natural left action of the semimonomial group on vectors.
|
|
412
|
+
|
|
413
|
+
The action is defined by:
|
|
414
|
+
`(\phi, \pi, \alpha)*(v_0, \ldots, v_{n-1}) :=
|
|
415
|
+
(\alpha(v_{\pi(1)-1}) \cdot \phi_0^{-1}, \ldots, \alpha(v_{\pi(n)-1}) \cdot \phi_{n-1}^{-1})`.
|
|
416
|
+
(The indexing of vectors is `0`-based here, so
|
|
417
|
+
`\psi = (\psi_0, \psi_1, \ldots, \psi_{n-1})`.)
|
|
418
|
+
"""
|
|
419
|
+
def __init__(self, G, V, check=True):
|
|
420
|
+
r"""
|
|
421
|
+
Initialization.
|
|
422
|
+
|
|
423
|
+
EXAMPLES::
|
|
424
|
+
|
|
425
|
+
sage: F.<a> = GF(4)
|
|
426
|
+
sage: s = SemimonomialTransformationGroup(F, 3).an_element()
|
|
427
|
+
sage: v = (F**3).1
|
|
428
|
+
sage: s*v # indirect doctest
|
|
429
|
+
(0, 0, 1)
|
|
430
|
+
"""
|
|
431
|
+
if check:
|
|
432
|
+
from sage.modules.free_module import FreeModule_generic
|
|
433
|
+
if not isinstance(G, SemimonomialTransformationGroup):
|
|
434
|
+
raise ValueError('%s is not a semimonomial group' % G)
|
|
435
|
+
if not isinstance(V, FreeModule_generic):
|
|
436
|
+
raise ValueError('%s is not a free module' % V)
|
|
437
|
+
if V.ambient_module() != V:
|
|
438
|
+
raise ValueError('%s is not equal to its ambient module' % V)
|
|
439
|
+
if V.dimension() != G.degree():
|
|
440
|
+
raise ValueError('%s has a dimension different to the degree of %s' % (V, G))
|
|
441
|
+
if V.base_ring() != G.base_ring():
|
|
442
|
+
raise ValueError('%s and %s have different base rings' % (V, G))
|
|
443
|
+
|
|
444
|
+
Action.__init__(self, G, V.dense_module())
|
|
445
|
+
|
|
446
|
+
def _act_(self, a, b):
|
|
447
|
+
r"""
|
|
448
|
+
Apply the semimonomial group element `a` to the vector `b`.
|
|
449
|
+
|
|
450
|
+
EXAMPLES::
|
|
451
|
+
|
|
452
|
+
sage: F.<a> = GF(4)
|
|
453
|
+
sage: s = SemimonomialTransformationGroup(F, 3).an_element()
|
|
454
|
+
sage: v = (F**3).1
|
|
455
|
+
sage: s*v # indirect doctest
|
|
456
|
+
(0, 0, 1)
|
|
457
|
+
"""
|
|
458
|
+
b = b.apply_map(a.get_autom())
|
|
459
|
+
b = self.codomain()(a.get_perm().action(b))
|
|
460
|
+
return b.pairwise_product(self.codomain()(a.get_v_inverse()))
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
class SemimonomialActionMat(Action):
|
|
464
|
+
r"""
|
|
465
|
+
The left action of
|
|
466
|
+
:class:`~sage.groups.semimonomial_transformations.semimonomial_transformation_group.SemimonomialTransformationGroup`
|
|
467
|
+
on matrices over the same ring whose number of columns is equal to the degree.
|
|
468
|
+
See :class:`~sage.groups.semimonomial_transformations.semimonomial_transformation_group.SemimonomialActionVec`
|
|
469
|
+
for the definition of the action on the row vectors of such a matrix.
|
|
470
|
+
"""
|
|
471
|
+
def __init__(self, G, M, check=True):
|
|
472
|
+
r"""
|
|
473
|
+
Initialization.
|
|
474
|
+
|
|
475
|
+
EXAMPLES::
|
|
476
|
+
|
|
477
|
+
sage: F.<a> = GF(4)
|
|
478
|
+
sage: s = SemimonomialTransformationGroup(F, 3).an_element()
|
|
479
|
+
sage: M = MatrixSpace(F, 3).one()
|
|
480
|
+
sage: s*M # indirect doctest
|
|
481
|
+
[ 0 1 0]
|
|
482
|
+
[ 0 0 1]
|
|
483
|
+
[a + 1 0 0]
|
|
484
|
+
"""
|
|
485
|
+
if check:
|
|
486
|
+
from sage.matrix.matrix_space import MatrixSpace
|
|
487
|
+
if not isinstance(G, SemimonomialTransformationGroup):
|
|
488
|
+
raise ValueError('%s is not a semimonomial group' % G)
|
|
489
|
+
if not isinstance(M, MatrixSpace):
|
|
490
|
+
raise ValueError('%s is not a matrix space' % M)
|
|
491
|
+
if M.ncols() != G.degree():
|
|
492
|
+
raise ValueError('the number of columns of %s' % M +
|
|
493
|
+
' and the degree of %s are different' % G)
|
|
494
|
+
if M.base_ring() != G.base_ring():
|
|
495
|
+
raise ValueError('%s and %s have different base rings' % (M, G))
|
|
496
|
+
Action.__init__(self, G, M)
|
|
497
|
+
|
|
498
|
+
def _act_(self, a, b):
|
|
499
|
+
r"""
|
|
500
|
+
Apply the semimonomial group element `a` to the matrix `b`.
|
|
501
|
+
|
|
502
|
+
EXAMPLES::
|
|
503
|
+
|
|
504
|
+
sage: F.<a> = GF(4)
|
|
505
|
+
sage: s = SemimonomialTransformationGroup(F, 3).an_element()
|
|
506
|
+
sage: M = MatrixSpace(F, 3).one()
|
|
507
|
+
sage: s*M # indirect doctest
|
|
508
|
+
[ 0 1 0]
|
|
509
|
+
[ 0 0 1]
|
|
510
|
+
[a + 1 0 0]
|
|
511
|
+
"""
|
|
512
|
+
return self.codomain()([a * x for x in b.rows()])
|