Ticket #7244: trac_7244_dicyclic_groups.patch

File trac_7244_dicyclic_groups.patch, 11.2 KB (added by rbeezer, 12 years ago)
  • sage/groups/perm_gps/all.py

    # HG changeset patch
    # User Rob Beezer <beezer@ups.edu>
    # Date 1256178808 25200
    # Node ID d23bfc1efdc262769e5c455c1a5fccc9b8805427
    # Parent  b2e4f0a8408e8c3c8bbee22946410ca3771f213f
    Trac 7244: dicyclic groups as permutation groups
    
    diff -r b2e4f0a8408e -r d23bfc1efdc2 sage/groups/perm_gps/all.py
    a b  
    33
    44from permgroup_named import (SymmetricGroup, AlternatingGroup,
    55                       DihedralGroup, CyclicPermutationGroup,
    6                        TransitiveGroup, PGL, PSL, PSp,PSU,PGU,
    7                        MathieuGroup, KleinFourGroup, SuzukiGroup)
     6                       DiCyclicGroup, TransitiveGroup, PGL, PSL, PSp,PSU,PGU,
     7                       MathieuGroup, KleinFourGroup, QuaternionGroup,
     8                       SuzukiGroup)
    89
    910from permgroup import  PermutationGroup, PermutationGroup_generic, PermutationGroup_subgroup, direct_product_permgroups
    1011
  • sage/groups/perm_gps/permgroup_named.py

    diff -r b2e4f0a8408e -r d23bfc1efdc2 sage/groups/perm_gps/permgroup_named.py
    a b  
    11r"""
    22"Named" Permutation groups (such as the symmetric group, S_n)
    3            
     3
    44You can construct the following permutation groups:
    55
    66-- SymmetricGroup, $S_n$ of order $n!$ (n can also be a list $X$ of distinct
    77                   positive integers, in which case it returns $S_X$)
    8      
     8
    99-- AlternatingGroup, $A_n$ or order $n!/2$ (n can also be a list $X$
    1010                   of distinct positive integers, in which case it returns
    1111                   $A_X$)
    12        
     12
    1313-- DihedralGroup, $D_n$ of order $2n$
    14        
     14
    1515-- CyclicPermutationGroup, $C_n$ of order $n$
    16        
     16
     17-- DiCyclicGroup, nonabelian groups of order `4m` with a unique element of order 2
     18
    1719-- TransitiveGroup, $i^{th}$ transitive group of degree $n$
    1820                      from the GAP tables of transitive groups (requires
    1921                      the "optional" package database_gap)
     
    2224
    2325-- KleinFourGroup, subgroup of $S_4$ of order $4$ which is not $C_2 \times C_2$
    2426
     27-- QuaternionGroup, non-abelian group of order `8`, `\{\pm 1, \pm I, \pm J, \pm K\}`
     28
    2529-- PGL(n,q), projective general linear group of $n\times n$ matrices over
    2630             the finite field GF(q)
    2731
     
    350354        invs = [x[0]**x[1] for x in a]
    351355        G = AbelianGroup(len(a),invs)
    352356        return G
    353                
     357
     358class DiCyclicGroup(PermutationGroup_generic):
     359    r"""
     360    The dicyclic group of order `4n`, for `n\geq 2`.
     361
     362    INPUT:
     363        - n -- a positive integer, two or greater
     364
     365    OUTPUT:
     366
     367    This is a nonabelian group similar in some respects to the
     368    dihedral group of the same order, but with far fewer
     369    elements of order 2 (it has just one).  The permutation
     370    representation constructed here is based on the presentation
     371
     372    .. MATH::
     373
     374        \langle a, x\mid a^{2n}=1, x^{2}=a^{n}, x^{-1}ax=a^{-1}\rangle
     375
     376    For `n=2` this is the group of quaternions
     377    (`{\pm 1, \pm I,\pm J, \pm K}`), which is the nonabelian
     378    group of order 8 that is not the dihedral group `D_4`,
     379    the symmetries of a square.  For `n=3` this is the nonabelian
     380    group of order 12 that is not the dihedral group `D_6`
     381    nor the alternating group `A_4`.  This group of order 12 is
     382    also the semi-direct product of of `C_2` by `C_4`,
     383    `C_3\rtimes C_4`.  [CONRAD2009]_
     384
     385
     386    When the order of the group is a
     387    power of 2 it is known as a "generalized quaternion group."
     388
     389    IMPLEMENTATION:
     390
     391    The presentation above means every element can be written as
     392    `a^{i}x^{j}` with `0\leq j<2n`, `j=0,1`.  We code `a^i` as the symbol
     393    `i+1` and code `a^{i}x` as the symbol `2n+i+1`.  The two generators
     394    are then represented using a left regular representation.
     395
     396    EXAMPLES:
     397
     398    A dicyclic group of order 384, with a large power of 2 as a divisor::
     399
     400        sage: n = 3*2^5
     401        sage: G = DiCyclicGroup(n)
     402        sage: G.order()
     403        384
     404        sage: a = G.gen(0)
     405        sage: x = G.gen(1)
     406        sage: a^(2*n)
     407        ()
     408        sage: a^n==x^2
     409        True
     410        sage: x^-1*a*x==a^-1
     411        True
     412
     413    A large generalized quaternion group (order is a power of 2)::
     414
     415        sage: n = 2^10
     416        sage: G=DiCyclicGroup(n)
     417        sage: G.order()
     418        4096
     419        sage: a = G.gen(0)
     420        sage: x = G.gen(1)
     421        sage: a^(2*n)
     422        ()
     423        sage: a^n==x^2
     424        True
     425        sage: x^-1*a*x==a^-1
     426        True
     427
     428    Just like the dihedral group, the dicyclic group has
     429    an element whose order is half the order of the group.
     430    Unlike the dihedral group, the dicyclic group has only
     431    one element of order 2.  Like the dihedral groups of
     432    even order, the center of the dicyclic group is a
     433    subgroup of order 2 (thus has the unique element of
     434    order 2 as its non-identity element). ::
     435
     436        sage: G=DiCyclicGroup(3*5*4)
     437        sage: G.order()
     438        240
     439        sage: two = [g for g in G if g.order()==2]; two
     440        [(1,5)(2,6)(3,7)(4,8)(9,13)(10,14)(11,15)(12,16)]
     441        sage: G.center().order()
     442        2
     443
     444    For small orders, we check this is really a group
     445    we do not have in Sage otherwise. ::
     446
     447        sage: G = DiCyclicGroup(2)
     448        sage: H = DihedralGroup(4)
     449        sage: G.is_isomorphic(H)
     450        False
     451        sage: G = DiCyclicGroup(3)
     452        sage: H = DihedralGroup(6)
     453        sage: K = AlternatingGroup(6)
     454        sage: G.is_isomorphic(H) or G.is_isomorphic(K)
     455        False
     456
     457    REFERENCES:
     458
     459        .. [CONRAD2009] `Groups of order 12
     460          <http://www.math.uconn.edu/~kconrad/blurbs/grouptheory/group12.pdf>`_.
     461          Keith Conrad, accessed 21 October 2009.
     462
     463    AUTHOR:
     464        - Rob Beezer (2009-10-18)
     465    """
     466    def __init__(self, n):
     467        r"""
     468        The dicyclic group of order `4*n`, as a permutation group.
     469
     470        INPUT:
     471            n -- a positive integer, two or greater
     472
     473        EXAMPLES:
     474            sage: G = DiCyclicGroup(3*8)
     475            sage: G.order()
     476            96
     477            sage: loads(G.dumps()) == G
     478            True
     479        """
     480        n = Integer(n)
     481        if n < 2:
     482            raise ValueError, "n (=%s) must be 2 or greater"%n
     483
     484        # Certainly 2^2 is part of the first factor of the order
     485        #   r is maximum power of 2 in the order
     486        #   m is the rest, the odd part
     487        order = 4*n
     488        factored = order.factor()
     489        r = factored[0][0]**factored[0][1]
     490        m = order//r
     491        halfr, fourthr = r//2, r//4
     492
     493        # Representation of  a
     494        # Two cycles of length halfr
     495        a = [tuple(range(1, halfr+1)), tuple(range(halfr+1, r+1))]
     496        # With an odd part, a cycle of length m will give the right order for a
     497        if m > 1:
     498            a.append( tuple(range(r+1,r+m+1)) )
     499
     500        # Representation of  x
     501        # Four-cycles that will conjugate the generator  a  properly
     502        x = [(i+1, (-i)%halfr + halfr + 1, (fourthr+i)%halfr + 1, (-fourthr-i)%halfr + halfr + 1)
     503                for i in range(0, fourthr)]
     504        # With an odd part, transpositions will conjugate the m-cycle to create inverse
     505        if m > 1:
     506            x += [(r+i+1,r+m-i) for i in range(0, (m-1)//2)]
     507
     508        PermutationGroup_generic.__init__(self, gens=[a,x])
     509
     510    def _repr_(self):
     511        r"""
     512        EXAMPLES:
     513            sage: DiCyclicGroup(12)
     514            Diyclic group of order 48 as a permutation group
     515        """
     516        return "Diyclic group of order %s as a permutation group"%self.order()
     517
     518    def is_commutative(self):
     519        r"""
     520        Return True if this group is commutative.
     521
     522        EXAMPLES::
     523       
     524            sage: D = DiCyclicGroup(12)
     525            sage: D.is_commutative()
     526            False
     527        """
     528        return False
     529
     530    def is_abelian(self):
     531        r"""
     532        Return True if this group is abelian.
     533
     534        EXAMPLES::
     535       
     536            sage: D = DiCyclicGroup(12)
     537            sage: D.is_abelian()
     538            False
     539        """
     540        return False
     541
    354542class KleinFourGroup(PermutationGroup_generic):
    355543    def __init__(self):
    356544        r"""
     
    364552            sage: G = KleinFourGroup(); G
    365553            The Klein 4 group of order 4, as a permutation group
    366554            sage: list(G)
    367             [(), (3,4), (1,2), (1,2)(3,4)]       
     555            [(), (3,4), (1,2), (1,2)(3,4)]
    368556
    369557        TESTS:
    370558            sage: G == loads(dumps(G))
     
    383571            The Klein 4 group of order 4, as a permutation group
    384572        """
    385573        return 'The Klein 4 group of order 4, as a permutation group'
    386        
     574
     575class QuaternionGroup(DiCyclicGroup):
     576    r"""
     577    The quaternion group of order 8.
     578
     579    OUTPUT:
     580        The quaternion group of order 8, as a permutation group.
     581        See the ``DiCyclicGroup`` class for a generalization of this
     582        construction.
     583
     584    EXAMPLES:
     585
     586    The quaternion group is one of two non-abelian groups of order 8,
     587    the other being the dihedral group `D_4`.  One way to describe this
     588    group is with three generators, `I, J, K`, so the whole group is
     589    then given as the set `\{\pm 1, \pm I, \pm J, \pm K\}` with relations
     590    such as `I^2=J^2=K^2=-1`, `IJ=K` and `JI=-K`.
     591
     592    The examples below illustrate how to use this group in a similar
     593    manner, by testing some of these relations.  The representation used
     594    here is the left-regular representation. ::
     595
     596        sage: Q = QuaternionGroup()
     597        sage: I = Q.gen(0)
     598        sage: J = Q.gen(1)
     599        sage: K = I*J
     600        sage: [I,J,K]
     601        [(1,2,3,4)(5,6,7,8), (1,5,3,7)(2,8,4,6), (1,8,3,6)(2,7,4,5)]
     602        sage: neg_one = I^2; neg_one
     603        (1,3)(2,4)(5,7)(6,8)
     604        sage: J^2 == neg_one and K^2 == neg_one
     605        True
     606        sage: J*I == neg_one*K
     607        True
     608        sage: Q.center().order() == 2
     609        True
     610        sage: neg_one in Q.center()
     611        True
     612
     613    AUTHOR:
     614        -- Rob Beezer (2009-10-09)
     615    """
     616    def __init__(self):
     617        r"""
     618        TESTS::
     619
     620            sage: Q = QuaternionGroup()
     621            sage: Q == loads(dumps(Q))
     622            True
     623        """
     624        DiCyclicGroup.__init__(self, 2)
     625
     626    def _repr_(self):
     627        r"""
     628        EXAMPLES:
     629            sage: Q=QuaternionGroup(); Q
     630            Quaternion group of order 8 as a permutation group
     631        """
     632        return "Quaternion group of order 8 as a permutation group"
    387633
    388634class DihedralGroup(PermutationGroup_generic):
    389635    def __init__(self, n):
     
    431677        TESTS:
    432678            sage: G == loads(dumps(G))
    433679            True
    434         """       
     680        """
    435681        n = Integer(n)
    436682        if n <= 0:
    437683            raise ValueError, "n must be positive"
     
    453699            gens = tuple([tuple(gen0),tuple(gen1)])
    454700
    455701        PermutationGroup_generic.__init__(self, gens)
    456        
     702
    457703    def _repr_(self):
    458704        """
    459705        EXAMPLES:
    460706            sage: G = DihedralGroup(5); G
    461             Dihedral group of order 10 as a permutation group       
     707            Dihedral group of order 10 as a permutation group
    462708        """
    463709        return "Dihedral group of order %s as a permutation group"%self.order()
    464710