Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/groups/conjugacy_classes.py
8814 views
1
# -*- coding: utf-8 -*-
2
r"""
3
Conjugacy classes of groups
4
5
This module implements a wrapper of GAP's ``ConjugacyClass`` function.
6
7
There are two main classes, :class:`ConjugacyClass` and
8
:class:`ConjugacyClassGAP`. All generic methods should go into
9
:class:`ConjugacyClass`, whereas :class:`ConjugacyClassGAP` should only
10
contain wrappers for GAP functions. :class:`ConjugacyClass` contains some
11
fallback methods in case some group cannot be defined as a GAP object.
12
13
.. TODO::
14
15
- Implement a non-naive fallback method for computing all the elements of
16
the conjugacy class when the group is not defined in GAP, as the one in
17
Butler's paper.
18
- Define a sage method for gap matrices so that groups of matrices can
19
use the quicker GAP algorithm rather than the naive one.
20
21
EXAMPLES:
22
23
Conjugacy classes for groups of permutations::
24
25
sage: G = SymmetricGroup(4)
26
sage: g = G((1,2,3,4))
27
sage: G.conjugacy_class(g)
28
Conjugacy class of (1,2,3,4) in Symmetric group of order 4! as a permutation group
29
30
Conjugacy classes for groups of matrices::
31
32
sage: F = GF(5)
33
sage: gens = [matrix(F,2,[1,2, -1, 1]), matrix(F,2, [1,1, 0,1])]
34
sage: H = MatrixGroup(gens)
35
sage: h = H(matrix(F,2,[1,2, -1, 1]))
36
sage: H.conjugacy_class(h)
37
Conjugacy class of [1 2]
38
[4 1] in Matrix group over Finite Field of size 5 with 2 generators (
39
[1 2] [1 1]
40
[4 1], [0 1]
41
)
42
43
TESTS::
44
45
sage: G = SymmetricGroup(3)
46
sage: g = G((1,2,3))
47
sage: C = ConjugacyClass(G,g)
48
sage: TestSuite(C).run()
49
"""
50
51
#****************************************************************************
52
# Copyright (C) 2011 Javier López Peña <[email protected]>
53
#
54
# Distributed under the terms of the GNU General Public License (GPL)
55
# http://www.gnu.org/licenses/
56
#****************************************************************************
57
58
from sage.structure.parent import Parent
59
from sage.misc.cachefunc import cached_method
60
from sage.categories.enumerated_sets import EnumeratedSets
61
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
62
63
# TODO
64
#
65
# Don't derive from Parent if there are no elements
66
#
67
# @cached_method must not return mutable containers (lists), use
68
# tuples instead.
69
70
71
72
class ConjugacyClass(Parent):
73
r"""
74
Generic conjugacy classes for elements in a group.
75
76
This is the default fall-back implementation to be used whenever
77
GAP cannot handle the group.
78
79
EXAMPLES::
80
81
sage: G = SymmetricGroup(4)
82
sage: g = G((1,2,3,4))
83
sage: ConjugacyClass(G,g)
84
Conjugacy class of (1,2,3,4) in Symmetric group of order 4! as a
85
permutation group
86
"""
87
def __init__(self, group, element):
88
r"""
89
Generic conjugacy classes for elements in a group.
90
This is the default fall-back implementation to be used whenever
91
GAP cannot handle the group.
92
93
EXAMPLES::
94
95
sage: G = SymmetricGroup(4)
96
sage: g = G((1,2,3,4))
97
sage: ConjugacyClass(G,g)
98
Conjugacy class of (1,2,3,4) in Symmetric group of order 4! as a
99
permutation group
100
sage: TestSuite(G).run()
101
"""
102
self._parent = group
103
self._representative = element
104
try:
105
finite = group.is_finite()
106
except (AttributeError, NotImplementedError):
107
finite = False
108
if finite:
109
Parent.__init__(self, category=FiniteEnumeratedSets())
110
else: # If the group is not finite, then we do not know if we are finite or not
111
Parent.__init__(self, category=EnumeratedSets())
112
113
def __repr__(self):
114
r"""
115
EXAMPLES::
116
117
sage: G = SymmetricGroup(4)
118
sage: g = G((1,2,3,4))
119
sage: C = ConjugacyClass(G,g)
120
sage: C
121
Conjugacy class of (1,2,3,4) in Symmetric group of order 4! as a
122
permutation group
123
124
"""
125
return "Conjugacy class of %s in %s"%(self._representative,self._parent)
126
127
def __cmp__(self, other):
128
r"""
129
Comparison of conjugacy classes is done by comparing the
130
underlying sets.
131
132
EXAMPLES::
133
134
sage: F = GF(5)
135
sage: gens = [matrix(F,2,[1,2, -1, 1]), matrix(F,2, [1,1, 0,1])]
136
sage: H = MatrixGroup(gens)
137
sage: h = H(matrix(F,2,[1,2, -1, 1]))
138
sage: h2 = H(matrix(F,2,[1,1, 0, 1]))
139
sage: g = h2*h*h2^(-1)
140
sage: C = ConjugacyClass(H,h)
141
sage: D = ConjugacyClass(H,g)
142
sage: C == D
143
True
144
"""
145
c = cmp(type(self),type(other))
146
if c:
147
return c
148
return cmp(self.set(), other.set())
149
150
def __contains__(self, element):
151
r"""
152
Checks if ``element`` belongs to the conjugacy class ``self``.
153
154
EXAMPLES::
155
156
sage: G = SymmetricGroup(4)
157
sage: g = G((1,2,3,4))
158
sage: C = ConjugacyClass(G,g)
159
sage: g in C
160
True
161
"""
162
return element in self.set()
163
164
@cached_method
165
def set(self):
166
r"""
167
Naive algorithm to give a set with all the elements of the conjugacy
168
class.
169
170
.. TODO::
171
172
Implement a non-naive algorithm, cf. for instance
173
G. Butler: "An Inductive Schema for Computing Conjugacy Classes
174
in Permutation Groups", Math. of Comp. Vol. 62, No. 205 (1994)
175
176
EXAMPLES:
177
178
Groups of permutations::
179
180
sage: G = SymmetricGroup(3)
181
sage: g = G((1,2))
182
sage: C = ConjugacyClass(G,g)
183
sage: S = [(2,3), (1,2), (1,3)]
184
sage: C.set() == Set(G(x) for x in S)
185
True
186
187
Groups of matrices over finite fields::
188
189
sage: F = GF(5)
190
sage: gens = [matrix(F,2,[1,2, -1, 1]), matrix(F,2, [1,1, 0,1])]
191
sage: H = MatrixGroup(gens)
192
sage: h = H(matrix(F,2,[1,2, -1, 1]))
193
sage: C = ConjugacyClass(H,h)
194
sage: S = [[[3, 2], [2, 4]], [[0, 1], [2, 2]], [[3, 4], [1, 4]],\
195
[[0, 3], [4, 2]], [[1, 2], [4, 1]], [[2, 1], [2, 0]],\
196
[[4, 1], [4, 3]], [[4, 4], [1, 3]], [[2, 4], [3, 0]],\
197
[[1, 4], [2, 1]], [[3, 3], [3, 4]], [[2, 3], [4, 0]],\
198
[[0, 2], [1, 2]], [[1, 3], [1, 1]], [[4, 3], [3, 3]],\
199
[[4, 2], [2, 3]], [[0, 4], [3, 2]], [[1, 1], [3, 1]],\
200
[[2, 2], [1, 0]], [[3, 1], [4, 4]]]
201
sage: C.set() == Set(H(x) for x in S)
202
True
203
"""
204
from sage.sets.set import Set
205
from sage.combinat.backtrack import TransitiveIdeal
206
if self._parent.is_finite():
207
g = self._representative
208
G = self._parent
209
gens = G.gens()
210
return Set(x for x in TransitiveIdeal(lambda y: [c*y*c**-1 for c in gens], [g]))
211
else:
212
raise NotImplementedError("Listing the elements of conjugacy classes is not implemented for infinite groups!")
213
214
@cached_method
215
def list(self):
216
r"""
217
Return a list with all the elements of ``self``.
218
219
EXAMPLES:
220
221
Groups of permutations::
222
223
sage: G = SymmetricGroup(3)
224
sage: g = G((1,2,3))
225
sage: c = ConjugacyClass(G,g)
226
sage: L = c.list()
227
sage: Set(L) == Set([G((1,3,2)), G((1,2,3))])
228
True
229
"""
230
return list(self.set())
231
232
def is_real(self):
233
"""
234
Checks if ``self`` is real (closed for inverses).
235
236
EXAMPLES::
237
238
sage: G = SymmetricGroup(4)
239
sage: g = G((1,2,3,4))
240
sage: c = ConjugacyClass(G,g)
241
sage: c.is_real()
242
True
243
244
"""
245
return self._representative**(-1) in self
246
247
def is_rational(self):
248
"""
249
Checks if ``self`` is rational (closed for powers).
250
251
EXAMPLES::
252
253
sage: G = SymmetricGroup(4)
254
sage: g = G((1,2,3,4))
255
sage: c = ConjugacyClass(G,g)
256
sage: c.is_rational()
257
False
258
"""
259
g = self._representative
260
return all(g**k in self.set() for k in range(1,g.order()))
261
262
def representative(self):
263
"""
264
Return a representative of ``self``.
265
266
EXAMPLES::
267
268
sage: G = SymmetricGroup(3)
269
sage: g = G((1,2,3))
270
sage: C = ConjugacyClass(G,g)
271
sage: C.representative()
272
(1,2,3)
273
"""
274
return self._representative
275
276
277
class ConjugacyClassGAP(ConjugacyClass):
278
r"""
279
Class for a conjugacy class for groups defined over GAP.
280
Intended for wrapping GAP methods on conjugacy classes.
281
282
INPUT:
283
284
- ``group`` -- the group in which the conjugacy class is taken
285
286
- ``element`` -- the element generating the conjugacy class
287
288
EXAMPLES::
289
290
sage: G = SymmetricGroup(4)
291
sage: g = G((1,2,3,4))
292
sage: ConjugacyClassGAP(G,g)
293
Conjugacy class of (1,2,3,4) in Symmetric group of order 4! as a
294
permutation group
295
"""
296
297
def __init__(self, group, element):
298
r"""
299
Constructor for the class.
300
301
EXAMPLES:
302
303
Conjugacy classes for groups of permutations::
304
305
sage: G = SymmetricGroup(4)
306
sage: g = G((1,2,3,4))
307
sage: ConjugacyClassGAP(G,g)
308
Conjugacy class of (1,2,3,4) in Symmetric group of order 4! as a permutation group
309
310
Conjugacy classes for groups of matrices::
311
312
sage: F = GF(5)
313
sage: gens = [matrix(F,2,[1,2, -1, 1]), matrix(F,2, [1,1, 0,1])]
314
sage: H = MatrixGroup(gens)
315
sage: h = H(matrix(F,2,[1,2, -1, 1]))
316
sage: ConjugacyClassGAP(H,h)
317
Conjugacy class of [1 2]
318
[4 1] in Matrix group over Finite Field of size 5 with 2 generators (
319
[1 2] [1 1]
320
[4 1], [0 1]
321
)
322
"""
323
try:
324
# GAP interface
325
self._gap_group = group._gap_()
326
self._gap_representative = element._gap_()
327
except (AttributeError, TypeError):
328
try:
329
# LibGAP
330
self._gap_group = group.gap()
331
self._gap_representative = element.gap()
332
except (AttributeError, TypeError):
333
raise TypeError("The group %s cannot be defined as a GAP group"%group)
334
335
self._gap_conjugacy_class = self._gap_group.ConjugacyClass(self._gap_representative)
336
ConjugacyClass.__init__(self, group, element)
337
338
def _gap_(self):
339
r"""
340
Return the gap object corresponding to ``self``.
341
342
EXAMPLES::
343
344
sage: G = SymmetricGroup(3)
345
sage: g = G((1,2,3))
346
sage: C = ConjugacyClassGAP(G,g)
347
sage: C._gap_()
348
ConjugacyClass( SymmetricGroup( [ 1 .. 3 ] ), (1,2,3) )
349
"""
350
return self._gap_conjugacy_class
351
352
@cached_method
353
def set(self):
354
r"""
355
Return a Sage ``Set`` with all the elements of the conjugacy class.
356
357
By default attempts to use GAP construction of the conjugacy class.
358
If GAP method is not implemented for the given group, and the group
359
is finite, falls back to a naive algorithm.
360
361
.. WARNING::
362
363
The naive algorithm can be really slow and memory intensive.
364
365
EXAMPLES:
366
367
Groups of permutations::
368
369
sage: G = SymmetricGroup(4)
370
sage: g = G((1,2,3,4))
371
sage: C = ConjugacyClassGAP(G,g)
372
sage: S = [(1,3,2,4), (1,4,3,2), (1,3,4,2), (1,2,3,4), (1,4,2,3), (1,2,4,3)]
373
sage: C.set() == Set(G(x) for x in S)
374
True
375
376
"""
377
from sage.sets.set import Set
378
try:
379
cc = self._gap_conjugacy_class.AsList().sage()
380
return Set([self._parent(x) for x in cc])
381
except NotImplementedError: # If GAP doesn't work, fall back to naive method
382
return ConjugacyClass.set.f(self) # Need the f because the base-class mehod is also cached
383
384
385