Ticket #10976: trac_10976.7.patch

File trac_10976.7.patch, 5.1 KB (added by swenson, 9 years ago)
  • sage/groups/perm_gps/permgroup.py

    # HG changeset patch
    # User Christopher Swenson <chris@caswenson.com>
    # Date 1330946247 18000
    # Node ID bec44d96096cc966d6fe0a8f4afb9c827fe94c2a
    # Parent  5cd9ba8e4eda25c80e887ef96cde7e422478a142
    Fixed comment in PermutationGroup._order
    
    diff --git a/sage/groups/perm_gps/permgroup.py b/sage/groups/perm_gps/permgroup.py
    a b  
    13311331        # S_n, where n is the number of generators supported.
    13321332        #
    13331333        # The code that follows checks that the following assumptions hold:
    1334         #     * All generators have order 2
    1335         #     * All generators share a common element
     1334        #     * All generators are transpositions (i.e., permutations that switch
     1335        #       two elements and leave everything else fixed),
     1336        #     * All generators share a common element.
    13361337        #
    13371338        # We then know that this group is isomorphic to S_n,
    13381339        # and therefore its order is n!.
  • sage/groups/perm_gps/permgroup.py

    # HG changeset patch
    # User Christopher Swenson <chris@caswenson.com>
    # Date 1329015846 18000
    # Node ID 5cd9ba8e4eda25c80e887ef96cde7e422478a142
    # Parent  c239be1054e01526a1b0b62da6691061b9dd5587
    Fixed the order of certain permutation groups to be much faster to compute.
    
    diff --git a/sage/groups/perm_gps/permgroup.py b/sage/groups/perm_gps/permgroup.py
    a b  
    9090
    9191- Nicolas Borie (2009): Added orbit, transversals, stabiliser and strong_generating_system methods
    9292
     93- Christopher Swenson (2012): Added a special case to compute the order efficiently.
     94  (This patch Copyright 2012 Google Inc. All Rights Reserved. )
     95
    9396REFERENCES:
    9497
    9598- Cameron, P., Permutation Groups. New York: Cambridge University
     
    132135from sage.misc.package import is_package_installed
    133136from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
    134137from sage.categories.all import FiniteEnumeratedSets
     138from sage.functions.other import factorial
    135139
    136140def load_hap():
    137141    """
     
    12891293        return '\\langle ' + \
    12901294               ', '.join([x._latex_() for x in self.gens()]) + ' \\rangle'
    12911295
     1296    def _order(self):
     1297        """
     1298        This handles a few special cases of computing the subgroup order much
     1299        faster than GAP.
     1300
     1301        This currently operates very quickly for stabilizer subgroups of
     1302        permutation groups, for one.
     1303
     1304        Will return None if the we could not easily compute it.
     1305
     1306        Author: Christopher Swenson
     1307
     1308        EXAMPLES::
     1309
     1310            sage: SymmetricGroup(10).stabilizer(4)._order()
     1311            362880
     1312            sage: SymmetricGroup(10).stabilizer(4).stabilizer(5)._order()
     1313            40320
     1314            sage: SymmetricGroup(200).stabilizer(100)._order() == factorial(199) # this should be very fast
     1315            True
     1316       
     1317        TESTS::
     1318
     1319            sage: [SymmetricGroup(n).stabilizer(1)._gap_().Size() for n in [4..10]]
     1320            [6, 24, 120, 720, 5040, 40320, 362880]
     1321            sage: [SymmetricGroup(n).stabilizer(1)._order() for n in [4..10]]
     1322            [6, 24, 120, 720, 5040, 40320, 362880]
     1323        """
     1324        gens = self.gens()
     1325        # This special case only works with more than 1 generator.
     1326        if not gens or len(gens) < 2:
     1327            return None
     1328        # Special case: certain subgroups of the symmetric group for which Gap reports
     1329        # generators of the form ((1, 2), (1, 3), ...)
     1330        # This means that this group is isomorphic to a smaller symmetric group
     1331        # S_n, where n is the number of generators supported.
     1332        #
     1333        # The code that follows checks that the following assumptions hold:
     1334        #     * All generators have order 2
     1335        #     * All generators share a common element
     1336        #
     1337        # We then know that this group is isomorphic to S_n,
     1338        # and therefore its order is n!.
     1339       
     1340        # Check that all generators are order 2 and have length-1 cycle tuples.
     1341        for g in gens:
     1342            if g.order() != 2:
     1343                return None
     1344            if len(g.cycle_tuples()) != 1:
     1345                return None
     1346        # Find the common element.
     1347        g0 = gens[0].cycle_tuples()[0]
     1348        g1 = gens[1].cycle_tuples()[0]
     1349        a, b = g0
     1350        if a not in g1 and b not in g1:
     1351            return None
     1352        if a in g1:
     1353            elem = a
     1354        else:
     1355            elem = b
     1356        # Count the number of unique elements in the generators.
     1357        unique = set()
     1358        for g in gens:
     1359            a, b = g.cycle_tuples()[0]
     1360            if a != elem and b != elem:
     1361                return None
     1362            unique.add(a)
     1363            unique.add(b)
     1364        # Compute the order.
     1365        return factorial(len(unique))
     1366
    12921367    def order(self):
    12931368        """
    12941369        Return the number of elements of this group.
     
    13071382        """
    13081383        if not self.gens() or self.gens() == [self(1)]:
    13091384            return Integer(1)
     1385        subgroup_order = self._order()
     1386        if subgroup_order is not None:
     1387          return subgroup_order
    13101388        return Integer(self._gap_().Size())
    13111389
    13121390    def random_element(self):