Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/groups/perm_gps/permgroup_named.py
4069 views
1
r"""
2
"Named" Permutation groups (such as the symmetric group, S_n)
3
4
You can construct the following permutation groups:
5
6
-- SymmetricGroup, $S_n$ of order $n!$ (n can also be a list $X$ of distinct
7
positive integers, in which case it returns $S_X$)
8
9
-- AlternatingGroup, $A_n$ or order $n!/2$ (n can also be a list $X$
10
of distinct positive integers, in which case it returns
11
$A_X$)
12
13
-- DihedralGroup, $D_n$ of order $2n$
14
15
-- CyclicPermutationGroup, $C_n$ of order $n$
16
17
-- DiCyclicGroup, nonabelian groups of order `4m` with a unique element of order 2
18
19
-- TransitiveGroup, $n^{th}$ transitive group of degree $d$
20
from the GAP tables of transitive groups (requires
21
the "optional" package database_gap)
22
23
-- TransitiveGroups(d), TransitiveGroups(), set of all of the above
24
25
-- MathieuGroup(degree), Mathieu group of degree 9, 10, 11, 12, 21, 22, 23, or 24.
26
27
-- KleinFourGroup, subgroup of $S_4$ of order $4$ which is not $C_2 \times C_2$
28
29
-- QuaternionGroup, non-abelian group of order `8`, `\{\pm 1, \pm I, \pm J, \pm K\}`
30
31
-- PGL(n,q), projective general linear group of $n\times n$ matrices over
32
the finite field GF(q)
33
34
-- PSL(n,q), projective special linear group of $n\times n$ matrices over
35
the finite field GF(q)
36
37
-- PSp(2n,q), projective symplectic linear group of $2n\times 2n$ matrices
38
over the finite field GF(q)
39
40
-- PSU(n,q), projective special unitary group of $n \times n$ matrices having
41
coefficients in the finite field $GF(q^2)$ that respect a
42
fixed nondegenerate sesquilinear form, of determinant 1.
43
44
-- PGU(n,q), projective general unitary group of $n\times n$ matrices having
45
coefficients in the finite field $GF(q^2)$ that respect a
46
fixed nondegenerate sesquilinear form, modulo the centre.
47
48
-- SuzukiGroup(q), Suzuki group over GF(q), $^2 B_2(2^{2k+1}) = Sz(2^{2k+1})$.
49
50
51
AUTHOR:
52
- David Joyner (2007-06): split from permgp.py (suggested by Nick Alexander)
53
54
REFERENCES:
55
Cameron, P., Permutation Groups. New York: Cambridge University Press, 1999.
56
Wielandt, H., Finite Permutation Groups. New York: Academic Press, 1964.
57
Dixon, J. and Mortimer, B., Permutation Groups, Springer-Verlag, Berlin/New York, 1996.
58
59
NOTE:
60
Though Suzuki groups are okay, Ree groups should *not* be wrapped as
61
permutation groups - the construction is too slow - unless (for
62
small values or the parameter) they are made using explicit generators.
63
"""
64
65
#*****************************************************************************
66
# Copyright (C) 2006 William Stein <[email protected]>
67
# David Joyner <[email protected]>
68
#
69
# Distributed under the terms of the GNU General Public License (GPL)
70
# http://www.gnu.org/licenses/
71
#*****************************************************************************
72
73
from sage.rings.all import Integer
74
from sage.interfaces.all import gap
75
from sage.rings.finite_rings.constructor import FiniteField as GF
76
from sage.rings.arith import factor
77
from sage.rings.integer_ring import ZZ
78
from sage.groups.abelian_gps.abelian_group import AbelianGroup
79
from sage.misc.functional import is_even
80
from sage.misc.cachefunc import cached_method
81
from sage.misc.misc import deprecated_function_alias
82
from sage.groups.perm_gps.permgroup import PermutationGroup_generic
83
from sage.groups.perm_gps.permgroup_element import PermutationGroupElement
84
from sage.structure.unique_representation import UniqueRepresentation
85
from sage.structure.parent import Parent
86
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
87
from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
88
from sage.sets.disjoint_union_enumerated_sets import DisjointUnionEnumeratedSets
89
from sage.categories.enumerated_sets import EnumeratedSets
90
from sage.sets.non_negative_integers import NonNegativeIntegers
91
from sage.sets.family import Family
92
93
class PermutationGroup_unique(UniqueRepresentation, PermutationGroup_generic):
94
@staticmethod
95
def __classcall__(cls, *args, **kwds):
96
"""
97
This makes sure that domain is a FiniteEnumeratedSet before it gets passed
98
on to the __init__ method.
99
100
EXAMPLES::
101
102
sage: SymmetricGroup(['a','b']).domain() #indirect doctest
103
{'a', 'b'}
104
"""
105
domain = kwds.pop('domain', None)
106
if domain is not None:
107
if domain not in FiniteEnumeratedSets():
108
domain = FiniteEnumeratedSet(domain)
109
kwds['domain'] = domain
110
return super(PermutationGroup_unique, cls).__classcall__(cls, *args, **kwds)
111
112
def __eq__(self, other):
113
"""
114
Overrides the default equality testing provided by
115
UniqueRepresentation by forcing a call to :meth:.`__cmp__`.
116
117
EXAMPLES::
118
119
sage: G = SymmetricGroup(6)
120
sage: G3 = G.subgroup([G((1,2,3,4,5,6)),G((1,2))])
121
sage: G == G3
122
True
123
"""
124
return self.__cmp__(other) == 0
125
126
127
class PermutationGroup_symalt(PermutationGroup_unique):
128
"""
129
This is a class used to factor out some of the commonality
130
in the SymmetricGroup and AlternatingGroup classes.
131
"""
132
133
@staticmethod
134
def __classcall__(cls, domain):
135
"""
136
Normalizes the input of the constructor into a set
137
138
INPUT:
139
140
- ``n`` - an integer or list or tuple thereof
141
142
Calls the constructor with a tuple representing the set.
143
144
EXAMPLES::
145
146
sage: S1 = SymmetricGroup(4)
147
sage: S2 = SymmetricGroup([1,2,3,4])
148
sage: S3 = SymmetricGroup((1,2,3,4))
149
sage: S1 is S2
150
True
151
sage: S1 is S3
152
True
153
154
TESTS::
155
156
sage: SymmetricGroup(0)
157
Symmetric group of order 0! as a permutation group
158
sage: SymmetricGroup(1)
159
Symmetric group of order 1! as a permutation group
160
sage: SymmetricGroup(-1)
161
Traceback (most recent call last):
162
...
163
ValueError: domain (=-1) must be an integer >= 0 or a list
164
"""
165
if domain not in FiniteEnumeratedSets():
166
if not isinstance(domain, (tuple, list)):
167
try:
168
domain = Integer(domain)
169
except TypeError:
170
raise ValueError, "domain (=%s) must be an integer >= 0 or a finite set (but domain has type %s)"%(domain,type(domain))
171
172
if domain < 0:
173
raise ValueError, "domain (=%s) must be an integer >= 0 or a list"%domain
174
else:
175
domain = range(1, domain+1)
176
v = FiniteEnumeratedSet(domain)
177
else:
178
v = domain
179
180
return super(PermutationGroup_symalt, cls).__classcall__(cls, domain=v)
181
182
set = deprecated_function_alias(PermutationGroup_generic.domain, 'Sage Version 4.7.1')
183
184
class SymmetricGroup(PermutationGroup_symalt):
185
def __init__(self, domain=None):
186
"""
187
The full symmetric group of order $n!$, as a permutation group.
188
If n is a list or tuple of positive integers then it returns the
189
symmetric group of the associated set.
190
191
INPUT:
192
193
- ``n`` - a positive integer, or list or tuple thereof
194
195
EXAMPLES::
196
197
sage: G = SymmetricGroup(8)
198
sage: G.order()
199
40320
200
sage: G
201
Symmetric group of order 8! as a permutation group
202
sage: G.degree()
203
8
204
sage: S8 = SymmetricGroup(8)
205
sage: G = SymmetricGroup([1,2,4,5])
206
sage: G
207
Symmetric group of order 4! as a permutation group
208
sage: G.domain()
209
{1, 2, 4, 5}
210
sage: G = SymmetricGroup(4)
211
sage: G
212
Symmetric group of order 4! as a permutation group
213
sage: G.domain()
214
{1, 2, 3, 4}
215
sage: G.category()
216
Join of Category of finite permutation groups and Category of finite weyl groups
217
sage: TestSuite(G).run()
218
219
TESTS::
220
221
sage: TestSuite(SymmetricGroup(0)).run()
222
"""
223
from sage.categories.finite_weyl_groups import FiniteWeylGroups
224
from sage.categories.finite_permutation_groups import FinitePermutationGroups
225
from sage.categories.category import Category
226
227
#Note that we skip the call to the superclass initializer in order to
228
#avoid infinite recursion since SymmetricGroup is called by
229
#PermutationGroupElement
230
super(PermutationGroup_generic, self).__init__(category = Category.join([FinitePermutationGroups(), FiniteWeylGroups()]))
231
232
self._domain = domain
233
self._deg = len(self._domain)
234
self._domain_to_gap = dict((key, i+1) for i, key in enumerate(self._domain))
235
self._domain_from_gap = dict((i+1, key) for i, key in enumerate(self._domain))
236
237
#Create the generators for the symmetric group
238
gens = [ tuple(self._domain) ]
239
if len(self._domain) > 2:
240
gens.append( tuple(self._domain[:2]) )
241
self._gens = [PermutationGroupElement(g, self, check=False) for g in gens]
242
243
244
def _gap_init_(self, gap=None):
245
"""
246
Returns the string used to create this group in GAP.
247
248
EXAMPLES::
249
250
sage: S = SymmetricGroup(3)
251
sage: S._gap_init_()
252
'SymmetricGroup(3)'
253
sage: S = SymmetricGroup(['a', 'b', 'c'])
254
sage: S._gap_init_()
255
'SymmetricGroup(3)'
256
"""
257
return 'SymmetricGroup(%s)'%self.degree()
258
259
@cached_method
260
def index_set(self):
261
"""
262
Indexing sets of descent of the symmetric group.
263
264
EXAMPLES::
265
266
sage: S8 = SymmetricGroup(8)
267
sage: S8.index_set()
268
[1, 2, 3, 4, 5, 6, 7]
269
270
sage: S = SymmetricGroup([3,1,4,5])
271
sage: S.index_set()
272
[3, 1, 4]
273
"""
274
return self.domain()[:-1]
275
276
def __cmp__(self, x):
277
"""
278
Fast comparison for SymmetricGroups.
279
280
EXAMPLES:
281
sage: S8 = SymmetricGroup(8)
282
sage: S3 = SymmetricGroup(3)
283
sage: S8 > S3
284
True
285
"""
286
if isinstance(x, SymmetricGroup):
287
return cmp((self._deg, self._domain), (x._deg, x._domain))
288
else:
289
return PermutationGroup_generic.__cmp__(self, x)
290
291
def _repr_(self):
292
"""
293
EXAMPLES:
294
sage: A = SymmetricGroup([2,3,7]); A
295
Symmetric group of order 3! as a permutation group
296
"""
297
return "Symmetric group of order %s! as a permutation group"%self.degree()
298
299
def simple_reflection(self, i):
300
"""
301
For `i` in the index set of ``self``, this returns the
302
elementary transposition `s_i=(i,i+1)`.
303
304
EXAMPLES::
305
306
sage: A = SymmetricGroup(5)
307
sage: A.simple_reflection(3)
308
(3,4)
309
310
sage: A = SymmetricGroup([2,3,7])
311
sage: A.simple_reflections()
312
Finite family {2: (2,3), 3: (3,7)}
313
"""
314
return self([(i, self._domain[self._domain.index(i)+1])], check=False)
315
316
def major_index(self, parameter=None):
317
r"""
318
Returns the *major index generating polynomial* of ``self``,
319
which is a gadget counting the elements of ``self`` by major
320
index.
321
322
INPUT:
323
324
- ``parameter`` - an element of a ring. The result is
325
more explicit with a formal variable. (default:
326
element q of Univariate Polynomial Ring in q over
327
Integer Ring)
328
329
.. math::
330
331
P(q) = \sum_{g\in S_n} q^{ \operatorname{major\ index}(g) }
332
333
EXAMPLES::
334
335
sage: S4 = SymmetricGroup(4)
336
sage: S4.major_index()
337
q^6 + 3*q^5 + 5*q^4 + 6*q^3 + 5*q^2 + 3*q + 1
338
sage: K.<t> = QQ[]
339
sage: S4.major_index(t)
340
t^6 + 3*t^5 + 5*t^4 + 6*t^3 + 5*t^2 + 3*t + 1
341
"""
342
from sage.combinat.q_analogues import q_factorial
343
return q_factorial(self.degree(), parameter)
344
345
class AlternatingGroup(PermutationGroup_symalt):
346
def __init__(self, domain=None):
347
"""
348
The alternating group of order $n!/2$, as a permutation group.
349
350
INPUT:
351
352
``n`` -- a positive integer, or list or tuple thereof
353
354
EXAMPLES::
355
356
sage: G = AlternatingGroup(6)
357
sage: G.order()
358
360
359
sage: G
360
Alternating group of order 6!/2 as a permutation group
361
sage: G.category()
362
Category of finite permutation groups
363
sage: TestSuite(G).run()
364
365
sage: G = AlternatingGroup([1,2,4,5])
366
sage: G
367
Alternating group of order 4!/2 as a permutation group
368
sage: G.domain()
369
{1, 2, 4, 5}
370
sage: G.category()
371
Category of finite permutation groups
372
sage: TestSuite(G).run()
373
"""
374
PermutationGroup_symalt.__init__(self, gap_group='AlternatingGroup(%s)'%len(domain), domain=domain)
375
376
def _repr_(self):
377
"""
378
EXAMPLES:
379
sage: A = AlternatingGroup([2,3,7]); A
380
Alternating group of order 3!/2 as a permutation group
381
"""
382
return "Alternating group of order %s!/2 as a permutation group"%self.degree()
383
384
def _gap_init_(self, gap=None):
385
"""
386
Returns the string used to create this group in GAP.
387
388
EXAMPLES::
389
390
sage: A = AlternatingGroup(3)
391
sage: A._gap_init_()
392
'AlternatingGroup(3)'
393
sage: A = AlternatingGroup(['a', 'b', 'c'])
394
sage: A._gap_init_()
395
'AlternatingGroup(3)'
396
"""
397
return 'AlternatingGroup(%s)'%(self.degree())
398
399
class CyclicPermutationGroup(PermutationGroup_unique):
400
def __init__(self, n):
401
"""
402
A cyclic group of order n, as a permutation group.
403
404
INPUT:
405
n -- a positive integer
406
407
EXAMPLES::
408
409
sage: G = CyclicPermutationGroup(8)
410
sage: G.order()
411
8
412
sage: G
413
Cyclic group of order 8 as a permutation group
414
sage: G.category()
415
Category of finite permutation groups
416
sage: TestSuite(G).run()
417
sage: C = CyclicPermutationGroup(10)
418
sage: C.is_abelian()
419
True
420
sage: C = CyclicPermutationGroup(10)
421
sage: C.as_AbelianGroup()
422
Multiplicative Abelian Group isomorphic to C2 x C5
423
"""
424
n = Integer(n)
425
if n < 1:
426
raise ValueError, "n (=%s) must be >= 1"%n
427
gens = tuple(range(1, n+1))
428
PermutationGroup_generic.__init__(self, [gens], n)
429
430
def _repr_(self):
431
"""
432
EXAMPLES:
433
sage: CyclicPermutationGroup(8)
434
Cyclic group of order 8 as a permutation group
435
"""
436
return "Cyclic group of order %s as a permutation group"%self.order()
437
438
def is_commutative(self):
439
"""
440
Return True if this group is commutative.
441
442
EXAMPLES:
443
sage: C = CyclicPermutationGroup(8)
444
sage: C.is_commutative()
445
True
446
"""
447
return True
448
449
def is_abelian(self):
450
"""
451
Return True if this group is abelian.
452
453
EXAMPLES:
454
sage: C = CyclicPermutationGroup(8)
455
sage: C.is_abelian()
456
True
457
"""
458
return True
459
460
def as_AbelianGroup(self):
461
"""
462
Returns the corresponding Abelian Group instance.
463
464
EXAMPLES:
465
sage: C = CyclicPermutationGroup(8)
466
sage: C.as_AbelianGroup()
467
Multiplicative Abelian Group isomorphic to C8
468
469
"""
470
n = self.order()
471
a = list(factor(n))
472
invs = [x[0]**x[1] for x in a]
473
G = AbelianGroup(len(a), invs)
474
return G
475
476
class DiCyclicGroup(PermutationGroup_unique):
477
r"""
478
The dicyclic group of order `4n`, for `n\geq 2`.
479
480
INPUT:
481
- n -- a positive integer, two or greater
482
483
OUTPUT:
484
485
This is a nonabelian group similar in some respects to the
486
dihedral group of the same order, but with far fewer
487
elements of order 2 (it has just one). The permutation
488
representation constructed here is based on the presentation
489
490
.. MATH::
491
492
\langle a, x\mid a^{2n}=1, x^{2}=a^{n}, x^{-1}ax=a^{-1}\rangle
493
494
For `n=2` this is the group of quaternions
495
(`{\pm 1, \pm I,\pm J, \pm K}`), which is the nonabelian
496
group of order 8 that is not the dihedral group `D_4`,
497
the symmetries of a square. For `n=3` this is the nonabelian
498
group of order 12 that is not the dihedral group `D_6`
499
nor the alternating group `A_4`. This group of order 12 is
500
also the semi-direct product of of `C_2` by `C_4`,
501
`C_3\rtimes C_4`. [CONRAD2009]_
502
503
504
When the order of the group is a
505
power of 2 it is known as a "generalized quaternion group."
506
507
IMPLEMENTATION:
508
509
The presentation above means every element can be written as
510
`a^{i}x^{j}` with `0\leq i<2n`, `j=0,1`. We code `a^i` as the symbol
511
`i+1` and code `a^{i}x` as the symbol `2n+i+1`. The two generators
512
are then represented using a left regular representation.
513
514
EXAMPLES:
515
516
A dicyclic group of order 384, with a large power of 2 as a divisor::
517
518
sage: n = 3*2^5
519
sage: G = DiCyclicGroup(n)
520
sage: G.order()
521
384
522
sage: a = G.gen(0)
523
sage: x = G.gen(1)
524
sage: a^(2*n)
525
()
526
sage: a^n==x^2
527
True
528
sage: x^-1*a*x==a^-1
529
True
530
531
A large generalized quaternion group (order is a power of 2)::
532
533
sage: n = 2^10
534
sage: G=DiCyclicGroup(n)
535
sage: G.order()
536
4096
537
sage: a = G.gen(0)
538
sage: x = G.gen(1)
539
sage: a^(2*n)
540
()
541
sage: a^n==x^2
542
True
543
sage: x^-1*a*x==a^-1
544
True
545
546
Just like the dihedral group, the dicyclic group has
547
an element whose order is half the order of the group.
548
Unlike the dihedral group, the dicyclic group has only
549
one element of order 2. Like the dihedral groups of
550
even order, the center of the dicyclic group is a
551
subgroup of order 2 (thus has the unique element of
552
order 2 as its non-identity element). ::
553
554
sage: G=DiCyclicGroup(3*5*4)
555
sage: G.order()
556
240
557
sage: two = [g for g in G if g.order()==2]; two
558
[(1,5)(2,6)(3,7)(4,8)(9,13)(10,14)(11,15)(12,16)]
559
sage: G.center().order()
560
2
561
562
For small orders, we check this is really a group
563
we do not have in Sage otherwise. ::
564
565
sage: G = DiCyclicGroup(2)
566
sage: H = DihedralGroup(4)
567
sage: G.is_isomorphic(H)
568
False
569
sage: G = DiCyclicGroup(3)
570
sage: H = DihedralGroup(6)
571
sage: K = AlternatingGroup(6)
572
sage: G.is_isomorphic(H) or G.is_isomorphic(K)
573
False
574
575
REFERENCES:
576
577
.. [CONRAD2009] `Groups of order 12
578
<http://www.math.uconn.edu/~kconrad/blurbs/grouptheory/group12.pdf>`_.
579
Keith Conrad, accessed 21 October 2009.
580
581
AUTHOR:
582
- Rob Beezer (2009-10-18)
583
"""
584
def __init__(self, n):
585
r"""
586
The dicyclic group of order `4*n`, as a permutation group.
587
588
INPUT:
589
n -- a positive integer, two or greater
590
591
EXAMPLES:
592
sage: G = DiCyclicGroup(3*8)
593
sage: G.order()
594
96
595
sage: TestSuite(G).run()
596
"""
597
n = Integer(n)
598
if n < 2:
599
raise ValueError, "n (=%s) must be 2 or greater"%n
600
601
# Certainly 2^2 is part of the first factor of the order
602
# r is maximum power of 2 in the order
603
# m is the rest, the odd part
604
order = 4*n
605
factored = order.factor()
606
r = factored[0][0]**factored[0][1]
607
m = order//r
608
halfr, fourthr = r//2, r//4
609
610
# Representation of a
611
# Two cycles of length halfr
612
a = [tuple(range(1, halfr+1)), tuple(range(halfr+1, r+1))]
613
# With an odd part, a cycle of length m will give the right order for a
614
if m > 1:
615
a.append( tuple(range(r+1, r+m+1)) )
616
617
# Representation of x
618
# Four-cycles that will conjugate the generator a properly
619
x = [(i+1, (-i)%halfr + halfr + 1, (fourthr+i)%halfr + 1, (-fourthr-i)%halfr + halfr + 1)
620
for i in range(0, fourthr)]
621
# With an odd part, transpositions will conjugate the m-cycle to create inverse
622
if m > 1:
623
x += [(r+i+1, r+m-i) for i in range(0, (m-1)//2)]
624
625
PermutationGroup_generic.__init__(self, gens=[a, x])
626
627
def _repr_(self):
628
r"""
629
EXAMPLES:
630
sage: DiCyclicGroup(12)
631
Diyclic group of order 48 as a permutation group
632
"""
633
return "Diyclic group of order %s as a permutation group"%self.order()
634
635
def is_commutative(self):
636
r"""
637
Return True if this group is commutative.
638
639
EXAMPLES::
640
641
sage: D = DiCyclicGroup(12)
642
sage: D.is_commutative()
643
False
644
"""
645
return False
646
647
def is_abelian(self):
648
r"""
649
Return True if this group is abelian.
650
651
EXAMPLES::
652
653
sage: D = DiCyclicGroup(12)
654
sage: D.is_abelian()
655
False
656
"""
657
return False
658
659
class KleinFourGroup(PermutationGroup_unique):
660
def __init__(self):
661
r"""
662
The Klein 4 Group, which has order $4$ and exponent $2$, viewed
663
as a subgroup of $S_4$.
664
665
OUTPUT:
666
-- the Klein 4 group of order 4, as a permutation group of degree 4.
667
668
EXAMPLES:
669
sage: G = KleinFourGroup(); G
670
The Klein 4 group of order 4, as a permutation group
671
sage: list(G)
672
[(), (3,4), (1,2), (1,2)(3,4)]
673
674
TESTS::
675
676
sage: G.category()
677
Category of finite permutation groups
678
sage: TestSuite(G).run()
679
680
AUTHOR:
681
-- Bobby Moretti (2006-10)
682
"""
683
gens = [(1,2),(3,4)]
684
PermutationGroup_generic.__init__(self, gens)
685
686
def _repr_(self):
687
"""
688
EXAMPLES:
689
sage: G = KleinFourGroup(); G
690
The Klein 4 group of order 4, as a permutation group
691
"""
692
return 'The Klein 4 group of order 4, as a permutation group'
693
694
class QuaternionGroup(DiCyclicGroup):
695
r"""
696
The quaternion group of order 8.
697
698
OUTPUT:
699
The quaternion group of order 8, as a permutation group.
700
See the ``DiCyclicGroup`` class for a generalization of this
701
construction.
702
703
EXAMPLES:
704
705
The quaternion group is one of two non-abelian groups of order 8,
706
the other being the dihedral group `D_4`. One way to describe this
707
group is with three generators, `I, J, K`, so the whole group is
708
then given as the set `\{\pm 1, \pm I, \pm J, \pm K\}` with relations
709
such as `I^2=J^2=K^2=-1`, `IJ=K` and `JI=-K`.
710
711
The examples below illustrate how to use this group in a similar
712
manner, by testing some of these relations. The representation used
713
here is the left-regular representation. ::
714
715
sage: Q = QuaternionGroup()
716
sage: I = Q.gen(0)
717
sage: J = Q.gen(1)
718
sage: K = I*J
719
sage: [I,J,K]
720
[(1,2,3,4)(5,6,7,8), (1,5,3,7)(2,8,4,6), (1,8,3,6)(2,7,4,5)]
721
sage: neg_one = I^2; neg_one
722
(1,3)(2,4)(5,7)(6,8)
723
sage: J^2 == neg_one and K^2 == neg_one
724
True
725
sage: J*I == neg_one*K
726
True
727
sage: Q.center().order() == 2
728
True
729
sage: neg_one in Q.center()
730
True
731
732
AUTHOR:
733
-- Rob Beezer (2009-10-09)
734
"""
735
def __init__(self):
736
r"""
737
TESTS::
738
739
sage: Q = QuaternionGroup()
740
sage: TestSuite(Q).run()
741
"""
742
DiCyclicGroup.__init__(self, 2)
743
744
def _repr_(self):
745
r"""
746
EXAMPLES:
747
sage: Q=QuaternionGroup(); Q
748
Quaternion group of order 8 as a permutation group
749
"""
750
return "Quaternion group of order 8 as a permutation group"
751
752
class DihedralGroup(PermutationGroup_unique):
753
def __init__(self, n):
754
"""
755
The Dihedral group of order $2n$ for any integer $n\geq 1$.
756
757
INPUT:
758
n -- a positive integer
759
760
OUTPUT:
761
-- the dihedral group of order 2*n, as a permutation group
762
763
EXAMPLES:
764
sage: DihedralGroup(1)
765
Dihedral group of order 2 as a permutation group
766
767
sage: DihedralGroup(2)
768
Dihedral group of order 4 as a permutation group
769
sage: DihedralGroup(2).gens()
770
[(3,4), (1,2)]
771
772
sage: DihedralGroup(5).gens()
773
[(1,2,3,4,5), (1,5)(2,4)]
774
sage: list(DihedralGroup(5))
775
[(), (2,5)(3,4), (1,2)(3,5), (1,2,3,4,5), (1,3)(4,5), (1,3,5,2,4), (1,4)(2,3), (1,4,2,5,3), (1,5,4,3,2), (1,5)(2,4)]
776
777
sage: G = DihedralGroup(6)
778
sage: G.order()
779
12
780
sage: G = DihedralGroup(5)
781
sage: G.order()
782
10
783
sage: G
784
Dihedral group of order 10 as a permutation group
785
sage: G.gens()
786
[(1,2,3,4,5), (1,5)(2,4)]
787
788
sage: DihedralGroup(0)
789
Traceback (most recent call last):
790
...
791
ValueError: n must be positive
792
793
TESTS::
794
795
sage: TestSuite(G).run()
796
sage: G.category()
797
Category of finite permutation groups
798
sage: TestSuite(G).run()
799
"""
800
n = Integer(n)
801
if n <= 0:
802
raise ValueError, "n must be positive"
803
804
# the first generator generates the cyclic subgroup of D_n, <(1...n)> in
805
# cycle notation
806
gen0 = range(1,n+1)
807
808
if n < 1:
809
raise ValueError, "n (=%s) must be >= 1"%n
810
811
# D_1 is a subgroup of S_2, we need the cyclic group of order 2
812
if n == 1:
813
gens = CyclicPermutationGroup(2).gens()
814
elif n == 2:
815
gens = ((1,2),(3,4))
816
else:
817
gen1 = [(i, n-i+1) for i in range(1, n//2 +1)]
818
gens = tuple([tuple(gen0),tuple(gen1)])
819
820
PermutationGroup_generic.__init__(self, gens)
821
822
def _repr_(self):
823
"""
824
EXAMPLES:
825
sage: G = DihedralGroup(5); G
826
Dihedral group of order 10 as a permutation group
827
"""
828
return "Dihedral group of order %s as a permutation group"%self.order()
829
830
class MathieuGroup(PermutationGroup_unique):
831
def __init__(self, n):
832
"""
833
The Mathieu group of degree $n$.
834
835
INPUT:
836
n -- a positive integer in {9, 10, 11, 12, 21, 22, 23, 24}.
837
838
OUTPUT:
839
-- the Mathieu group of degree n, as a permutation group
840
841
EXAMPLES::
842
843
sage: G = MathieuGroup(12)
844
sage: G
845
Mathieu group of degree 12 and order 95040 as a permutation group
846
847
TESTS::
848
849
sage: G.category()
850
Category of finite permutation groups
851
sage: TestSuite(G).run(skip=["_test_enumerated_set_contains", "_test_enumerated_set_iter_list"])
852
853
Note: this is a fairly big group, so we skip some tests that
854
currently require to list all the elements of the group,
855
because there is no proper iterator yet.
856
"""
857
n = Integer(n)
858
self._n = n
859
if not(n in [9, 10, 11, 12, 21, 22, 23, 24]):
860
raise ValueError,"argument must belong to {9, 10, 11, 12, 21, 22, 23, 24}."
861
id = 'MathieuGroup(%s)'%n
862
PermutationGroup_generic.__init__(self, gap_group=id)
863
864
def _repr_(self):
865
"""
866
EXAMPLES:
867
sage: G = MathieuGroup(12); G
868
Mathieu group of degree 12 and order 95040 as a permutation group
869
"""
870
return "Mathieu group of degree %s and order %s as a permutation group"%(self._n,self.order())
871
872
class TransitiveGroup(PermutationGroup_unique):
873
def __init__(self, d, n):
874
"""
875
The transitive group from the GAP tables of transitive groups.
876
877
INPUT:
878
d -- positive integer; the degree
879
n -- positive integer; the number
880
881
OUTPUT:
882
the n-th transitive group of degree d
883
884
EXAMPLES::
885
886
sage: TransitiveGroup(0,1)
887
Transitive group number 1 of degree 0
888
sage: TransitiveGroup(1,1)
889
Transitive group number 1 of degree 1
890
sage: G = TransitiveGroup(5, 2); G # requires optional database_gap
891
Transitive group number 2 of degree 5
892
sage: G.gens() # requires optional database_gap
893
[(1,2,3,4,5), (1,4)(2,3)]
894
895
sage: G.category() # requires optional database_gap
896
Category of finite permutation groups
897
898
.. warning:: this follows GAP's naming convention of indexing
899
the transitive groups starting from ``1``::
900
901
sage: TransitiveGroup(5,0)
902
Traceback (most recent call last):
903
...
904
assert n > 0
905
AssertionError
906
907
.. warning:: only transitive groups of "small" degree are
908
available in GAP's database::
909
910
sage: TransitiveGroup(31,1) # requires optional database_gap
911
Traceback (most recent call last):
912
...
913
NotImplementedError: Only the transitive groups of order less than 30 are available in GAP's database
914
915
TESTS::
916
917
sage: TestSuite(TransitiveGroup(0,1)).run()
918
sage: TestSuite(TransitiveGroup(1,1)).run()
919
sage: TestSuite(TransitiveGroup(5,2)).run()# requires optional database_gap
920
921
sage: TransitiveGroup(1,5)
922
Traceback (most recent call last):
923
...
924
AssertionError: n should be in {1,..,1}
925
"""
926
d = ZZ(d)
927
n = ZZ(n)
928
assert d >= 0
929
assert n > 0
930
max_n = TransitiveGroups(d).cardinality()
931
assert n <= max_n, "n should be in {1,..,%s}"%max_n
932
gap_group = 'Group([()])' if d in [0,1] else 'TransitiveGroup(%s,%s)'%(d,n)
933
try:
934
PermutationGroup_generic.__init__(self, gap_group=gap_group)
935
except RuntimeError:
936
from sage.misc.misc import verbose
937
verbose("Warning: Computing with TransitiveGroups requires the optional database_gap package. Please install it.", level=0)
938
939
self._d = d
940
self._n = n
941
self._domain = range(1, d+1)
942
943
def _repr_(self):
944
"""
945
EXAMPLES:
946
sage: G = TransitiveGroup(1,1); G
947
Transitive group number 1 of degree 1
948
"""
949
return "Transitive group number %s of degree %s"%(self._n, self._d)
950
951
def TransitiveGroups(d=None):
952
"""
953
INPUT:
954
955
- ``d`` -- an integer (optional)
956
957
Returns the set of all transitive groups of a given degree
958
``d``. If ``d`` is not specified, it returns the set of all
959
transitive groups.
960
961
Warning: TransitiveGroups requires the optional GAP database
962
package. Please install it with ``sage -i database_gap``.
963
964
EXAMPLES::
965
966
sage: TransitiveGroups(3)
967
Transitive Groups of degree 3
968
sage: TransitiveGroups(7)
969
Transitive Groups of degree 7
970
sage: TransitiveGroups(8)
971
Transitive Groups of degree 8
972
973
sage: TransitiveGroups()
974
Transitive Groups
975
976
.. warning:: in practice, the database currently only contains
977
transitive groups up to degree 30::
978
979
sage: TransitiveGroups(31).cardinality() # requires optional database_gap
980
Traceback (most recent call last):
981
...
982
NotImplementedError: Only the transitive groups of order less than 30 are available in GAP's database
983
984
"""
985
if d == None:
986
return TransitiveGroupsAll()
987
else:
988
d == Integer(d)
989
assert d >= 0, "A transitive group acts on a non negative integer number of positions"
990
return TransitiveGroupsOfDegree(d)
991
992
class TransitiveGroupsAll(DisjointUnionEnumeratedSets):
993
"""
994
The infinite set of all transitive groups.
995
996
EXAMPLES::
997
998
sage: L = TransitiveGroups(); L
999
Transitive Groups
1000
sage: L.category()
1001
Category of infinite enumerated sets
1002
sage: L.cardinality()
1003
+Infinity
1004
1005
sage: p = L.__iter__() # requires optional database_gap
1006
sage: (p.next(), p.next(), p.next(), p.next(), p.next(), p.next(), p.next(), p.next()) # requires optional database_gap
1007
(Transitive group number 1 of degree 0, Transitive group number 1 of degree 1, Transitive group number 1 of degree 2, Transitive group number 1 of degree 3, Transitive group number 2 of degree 3, Transitive group number 1 of degree 4, Transitive group number 2 of degree 4, Transitive group number 3 of degree 4)
1008
1009
TESTS::
1010
1011
sage: TestSuite(TransitiveGroups()).run() # requires optional database_gap # long time
1012
"""
1013
def __init__(self):
1014
"""
1015
TESTS::
1016
1017
sage: S = TransitiveGroups() # requires optional database_gap
1018
sage: S.category() # requires optional database_gap
1019
Category of infinite enumerated sets
1020
"""
1021
DisjointUnionEnumeratedSets.__init__(self, Family(NonNegativeIntegers(), lambda i: TransitiveGroups(i)) )
1022
1023
def _repr_(self):
1024
"""
1025
TESTS::
1026
1027
sage: TransitiveGroups() # requires optional database_gap # indirect doctest
1028
Transitive Groups
1029
"""
1030
return "Transitive Groups"
1031
1032
def __contains__(self, G):
1033
r"""
1034
EXAMPLES::
1035
1036
sage: TransitiveGroup(5,2) in TransitiveGroups() # requires optional database_gap
1037
True
1038
sage: TransitiveGroup(6,5) in TransitiveGroups() # requires optional database_gap
1039
True
1040
sage: 1 in TransitiveGroups() # requires optional database_gap
1041
False
1042
"""
1043
return isinstance(G,TransitiveGroup)
1044
1045
def _an_element_(self):
1046
"""
1047
Returns an element of ``self``.
1048
1049
EXAMPLES::
1050
1051
sage: TransitiveGroups(5).an_element() # requires optional database_gap # indirect doctest
1052
Transitive group number 1 of degree 5
1053
"""
1054
return TransitiveGroup(7,3)
1055
1056
class TransitiveGroupsOfDegree(UniqueRepresentation, Parent):
1057
"""
1058
The set of all transitive groups of a given (small) degree.
1059
1060
EXAMPLES::
1061
1062
sage: S = TransitiveGroups(4); S # requires optional database_gap
1063
Transitive Groups of degree 4
1064
sage: list(S) # requires optional database_gap
1065
[Transitive group number 1 of degree 4, Transitive group number 2 of degree 4, Transitive group number 3 of degree 4, Transitive group number 4 of degree 4, Transitive group number 5 of degree 4]
1066
1067
sage: TransitiveGroups(5).an_element() # requires optional database_gap
1068
Transitive group number 1 of degree 5
1069
1070
We write the cardinality of all transitive groups of degree 5::
1071
1072
sage: for G in TransitiveGroups(5): # requires optional database_gap
1073
... print G.cardinality()
1074
5
1075
10
1076
20
1077
60
1078
120
1079
1080
TESTS::
1081
1082
sage: TestSuite(TransitiveGroups(3)).run() # requires optional database_gap
1083
1084
1085
"""
1086
def __init__(self, n):
1087
"""
1088
TESTS::
1089
1090
sage: S = TransitiveGroups(4) # requires optional database_gap
1091
sage: S.category() # requires optional database_gap
1092
Category of finite enumerated sets
1093
"""
1094
self._degree = n
1095
Parent.__init__(self, category = FiniteEnumeratedSets())
1096
1097
def _repr_(self):
1098
"""
1099
TESTS::
1100
1101
sage: TransitiveGroups(6) # requires optional database_gap
1102
Transitive Groups of degree 6
1103
"""
1104
return "Transitive Groups of degree %s"%(self._degree)
1105
1106
def __contains__(self, G):
1107
r"""
1108
EXAMPLES::
1109
1110
sage: TransitiveGroup(6,5) in TransitiveGroups(4) # requires optional database_gap
1111
False
1112
sage: TransitiveGroup(4,3) in TransitiveGroups(4) # requires optional database_gap
1113
True
1114
sage: 1 in TransitiveGroups(4) # requires optional database_gap
1115
False
1116
"""
1117
if isinstance(G,TransitiveGroup):
1118
return G._d == self._degree
1119
else:
1120
False
1121
1122
def __getitem__(self, n):
1123
r"""
1124
INPUT:
1125
1126
- ``n`` -- a positive integer
1127
1128
Returns the `n`-th transitive group of a given degree.
1129
1130
EXAMPLES::
1131
1132
sage: TransitiveGroups(5)[3] # requires optional database_gap#
1133
Transitive group number 3 of degree 5
1134
1135
.. warning:: this follows GAP's naming convention of indexing
1136
the transitive groups starting from ``1``::
1137
1138
sage: TransitiveGroups(5)[0]
1139
Traceback (most recent call last):
1140
...
1141
assert n > 0
1142
AssertionError
1143
"""
1144
return TransitiveGroup(self._degree, n)
1145
1146
def __iter__(self):
1147
"""
1148
EXAMPLES::
1149
1150
sage: list(TransitiveGroups(5)) # indirect doctest # requires optional database_gap
1151
[Transitive group number 1 of degree 5, Transitive group number 2 of degree 5, Transitive group number 3 of degree 5, Transitive group number 4 of degree 5, Transitive group number 5 of degree 5]
1152
"""
1153
for n in xrange(1, self.cardinality() + 1):
1154
yield self[n]
1155
1156
_an_element_ = EnumeratedSets.ParentMethods._an_element_
1157
1158
@cached_method
1159
def cardinality(self):
1160
r"""
1161
Returns the cardinality of ``self``, that is the number of
1162
transitive groups of a given degree.
1163
1164
EXAMPLES::
1165
1166
sage: TransitiveGroups(0).cardinality() # requires optional database_gap
1167
1
1168
sage: TransitiveGroups(2).cardinality() # requires optional database_gap
1169
1
1170
sage: TransitiveGroups(7).cardinality() # requires optional database_gap
1171
7
1172
sage: TransitiveGroups(12).cardinality() # requires optional database_gap
1173
301
1174
sage: [TransitiveGroups(i).cardinality() for i in range(11)] # requires optional database_gap
1175
[1, 1, 1, 2, 5, 5, 16, 7, 50, 34, 45]
1176
1177
.. warning::
1178
1179
The database_gap contains all transitive groups
1180
up to degree 30::
1181
1182
sage: TransitiveGroups(31).cardinality() # requires optional database_gap
1183
Traceback (most recent call last):
1184
...
1185
NotImplementedError: Only the transitive groups of order less than 30 are available in GAP's database
1186
1187
TESTS::
1188
1189
sage: type(TransitiveGroups(12).cardinality()) # requires optional database_gap
1190
<type 'sage.rings.integer.Integer'>
1191
sage: type(TransitiveGroups(0).cardinality())
1192
<type 'sage.rings.integer.Integer'>
1193
"""
1194
# gap.NrTransitiveGroups(0) fails, so Sage needs to handle this
1195
1196
# While we are at it, and since Sage also handles the
1197
# transitive group of degree 1, we may as well handle 1
1198
if self._degree <= 1:
1199
return ZZ(1)
1200
else:
1201
try:
1202
return Integer(gap.NrTransitiveGroups(gap(self._degree)))
1203
except RuntimeError:
1204
from sage.misc.misc import verbose
1205
verbose("Warning: TransitiveGroups requires the GAP database package. Please install it with ``sage -i database_gap``.", level=0)
1206
except TypeError:
1207
raise NotImplementedError, "Only the transitive groups of order less than 30 are available in GAP's database"
1208
1209
class PermutationGroup_plg(PermutationGroup_unique):
1210
def base_ring(self):
1211
"""
1212
EXAMPLES:
1213
sage: G = PGL(2,3)
1214
sage: G.base_ring()
1215
Finite Field of size 3
1216
1217
sage: G = PSL(2,3)
1218
sage: G.base_ring()
1219
Finite Field of size 3
1220
"""
1221
return self._base_ring
1222
1223
def matrix_degree(self):
1224
"""
1225
EXAMPLES:
1226
sage: G = PSL(2,3)
1227
sage: G.matrix_degree()
1228
2
1229
"""
1230
return self._n
1231
1232
class PGL(PermutationGroup_plg):
1233
def __init__(self, n, q, name='a'):
1234
"""
1235
The projective general linear groups over GF(q).
1236
1237
INPUT:
1238
n -- positive integer; the degree
1239
q -- prime power; the size of the ground field
1240
name -- (default: 'a') variable name of indeterminate of finite field GF(q)
1241
1242
OUTPUT:
1243
PGL(n,q)
1244
1245
EXAMPLES:
1246
sage: G = PGL(2,3); G
1247
Permutation Group with generators [(3,4), (1,2,4)]
1248
sage: print G
1249
The projective general linear group of degree 2 over Finite Field of size 3
1250
sage: G.base_ring()
1251
Finite Field of size 3
1252
sage: G.order()
1253
24
1254
1255
sage: G = PGL(2, 9, 'b'); G
1256
Permutation Group with generators [(3,10,9,8,4,7,6,5), (1,2,4)(5,6,8)(7,9,10)]
1257
sage: G.base_ring()
1258
Finite Field in b of size 3^2
1259
1260
sage: G.category()
1261
Category of finite permutation groups
1262
sage: TestSuite(G).run()
1263
"""
1264
id = 'Group([()])' if n == 1 else 'PGL(%s,%s)'%(n,q)
1265
PermutationGroup_generic.__init__(self, gap_group=id)
1266
self._q = q
1267
self._base_ring = GF(q, name=name)
1268
self._n = n
1269
1270
def __str__(self):
1271
"""
1272
EXAMPLES:
1273
sage: G = PGL(2,3); G
1274
Permutation Group with generators [(3,4), (1,2,4)]
1275
sage: print G
1276
The projective general linear group of degree 2 over Finite Field of size 3
1277
"""
1278
return "The projective general linear group of degree %s over %s"%(self._n, self.base_ring())
1279
1280
class PSL(PermutationGroup_plg):
1281
def __init__(self, n, q, name='a'):
1282
"""
1283
The projective special linear groups over GF(q).
1284
1285
INPUT:
1286
n -- positive integer; the degree
1287
q -- prime power; the size of the ground field
1288
name -- (default: 'a') variable name of indeterminate of finite field GF(q)
1289
1290
OUTPUT:
1291
PSL(n,q)
1292
1293
EXAMPLES:
1294
sage: G = PSL(2,3); G
1295
Permutation Group with generators [(2,3,4), (1,2)(3,4)]
1296
sage: G.order()
1297
12
1298
sage: G.base_ring()
1299
Finite Field of size 3
1300
sage: print G
1301
The projective special linear group of degree 2 over Finite Field of size 3
1302
1303
We create two groups over nontrivial finite fields:
1304
sage: G = PSL(2, 4, 'b'); G
1305
Permutation Group with generators [(3,4,5), (1,2,3)]
1306
sage: G.base_ring()
1307
Finite Field in b of size 2^2
1308
sage: G = PSL(2, 8); G
1309
Permutation Group with generators [(3,8,6,4,9,7,5), (1,2,3)(4,7,5)(6,9,8)]
1310
sage: G.base_ring()
1311
Finite Field in a of size 2^3
1312
1313
sage: G.category()
1314
Category of finite permutation groups
1315
sage: TestSuite(G).run()
1316
"""
1317
if n == 1:
1318
id = 'Group([()])'
1319
else:
1320
id = 'PSL(%s,%s)'%(n,q)
1321
PermutationGroup_generic.__init__(self, gap_group=id)
1322
self._q = q
1323
self._base_ring = GF(q, name=name)
1324
self._n = n
1325
1326
1327
def __str__(self):
1328
"""
1329
EXAMPLES:
1330
sage: G = PSL(2,3)
1331
sage: print G
1332
The projective special linear group of degree 2 over Finite Field of size 3
1333
"""
1334
return "The projective special linear group of degree %s over %s"%(self._n, self.base_ring())
1335
1336
def ramification_module_decomposition_hurwitz_curve(self):
1337
"""
1338
Helps compute the decomposition of the ramification module
1339
for the Hurwitz curves X (over CC say) with automorphism group
1340
G = PSL(2,q), q a "Hurwitz prime" (ie, p is $\pm 1 \pmod 7$).
1341
Using this computation and Borne's formula helps determine the
1342
G-module structure of the RR spaces of equivariant
1343
divisors can be determined explicitly.
1344
1345
The output is a list of integer multiplicities: [m1,...,mn],
1346
where n is the number of conj classes of G=PSL(2,p) and mi is the
1347
multiplicity of pi_i in the ramification module of a
1348
Hurwitz curve with automorphism group G.
1349
Here IrrRepns(G) = [pi_1,...,pi_n] (in the order listed in the
1350
output of self.character_table()).
1351
1352
REFERENCE: David Joyner, Amy Ksir, Roger Vogeler,
1353
"Group representations on Riemann-Roch spaces of some
1354
Hurwitz curves," preprint, 2006.
1355
1356
EXAMPLES:
1357
sage: G = PSL(2,13)
1358
sage: G.ramification_module_decomposition_hurwitz_curve() #random
1359
[0, 7, 7, 12, 12, 12, 13, 15, 14]
1360
1361
This means, for example, that the trivial representation does not
1362
occur in the ramification module of a Hurwitz curve with automorphism
1363
group PSL(2,13), since the trivial representation is listed first
1364
and that entry has multiplicity 0. The "randomness" is due to the
1365
fact that GAP randomly orders the conjugacy classes of the same order
1366
in the list of all conjugacy classes. Similarly, there is some
1367
randomness to the ordering of the characters.
1368
1369
If you try to use this function on a group PSL(2,q) where q is
1370
not a (smallish) "Hurwitz prime", an error message will be printed.
1371
"""
1372
if self.matrix_degree()!=2:
1373
raise ValueError("Degree must be 2.")
1374
F = self.base_ring()
1375
q = F.order()
1376
from sage.misc.misc import SAGE_EXTCODE
1377
gapcode = SAGE_EXTCODE + '/gap/joyner/hurwitz_crv_rr_sp.gap'
1378
gap.eval('Read("'+gapcode+'")')
1379
mults = gap.eval("ram_module_hurwitz("+str(q)+")")
1380
return eval(mults)
1381
1382
def ramification_module_decomposition_modular_curve(self):
1383
"""
1384
Helps compute the decomposition of the ramification module
1385
for the modular curve X(p) (over CC say) with automorphism group G = PSL(2,q),
1386
q a prime > 5. Using this computation and Borne's formula helps determine the
1387
G-module structure of the RR spaces of equivariant
1388
divisors can be determined explicitly.
1389
1390
The output is a list of integer multiplicities: [m1,...,mn],
1391
where n is the number of conj classes of G=PSL(2,p) and mi is the
1392
multiplicity of pi_i in the ramification module of a
1393
modular curve with automorphism group G.
1394
Here IrrRepns(G) = [pi_1,...,pi_n] (in the order listed in the
1395
output of self.character_table()).
1396
1397
REFERENCE: D. Joyner and A. Ksir, 'Modular representations
1398
on some Riemann-Roch spaces of modular curves
1399
$X(N)$', Computational Aspects of Algebraic Curves,
1400
(Editor: T. Shaska) Lecture Notes in Computing, WorldScientific,
1401
2005.)
1402
1403
EXAMPLES:
1404
sage: G = PSL(2,7)
1405
sage: G.ramification_module_decomposition_modular_curve() ## random
1406
[0, 4, 3, 6, 7, 8]
1407
1408
This means, for example, that the trivial representation does not
1409
occur in the ramification module of X(7), since the trivial representation
1410
is listed first and that entry has multiplicity 0. The "randomness" is due to the
1411
fact that GAP randomly orders the conjugacy classes of the same order
1412
in the list of all conjugacy classes. Similarly, there is some
1413
randomness to the ordering of the characters.
1414
"""
1415
if self.matrix_degree()!=2:
1416
raise ValueError("Degree must be 2.")
1417
F = self.base_ring()
1418
q = F.order()
1419
from sage.misc.misc import SAGE_EXTCODE
1420
gapcode = SAGE_EXTCODE + '/gap/joyner/modular_crv_rr_sp.gap'
1421
gap.eval('Read("'+gapcode+'")')
1422
mults = gap.eval("ram_module_X("+str(q)+")")
1423
return eval(mults)
1424
1425
class PSp(PermutationGroup_plg):
1426
def __init__(self, n, q, name='a'):
1427
"""
1428
The projective symplectic linear groups over GF(q).
1429
1430
INPUT:
1431
n -- positive integer; the degree
1432
q -- prime power; the size of the ground field
1433
name -- (default: 'a') variable name of indeterminate of finite field GF(q)
1434
1435
OUTPUT:
1436
PSp(n,q)
1437
1438
EXAMPLES:
1439
sage: G = PSp(2,3); G
1440
Permutation Group with generators [(2,3,4), (1,2)(3,4)]
1441
sage: G.order()
1442
12
1443
sage: G = PSp(4,3); G
1444
Permutation Group with generators [(3,4)(6,7)(9,10)(12,13)(17,20)(18,21)(19,22)(23,32)(24,33)(25,34)(26,38)(27,39)(28,40)(29,35)(30,36)(31,37), (1,5,14,17,27,22,19,36,3)(2,6,32)(4,7,23,20,37,13,16,26,40)(8,24,29,30,39,10,33,11,34)(9,15,35)(12,25,38)(21,28,31)]
1445
sage: G.order()
1446
25920
1447
sage: print G
1448
The projective symplectic linear group of degree 4 over Finite Field of size 3
1449
sage: G.base_ring()
1450
Finite Field of size 3
1451
1452
sage: G = PSp(2, 8, name='alpha'); G
1453
Permutation Group with generators [(3,8,6,4,9,7,5), (1,2,3)(4,7,5)(6,9,8)]
1454
sage: G.base_ring()
1455
Finite Field in alpha of size 2^3
1456
"""
1457
if n%2 == 1:
1458
raise TypeError, "The degree n must be even"
1459
else:
1460
id = 'PSp(%s,%s)'%(n,q)
1461
PermutationGroup_generic.__init__(self, gap_group=id)
1462
self._q = q
1463
self._base_ring = GF(q, name=name)
1464
self._n = n
1465
1466
def __str__(self):
1467
"""
1468
EXAMPLES:
1469
sage: G = PSp(4,3)
1470
sage: print G
1471
The projective symplectic linear group of degree 4 over Finite Field of size 3
1472
"""
1473
return "The projective symplectic linear group of degree %s over %s"%(self._n, self.base_ring())
1474
1475
PSP = PSp
1476
1477
class PermutationGroup_pug(PermutationGroup_plg):
1478
def field_of_definition(self):
1479
"""
1480
EXAMPLES:
1481
sage: PSU(2,3).field_of_definition()
1482
Finite Field in a of size 3^2
1483
"""
1484
return self._field_of_definition
1485
1486
class PSU(PermutationGroup_pug):
1487
def __init__(self, n, q, name='a'):
1488
"""
1489
The projective special unitary groups over GF(q).
1490
1491
INPUT:
1492
n -- positive integer; the degree
1493
q -- prime power; the size of the ground field
1494
name -- (default: 'a') variable name of indeterminate of finite field GF(q)
1495
OUTPUT:
1496
PSU(n,q)
1497
1498
EXAMPLES:
1499
sage: PSU(2,3)
1500
The projective special unitary group of degree 2 over Finite Field of size 3
1501
1502
sage: G = PSU(2, 8, name='alpha'); G
1503
The projective special unitary group of degree 2 over Finite Field in alpha of size 2^3
1504
sage: G.base_ring()
1505
Finite Field in alpha of size 2^3
1506
"""
1507
id = 'PSU(%s,%s)'%(n,q)
1508
PermutationGroup_generic.__init__(self, gap_group=id)
1509
self._q = q
1510
self._base_ring = GF(q, name=name)
1511
self._field_of_definition = GF(q**2, name)
1512
self._n = n
1513
1514
def _repr_(self):
1515
"""
1516
EXAMPLES:
1517
sage: PSU(2,3)
1518
The projective special unitary group of degree 2 over Finite Field of size 3
1519
1520
"""
1521
return "The projective special unitary group of degree %s over %s"%(self._n, self.base_ring())
1522
1523
class PGU(PermutationGroup_pug):
1524
def __init__(self, n, q, name='a'):
1525
"""
1526
The projective general unitary groups over GF(q).
1527
1528
INPUT:
1529
n -- positive integer; the degree
1530
q -- prime power; the size of the ground field
1531
name -- (default: 'a') variable name of indeterminate of finite field GF(q)
1532
1533
OUTPUT:
1534
PGU(n,q)
1535
1536
EXAMPLES:
1537
sage: PGU(2,3)
1538
The projective general unitary group of degree 2 over Finite Field of size 3
1539
1540
sage: G = PGU(2, 8, name='alpha'); G
1541
The projective general unitary group of degree 2 over Finite Field in alpha of size 2^3
1542
sage: G.base_ring()
1543
Finite Field in alpha of size 2^3
1544
"""
1545
id = 'PGU(%s,%s)'%(n,q)
1546
PermutationGroup_generic.__init__(self, gap_group=id)
1547
self._q = q
1548
self._base_ring = GF(q, name=name)
1549
self._field_of_definition = GF(q**2, name)
1550
self._n = n
1551
1552
def _repr_(self):
1553
"""
1554
EXAMPLES:
1555
sage: PGU(2,3)
1556
The projective general unitary group of degree 2 over Finite Field of size 3
1557
1558
"""
1559
return "The projective general unitary group of degree %s over %s"%(self._n, self.base_ring())
1560
1561
1562
class SuzukiGroup(PermutationGroup_unique):
1563
def __init__(self, q, name='a'):
1564
r"""
1565
The Suzuki group over GF(q),
1566
$^2 B_2(2^{2k+1}) = Sz(2^{2k+1})$.
1567
1568
A wrapper for the GAP function SuzukiGroup.
1569
1570
INPUT:
1571
q -- 2^n, an odd power of 2; the size of the ground
1572
field. (Strictly speaking, n should be greater than 1, or
1573
else this group os not simple.)
1574
name -- (default: 'a') variable name of indeterminate of
1575
finite field GF(q)
1576
1577
OUTPUT:
1578
1579
- A Suzuki group.
1580
1581
EXAMPLES::
1582
1583
sage: SuzukiGroup(8)
1584
Permutation Group with generators [(1,2)(3,10)(4,42)(5,18)(6,50)(7,26)(8,58)(9,34)(12,28)(13,45)(14,44)(15,23)(16,31)(17,21)(19,39)(20,38)(22,25)(24,61)(27,60)(29,65)(30,55)(32,33)(35,52)(36,49)(37,59)(40,54)(41,62)(43,53)(46,48)(47,56)(51,63)(57,64), (1,28,10,44)(3,50,11,42)(4,43,53,64)(5,9,39,52)(6,36,63,13)(7,51,60,57)(8,33,37,16)(12,24,55,29)(14,30,48,47)(15,19,61,54)(17,59,22,62)(18,23,34,31)(20,38,49,25)(21,26,45,58)(27,32,41,65)(35,46,40,56)]
1585
sage: print SuzukiGroup(8)
1586
The Suzuki group over Finite Field in a of size 2^3
1587
1588
sage: G = SuzukiGroup(32, name='alpha')
1589
sage: G.order()
1590
32537600
1591
sage: G.order().factor()
1592
2^10 * 5^2 * 31 * 41
1593
sage: G.base_ring()
1594
Finite Field in alpha of size 2^5
1595
1596
REFERENCES:
1597
1598
- http://en.wikipedia.org/wiki/Group_of_Lie_type\#Suzuki-Ree_groups
1599
"""
1600
q = Integer(q)
1601
from sage.rings.arith import valuation
1602
t = valuation(q, 2)
1603
if 2**t != q or is_even(t):
1604
raise ValueError,"The ground field size %s must be an odd power of 2."%q
1605
id = 'SuzukiGroup(IsPermGroup,%s)'%q
1606
PermutationGroup_generic.__init__(self, gap_group=id)
1607
self._q = q
1608
self._base_ring = GF(q, name=name)
1609
1610
def base_ring(self):
1611
"""
1612
EXAMPLES:
1613
sage: G = SuzukiGroup(32, name='alpha')
1614
sage: G.base_ring()
1615
Finite Field in alpha of size 2^5
1616
1617
"""
1618
return self._base_ring
1619
1620
def __str__(self):
1621
"""
1622
EXAMPLES:
1623
sage: G = SuzukiGroup(32, name='alpha')
1624
sage: print G
1625
The Suzuki group over Finite Field in alpha of size 2^5
1626
1627
"""
1628
return "The Suzuki group over %s"%self.base_ring()
1629
1630
1631
1632
1633
1634
1635
1636
1637