Path: blob/master/src/sage/groups/perm_gps/permgroup_named.py
8815 views
r"""1"Named" Permutation groups (such as the symmetric group, S_n)23You can construct the following permutation groups:45-- SymmetricGroup, $S_n$ of order $n!$ (n can also be a list $X$ of distinct6positive integers, in which case it returns $S_X$)78-- AlternatingGroup, $A_n$ or order $n!/2$ (n can also be a list $X$9of distinct positive integers, in which case it returns10$A_X$)1112-- DihedralGroup, $D_n$ of order $2n$1314-- GeneralDihedralGroup, $Dih(G)$, where G is an abelian group1516-- CyclicPermutationGroup, $C_n$ of order $n$1718-- DiCyclicGroup, nonabelian groups of order `4m` with a unique element of order 21920-- TransitiveGroup, $n^{th}$ transitive group of degree $d$21from the GAP tables of transitive groups (requires22the "optional" package database_gap)2324-- TransitiveGroups(d), TransitiveGroups(), set of all of the above2526-- PrimitiveGroup, $n^{th}$ primitive group of degree $d$27from the GAP tables of primitive groups (requires28the "optional" package database_gap)2930-- PrimitiveGroups(d), PrimitiveGroups(), set of all of the above3132-- MathieuGroup(degree), Mathieu group of degree 9, 10, 11, 12, 21, 22, 23, or 24.3334-- KleinFourGroup, subgroup of $S_4$ of order $4$ which is not $C_2 \times C_2$3536-- QuaternionGroup, non-abelian group of order `8`, `\{\pm 1, \pm I, \pm J, \pm K\}`3738-- SplitMetacyclicGroup, nonabelian groups of order `p^m` with cyclic39subgroups of index p4041-- SemidihedralGroup, nonabelian 2-groups with cyclic subgroups of index 24243-- PGL(n,q), projective general linear group of $n\times n$ matrices over44the finite field GF(q)4546-- PSL(n,q), projective special linear group of $n\times n$ matrices over47the finite field GF(q)4849-- PSp(2n,q), projective symplectic linear group of $2n\times 2n$ matrices50over the finite field GF(q)5152-- PSU(n,q), projective special unitary group of $n \times n$ matrices having53coefficients in the finite field $GF(q^2)$ that respect a54fixed nondegenerate sesquilinear form, of determinant 1.5556-- PGU(n,q), projective general unitary group of $n\times n$ matrices having57coefficients in the finite field $GF(q^2)$ that respect a58fixed nondegenerate sesquilinear form, modulo the centre.5960-- SuzukiGroup(q), Suzuki group over GF(q), $^2 B_2(2^{2k+1}) = Sz(2^{2k+1})$.616263AUTHOR:64- David Joyner (2007-06): split from permgp.py (suggested by Nick Alexander)6566REFERENCES:67Cameron, P., Permutation Groups. New York: Cambridge University Press, 1999.68Wielandt, H., Finite Permutation Groups. New York: Academic Press, 1964.69Dixon, J. and Mortimer, B., Permutation Groups, Springer-Verlag, Berlin/New York, 1996.7071NOTE:72Though Suzuki groups are okay, Ree groups should *not* be wrapped as73permutation groups - the construction is too slow - unless (for74small values or the parameter) they are made using explicit generators.75"""7677#*****************************************************************************78# Copyright (C) 2006 William Stein <[email protected]>79# David Joyner <[email protected]>80#81# Distributed under the terms of the GNU General Public License (GPL)82# http://www.gnu.org/licenses/83#*****************************************************************************8485from sage.rings.all import Integer86from sage.interfaces.all import gap87from sage.rings.finite_rings.constructor import FiniteField as GF88from sage.rings.arith import factor89from sage.groups.abelian_gps.abelian_group import AbelianGroup90from sage.misc.functional import is_even91from sage.misc.cachefunc import cached_method, weak_cached_function92from sage.misc.classcall_metaclass import typecall93from sage.misc.superseded import deprecated_function_alias94from sage.groups.perm_gps.permgroup import PermutationGroup_generic95from sage.groups.perm_gps.permgroup_element import PermutationGroupElement96from sage.structure.unique_representation import CachedRepresentation97from sage.structure.parent import Parent98from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets99from sage.sets.finite_enumerated_set import FiniteEnumeratedSet100from sage.sets.disjoint_union_enumerated_sets import DisjointUnionEnumeratedSets101from sage.categories.enumerated_sets import EnumeratedSets102from sage.sets.non_negative_integers import NonNegativeIntegers103from sage.sets.family import Family104from sage.sets.primes import Primes105106class PermutationGroup_unique(CachedRepresentation, PermutationGroup_generic):107"""108.. TODO::109110Fix the broken hash.111::112113sage: G = SymmetricGroup(6)114sage: G3 = G.subgroup([G((1,2,3,4,5,6)),G((1,2))])115sage: hash(G) == hash(G3) # todo: Should be True!116False117"""118@weak_cached_function119def __classcall__(cls, *args, **kwds):120"""121This makes sure that domain is a FiniteEnumeratedSet before it gets passed122on to the __init__ method.123124EXAMPLES::125126sage: SymmetricGroup(['a','b']).domain() #indirect doctest127{'a', 'b'}128"""129domain = kwds.pop('domain', None)130if domain is not None:131if domain not in FiniteEnumeratedSets():132domain = FiniteEnumeratedSet(domain)133kwds['domain'] = domain134return super(PermutationGroup_unique, cls).__classcall__(cls, *args, **kwds)135136def __eq__(self, other):137"""138EXAMPLES::139140sage: G = SymmetricGroup(6)141sage: G3 = G.subgroup([G((1,2,3,4,5,6)),G((1,2))])142sage: G == G3143True144145.. WARNING::146147The hash currently is broken for this comparison.148"""149return self.__cmp__(other) == 0150151152class PermutationGroup_symalt(PermutationGroup_unique):153"""154This is a class used to factor out some of the commonality155in the SymmetricGroup and AlternatingGroup classes.156"""157158@staticmethod159def __classcall__(cls, domain):160"""161Normalizes the input of the constructor into a set162163INPUT:164165- ``n`` - an integer or list or tuple thereof166167Calls the constructor with a tuple representing the set.168169EXAMPLES::170171sage: S1 = SymmetricGroup(4)172sage: S2 = SymmetricGroup([1,2,3,4])173sage: S3 = SymmetricGroup((1,2,3,4))174sage: S1 is S2175True176sage: S1 is S3177True178179TESTS::180181sage: SymmetricGroup(0)182Symmetric group of order 0! as a permutation group183sage: SymmetricGroup(1)184Symmetric group of order 1! as a permutation group185sage: SymmetricGroup(-1)186Traceback (most recent call last):187...188ValueError: domain (=-1) must be an integer >= 0 or a list189"""190if domain not in FiniteEnumeratedSets():191if not isinstance(domain, (tuple, list)):192try:193domain = Integer(domain)194except TypeError:195raise ValueError("domain (=%s) must be an integer >= 0 or a finite set (but domain has type %s)"%(domain,type(domain)))196197if domain < 0:198raise ValueError("domain (=%s) must be an integer >= 0 or a list"%domain)199else:200domain = range(1, domain+1)201v = FiniteEnumeratedSet(domain)202else:203v = domain204205return super(PermutationGroup_symalt, cls).__classcall__(cls, domain=v)206207set = deprecated_function_alias(10335, PermutationGroup_generic.domain)208209class SymmetricGroup(PermutationGroup_symalt):210def __init__(self, domain=None):211"""212The full symmetric group of order $n!$, as a permutation group.213If n is a list or tuple of positive integers then it returns the214symmetric group of the associated set.215216INPUT:217218- ``n`` - a positive integer, or list or tuple thereof219220.. note::221This group is also available via ``groups.permutation.Symmetric()``.222223EXAMPLES::224225sage: G = SymmetricGroup(8)226sage: G.order()22740320228sage: G229Symmetric group of order 8! as a permutation group230sage: G.degree()2318232sage: S8 = SymmetricGroup(8)233sage: G = SymmetricGroup([1,2,4,5])234sage: G235Symmetric group of order 4! as a permutation group236sage: G.domain()237{1, 2, 4, 5}238sage: G = SymmetricGroup(4)239sage: G240Symmetric group of order 4! as a permutation group241sage: G.domain()242{1, 2, 3, 4}243sage: G.category()244Join of Category of finite permutation groups and Category of finite weyl groups245sage: TestSuite(G).run()246247TESTS::248249sage: TestSuite(SymmetricGroup(0)).run()250251sage: groups.permutation.Symmetric(4)252Symmetric group of order 4! as a permutation group253"""254from sage.categories.finite_weyl_groups import FiniteWeylGroups255from sage.categories.finite_permutation_groups import FinitePermutationGroups256from sage.categories.category import Category257258#Note that we skip the call to the superclass initializer in order to259#avoid infinite recursion since SymmetricGroup is called by260#PermutationGroupElement261super(PermutationGroup_generic, self).__init__(category = Category.join([FinitePermutationGroups(), FiniteWeylGroups()]))262263self._domain = domain264self._deg = len(self._domain)265self._domain_to_gap = dict((key, i+1) for i, key in enumerate(self._domain))266self._domain_from_gap = dict((i+1, key) for i, key in enumerate(self._domain))267268#Create the generators for the symmetric group269gens = [ tuple(self._domain) ]270if len(self._domain) > 2:271gens.append( tuple(self._domain[:2]) )272self._gens = [PermutationGroupElement(g, self, check=False) for g in gens]273274275def _gap_init_(self, gap=None):276"""277Returns the string used to create this group in GAP.278279EXAMPLES::280281sage: S = SymmetricGroup(3)282sage: S._gap_init_()283'SymmetricGroup(3)'284sage: S = SymmetricGroup(['a', 'b', 'c'])285sage: S._gap_init_()286'SymmetricGroup(3)'287"""288return 'SymmetricGroup(%s)'%self.degree()289290@cached_method291def index_set(self):292"""293Indexing sets of descent of the symmetric group.294295EXAMPLES::296297sage: S8 = SymmetricGroup(8)298sage: S8.index_set()299[1, 2, 3, 4, 5, 6, 7]300301sage: S = SymmetricGroup([3,1,4,5])302sage: S.index_set()303[3, 1, 4]304"""305return self.domain()[:-1]306307def __cmp__(self, x):308"""309Fast comparison for SymmetricGroups.310311EXAMPLES::312313sage: S8 = SymmetricGroup(8)314sage: S3 = SymmetricGroup(3)315sage: S8 > S3316True317"""318if isinstance(x, SymmetricGroup):319return cmp((self._deg, self._domain), (x._deg, x._domain))320else:321return PermutationGroup_generic.__cmp__(self, x)322323def _repr_(self):324"""325EXAMPLES::326327sage: A = SymmetricGroup([2,3,7]); A328Symmetric group of order 3! as a permutation group329"""330return "Symmetric group of order %s! as a permutation group"%self.degree()331332def simple_reflection(self, i):333"""334For `i` in the index set of ``self``, this returns the335elementary transposition `s_i=(i,i+1)`.336337EXAMPLES::338339sage: A = SymmetricGroup(5)340sage: A.simple_reflection(3)341(3,4)342343sage: A = SymmetricGroup([2,3,7])344sage: A.simple_reflections()345Finite family {2: (2,3), 3: (3,7)}346"""347return self([(i, self._domain[self._domain.index(i)+1])], check=False)348349def young_subgroup(self, comp):350"""351Return the Young subgroup associated with the composition ``comp``.352353EXAMPLES::354355sage: S = SymmetricGroup(8)356sage: c = Composition([2,2,2,2])357sage: S.young_subgroup(c)358Subgroup of (Symmetric group of order 8! as a permutation group) generated by [(7,8), (5,6), (3,4), (1,2)]359360sage: S = SymmetricGroup(['a','b','c'])361sage: S.young_subgroup([2,1])362Subgroup of (Symmetric group of order 3! as a permutation group) generated by [('a','b')]363364sage: Y = S.young_subgroup([2,2,2,2,2])365Traceback (most recent call last):366...367ValueError: The composition is not of expected size368"""369if sum(comp) != self.degree():370raise ValueError('The composition is not of expected size')371372domain = self.domain()373gens = []374pos = 0375for c in comp:376for i in range(c-1):377gens.append(self((domain[pos + i], domain[pos + i + 1])))378pos += c379380return self.subgroup(gens)381382def major_index(self, parameter=None):383r"""384Returns the *major index generating polynomial* of ``self``,385which is a gadget counting the elements of ``self`` by major386index.387388INPUT:389390- ``parameter`` - an element of a ring. The result is391more explicit with a formal variable. (default:392element q of Univariate Polynomial Ring in q over393Integer Ring)394395.. math::396397P(q) = \sum_{g\in S_n} q^{ \operatorname{major\ index}(g) }398399EXAMPLES::400401sage: S4 = SymmetricGroup(4)402sage: S4.major_index()403q^6 + 3*q^5 + 5*q^4 + 6*q^3 + 5*q^2 + 3*q + 1404sage: K.<t> = QQ[]405sage: S4.major_index(t)406t^6 + 3*t^5 + 5*t^4 + 6*t^3 + 5*t^2 + 3*t + 1407"""408from sage.combinat.q_analogues import q_factorial409return q_factorial(self.degree(), parameter)410411class AlternatingGroup(PermutationGroup_symalt):412def __init__(self, domain=None):413"""414The alternating group of order $n!/2$, as a permutation group.415416INPUT:417418``n`` -- a positive integer, or list or tuple thereof419420.. note::421This group is also available via ``groups.permutation.Alternating()``.422423EXAMPLES::424425sage: G = AlternatingGroup(6)426sage: G.order()427360428sage: G429Alternating group of order 6!/2 as a permutation group430sage: G.category()431Category of finite permutation groups432sage: TestSuite(G).run()433434sage: G = AlternatingGroup([1,2,4,5])435sage: G436Alternating group of order 4!/2 as a permutation group437sage: G.domain()438{1, 2, 4, 5}439sage: G.category()440Category of finite permutation groups441sage: TestSuite(G).run()442443TESTS::444445sage: groups.permutation.Alternating(6)446Alternating group of order 6!/2 as a permutation group447"""448PermutationGroup_symalt.__init__(self, gap_group='AlternatingGroup(%s)'%len(domain), domain=domain)449450def _repr_(self):451"""452EXAMPLES::453454sage: A = AlternatingGroup([2,3,7]); A455Alternating group of order 3!/2 as a permutation group456"""457return "Alternating group of order %s!/2 as a permutation group"%self.degree()458459def _gap_init_(self, gap=None):460"""461Returns the string used to create this group in GAP.462463EXAMPLES::464465sage: A = AlternatingGroup(3)466sage: A._gap_init_()467'AlternatingGroup(3)'468sage: A = AlternatingGroup(['a', 'b', 'c'])469sage: A._gap_init_()470'AlternatingGroup(3)'471"""472return 'AlternatingGroup(%s)'%(self.degree())473474class CyclicPermutationGroup(PermutationGroup_unique):475def __init__(self, n):476"""477A cyclic group of order n, as a permutation group.478479INPUT:480n -- a positive integer481482.. note::483This group is also available via ``groups.permutation.Cyclic()``.484485EXAMPLES::486487sage: G = CyclicPermutationGroup(8)488sage: G.order()4898490sage: G491Cyclic group of order 8 as a permutation group492sage: G.category()493Category of finite permutation groups494sage: TestSuite(G).run()495sage: C = CyclicPermutationGroup(10)496sage: C.is_abelian()497True498sage: C = CyclicPermutationGroup(10)499sage: C.as_AbelianGroup()500Multiplicative Abelian group isomorphic to C2 x C5501502TESTS::503504sage: groups.permutation.Cyclic(6)505Cyclic group of order 6 as a permutation group506"""507n = Integer(n)508if n < 1:509raise ValueError("n (=%s) must be >= 1" % n)510gens = tuple(range(1, n+1))511PermutationGroup_generic.__init__(self, [gens], n)512513def _repr_(self):514"""515EXAMPLES::516517sage: CyclicPermutationGroup(8)518Cyclic group of order 8 as a permutation group519"""520return "Cyclic group of order %s as a permutation group"%self.order()521522def is_commutative(self):523"""524Return True if this group is commutative.525526EXAMPLES::527528sage: C = CyclicPermutationGroup(8)529sage: C.is_commutative()530True531"""532return True533534def is_abelian(self):535"""536Return True if this group is abelian.537538EXAMPLES::539540sage: C = CyclicPermutationGroup(8)541sage: C.is_abelian()542True543"""544return True545546def as_AbelianGroup(self):547"""548Returns the corresponding Abelian Group instance.549550EXAMPLES::551552sage: C = CyclicPermutationGroup(8)553sage: C.as_AbelianGroup()554Multiplicative Abelian group isomorphic to C8555"""556n = self.order()557a = list(factor(n))558invs = [x[0]**x[1] for x in a]559G = AbelianGroup(len(a), invs)560return G561562class DiCyclicGroup(PermutationGroup_unique):563r"""564The dicyclic group of order `4n`, for `n\geq 2`.565566INPUT:567- n -- a positive integer, two or greater568569OUTPUT:570571This is a nonabelian group similar in some respects to the572dihedral group of the same order, but with far fewer573elements of order 2 (it has just one). The permutation574representation constructed here is based on the presentation575576.. MATH::577578\langle a, x\mid a^{2n}=1, x^{2}=a^{n}, x^{-1}ax=a^{-1}\rangle579580For `n=2` this is the group of quaternions581(`{\pm 1, \pm I,\pm J, \pm K}`), which is the nonabelian582group of order 8 that is not the dihedral group `D_4`,583the symmetries of a square. For `n=3` this is the nonabelian584group of order 12 that is not the dihedral group `D_6`585nor the alternating group `A_4`. This group of order 12 is586also the semi-direct product of of `C_2` by `C_4`,587`C_3\rtimes C_4`. [CONRAD2009]_588589590When the order of the group is a591power of 2 it is known as a "generalized quaternion group."592593IMPLEMENTATION:594595The presentation above means every element can be written as596`a^{i}x^{j}` with `0\leq i<2n`, `j=0,1`. We code `a^i` as the symbol597`i+1` and code `a^{i}x` as the symbol `2n+i+1`. The two generators598are then represented using a left regular representation.599600.. note::601This group is also available via ``groups.permutation.DiCyclic()``.602603EXAMPLES:604605A dicyclic group of order 384, with a large power of 2 as a divisor::606607sage: n = 3*2^5608sage: G = DiCyclicGroup(n)609sage: G.order()610384611sage: a = G.gen(0)612sage: x = G.gen(1)613sage: a^(2*n)614()615sage: a^n==x^2616True617sage: x^-1*a*x==a^-1618True619620A large generalized quaternion group (order is a power of 2)::621622sage: n = 2^10623sage: G=DiCyclicGroup(n)624sage: G.order()6254096626sage: a = G.gen(0)627sage: x = G.gen(1)628sage: a^(2*n)629()630sage: a^n==x^2631True632sage: x^-1*a*x==a^-1633True634635Just like the dihedral group, the dicyclic group has636an element whose order is half the order of the group.637Unlike the dihedral group, the dicyclic group has only638one element of order 2. Like the dihedral groups of639even order, the center of the dicyclic group is a640subgroup of order 2 (thus has the unique element of641order 2 as its non-identity element). ::642643sage: G=DiCyclicGroup(3*5*4)644sage: G.order()645240646sage: two = [g for g in G if g.order()==2]; two647[(1,5)(2,6)(3,7)(4,8)(9,13)(10,14)(11,15)(12,16)]648sage: G.center().order()6492650651For small orders, we check this is really a group652we do not have in Sage otherwise. ::653654sage: G = DiCyclicGroup(2)655sage: H = DihedralGroup(4)656sage: G.is_isomorphic(H)657False658sage: G = DiCyclicGroup(3)659sage: H = DihedralGroup(6)660sage: K = AlternatingGroup(6)661sage: G.is_isomorphic(H) or G.is_isomorphic(K)662False663664TESTS::665666sage: groups.permutation.DiCyclic(6)667Diyclic group of order 24 as a permutation group668669REFERENCES:670671.. [CONRAD2009] `Groups of order 12672<http://www.math.uconn.edu/~kconrad/blurbs/grouptheory/group12.pdf>`_.673Keith Conrad, accessed 21 October 2009.674675AUTHOR:676- Rob Beezer (2009-10-18)677"""678def __init__(self, n):679r"""680The dicyclic group of order `4*n`, as a permutation group.681682INPUT:683n -- a positive integer, two or greater684685EXAMPLES::686687sage: G = DiCyclicGroup(3*8)688sage: G.order()68996690sage: TestSuite(G).run()691"""692n = Integer(n)693if n < 2:694raise ValueError("n (=%s) must be 2 or greater" % n)695696# Certainly 2^2 is part of the first factor of the order697# r is maximum power of 2 in the order698# m is the rest, the odd part699order = 4*n700factored = order.factor()701r = factored[0][0]**factored[0][1]702m = order//r703halfr, fourthr = r//2, r//4704705# Representation of a706# Two cycles of length halfr707a = [tuple(range(1, halfr+1)), tuple(range(halfr+1, r+1))]708# With an odd part, a cycle of length m will give the right order for a709if m > 1:710a.append( tuple(range(r+1, r+m+1)) )711712# Representation of x713# Four-cycles that will conjugate the generator a properly714x = [(i+1, (-i)%halfr + halfr + 1, (fourthr+i)%halfr + 1, (-fourthr-i)%halfr + halfr + 1)715for i in range(0, fourthr)]716# With an odd part, transpositions will conjugate the m-cycle to create inverse717if m > 1:718x += [(r+i+1, r+m-i) for i in range(0, (m-1)//2)]719720PermutationGroup_generic.__init__(self, gens=[a, x])721722def _repr_(self):723r"""724EXAMPLES::725726sage: DiCyclicGroup(12)727Diyclic group of order 48 as a permutation group728"""729return "Diyclic group of order %s as a permutation group"%self.order()730731def is_commutative(self):732r"""733Return True if this group is commutative.734735EXAMPLES::736737sage: D = DiCyclicGroup(12)738sage: D.is_commutative()739False740"""741return False742743def is_abelian(self):744r"""745Return True if this group is abelian.746747EXAMPLES::748749sage: D = DiCyclicGroup(12)750sage: D.is_abelian()751False752"""753return False754755class KleinFourGroup(PermutationGroup_unique):756def __init__(self):757r"""758The Klein 4 Group, which has order $4$ and exponent $2$, viewed759as a subgroup of $S_4$.760761OUTPUT:762-- the Klein 4 group of order 4, as a permutation group of degree 4.763764.. note::765This group is also available via ``groups.permutation.KleinFour()``.766767EXAMPLES::768769sage: G = KleinFourGroup(); G770The Klein 4 group of order 4, as a permutation group771sage: list(G)772[(), (3,4), (1,2), (1,2)(3,4)]773774TESTS::775776sage: G.category()777Category of finite permutation groups778sage: TestSuite(G).run()779780sage: groups.permutation.KleinFour()781The Klein 4 group of order 4, as a permutation group782783AUTHOR:784-- Bobby Moretti (2006-10)785"""786gens = [(1,2),(3,4)]787PermutationGroup_generic.__init__(self, gens)788789def _repr_(self):790"""791EXAMPLES::792793sage: G = KleinFourGroup(); G794The Klein 4 group of order 4, as a permutation group795"""796return 'The Klein 4 group of order 4, as a permutation group'797798class QuaternionGroup(DiCyclicGroup):799r"""800The quaternion group of order 8.801802OUTPUT:803The quaternion group of order 8, as a permutation group.804See the ``DiCyclicGroup`` class for a generalization of this805construction.806807.. note::808This group is also available via ``groups.permutation.Quaternion()``.809810EXAMPLES:811812The quaternion group is one of two non-abelian groups of order 8,813the other being the dihedral group `D_4`. One way to describe this814group is with three generators, `I, J, K`, so the whole group is815then given as the set `\{\pm 1, \pm I, \pm J, \pm K\}` with relations816such as `I^2=J^2=K^2=-1`, `IJ=K` and `JI=-K`.817818The examples below illustrate how to use this group in a similar819manner, by testing some of these relations. The representation used820here is the left-regular representation. ::821822sage: Q = QuaternionGroup()823sage: I = Q.gen(0)824sage: J = Q.gen(1)825sage: K = I*J826sage: [I,J,K]827[(1,2,3,4)(5,6,7,8), (1,5,3,7)(2,8,4,6), (1,8,3,6)(2,7,4,5)]828sage: neg_one = I^2; neg_one829(1,3)(2,4)(5,7)(6,8)830sage: J^2 == neg_one and K^2 == neg_one831True832sage: J*I == neg_one*K833True834sage: Q.center().order() == 2835True836sage: neg_one in Q.center()837True838839TESTS::840841sage: groups.permutation.Quaternion()842Quaternion group of order 8 as a permutation group843844AUTHOR:845-- Rob Beezer (2009-10-09)846"""847def __init__(self):848r"""849TESTS::850851sage: Q = QuaternionGroup()852sage: TestSuite(Q).run()853"""854DiCyclicGroup.__init__(self, 2)855856def _repr_(self):857r"""858EXAMPLES::859860sage: Q=QuaternionGroup(); Q861Quaternion group of order 8 as a permutation group862"""863return "Quaternion group of order 8 as a permutation group"864865class GeneralDihedralGroup(PermutationGroup_generic):866r"""867The Generalized Dihedral Group generated by the abelian group with868direct factors in the input list.869870INPUT:871872- ``factors`` - a list of the sizes of the cyclic factors of the873abelian group being dihedralized (this will be sorted once874entered)875876OUTPUT:877878For a given abelian group (noting that each finite abelian group879can be represented as the direct product of cyclic groups), the880General Dihedral Group it generates is simply the semi-direct881product of the given group with `C_2`, where the nonidentity882element of `C_2` acts on the abelian group by turning each element883into its inverse. In this implementation, each input abelian group884will be standardized so as to act on a minimal amount of letters.885This will be done by breaking the direct factors into products of886p-groups, before this new set of factors is ordered from smallest887to largest for complete standardization. Note that the generalized888dihedral group corresponding to a cyclic group, `C_n`, is simply889the dihedral group `D_n`.890891EXAMPLES:892893As is noted in [1], `Dih(C_3 \times C_3)` has the presentation894895.. MATH::896897\langle a, b, c\mid a^{3}, b^{3}, c^{2}, ab = ba, ac = ca^{-1}, bc = cb^{-1} \rangle898899Note also the fact, verified by [1]_, that the dihedralization of900`C_3 \times C_3` is the only nonabelian group of order 18901with no element of order 6. ::902903sage: G = GeneralDihedralGroup([3,3])904sage: G905Generalized dihedral group generated by C3 x C3906sage: G.order()90718908sage: G.gens()909[(4,5,6), (2,3)(5,6), (1,2,3)]910sage: a = G.gens()[2]; b = G.gens()[0]; c = G.gens()[1]911sage: a.order() == 3, b.order() == 3, c.order() == 2912(True, True, True)913sage: a*b == b*a, a*c == c*a.inverse(), b*c == c*b.inverse()914(True, True, True)915sage: G.subgroup([a,b,c]) == G916True917sage: G.is_abelian()918False919sage: all([x.order() != 6 for x in G])920True921922If all of the direct factors are `C_2`, then the action turning923each element into its inverse is trivial, and the semi-direct924product becomes a direct product. ::925926sage: G = GeneralDihedralGroup([2,2,2])927sage: G.order()92816929sage: G.gens()930[(7,8), (5,6), (3,4), (1,2)]931sage: G.is_abelian()932True933sage: H = KleinFourGroup()934sage: G.is_isomorphic(H.direct_product(H)[0])935True936937If two nonidentical input lists generate isomorphic abelian938groups, then they will generate identical groups (with each direct939factor broken up into its prime factors), but they will still have940distinct descriptions. Note that If `gcd(n,m)=1`, then `C_n \times941C_m \cong C_{nm}`, while the general dihedral groups942generated by isomorphic abelian groups should be themselves943isomorphic. ::944945sage: G = GeneralDihedralGroup([6,34,46,14])946sage: H = GeneralDihedralGroup([7,17,3,46,2,2,2])947sage: G == H, G.gens() == H.gens()948(True, True)949sage: [x.order() for x in G.gens()]950[23, 17, 7, 2, 3, 2, 2, 2, 2]951sage: G952Generalized dihedral group generated by C6 x C34 x C46 x C14953sage: H954Generalized dihedral group generated by C7 x C17 x C3 x C46 x C2 x C2 x C2955956A cyclic input yields a Classical Dihedral Group. ::957958sage: G = GeneralDihedralGroup([6])959sage: D = DihedralGroup(6)960sage: G.is_isomorphic(D)961True962963A Generalized Dihedral Group will always have size twice the964underlying group, be solvable (as it has an abelian subgroup with965index 2), and, unless the underlying group is of the form966`{C_2}^n`, be nonabelian (by the structure theorem of finite967abelian groups and the fact that a semi-direct product is a968direct product only when the underlying action is trivial). ::969970sage: G = GeneralDihedralGroup([6,18,33,60])971sage: (6*18*33*60)*2972427680973sage: G.order()974427680975sage: G.is_solvable()976True977sage: G.is_abelian()978False979980TESTS::981982sage: G = GeneralDihedralGroup("foobar")983Traceback (most recent call last):984...985TypeError: factors of abelian group must be a list, not foobar986987sage: GeneralDihedralGroup([])988Traceback (most recent call last):989...990ValueError: there must be at least one direct factor in the abelian group being dihedralized991992sage: GeneralDihedralGroup([3, 1.5])993Traceback (most recent call last):994...995TypeError: the input list must consist of Integers996997sage: GeneralDihedralGroup([4, -8])998Traceback (most recent call last):999...1000ValueError: all direct factors must be greater than 110011002REFERENCES:10031004.. [1] A.D. Thomas and G.V. Wood, Group Tables (Exeter: Shiva Publishing, 1980)10051006AUTHOR:10071008- Kevin Halasz (2012-7-12)10091010"""1011def __init__(self, factors):1012r"""1013Init method of class <GeneralDihedralGroup>. See the docstring1014for :class:`<GeneralDihedralGroup>`.10151016EXAMPLES::10171018sage: G = GeneralDihedralGroup([5,5,5])1019sage: G.order()10202501021sage: TestSuite(G).run()1022"""102310241025if not isinstance(factors, list):1026msg = "factors of abelian group must be a list, not {}"1027raise TypeError(msg.format(factors))10281029if len(factors) < 1:1030raise ValueError('there must be at least one direct factor in the abelian group being dihedralized')10311032if not all(isinstance(x, Integer) for x in factors):1033raise TypeError('the input list must consist of Integers')10341035if not all(x >= 2 for x in factors):1036s = 'all direct factors must be greater than 1'1037raise ValueError(s)10381039self.factors = factors1040# To get uniform outputs for isomorphic inputs, we break1041# each inputted cyclic group into a direct product of cyclic1042# p-groups1043simplified = [term[0]**term[1] for a in factors for term in a.factor()]1044simplified.sort()10451046gens = []1047# genx is an element of order two that turns each of the1048# generators of the abelian group into its inverse via1049# conjugation1050genx = []1051jumppoint = Integer(1)1052for a in simplified:1053# create one of the generators for the abelian group1054gens.append([tuple(range(jumppoint, jumppoint+a))])1055# make contribution to the generator that dihedralizes the1056# abelian group1057for i in range(1, (a//2)+1):1058if i != a-i:1059genx.append(tuple((jumppoint+i, jumppoint+a-i)))1060jumppoint = jumppoint + a1061# If all of the direct factors are C2, then the action turning1062# each element into its inverse is trivial, and the1063# semi-direct product becomes a direct product, so we simply1064# tack on another disjoint transposition1065if all(x==2 for x in simplified):1066genx.append(tuple((jumppoint, jumppoint+1)))1067gens.append(genx)1068PermutationGroup_generic.__init__(self, gens=gens)10691070def _repr_(self):1071r"""1072EXAMPLES::10731074sage: G = GeneralDihedralGroup([2,4,8])1075sage: G1076Generalized dihedral group generated by C2 x C4 x C81077"""1078grouplist = []1079for n in self.factors:1080grouplist.append('C{}'.format(n))1081return 'Generalized dihedral group generated by ' + ' x '.join(grouplist)10821083class DihedralGroup(PermutationGroup_unique):1084def __init__(self, n):1085"""1086The Dihedral group of order $2n$ for any integer $n\geq 1$.10871088INPUT:1089n -- a positive integer10901091OUTPUT:1092-- the dihedral group of order 2*n, as a permutation group10931094.. note::1095This group is also available via ``groups.permutation.Dihedral()``.10961097EXAMPLES::10981099sage: DihedralGroup(1)1100Dihedral group of order 2 as a permutation group11011102sage: DihedralGroup(2)1103Dihedral group of order 4 as a permutation group1104sage: DihedralGroup(2).gens()1105[(3,4), (1,2)]11061107sage: DihedralGroup(5).gens()1108[(1,2,3,4,5), (1,5)(2,4)]1109sage: list(DihedralGroup(5))1110[(), (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)]11111112sage: G = DihedralGroup(6)1113sage: G.order()1114121115sage: G = DihedralGroup(5)1116sage: G.order()1117101118sage: G1119Dihedral group of order 10 as a permutation group1120sage: G.gens()1121[(1,2,3,4,5), (1,5)(2,4)]11221123sage: DihedralGroup(0)1124Traceback (most recent call last):1125...1126ValueError: n must be positive11271128TESTS::11291130sage: TestSuite(G).run()1131sage: G.category()1132Category of finite permutation groups1133sage: TestSuite(G).run()11341135sage: groups.permutation.Dihedral(6)1136Dihedral group of order 12 as a permutation group1137"""1138n = Integer(n)1139if n <= 0:1140raise ValueError("n must be positive")11411142# the first generator generates the cyclic subgroup of D_n, <(1...n)> in1143# cycle notation1144gen0 = range(1,n+1)11451146if n < 1:1147raise ValueError("n (=%s) must be >= 1" % n)11481149# D_1 is a subgroup of S_2, we need the cyclic group of order 21150if n == 1:1151gens = CyclicPermutationGroup(2).gens()1152elif n == 2:1153gens = ((1,2),(3,4))1154else:1155gen1 = [(i, n-i+1) for i in range(1, n//2 +1)]1156gens = tuple([tuple(gen0),tuple(gen1)])11571158PermutationGroup_generic.__init__(self, gens)11591160def _repr_(self):1161"""1162EXAMPLES::11631164sage: G = DihedralGroup(5); G1165Dihedral group of order 10 as a permutation group1166"""1167return "Dihedral group of order %s as a permutation group"%self.order()1168116911701171class SplitMetacyclicGroup(PermutationGroup_unique):1172def __init__(self, p, m):1173r"""1174The split metacyclic group of order `p^m`.11751176INPUT:11771178- ``p`` - a prime number that is the prime underlying this1179p-group11801181- ``m`` - a positive integer such that the order of this1182group is the `p^m`. Be aware that, for even `p`, `m` must be1183greater than 3, while for odd `p`, `m` must be greater than11842.11851186OUTPUT:11871188The split metacyclic group of order `p^m`. This family of1189groups has presentation11901191.. MATH::11921193\langle x, y\mid x^{p^{m-1}}, y^{p}, y^{-1}xy=x^{1+p^{m-2}} \rangle11941195This family is notable because, for odd `p`, these are the1196only `p`-groups with a cyclic subgroup of index `p`, a1197result proven in [GORENSTEIN]_. It is also shown in1198[GORENSTEIN]_ that this is one of four families containing1199nonabelian 2-groups with a cyclic subgroup of index 21200(with the others being the dicyclic groups, the dihedral1201groups, and the semidihedral groups).12021203EXAMPLES:12041205Using the last relation in the group's presentation,1206one can see that the elements of the form `y^{i}x`,1207`0 \leq i \leq p-1` all have order `p^{m-1}`, as it can be1208shown that their `p` th powers are all `x^{p^{m-2}+p}`,1209an element with order `p^{m-2}`. Manipulation of the same1210relation shows that none of these elements are powers of1211any other. Thus, there are `p` cyclic maximal subgroups in1212each split metacyclic group. It is also proven in1213[GORENSTEIN]_ that this family has commutator subgroup1214of order `p`, and the Frattini subgroup is equal to the1215center, with this group being cyclic of order `p^{m-2}`.1216These characteristics are necessary to identify these1217groups in the case that `p=2`, although the possession of1218a cyclic maximal subgroup in a non-abelian `p`-group is1219enough for odd `p` given the group's order. ::12201221sage: G = SplitMetacyclicGroup(2,8)1222sage: G.order() == 2**81223True1224sage: G.is_abelian()1225False1226sage: len([H for H in G.subgroups() if H.order() == 2^7 and H.is_cyclic()])122721228sage: G.commutator().order()122921230sage: G.frattini_subgroup() == G.center()1231True1232sage: G.center().order() == 2^61233True1234sage: G.center().is_cyclic()1235True12361237sage: G = SplitMetacyclicGroup(3,3)1238sage: len([H for H in G.subgroups() if H.order() == 3^2 and H.is_cyclic()])123931240sage: G.commutator().order()124131242sage: G.frattini_subgroup() == G.center()1243True1244sage: G.center().order()1245312461247TESTS::12481249sage: G = SplitMetacyclicGroup(3,2.5)1250Traceback (most recent call last):1251...1252TypeError: both p and m must be integers12531254sage: G = SplitMetacyclicGroup(4,3)1255Traceback (most recent call last):1256...1257ValueError: p must be prime, 4 is not prime12581259sage: G = SplitMetacyclicGroup(2,2)1260Traceback (most recent call last):1261...1262ValueError: if prime is 2, the exponent must be greater than 3, not 212631264sage: G = SplitMetacyclicGroup(11,2)1265Traceback (most recent call last):1266...1267ValueError: if prime is odd, the exponent must be greater than 2, not 212681269REFERENCES:12701271.. [GORENSTEIN] Daniel Gorenstein, Finite Groups (New York: Chelsea Publishing, 1980)12721273AUTHOR:12741275- Kevin Halasz (2012-8-7)12761277"""12781279if not isinstance(p, Integer) or not isinstance(m, Integer):1280raise TypeError('both p and m must be integers')12811282if not p in Primes():1283raise ValueError('p must be prime, %s is not prime' % p)12841285if p == 2 and m <= 3:1286raise ValueError('if prime is 2, the exponent must be greater than 3, not %s' % m)12871288if p%2 == 1 and m <= 2:1289raise ValueError('if prime is odd, the exponent must be greater than 2, not %s' % m)12901291self.p = p1292self.m = m12931294# x is created with list, rather than cycle, notation1295x = range(2, p**(m-1)+1)1296x.append(1)1297# y is also created with list notation, where the list1298# used is equivalent to the cycle notation representation of1299# x^(1+p^(m-2)). This technique is inspired by exercise 5.301300# Judson's "Abstract Algebra" (abstract.pugetsound.edu).1301y = [1]1302point = 11303for i in range(p**(m-1)-1):1304next = (point + 1 + p**(m-2))%(p**(m-1))1305if next == 0:1306next = p**(m-1)1307y.append(next)1308point = next1309PermutationGroup_unique.__init__(self, gens = [x,y])13101311def _repr_(self):1312"""1313EXAMPLES::13141315sage: G = SplitMetacyclicGroup(7,4);G1316The split metacyclic group of order 7 ^ 41317"""1318return 'The split metacyclic group of order %s ^ %s'%(self.p,self.m)13191320class SemidihedralGroup(PermutationGroup_unique):1321def __init__(self,m):1322r"""1323The semidihedral group of order `2^m`.13241325INPUT:13261327- ``m`` - a positive integer; the power of 2 that is the1328group's order13291330OUTPUT:13311332The semidihedral group of order `2^m`. These groups can be1333thought of as a semidirect product of `C_{2^{m-1}}` with1334`C_2`, where the nontrivial element of `C_2` is sent to1335the element of the automorphism group of `C_{2^{m-1}}` that1336sends elements to their `-1+2^{m-2}` th power. Thus, the1337group has the presentation:13381339.. MATH::13401341\langle x, y\mid x^{2^{m-1}}, y^{2}, y^{-1}xy=x^{-1+2^{m-2}} \rangle13421343This family is notable because it is made up of non-abelian13442-groups that all contain cyclic subgroups of index 2. It1345is one of only four such families.13461347EXAMPLES:13481349In [GORENSTEIN1980]_ it is shown that the semidihedral groups1350have center of order 2. It is also shown that they have a1351Frattini subgroup equal to their commutator, which is a1352cyclic subgroup of order `2^{m-2}`. ::13531354sage: G = SemidihedralGroup(12)1355sage: G.order() == 2^121356True1357sage: G.commutator() == G.frattini_subgroup()1358True1359sage: G.commutator().order() == 2^101360True1361sage: G.commutator().is_cyclic()1362True1363sage: G.center().order()1364213651366sage: G = SemidihedralGroup(4)1367sage: len([H for H in G.subgroups() if H.is_cyclic() and H.order() == 8])136811369sage: G.gens()1370[(2,4)(3,7)(6,8), (1,2,3,4,5,6,7,8)]1371sage: x = G.gens()[1]; y = G.gens()[0]1372sage: x.order() == 2^3; y.order() == 21373True1374True1375sage: y*x*y == x^(-1+2^2)1376True13771378TESTS::13791380sage: G = SemidihedralGroup(4.4)1381Traceback (most recent call last):1382...1383TypeError: m must be an integer, not 4.4000000000000013841385sage: G = SemidihedralGroup(-5)1386Traceback (most recent call last):1387...1388ValueError: the exponent must be greater than 3, not -513891390REFERENCES:13911392.. [GORENSTEIN1980] Daniel Gorenstein, Finite Groups (New York: Chelsea Publishing, 1980)13931394AUTHOR:13951396- Kevin Halasz (2012-8-7)13971398"""1399if not isinstance(m, Integer):1400raise TypeError('m must be an integer, not %s' % m)14011402if m <= 3:1403raise ValueError('the exponent must be greater than 3, not %s' % m)14041405self.m = m14061407# x is created with list, rather than cycle, notation1408x = range(2, 2**(m-1)+1)1409x.append(1)1410# y is also created with list notation, where the list1411# used is equivalent to the cycle notation representation of1412# x^(1+p^(m-2)). This technique is inspired by exercise 5.301413# Judson's "Abstract Algebra" (abstract.pugetsound.edu).1414y = [1]1415k = 11416for i in range(2**(m-1)-1):1417next = (k - 1 + 2**(m-2))%(2**(m-1))1418if next == 0:1419next = 2**(m-1)1420y.append(next)1421k = next1422PermutationGroup_unique.__init__(self, gens = [x,y])14231424def _repr_(self):1425r"""1426EXAMPLES::14271428sage: G = SemidihedralGroup(6); G1429The semidiheral group of order 641430"""1431return 'The semidiheral group of order %s'%(2**self.m)14321433class MathieuGroup(PermutationGroup_unique):1434def __init__(self, n):1435"""1436The Mathieu group of degree $n$.14371438INPUT:1439n -- a positive integer in {9, 10, 11, 12, 21, 22, 23, 24}.14401441OUTPUT:1442-- the Mathieu group of degree n, as a permutation group14431444.. note::1445This group is also available via ``groups.permutation.Mathieu()``.14461447EXAMPLES::14481449sage: G = MathieuGroup(12)1450sage: G1451Mathieu group of degree 12 and order 95040 as a permutation group14521453TESTS::14541455sage: G.category()1456Category of finite permutation groups1457sage: TestSuite(G).run(skip=["_test_enumerated_set_contains", "_test_enumerated_set_iter_list"])14581459sage: groups.permutation.Mathieu(9)1460Mathieu group of degree 9 and order 72 as a permutation group14611462Note: this is a fairly big group, so we skip some tests that1463currently require to list all the elements of the group,1464because there is no proper iterator yet.1465"""1466n = Integer(n)1467self._n = n1468if not(n in [9, 10, 11, 12, 21, 22, 23, 24]):1469raise ValueError("argument must belong to {9, 10, 11, 12, 21, 22, 23, 24}.")1470id = 'MathieuGroup(%s)'%n1471PermutationGroup_generic.__init__(self, gap_group=id)14721473def _repr_(self):1474"""1475EXAMPLES::14761477sage: G = MathieuGroup(12); G1478Mathieu group of degree 12 and order 95040 as a permutation group1479"""1480return "Mathieu group of degree %s and order %s as a permutation group"%(self._n,self.order())14811482class TransitiveGroup(PermutationGroup_unique):1483def __init__(self, d, n):1484"""1485The transitive group from the GAP tables of transitive groups.14861487INPUT:1488d -- non-negative integer; the degree1489n -- positive integer; the index of the group in the GAP database, starting at 1149014911492OUTPUT:1493the n-th transitive group of degree d14941495.. note::1496This group is also available via ``groups.permutation.Transitive()``.14971498EXAMPLES::14991500sage: TransitiveGroup(0,1)1501Transitive group number 1 of degree 01502sage: TransitiveGroup(1,1)1503Transitive group number 1 of degree 11504sage: G = TransitiveGroup(5, 2); G # optional - database_gap1505Transitive group number 2 of degree 51506sage: G.gens() # optional - database_gap1507[(1,2,3,4,5), (1,4)(2,3)]15081509sage: G.category() # optional - database_gap1510Category of finite permutation groups15111512.. warning:: this follows GAP's naming convention of indexing1513the transitive groups starting from ``1``::15141515sage: TransitiveGroup(5,0) # optional - database_gap1516Traceback (most recent call last):1517...1518ValueError: Index n must be in {1,..,5}15191520.. warning:: only transitive groups of "small" degree are1521available in GAP's database::15221523sage: TransitiveGroup(31,1) # optional - database_gap1524Traceback (most recent call last):1525...1526NotImplementedError: Only the transitive groups of order less than 30 are available in GAP's database15271528TESTS::152915301531sage: groups.permutation.Transitive(1, 1)1532Transitive group number 1 of degree 115331534sage: TestSuite(TransitiveGroup(0,1)).run()1535sage: TestSuite(TransitiveGroup(1,1)).run()1536sage: TestSuite(TransitiveGroup(5,2)).run()# optional - database_gap15371538sage: TransitiveGroup(1,5) # optional - database_gap1539Traceback (most recent call last):1540...1541ValueError: Index n must be in {1,..,1}1542"""1543d = Integer(d)1544n = Integer(n)1545if d < 0:1546raise ValueError("Degree d must not be negative")1547max_n = TransitiveGroups(d).cardinality()1548if n > max_n or n <= 0:1549raise ValueError("Index n must be in {1,..,%s}" % max_n)1550gap_group = 'Group([()])' if d in [0,1] else 'TransitiveGroup(%s,%s)'%(d,n)1551try:1552PermutationGroup_generic.__init__(self, gap_group=gap_group)1553except RuntimeError:1554from sage.misc.misc import verbose1555verbose("Warning: Computing with TransitiveGroups requires the optional database_gap package. Please install it.", level=0)15561557self._d = d1558self._n = n1559self._domain = range(1, d+1)15601561def _repr_(self):1562"""1563EXAMPLES::15641565sage: G = TransitiveGroup(1,1); G1566Transitive group number 1 of degree 11567"""1568return "Transitive group number %s of degree %s"%(self._n, self._d)15691570def TransitiveGroups(d=None):1571"""1572INPUT:15731574- ``d`` -- an integer (optional)15751576Returns the set of all transitive groups of a given degree1577``d`` up to isomorphisms. If ``d`` is not specified, it returns the set of all1578transitive groups up to isomorphisms.15791580Warning: TransitiveGroups requires the optional GAP database1581package. Please install it with ``sage -i database_gap``.15821583EXAMPLES::15841585sage: TransitiveGroups(3)1586Transitive Groups of degree 31587sage: TransitiveGroups(7)1588Transitive Groups of degree 71589sage: TransitiveGroups(8)1590Transitive Groups of degree 815911592sage: TransitiveGroups()1593Transitive Groups15941595.. warning:: in practice, the database currently only contains1596transitive groups up to degree 30::15971598sage: TransitiveGroups(31).cardinality() # optional - database_gap1599Traceback (most recent call last):1600...1601NotImplementedError: Only the transitive groups of order less than 30 are available in GAP's database16021603"""1604if d == None:1605return TransitiveGroupsAll()1606else:1607d = Integer(d)1608if d < 0:1609raise ValueError("A transitive group acts on a non negative integer number of positions")1610return TransitiveGroupsOfDegree(d)16111612class TransitiveGroupsAll(DisjointUnionEnumeratedSets):1613"""1614The infinite set of all transitive groups up to isomorphisms.16151616EXAMPLES::16171618sage: L = TransitiveGroups(); L1619Transitive Groups1620sage: L.category()1621Category of infinite enumerated sets1622sage: L.cardinality()1623+Infinity16241625sage: p = L.__iter__() # optional - database_gap1626sage: (p.next(), p.next(), p.next(), p.next(), p.next(), p.next(), p.next(), p.next()) # optional - database_gap1627(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)16281629TESTS::16301631sage: TestSuite(TransitiveGroups()).run() # optional - database_gap # long time1632"""1633def __init__(self):1634"""1635TESTS::16361637sage: S = TransitiveGroups() # optional - database_gap1638sage: S.category() # optional - database_gap1639Category of infinite enumerated sets1640"""1641DisjointUnionEnumeratedSets.__init__(self, Family(NonNegativeIntegers(), lambda i: TransitiveGroups(i)) )16421643def _repr_(self):1644"""1645TESTS::16461647sage: TransitiveGroups() # optional - database_gap # indirect doctest1648Transitive Groups1649"""1650return "Transitive Groups"16511652def __contains__(self, G):1653r"""1654EXAMPLES::16551656sage: TransitiveGroup(5,2) in TransitiveGroups() # optional - database_gap1657True1658sage: TransitiveGroup(6,5) in TransitiveGroups() # optional - database_gap1659True1660sage: 1 in TransitiveGroups() # optional - database_gap1661False1662"""1663return isinstance(G,TransitiveGroup)16641665class TransitiveGroupsOfDegree(CachedRepresentation, Parent):1666"""1667The set of all transitive groups of a given (small) degree up to isomorphisms.16681669EXAMPLES::16701671sage: S = TransitiveGroups(4); S # optional - database_gap1672Transitive Groups of degree 41673sage: list(S) # optional - database_gap1674[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]16751676sage: TransitiveGroups(5).an_element() # optional - database_gap1677Transitive group number 1 of degree 516781679We write the cardinality of all transitive groups of degree 5::16801681sage: for G in TransitiveGroups(5): # optional - database_gap1682... print G.cardinality()16835168410168520168660168712016881689TESTS::16901691sage: TestSuite(TransitiveGroups(3)).run() # optional - database_gap169216931694"""1695def __init__(self, n):1696"""1697TESTS::16981699sage: S = TransitiveGroups(4) # optional - database_gap1700sage: S.category() # optional - database_gap1701Category of finite enumerated sets1702"""1703self._degree = n1704Parent.__init__(self, category = FiniteEnumeratedSets())17051706def _repr_(self):1707"""1708TESTS::17091710sage: TransitiveGroups(6) # optional - database_gap1711Transitive Groups of degree 61712"""1713return "Transitive Groups of degree %s"%(self._degree)17141715def __contains__(self, G):1716r"""1717EXAMPLES::17181719sage: TransitiveGroup(6,5) in TransitiveGroups(4) # optional - database_gap1720False1721sage: TransitiveGroup(4,3) in TransitiveGroups(4) # optional - database_gap1722True1723sage: 1 in TransitiveGroups(4) # optional - database_gap1724False1725"""1726if isinstance(G,TransitiveGroup):1727return G._d == self._degree1728else:1729False17301731def __getitem__(self, n):1732r"""1733INPUT:17341735- ``n`` -- a positive integer17361737Returns the `n`-th transitive group of a given degree.17381739EXAMPLES::17401741sage: TransitiveGroups(5)[3] # optional - database_gap1742Transitive group number 3 of degree 517431744.. warning:: this follows GAP's naming convention of indexing1745the transitive groups starting from ``1``::17461747sage: TransitiveGroups(5)[0] # optional - database_gap1748Traceback (most recent call last):1749...1750ValueError: Index n must be in {1,..,5}1751"""1752return TransitiveGroup(self._degree, n)17531754def __iter__(self):1755"""1756EXAMPLES::17571758sage: list(TransitiveGroups(5)) # indirect doctest # optional - database_gap1759[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]1760"""1761for n in xrange(1, self.cardinality() + 1):1762yield self[n]17631764@cached_method1765def cardinality(self):1766r"""1767Returns the cardinality of ``self``, that is the number of1768transitive groups of a given degree.17691770EXAMPLES::17711772sage: TransitiveGroups(0).cardinality() # optional - database_gap177311774sage: TransitiveGroups(2).cardinality() # optional - database_gap177511776sage: TransitiveGroups(7).cardinality() # optional - database_gap177771778sage: TransitiveGroups(12).cardinality() # optional - database_gap17793011780sage: [TransitiveGroups(i).cardinality() for i in range(11)] # optional - database_gap1781[1, 1, 1, 2, 5, 5, 16, 7, 50, 34, 45]17821783.. warning::17841785The database_gap contains all transitive groups1786up to degree 30::17871788sage: TransitiveGroups(31).cardinality() # optional - database_gap1789Traceback (most recent call last):1790...1791NotImplementedError: Only the transitive groups of order less than 30 are available in GAP's database17921793TESTS::17941795sage: type(TransitiveGroups(12).cardinality()) # optional - database_gap1796<type 'sage.rings.integer.Integer'>1797sage: type(TransitiveGroups(0).cardinality())1798<type 'sage.rings.integer.Integer'>1799"""1800# gap.NrTransitiveGroups(0) fails, so Sage needs to handle this18011802# While we are at it, and since Sage also handles the1803# transitive group of degree 1, we may as well handle 11804if self._degree <= 1:1805return Integer(1)1806else:1807try:1808return Integer(gap.NrTransitiveGroups(gap(self._degree)))1809except RuntimeError:1810from sage.misc.misc import verbose1811verbose("Warning: TransitiveGroups requires the GAP database package. Please install it with ``sage -i database_gap``.", level=0)1812except TypeError:1813raise NotImplementedError("Only the transitive groups of order less than 30 are available in GAP's database")18141815class PrimitiveGroup(PermutationGroup_unique):1816"""1817The primitive group from the GAP tables of primitive groups.18181819INPUT:18201821- ``d`` -- non-negative integer. the degree of the group.18221823- ``n`` -- positive integer. the index of the group in the GAP1824database, starting at 118251826OUTPUT:18271828The ``n``-th primitive group of degree ``d``.18291830EXAMPLES::18311832sage: PrimitiveGroup(0,1)1833Trivial group1834sage: PrimitiveGroup(1,1)1835Trivial group1836sage: G = PrimitiveGroup(5, 2); G # optional - database_gap1837D(2*5)1838sage: G.gens() # optional - database_gap1839[(2,4)(3,5), (1,2,3,5,4)]1840sage: G.category() # optional - database_gap1841Category of finite permutation groups18421843.. warning::18441845this follows GAP's naming convention of indexing the primitive1846groups starting from ``1``::18471848sage: PrimitiveGroup(5,0) # optional - database_gap1849Traceback (most recent call last):1850...1851ValueError: Index n must be in {1,..,5}18521853Only primitive groups of "small" degree are available in GAP's1854database::18551856sage: PrimitiveGroup(2500,1) # optional - database_gap1857Traceback (most recent call last):1858...1859NotImplementedError: Only the primitive groups of degree less1860than 2500 are available in GAP's database1861"""18621863def __init__(self, d, n):1864"""1865The Python constructor.18661867INPUT/OUTPUT:18681869See :class:`PrimitiveGroup`.18701871TESTS::18721873sage: TestSuite(PrimitiveGroup(0,1)).run()1874sage: TestSuite(PrimitiveGroup(1,1)).run()1875sage: TestSuite(PrimitiveGroup(5,2)).run() # optional - database_gap1876sage: PrimitiveGroup(6,5) # optional - database_gap1877Traceback (most recent call last):1878...1879ValueError: Index n must be in {1,..,4}1880"""1881d = Integer(d)1882n = Integer(n)1883if d < 0:1884raise ValueError("Degree d must not be negative")1885max_n = PrimitiveGroups(d).cardinality()1886if n > max_n or n <= 0:1887raise ValueError("Index n must be in {1,..,%s}" % max_n)1888if d in [0,1]:1889gap_group = gap.Group("[()]")1890self._pretty_name = "Trivial group"1891else:1892gap_group = gap.PrimitiveGroup(d, n)1893self._pretty_name = gap_group.str()1894try:1895PermutationGroup_generic.__init__(self, gap_group=gap_group)1896except RuntimeError:1897from sage.misc.misc import verbose1898verbose("Warning: Computing with PrimitiveGroups requires the optional database_gap package. Please install it.", level=0)18991900self._d = d1901self._n = n1902self._domain = range(1, d+1)19031904def _repr_(self):1905"""1906Return a string representation.19071908OUTPUT:19091910String.19111912EXAMPLES::19131914sage: G = PrimitiveGroup(5,1); G # optional - database_gap1915C(5)1916"""1917return self._pretty_name19181919def group_primitive_id(self):1920"""1921Return the index of this group in the GAP database of primitive groups.19221923Requires "optional" database_gap package.19241925OUTPUT:19261927A positive integer, following GAP's conventions.19281929EXAMPLES::19301931sage: G = PrimitiveGroup(5,2); G.group_primitive_id() # optional - database_gap193221933"""1934return self._n19351936def PrimitiveGroups(d=None):1937"""1938Return the set of all primitive groups of a given degree ``d``19391940INPUT:19411942- ``d`` -- an integer (optional)19431944OUTPUT:19451946The set of all primitive groups of a given degree ``d`` up to1947isomorphisms using GAP. If ``d`` is not specified, it returns the1948set of all primitive groups up to isomorphisms stored in GAP.19491950.. attention::19511952PrimitiveGroups requires the optional GAP database1953package. Please install it with1954``install_package(`database_gap')``.19551956EXAMPLES::19571958sage: PrimitiveGroups(3)1959Primitive Groups of degree 31960sage: PrimitiveGroups(7)1961Primitive Groups of degree 71962sage: PrimitiveGroups(8)1963Primitive Groups of degree 81964sage: PrimitiveGroups()1965Primitive Groups19661967The database currently only contains primitive groups up to degree19682499::19691970sage: PrimitiveGroups(2500).cardinality() # optional - database_gap1971Traceback (most recent call last):1972...1973NotImplementedError: Only the primitive groups of degree less1974than 2500 are available in GAP's database19751976TODO:19771978This enumeration helper could be extended based on1979``PrimitiveGroupsIterator`` in GAP. This method allows to1980enumerate groups with specified properties such as transitivity,1981solvability, ..., without creating all groups.1982"""1983if d == None:1984return PrimitiveGroupsAll()1985else:1986d = Integer(d)1987if d < 0:1988raise ValueError("A primitive group acts on a non negative integer number of positions")1989return PrimitiveGroupsOfDegree(d)199019911992class PrimitiveGroupsAll(DisjointUnionEnumeratedSets):1993"""1994The infinite set of all primitive groups up to isomorphisms.19951996EXAMPLES::19971998sage: L = PrimitiveGroups(); L1999Primitive Groups2000sage: L.category()2001Category of infinite enumerated sets2002sage: L.cardinality()2003+Infinity20042005sage: p = L.__iter__() # optional - database_gap2006sage: (p.next(), p.next(), p.next(), p.next(), # optional - database_gap2007... p.next(), p.next(), p.next(), p.next())2008(Trivial group, Trivial group, S(2), A(3), S(3), A(4), S(4), C(5))20092010TESTS::20112012sage: TestSuite(PrimitiveGroups()).run() # optional - database_gap # long time2013"""2014def __init__(self):2015"""2016TESTS::20172018sage: S = PrimitiveGroups() # optional - database_gap2019sage: S.category() # optional - database_gap2020Category of infinite enumerated sets2021"""2022DisjointUnionEnumeratedSets.__init__(self, Family(NonNegativeIntegers(), lambda i: PrimitiveGroups(i)) )20232024def _repr_(self):2025"""2026Return a string representation.20272028OUTPUT:20292030String.20312032TESTS::20332034sage: PrimitiveGroups() # optional - database_gap # indirect doctest2035Primitive Groups2036"""2037return "Primitive Groups"20382039def __contains__(self, G):2040r"""2041Test whether `G` is in ``self``.20422043INPUT:20442045- `G` -- anything.20462047OUTPUT:20482049Boolean.20502051EXAMPLES::20522053sage: PrimitiveGroup(5,2) in PrimitiveGroups() # optional - database_gap2054True2055sage: PrimitiveGroup(6,4) in PrimitiveGroups() # optional - database_gap2056True2057sage: 1 in PrimitiveGroups() # optional - database_gap2058False2059"""2060return isinstance(G,PrimitiveGroup)20612062class PrimitiveGroupsOfDegree(CachedRepresentation, Parent):2063"""2064The set of all primitive groups of a given degree up to isomorphisms.20652066EXAMPLES::20672068sage: S = PrimitiveGroups(5); S # optional - database_gap2069Primitive Groups of degree 52070sage: S.list() # optional - database_gap2071[C(5), D(2*5), AGL(1, 5), A(5), S(5)]2072sage: S.an_element() # optional - database_gap2073C(5)20742075We write the cardinality of all primitive groups of degree 5::20762077sage: for G in PrimitiveGroups(5): # optional - database_gap2078... print G.cardinality()20795208010208120208260208312020842085TESTS::20862087sage: TestSuite(PrimitiveGroups(3)).run() # optional - database_gap2088"""2089def __init__(self, n):2090"""2091TESTS::20922093sage: S = PrimitiveGroups(4) # optional - database_gap2094sage: S.category() # optional - database_gap2095Category of finite enumerated sets2096"""2097self._degree = n2098Parent.__init__(self, category = FiniteEnumeratedSets())20992100def _repr_(self):2101"""2102Return a string representation.21032104OUTPUT:21052106String.21072108TESTS::21092110sage: PrimitiveGroups(6) # optional - database_gap2111Primitive Groups of degree 62112"""2113return "Primitive Groups of degree %s"%(self._degree)21142115def __contains__(self, G):2116r"""2117Test whether `G` is in ``self``.21182119INPUT:21202121- `G` -- anything.21222123OUTPUT:21242125Boolean.21262127EXAMPLES::21282129sage: PrimitiveGroup(6,4) in PrimitiveGroups(4) # optional - database_gap2130False2131sage: PrimitiveGroup(4,2) in PrimitiveGroups(4) # optional - database_gap2132True2133sage: 1 in PrimitiveGroups(4) # optional - database_gap2134False2135"""2136if isinstance(G,PrimitiveGroup):2137return G._d == self._degree2138else:2139False21402141def __getitem__(self, n):2142r"""2143Return the `n`-th primitive group of a given degree.21442145INPUT:21462147- ``n`` -- a positive integer21482149EXAMPLES::21502151sage: PrimitiveGroups(5)[3] # optional - database_gap2152AGL(1, 5)21532154.. warning::21552156this follows GAP's naming convention of indexing the2157primitive groups starting from ``1``::21582159sage: PrimitiveGroups(5)[0] # optional - database_gap2160Traceback (most recent call last):2161...2162ValueError: Index n must be in {1,..,5}2163"""2164return PrimitiveGroup(self._degree, n)21652166def __iter__(self):2167"""2168EXAMPLES::21692170sage: list(PrimitiveGroups(5)) # indirect doctest # optional - database_gap2171[C(5), D(2*5), AGL(1, 5), A(5), S(5)]2172"""2173for n in xrange(1, self.cardinality() + 1):2174yield self[n]21752176@cached_method2177def cardinality(self):2178r"""2179Return the cardinality of ``self``.21802181OUTPUT:21822183An integer. The number of primitive groups of a given degree2184up to isomorphism.21852186EXAMPLES::21872188sage: PrimitiveGroups(0).cardinality() # optional - database_gap218912190sage: PrimitiveGroups(2).cardinality() # optional - database_gap219112192sage: PrimitiveGroups(7).cardinality() # optional - database_gap219372194sage: PrimitiveGroups(12).cardinality() # optional - database_gap219562196sage: [PrimitiveGroups(i).cardinality() for i in range(11)] # optional - database_gap2197[1, 1, 1, 2, 2, 5, 4, 7, 7, 11, 9]21982199The database_gap contains all primitive groups up to degree22002499::22012202sage: PrimitiveGroups(2500).cardinality() # optional - database_gap2203Traceback (most recent call last):2204...2205NotImplementedError: Only the primitive groups of degree less than22062500 are available in GAP's database22072208TESTS::22092210sage: type(PrimitiveGroups(12).cardinality()) # optional - database_gap2211<type 'sage.rings.integer.Integer'>2212sage: type(PrimitiveGroups(0).cardinality())2213<type 'sage.rings.integer.Integer'>2214"""2215# gap.NrPrimitiveGroups(0) fails, so Sage needs to handle this2216# While we are at it, and since Sage also handles the2217# primitive group of degree 1, we may as well handle 12218if self._degree <= 1:2219return Integer(1)2220elif self._degree >= 2500:2221raise NotImplementedError("Only the primitive groups of degree less than 2500 are available in GAP's database")2222else:2223try:2224return Integer(gap.NrPrimitiveGroups(gap(self._degree)))2225except RuntimeError:2226from sage.misc.misc import verbose2227verbose("Warning: PrimitiveGroups requires the GAP database package. Please install it with ``sage -i database_gap``.", level=0)222822292230class PermutationGroup_plg(PermutationGroup_unique):2231def base_ring(self):2232"""2233EXAMPLES::22342235sage: G = PGL(2,3)2236sage: G.base_ring()2237Finite Field of size 322382239sage: G = PSL(2,3)2240sage: G.base_ring()2241Finite Field of size 32242"""2243return self._base_ring22442245def matrix_degree(self):2246"""2247EXAMPLES::22482249sage: G = PSL(2,3)2250sage: G.matrix_degree()225122252"""2253return self._n22542255class PGL(PermutationGroup_plg):2256def __init__(self, n, q, name='a'):2257"""2258The projective general linear groups over GF(q).22592260INPUT:2261n -- positive integer; the degree2262q -- prime power; the size of the ground field2263name -- (default: 'a') variable name of indeterminate of finite field GF(q)22642265OUTPUT:2266PGL(n,q)22672268.. note::2269This group is also available via ``groups.permutation.PGL()``.22702271EXAMPLES::22722273sage: G = PGL(2,3); G2274Permutation Group with generators [(3,4), (1,2,4)]2275sage: print G2276The projective general linear group of degree 2 over Finite Field of size 32277sage: G.base_ring()2278Finite Field of size 32279sage: G.order()22802422812282sage: G = PGL(2, 9, 'b'); G2283Permutation Group with generators [(3,10,9,8,4,7,6,5), (1,2,4)(5,6,8)(7,9,10)]2284sage: G.base_ring()2285Finite Field in b of size 3^222862287sage: G.category()2288Category of finite permutation groups2289sage: TestSuite(G).run()22902291TESTS::22922293sage: groups.permutation.PGL(2, 3)2294Permutation Group with generators [(3,4), (1,2,4)]2295"""2296id = 'Group([()])' if n == 1 else 'PGL(%s,%s)'%(n,q)2297PermutationGroup_generic.__init__(self, gap_group=id)2298self._q = q2299self._base_ring = GF(q, name=name)2300self._n = n23012302def __str__(self):2303"""2304EXAMPLES::23052306sage: G = PGL(2,3); G2307Permutation Group with generators [(3,4), (1,2,4)]2308sage: print G2309The projective general linear group of degree 2 over Finite Field of size 32310"""2311return "The projective general linear group of degree %s over %s"%(self._n, self.base_ring())23122313class PSL(PermutationGroup_plg):2314def __init__(self, n, q, name='a'):2315"""2316The projective special linear groups over GF(q).23172318INPUT:23192320- n -- positive integer; the degree2321- q -- either a prime power (the size of the ground field) or a finite field2322- name -- (default: 'a') variable name of indeterminate of finite field GF(q)23232324OUTPUT:23252326the group PSL(n,q)23272328.. note::23292330This group is also available via ``groups.permutation.PSL()``.23312332EXAMPLES::23332334sage: G = PSL(2,3); G2335Permutation Group with generators [(2,3,4), (1,2)(3,4)]2336sage: G.order()2337122338sage: G.base_ring()2339Finite Field of size 32340sage: print G2341The projective special linear group of degree 2 over Finite Field of size 323422343We create two groups over nontrivial finite fields::23442345sage: G = PSL(2, 4, 'b'); G2346Permutation Group with generators [(3,4,5), (1,2,3)]2347sage: G.base_ring()2348Finite Field in b of size 2^22349sage: G = PSL(2, 8); G2350Permutation Group with generators [(3,8,6,4,9,7,5), (1,2,3)(4,7,5)(6,9,8)]2351sage: G.base_ring()2352Finite Field in a of size 2^323532354sage: G.category()2355Category of finite permutation groups2356sage: TestSuite(G).run()23572358TESTS::23592360sage: groups.permutation.PSL(2, 3)2361Permutation Group with generators [(2,3,4), (1,2)(3,4)]23622363Check that :trac:`7424` is handled::23642365sage: PSL(2, GF(7,'x'))2366Permutation Group with generators [(3,7,5)(4,8,6), (1,2,6)(3,4,8)]2367sage: PSL(2, GF(3))2368Permutation Group with generators [(2,3,4), (1,2)(3,4)]2369sage: PSL(2, QQ)2370Traceback (most recent call last):2371...2372ValueError: q must be a prime power or a finite field2373"""2374from sage.categories.finite_fields import FiniteFields2375if q in FiniteFields():2376name = q.gen()2377q = q.cardinality()2378if not(q in NonNegativeIntegers()):2379raise ValueError('q must be a prime power or a finite field')2380if n == 1:2381id = 'Group([()])'2382else:2383id = 'PSL(%s,%s)' % (n, q)2384PermutationGroup_generic.__init__(self, gap_group=id)2385self._q = q2386self._base_ring = GF(q, name=name)2387self._n = n23882389def __str__(self):2390"""2391EXAMPLES::23922393sage: G = PSL(2,3)2394sage: print G2395The projective special linear group of degree 2 over Finite Field of size 32396"""2397return "The projective special linear group of degree %s over %s"%(self._n, self.base_ring())23982399def ramification_module_decomposition_hurwitz_curve(self):2400"""2401Helps compute the decomposition of the ramification module2402for the Hurwitz curves X (over CC say) with automorphism group2403G = PSL(2,q), q a "Hurwitz prime" (ie, p is $\pm 1 \pmod 7$).2404Using this computation and Borne's formula helps determine the2405G-module structure of the RR spaces of equivariant2406divisors can be determined explicitly.24072408The output is a list of integer multiplicities: [m1,...,mn],2409where n is the number of conj classes of G=PSL(2,p) and mi is the2410multiplicity of pi_i in the ramification module of a2411Hurwitz curve with automorphism group G.2412Here IrrRepns(G) = [pi_1,...,pi_n] (in the order listed in the2413output of self.character_table()).24142415REFERENCE: David Joyner, Amy Ksir, Roger Vogeler,2416"Group representations on Riemann-Roch spaces of some2417Hurwitz curves," preprint, 2006.24182419EXAMPLES::24202421sage: G = PSL(2,13)2422sage: G.ramification_module_decomposition_hurwitz_curve() #random2423[0, 7, 7, 12, 12, 12, 13, 15, 14]24242425This means, for example, that the trivial representation does not2426occur in the ramification module of a Hurwitz curve with automorphism2427group PSL(2,13), since the trivial representation is listed first2428and that entry has multiplicity 0. The "randomness" is due to the2429fact that GAP randomly orders the conjugacy classes of the same order2430in the list of all conjugacy classes. Similarly, there is some2431randomness to the ordering of the characters.24322433If you try to use this function on a group PSL(2,q) where q is2434not a (smallish) "Hurwitz prime", an error message will be printed.2435"""2436if self.matrix_degree()!=2:2437raise ValueError("Degree must be 2.")2438F = self.base_ring()2439q = F.order()2440from sage.misc.misc import SAGE_EXTCODE2441gapcode = SAGE_EXTCODE + '/gap/joyner/hurwitz_crv_rr_sp.gap'2442gap.eval('Read("'+gapcode+'")')2443mults = gap.eval("ram_module_hurwitz("+str(q)+")")2444return eval(mults)24452446def ramification_module_decomposition_modular_curve(self):2447"""2448Helps compute the decomposition of the ramification module2449for the modular curve X(p) (over CC say) with automorphism group G = PSL(2,q),2450q a prime > 5. Using this computation and Borne's formula helps determine the2451G-module structure of the RR spaces of equivariant2452divisors can be determined explicitly.24532454The output is a list of integer multiplicities: [m1,...,mn],2455where n is the number of conj classes of G=PSL(2,p) and mi is the2456multiplicity of pi_i in the ramification module of a2457modular curve with automorphism group G.2458Here IrrRepns(G) = [pi_1,...,pi_n] (in the order listed in the2459output of self.character_table()).24602461REFERENCE: D. Joyner and A. Ksir, 'Modular representations2462on some Riemann-Roch spaces of modular curves2463$X(N)$', Computational Aspects of Algebraic Curves,2464(Editor: T. Shaska) Lecture Notes in Computing, WorldScientific,24652005.)24662467EXAMPLES::24682469sage: G = PSL(2,7)2470sage: G.ramification_module_decomposition_modular_curve() ## random2471[0, 4, 3, 6, 7, 8]24722473This means, for example, that the trivial representation does not2474occur in the ramification module of X(7), since the trivial representation2475is listed first and that entry has multiplicity 0. The "randomness" is due to the2476fact that GAP randomly orders the conjugacy classes of the same order2477in the list of all conjugacy classes. Similarly, there is some2478randomness to the ordering of the characters.2479"""2480if self.matrix_degree()!=2:2481raise ValueError("Degree must be 2.")2482F = self.base_ring()2483q = F.order()2484from sage.misc.misc import SAGE_EXTCODE2485gapcode = SAGE_EXTCODE + '/gap/joyner/modular_crv_rr_sp.gap'2486gap.eval('Read("'+gapcode+'")')2487mults = gap.eval("ram_module_X("+str(q)+")")2488return eval(mults)24892490class PSp(PermutationGroup_plg):2491def __init__(self, n, q, name='a'):2492"""2493The projective symplectic linear groups over GF(q).24942495INPUT:2496n -- positive integer; the degree2497q -- prime power; the size of the ground field2498name -- (default: 'a') variable name of indeterminate of finite field GF(q)24992500OUTPUT:2501PSp(n,q)25022503.. note::2504This group is also available via ``groups.permutation.PSp()``.25052506EXAMPLES::25072508sage: G = PSp(2,3); G2509Permutation Group with generators [(2,3,4), (1,2)(3,4)]2510sage: G.order()2511122512sage: G = PSp(4,3); G2513Permutation 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)]2514sage: G.order()2515259202516sage: print G2517The projective symplectic linear group of degree 4 over Finite Field of size 32518sage: G.base_ring()2519Finite Field of size 325202521sage: G = PSp(2, 8, name='alpha'); G2522Permutation Group with generators [(3,8,6,4,9,7,5), (1,2,3)(4,7,5)(6,9,8)]2523sage: G.base_ring()2524Finite Field in alpha of size 2^325252526TESTS::25272528sage: groups.permutation.PSp(2, 3)2529Permutation Group with generators [(2,3,4), (1,2)(3,4)]2530"""2531if n%2 == 1:2532raise TypeError("The degree n must be even")2533else:2534id = 'PSp(%s,%s)'%(n,q)2535PermutationGroup_generic.__init__(self, gap_group=id)2536self._q = q2537self._base_ring = GF(q, name=name)2538self._n = n25392540def __str__(self):2541"""2542EXAMPLES::25432544sage: G = PSp(4,3)2545sage: print G2546The projective symplectic linear group of degree 4 over Finite Field of size 32547"""2548return "The projective symplectic linear group of degree %s over %s"%(self._n, self.base_ring())25492550PSP = PSp25512552class PermutationGroup_pug(PermutationGroup_plg):2553def field_of_definition(self):2554"""2555EXAMPLES::25562557sage: PSU(2,3).field_of_definition()2558Finite Field in a of size 3^22559"""2560return self._field_of_definition25612562class PSU(PermutationGroup_pug):2563def __init__(self, n, q, name='a'):2564"""2565The projective special unitary groups over GF(q).25662567INPUT:2568n -- positive integer; the degree2569q -- prime power; the size of the ground field2570name -- (default: 'a') variable name of indeterminate of finite field GF(q)2571OUTPUT:2572PSU(n,q)25732574.. note::2575This group is also available via ``groups.permutation.PSU()``.25762577EXAMPLES::25782579sage: PSU(2,3)2580The projective special unitary group of degree 2 over Finite Field of size 325812582sage: G = PSU(2, 8, name='alpha'); G2583The projective special unitary group of degree 2 over Finite Field in alpha of size 2^32584sage: G.base_ring()2585Finite Field in alpha of size 2^325862587TESTS::25882589sage: groups.permutation.PSU(2, 3)2590The projective special unitary group of degree 2 over Finite Field of size 32591"""2592id = 'PSU(%s,%s)'%(n,q)2593PermutationGroup_generic.__init__(self, gap_group=id)2594self._q = q2595self._base_ring = GF(q, name=name)2596self._field_of_definition = GF(q**2, name)2597self._n = n25982599def _repr_(self):2600"""2601EXAMPLES::26022603sage: PSU(2,3)2604The projective special unitary group of degree 2 over Finite Field of size 326052606"""2607return "The projective special unitary group of degree %s over %s"%(self._n, self.base_ring())26082609class PGU(PermutationGroup_pug):2610def __init__(self, n, q, name='a'):2611"""2612The projective general unitary groups over GF(q).26132614INPUT:2615n -- positive integer; the degree2616q -- prime power; the size of the ground field2617name -- (default: 'a') variable name of indeterminate of finite field GF(q)26182619OUTPUT:2620PGU(n,q)26212622.. note::2623This group is also available via ``groups.permutation.PGU()``.26242625EXAMPLES::26262627sage: PGU(2,3)2628The projective general unitary group of degree 2 over Finite Field of size 326292630sage: G = PGU(2, 8, name='alpha'); G2631The projective general unitary group of degree 2 over Finite Field in alpha of size 2^32632sage: G.base_ring()2633Finite Field in alpha of size 2^326342635TESTS::26362637sage: groups.permutation.PGU(2, 3)2638The projective general unitary group of degree 2 over Finite Field of size 32639"""2640id = 'PGU(%s,%s)'%(n,q)2641PermutationGroup_generic.__init__(self, gap_group=id)2642self._q = q2643self._base_ring = GF(q, name=name)2644self._field_of_definition = GF(q**2, name)2645self._n = n26462647def _repr_(self):2648"""2649EXAMPLES::26502651sage: PGU(2,3)2652The projective general unitary group of degree 2 over Finite Field of size 326532654"""2655return "The projective general unitary group of degree %s over %s"%(self._n, self.base_ring())265626572658class SuzukiGroup(PermutationGroup_unique):2659def __init__(self, q, name='a'):2660r"""2661The Suzuki group over GF(q),2662$^2 B_2(2^{2k+1}) = Sz(2^{2k+1})$.26632664A wrapper for the GAP function SuzukiGroup.26652666INPUT:2667q -- 2^n, an odd power of 2; the size of the ground2668field. (Strictly speaking, n should be greater than 1, or2669else this group os not simple.)2670name -- (default: 'a') variable name of indeterminate of2671finite field GF(q)26722673OUTPUT:26742675- A Suzuki group.26762677.. note::2678This group is also available via ``groups.permutation.Suzuki()``.26792680EXAMPLES::26812682sage: SuzukiGroup(8)2683Permutation 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),2684(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)]2685sage: print SuzukiGroup(8)2686The Suzuki group over Finite Field in a of size 2^326872688sage: G = SuzukiGroup(32, name='alpha')2689sage: G.order()2690325376002691sage: G.order().factor()26922^10 * 5^2 * 31 * 412693sage: G.base_ring()2694Finite Field in alpha of size 2^526952696TESTS::26972698sage: groups.permutation.Suzuki(8)2699Permutation 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),2700(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)]27012702REFERENCES:27032704- http://en.wikipedia.org/wiki/Group_of_Lie_type\#Suzuki-Ree_groups2705"""2706q = Integer(q)2707from sage.rings.arith import valuation2708t = valuation(q, 2)2709if 2**t != q or is_even(t):2710raise ValueError("The ground field size %s must be an odd power of 2." % q)2711id = 'SuzukiGroup(IsPermGroup,%s)'%q2712PermutationGroup_generic.__init__(self, gap_group=id)2713self._q = q2714self._base_ring = GF(q, name=name)27152716def base_ring(self):2717"""2718EXAMPLES::27192720sage: G = SuzukiGroup(32, name='alpha')2721sage: G.base_ring()2722Finite Field in alpha of size 2^52723"""2724return self._base_ring27252726def __str__(self):2727"""2728EXAMPLES::27292730sage: G = SuzukiGroup(32, name='alpha')2731sage: print G2732The Suzuki group over Finite Field in alpha of size 2^527332734"""2735return "The Suzuki group over %s"%self.base_ring()273627372738