Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/groups/semimonomial_transformations/semimonomial_transformation.pyx
8815 views
1
r"""
2
Elements of a semimonomial transformation group.
3
4
The semimonomial transformation group of degree `n` over a ring `R` is
5
the semidirect product of the monomial transformation group of degree `n`
6
(also known as the complete monomial group over the group of units
7
`R^{\times}` of `R`) and the group of ring automorphisms.
8
9
The multiplication of two elements `(\phi, \pi, \alpha)(\psi, \sigma, \beta)`
10
with
11
12
- `\phi, \psi \in {R^{\times}}^n`
13
14
- `\pi, \sigma \in S_n` (with the multiplication `\pi\sigma`
15
done from left to right (like in GAP) --
16
that is, `(\pi\sigma)(i) = \sigma(\pi(i))` for all `i`.)
17
18
- `\alpha, \beta \in Aut(R)`
19
20
is defined by
21
22
.. math::
23
24
(\phi, \pi, \alpha)(\psi, \sigma, \beta) =
25
(\phi \cdot \psi^{\pi, \alpha}, \pi\sigma, \alpha \circ \beta)
26
27
with
28
`\psi^{\pi, \alpha} = (\alpha(\psi_{\pi(1)-1}), \ldots, \alpha(\psi_{\pi(n)-1}))`
29
and an elementwisely defined multiplication of vectors. (The indexing
30
of vectors is `0`-based here, so `\psi = (\psi_0, \psi_1, \ldots, \psi_{n-1})`.)
31
32
33
34
The parent is
35
:class:`~sage.groups.semimonomial_transformations.semimonomial_transformation_group.SemimonomialTransformationGroup`.
36
37
AUTHORS:
38
39
- Thomas Feulner (2012-11-15): initial version
40
- Thomas Feulner (2013-12-27): :trac:`15576` dissolve dependency on
41
Permutations().global_options()['mul']
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(G[0]).run()
54
"""
55
include "../../ext/stdsage.pxi"
56
57
58
def _is_id(f, R):
59
"""
60
Test some automorphism `f` of a ring `R` if it is the identity
61
automorphism.
62
63
EXAMPLES::
64
65
sage: from sage.groups.semimonomial_transformations.semimonomial_transformation import _is_id
66
sage: F.<a> = GF(8)
67
sage: f = F.hom([a**2])
68
sage: _is_id(f, F)
69
False
70
"""
71
for r in R.gens():
72
if r != f(r):
73
return False
74
return True
75
76
77
def _inverse(f, R):
78
"""
79
Returns the inverse to the automorphism `f` of a ring `R`.
80
81
EXAMPLES::
82
83
sage: from sage.groups.semimonomial_transformations.semimonomial_transformation import _inverse
84
sage: F.<a> = GF(8)
85
sage: f = F.hom([a**2])
86
sage: _inverse(f, F)*f == F.hom([a])
87
True
88
"""
89
g = f
90
while not _is_id(g*f, R):
91
g *= f
92
return g
93
94
cdef class SemimonomialTransformation(MultiplicativeGroupElement):
95
r"""
96
An element in the semimonomial group over a ring `R`. See
97
:class:`~sage.groups.semimonomial_transformations.semimonomial_transformation_group.SemimonomialTransformationGroup`
98
for the details on the multiplication of two elements.
99
100
The init method should never be called directly. Use the call via the
101
parent
102
:class:`~sage.groups.semimonomial_transformations.semimonomial_transformation_group.SemimonomialTransformationGroup`.
103
instead.
104
105
EXAMPLES::
106
107
sage: F.<a> = GF(9)
108
sage: S = SemimonomialTransformationGroup(F, 4)
109
sage: g = S(v = [2, a, 1, 2])
110
sage: h = S(perm = Permutation('(1,2,3,4)'), autom=F.hom([a**3]))
111
sage: g*h
112
((2, a, 1, 2); (1,2,3,4), Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> 2*a + 1)
113
sage: h*g
114
((2*a + 1, 1, 2, 2); (1,2,3,4), 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); (), Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> a)
117
sage: S(1) # the one element in the group
118
((1, 1, 1, 1); (), Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> a)
119
"""
120
def __init__(self, parent, v, perm, alpha):
121
r"""
122
The init method should never be called directly. Use the call via the
123
parent instead. See
124
:meth:`sage.groups.semimonomial_transformations.semimonomial_transformation.SemimonomialTransformation.__call__`.
125
126
EXAMPLES::
127
128
sage: F.<a> = GF(9)
129
sage: S = SemimonomialTransformationGroup(F, 4)
130
sage: g = S(v = [2, a, 1, 2]) #indirect doctest
131
"""
132
MultiplicativeGroupElement.__init__(self, parent)
133
self.v = tuple(v)
134
self.perm = perm
135
self.alpha = alpha
136
137
cdef _new_c(self):
138
# Create a copy of self.
139
cdef SemimonomialTransformation x
140
x = PY_NEW(SemimonomialTransformation)
141
x._parent = self._parent
142
x.v = self.v
143
x.perm = self.perm
144
x.alpha = self.alpha
145
return x
146
147
def __copy__(self):
148
"""
149
Return a copy of ``self``.
150
151
EXAMPLES::
152
153
sage: F.<a> = GF(9)
154
sage: s = SemimonomialTransformationGroup(F, 4).an_element()
155
sage: t = copy(s) #indirect doctest
156
sage: t is s
157
False
158
sage: t == s
159
True
160
"""
161
return self._new_c()
162
163
def __hash__(self):
164
"""
165
Return hash of this element.
166
167
EXAMPLES::
168
169
sage: F.<a> = GF(9)
170
sage: hash( SemimonomialTransformationGroup(F, 4).an_element() ) #random #indirect doctest
171
6279637968393375107
172
"""
173
return hash(self.v) + hash(self.perm) + hash(self.get_autom())
174
175
cpdef MonoidElement _mul_(left, MonoidElement _right):
176
r"""
177
Multiplication of elements.
178
179
The multiplication of two elements `(\phi, \pi, \alpha)` and
180
`(\psi, \sigma, \beta)` with
181
182
- `\phi, \psi \in {R^{\times}}^n`
183
184
- `\pi, \sigma \in S_n`
185
186
- `\alpha, \beta \in Aut(R)`
187
188
is defined by:
189
190
.. math::
191
192
(\phi, \pi, \alpha)(\psi, \sigma, \beta) =
193
(\phi \cdot \psi^{\pi, \alpha}, \pi\sigma, \alpha \circ \beta)
194
195
with
196
`\psi^{\pi, \alpha} = (\alpha(\psi_{\pi(1)-1}), \ldots, \alpha(\psi_{\pi(n)-1}))`
197
and an elementwisely defined multiplication of vectors. (The indexing
198
of vectors is `0`-based here, so `\psi = (\psi_0, \psi_1, \ldots, \psi_{n-1})`.)
199
Furthermore, the multiplication `\pi\sigma` is done from left to right
200
(like in GAP) -- that is, `(\pi\sigma)(i) = \sigma(\pi(i))` for all `i`.
201
202
EXAMPLES::
203
204
sage: F.<a> = GF(9)
205
sage: s = SemimonomialTransformationGroup(F, 4).an_element()
206
sage: s*s #indirect doctest
207
((a, 2*a + 1, 1, 1); (1,3)(2,4), Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> a)
208
"""
209
cdef SemimonomialTransformation right = <SemimonomialTransformation> _right
210
cdef i
211
v = left.perm.action(right.v)
212
alpha = left.get_autom()
213
v = [left.v[i]*alpha(v[i]) for i in range(left.parent().degree())]
214
return left.parent()(v=v, perm=left.perm.right_action_product(right.perm),
215
autom=alpha*right.get_autom(), check=False)
216
217
def __invert__(self):
218
"""
219
Return the inverse of ``self``.
220
221
EXAMPLES::
222
223
sage: F.<a> = GF(9)
224
sage: S = SemimonomialTransformationGroup(F, 4)
225
sage: s = S.an_element()
226
sage: s*s**(-1) == S(1) # indirect doctest
227
True
228
"""
229
cdef i
230
alpha = _inverse(self.get_autom(), self.get_autom().domain())
231
inv_perm = self.perm.inverse()
232
v = [alpha(self.v[i]**(-1)) for i in range(len(self.v))]
233
return self.parent()(v=inv_perm.action(v), perm=inv_perm, autom=alpha,
234
check=False)
235
236
def __repr__(self):
237
"""
238
String representation of `self`.
239
240
EXAMPLES::
241
242
sage: F.<a> = GF(9)
243
sage: SemimonomialTransformationGroup(F, 4).an_element() # indirect doctest
244
((a, 1, 1, 1); (1,4,3,2), Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> 2*a + 1)
245
"""
246
return "(%s; %s, %s)"%(self.v, self.perm.cycle_string(),
247
self.get_autom())
248
249
def __cmp__(self, right):
250
"""
251
Compare group elements ``self`` and ``right``.
252
253
EXAMPLES::
254
255
sage: F.<a> = GF(9)
256
sage: g = SemimonomialTransformationGroup(F, 4).gens()
257
sage: g[0] > g[1] # indirect doctest
258
True
259
sage: g[1] != g[2] # indirect doctest
260
True
261
"""
262
return (<Element> self)._cmp(right)
263
264
cdef int _cmp_c_impl(left, Element _right) except -2:
265
cdef SemimonomialTransformation right = <SemimonomialTransformation> _right
266
return cmp([left.v, left.perm, left.get_autom()],
267
[right.v, right.perm, right.get_autom()])
268
269
def __reduce__(self):
270
"""
271
Returns a function and its arguments needed to create this
272
semimonomial group element. This is used in pickling.
273
274
EXAMPLES::
275
276
sage: F.<a> = GF(9)
277
sage: SemimonomialTransformationGroup(F, 4).an_element().__reduce__()
278
(Semimonomial transformation group over Finite Field in a of size 3^2 of degree 4, (0, (a, 1, 1, 1), [4, 1, 2, 3], Ring endomorphism of Finite Field in a of size 3^2
279
Defn: a |--> 2*a + 1))
280
"""
281
return (self.parent(), (0, self.v, self.perm, self.get_autom()))
282
283
def get_v(self):
284
"""
285
Returns the component corresponding to `{R^{\times}}^n` of ``self``.
286
287
EXAMPLES::
288
289
sage: F.<a> = GF(9)
290
sage: SemimonomialTransformationGroup(F, 4).an_element().get_v()
291
(a, 1, 1, 1)
292
"""
293
return self.v
294
295
def get_v_inverse(self):
296
"""
297
Returns the (elementwise) inverse of the component corresponding to
298
`{R^{\times}}^n` of ``self``.
299
300
EXAMPLES::
301
302
sage: F.<a> = GF(9)
303
sage: SemimonomialTransformationGroup(F, 4).an_element().get_v_inverse()
304
(a + 2, 1, 1, 1)
305
"""
306
return tuple(x**(-1) for x in self.v)
307
308
def get_perm(self):
309
"""
310
Returns the component corresponding to `S_n` of ``self``.
311
312
EXAMPLES::
313
314
sage: F.<a> = GF(9)
315
sage: SemimonomialTransformationGroup(F, 4).an_element().get_perm()
316
[4, 1, 2, 3]
317
"""
318
return self.perm
319
320
def get_autom(self):
321
"""
322
Returns the component corresponding to `Aut(R)` of ``self``.
323
324
EXAMPLES::
325
326
sage: F.<a> = GF(9)
327
sage: SemimonomialTransformationGroup(F, 4).an_element().get_autom()
328
Ring endomorphism of Finite Field in a of size 3^2 Defn: a |--> 2*a + 1
329
"""
330
return self.alpha
331
332
def invert_v(self):
333
"""
334
Elementwisely inverts all entries of ``self`` which
335
correspond to the component `{R^{\times}}^n`.
336
337
The other components of ``self`` keep unchanged.
338
339
EXAMPLES::
340
341
sage: F.<a> = GF(9)
342
sage: x = copy(SemimonomialTransformationGroup(F, 4).an_element())
343
sage: x.invert_v();
344
sage: x.get_v() == SemimonomialTransformationGroup(F, 4).an_element().get_v_inverse()
345
True
346
"""
347
self.v = tuple([x**(-1) for x in self.v])
348
349