Ticket #8500: trac_8500_transitive_groups-final.patch

File trac_8500_transitive_groups-final.patch, 16.0 KB (added by nthiery, 12 years ago)

Apply only this one

  • doc/en/reference/groups.rst

    # HG changeset patch
    # User Nicolas M. Thiery <nthiery@users.sf.net>
    # Date 1271698071 -7200
    # Node ID 9ec5f8429d440c4bb9354206d6073b6dc4718c17
    # Parent  653b64e8f580a66effc4530d333f61590ee1e323
    #8500: Adds the sets TransitiveGroups(d) and TransitiveGroups()
    
    diff --git a/doc/en/reference/groups.rst b/doc/en/reference/groups.rst
    a b Groups 
    1313   sage/groups/abelian_gps/abelian_group_morphism
    1414   sage/groups/abelian_gps/dual_abelian_group
    1515   sage/groups/perm_gps/permgroup
     16   sage/groups/perm_gps/permgroup_named
    1617   sage/groups/perm_gps/permgroup_element
    1718   sage/groups/perm_gps/permgroup_morphism
    1819   sage/groups/perm_gps/cubegroup
  • sage/groups/perm_gps/all.py

    diff --git a/sage/groups/perm_gps/all.py b/sage/groups/perm_gps/all.py
    a b from permgroup_named import (SymmetricGr 
    55                       DihedralGroup, CyclicPermutationGroup,
    66                       DiCyclicGroup, TransitiveGroup, PGL, PSL, PSp,PSU,PGU,
    77                       MathieuGroup, KleinFourGroup, QuaternionGroup,
    8                        SuzukiGroup)
     8                       SuzukiGroup, TransitiveGroups)
    99
    1010from permgroup import  PermutationGroup, PermutationGroup_generic, PermutationGroup_subgroup, direct_product_permgroups
    1111
  • sage/groups/perm_gps/permgroup_named.py

    diff --git a/sage/groups/perm_gps/permgroup_named.py b/sage/groups/perm_gps/permgroup_named.py
    a b You can construct the following permutat 
    1616
    1717-- DiCyclicGroup, nonabelian groups of order `4m` with a unique element of order 2
    1818
    19 -- TransitiveGroup, $i^{th}$ transitive group of degree $n$
     19-- TransitiveGroup, $n^{th}$ transitive group of degree $d$
    2020                      from the GAP tables of transitive groups (requires
    2121                      the "optional" package database_gap)
    2222
     23-- TransitiveGroups(d), TransitiveGroups(), set of all of the above
     24
    2325-- MathieuGroup(degree), Mathieu group of degree 9, 10, 11, 12, 21, 22, 23, or 24.
    2426
    2527-- KleinFourGroup, subgroup of $S_4$ of order $4$ which is not $C_2 \times C_2$
    from sage.rings.all import Integer 
    7274from sage.interfaces.all import gap
    7375from sage.rings.finite_field import FiniteField as GF
    7476from sage.rings.arith import factor
     77from sage.rings.integer_ring import ZZ
    7578from sage.groups.abelian_gps.abelian_group import AbelianGroup
    7679from sage.misc.functional import is_even
    7780from sage.misc.cachefunc import cached_method
    7881from sage.groups.perm_gps.permgroup import PermutationGroup_generic
    7982from sage.groups.perm_gps.permgroup_element import PermutationGroupElement
    8083from sage.structure.unique_representation import UniqueRepresentation
     84from sage.structure.parent import Parent
     85from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
     86from sage.sets.disjoint_union_enumerated_sets import DisjointUnionEnumeratedSets
     87from sage.categories.infinite_enumerated_sets import InfiniteEnumeratedSets
     88from sage.categories.enumerated_sets import EnumeratedSets
     89from sage.sets.non_negative_integers import NonNegativeIntegers
     90from sage.sets.family import Family
    8191
    8292class PermutationGroup_unique(UniqueRepresentation, PermutationGroup_generic):
    8393
    class MathieuGroup(PermutationGroup_uniq 
    853863            Mathieu group of degree 12 and order 95040 as a permutation group
    854864        """
    855865        return "Mathieu group of degree %s and order %s as a permutation group"%(self._n,self.order())
    856    
     866
    857867class TransitiveGroup(PermutationGroup_unique):
    858868    def __init__(self, d, n):
    859869        """
    860870        The transitive group from the GAP tables of transitive groups.
    861        
     871
    862872        INPUT:
    863873            d -- positive integer; the degree
    864874            n -- positive integer; the number
    class TransitiveGroup(PermutationGroup_u 
    868878
    869879        EXAMPLES::
    870880
    871             sage: G = TransitiveGroup(1,1); G
     881            sage: TransitiveGroup(0,1)
     882            Transitive group number 1 of degree 0
     883            sage: TransitiveGroup(1,1)
    872884            Transitive group number 1 of degree 1
    873             sage: G = TransitiveGroup(5, 2); G         # requires optional database_gap 
     885            sage: G = TransitiveGroup(5, 2); G         # requires optional database_gap
    874886            Transitive group number 2 of degree 5
    875             sage: G.gens()                             # requires optional database_gap 
     887            sage: G.gens()                             # requires optional database_gap
    876888            [(1,2,3,4,5), (1,4)(2,3)]
    877889
    878             sage: G.category()
     890            sage: G.category()                         # requires optional database_gap
    879891            Category of finite permutation groups
    880             sage: TestSuite(G).run()
     892
     893        .. warning:: this follows GAP's naming convention of indexing
     894          the transitive groups starting from ``1``::
     895
     896            sage: TransitiveGroup(5,0)
     897            Traceback (most recent call last):
     898            ...
     899              assert n > 0
     900            AssertionError
     901
     902        .. warning:: only transitive groups of "small" degree are
     903          available in GAP's database::
     904
     905            sage: TransitiveGroup(31,1)                # requires optional database_gap
     906            Traceback (most recent call last):
     907            ...
     908            NotImplementedError: Only the transitive groups of order less than 30 are available in GAP's database
     909
     910        TESTS::
     911
     912            sage: TestSuite(TransitiveGroup(0,1)).run()
     913            sage: TestSuite(TransitiveGroup(1,1)).run()
     914            sage: TestSuite(TransitiveGroup(5,2)).run()# requires optional database_gap
     915
     916            sage: TransitiveGroup(1,5)
     917            Traceback (most recent call last):
     918            ...
     919            AssertionError: n should be in {1,..,1}
    881920        """
    882         id = 'Group([()])' if d == 1 else 'TransitiveGroup(%s,%s)'%(d,n)
     921        d = ZZ(d)
     922        n = ZZ(n)
     923        assert d >= 0
     924        assert n > 0
     925        max_n = TransitiveGroups(d).cardinality()
     926        assert n <= max_n, "n should be in {1,..,%s}"%max_n
     927        gap_group = 'Group([()])' if d in [0,1] else 'TransitiveGroup(%s,%s)'%(d,n)
    883928        try:
    884             PermutationGroup_generic.__init__(self, gap_group=id)
     929            PermutationGroup_generic.__init__(self, gap_group=gap_group)
    885930        except RuntimeError:
    886931            from sage.misc.misc import verbose
    887932            verbose("Warning: Computing with TransitiveGroups requires the optional database_gap package. Please install it.", level=0)
    888        
     933
    889934        self._d = d
    890935        self._n = n
    891        
     936
    892937    def _repr_(self):
    893938        """
    894939        EXAMPLES:
    class TransitiveGroup(PermutationGroup_u 
    897942        """
    898943        return "Transitive group number %s of degree %s"%(self._n, self._d)
    899944
     945def TransitiveGroups(d=None):
     946    """
     947    INPUT:
     948
     949     - ``d`` -- an integer (optional)
     950
     951    Returns the set of all transitive groups of a given degree
     952    ``d``. If ``d`` is not specified, it returns the set of all
     953    transitive groups.
     954
     955    Warning: TransitiveGroups requires the optional GAP database
     956    package. Please install it with ``sage -i database_gap``.
     957
     958    EXAMPLES::
     959
     960        sage: TransitiveGroups(3)
     961        Transitive Groups of degree 3
     962        sage: TransitiveGroups(7)
     963        Transitive Groups of degree 7
     964        sage: TransitiveGroups(8)
     965        Transitive Groups of degree 8
     966
     967        sage: TransitiveGroups()
     968        Transitive Groups
     969
     970    .. warning:: in practice, the database currently only contains
     971      transitive groups up to degree 30::
     972
     973        sage: TransitiveGroups(31).cardinality() # requires optional database_gap
     974        Traceback (most recent call last):
     975        ...
     976        NotImplementedError: Only the transitive groups of order less than 30 are available in GAP's database
     977
     978    """
     979    if d == None:
     980        return TransitiveGroupsAll()
     981    else:
     982        d == Integer(d)
     983        assert d >= 0, "A transitive group acts on a non negative integer number of positions"
     984        return TransitiveGroupsOfDegree(d)
     985
     986class TransitiveGroupsAll(DisjointUnionEnumeratedSets):
     987    """
     988    The infinite set of all transitive groups.
     989
     990    EXAMPLES::
     991
     992        sage: L = TransitiveGroups(); L
     993        Transitive Groups
     994        sage: L.category()
     995        Category of infinite enumerated sets
     996        sage: L.cardinality()
     997        +Infinity
     998
     999        sage: p = L.__iter__()            # requires optional database_gap
     1000        sage: (p.next(), p.next(), p.next(), p.next(), p.next(), p.next(), p.next(), p.next()) # requires optional database_gap
     1001        (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)
     1002
     1003    TESTS::
     1004
     1005        sage: TestSuite(TransitiveGroups()).run() # requires optional database_gap # long time
     1006    """
     1007    def __init__(self):
     1008        """
     1009        TESTS::
     1010
     1011            sage: S = TransitiveGroups() # requires optional database_gap
     1012            sage: S.category() # requires optional database_gap
     1013            Category of infinite enumerated sets
     1014        """
     1015        DisjointUnionEnumeratedSets.__init__(self, Family(NonNegativeIntegers(), lambda i: TransitiveGroups(i)) )
     1016
     1017    def _repr_(self):
     1018        """
     1019        TESTS::
     1020
     1021            sage: TransitiveGroups() # requires optional database_gap # indirect doctest
     1022            Transitive Groups
     1023        """
     1024        return "Transitive Groups"
     1025
     1026    def __contains__(self, G):
     1027        r"""
     1028        EXAMPLES::
     1029
     1030            sage: TransitiveGroup(5,2) in TransitiveGroups() # requires optional database_gap
     1031            True
     1032            sage: TransitiveGroup(6,5) in TransitiveGroups() # requires optional database_gap
     1033            True
     1034            sage: 1 in TransitiveGroups() # requires optional database_gap
     1035            False
     1036        """
     1037        return isinstance(G,TransitiveGroup)
     1038
     1039    def _an_element_(self):
     1040        """
     1041        Returns an element of ``self``.
     1042
     1043        EXAMPLES::
     1044
     1045            sage: TransitiveGroups(5).an_element() # requires optional database_gap # indirect doctest
     1046            Transitive group number 1 of degree 5
     1047        """
     1048        return TransitiveGroup(7,3)
     1049
     1050class TransitiveGroupsOfDegree(UniqueRepresentation, Parent):
     1051    """
     1052    The set of all transitive groups of a given (small) degree.
     1053
     1054    EXAMPLES::
     1055
     1056        sage: S = TransitiveGroups(4); S       # requires optional database_gap
     1057        Transitive Groups of degree 4
     1058        sage: list(S)                          # requires optional database_gap
     1059        [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]
     1060
     1061        sage: TransitiveGroups(5).an_element() # requires optional database_gap
     1062        Transitive group number 1 of degree 5
     1063
     1064    We write the cardinality of all transitive groups of degree 5::
     1065
     1066        sage: for G in TransitiveGroups(5):    # requires optional database_gap
     1067        ...       print G.cardinality()
     1068        5
     1069        10
     1070        20
     1071        60
     1072        120
     1073
     1074    TESTS::
     1075
     1076        sage: TestSuite(TransitiveGroups(3)).run() # requires optional database_gap
     1077
     1078
     1079    """
     1080    def __init__(self, n):
     1081        """
     1082        TESTS::
     1083
     1084            sage: S = TransitiveGroups(4) # requires optional database_gap
     1085            sage: S.category() # requires optional database_gap
     1086            Category of finite enumerated sets
     1087        """
     1088        self._degree = n
     1089        Parent.__init__(self, category = FiniteEnumeratedSets())
     1090
     1091    def _repr_(self):
     1092        """
     1093        TESTS::
     1094
     1095            sage: TransitiveGroups(6) # requires optional database_gap
     1096            Transitive Groups of degree 6
     1097        """
     1098        return "Transitive Groups of degree %s"%(self._degree)
     1099
     1100    def __contains__(self, G):
     1101        r"""
     1102        EXAMPLES::
     1103
     1104            sage: TransitiveGroup(6,5) in TransitiveGroups(4) # requires optional database_gap
     1105            False
     1106            sage: TransitiveGroup(4,3) in TransitiveGroups(4) # requires optional database_gap
     1107            True
     1108            sage: 1 in TransitiveGroups(4) # requires optional database_gap
     1109            False
     1110        """
     1111        if isinstance(G,TransitiveGroup):
     1112            return G._d == self._degree
     1113        else:
     1114            False
     1115
     1116    def __getitem__(self, n):
     1117        r"""
     1118        INPUT:
     1119
     1120         - ``n`` -- a positive integer
     1121
     1122        Returns the `n`-th transitive group of a given degree.
     1123
     1124        EXAMPLES::
     1125
     1126            sage: TransitiveGroups(5)[3]          # requires optional database_gap#
     1127            Transitive group number 3 of degree 5
     1128
     1129        .. warning:: this follows GAP's naming convention of indexing
     1130        the transitive groups starting from ``1``::
     1131
     1132            sage: TransitiveGroups(5)[0]
     1133            Traceback (most recent call last):
     1134            ...
     1135                assert n > 0
     1136            AssertionError
     1137        """
     1138        return TransitiveGroup(self._degree, n)
     1139
     1140    def __iter__(self):
     1141        """
     1142        EXAMPLES::
     1143
     1144            sage: list(TransitiveGroups(5)) # indirect doctest # requires optional database_gap
     1145            [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]
     1146        """
     1147        for n in xrange(1, self.cardinality() + 1):
     1148            yield self[n]
     1149
     1150    _an_element_ = EnumeratedSets.ParentMethods._an_element_
     1151
     1152    @cached_method
     1153    def cardinality(self):
     1154        r"""
     1155        Returns the cardinality of ``self``, that is the number of
     1156        transitive groups of a given degree.
     1157
     1158        EXAMPLES::
     1159
     1160            sage: TransitiveGroups(0).cardinality()                      # requires optional database_gap
     1161            1
     1162            sage: TransitiveGroups(2).cardinality()                      # requires optional database_gap
     1163            1
     1164            sage: TransitiveGroups(7).cardinality()                      # requires optional database_gap
     1165            7
     1166            sage: TransitiveGroups(12).cardinality()                     # requires optional database_gap
     1167            301
     1168            sage: [TransitiveGroups(i).cardinality() for i in range(11)] # requires optional database_gap
     1169            [1, 1, 1, 2, 5, 5, 16, 7, 50, 34, 45]
     1170
     1171        .. warning:: The database_gap contains all transitive groups
     1172          up to degree 30::
     1173
     1174            sage: TransitiveGroups(31).cardinality()                     # requires optional database_gap
     1175            Traceback (most recent call last):
     1176            ...
     1177            NotImplementedError: Only the transitive groups of order less than 30 are available in GAP's database
     1178
     1179        TESTS::
     1180
     1181            sage: type(TransitiveGroups(12).cardinality())               # requires optional database_gap
     1182            <type 'sage.rings.integer.Integer'>
     1183            sage: type(TransitiveGroups(0).cardinality())
     1184            <type 'sage.rings.integer.Integer'>
     1185        """
     1186        # gap.NrTransitiveGroups(0) fails, so Sage needs to handle this
     1187
     1188        # While we are at it, and since Sage also handles the
     1189        # transitive group of degree 1, we may as well handle 1
     1190        if self._degree <= 1:
     1191            return ZZ(1)
     1192        else:
     1193            try:
     1194                return Integer(gap.NrTransitiveGroups(gap(self._degree)))
     1195            except RuntimeError:
     1196                from sage.misc.misc import verbose
     1197                verbose("Warning: TransitiveGroups requires the GAP database package. Please install it with ``sage -i database_gap``.", level=0)
     1198            except TypeError:
     1199                raise NotImplementedError, "Only the transitive groups of order less than 30 are available in GAP's database"
     1200
    9001201class PermutationGroup_plg(PermutationGroup_unique):
    9011202    def base_ring(self):
    9021203        """