Ticket #10976: trac_10976.6.patch

File trac_10976.6.patch, 4.1 KB (added by swenson, 10 years ago)
• 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 - Nicolas Borie (2009): Added orbit, transversals, stabiliser and strong_generating_system methods - Christopher Swenson (2012): Added a special case to compute the order efficiently. (This patch Copyright 2012 Google Inc. All Rights Reserved. ) REFERENCES: - Cameron, P., Permutation Groups. New York: Cambridge University from sage.misc.package import is_package_installed from sage.sets.finite_enumerated_set import FiniteEnumeratedSet from sage.categories.all import FiniteEnumeratedSets from sage.functions.other import factorial def load_hap(): """ return '\\langle ' + \ ', '.join([x._latex_() for x in self.gens()]) + ' \\rangle' def _order(self): """ This handles a few special cases of computing the subgroup order much faster than GAP. This currently operates very quickly for stabilizer subgroups of permutation groups, for one. Will return None if the we could not easily compute it. Author: Christopher Swenson EXAMPLES:: sage: SymmetricGroup(10).stabilizer(4)._order() 362880 sage: SymmetricGroup(10).stabilizer(4).stabilizer(5)._order() 40320 sage: SymmetricGroup(200).stabilizer(100)._order() == factorial(199) # this should be very fast True TESTS:: sage: [SymmetricGroup(n).stabilizer(1)._gap_().Size() for n in [4..10]] [6, 24, 120, 720, 5040, 40320, 362880] sage: [SymmetricGroup(n).stabilizer(1)._order() for n in [4..10]] [6, 24, 120, 720, 5040, 40320, 362880] """ gens = self.gens() # This special case only works with more than 1 generator. if not gens or len(gens) < 2: return None # Special case: certain subgroups of the symmetric group for which Gap reports # generators of the form ((1, 2), (1, 3), ...) # This means that this group is isomorphic to a smaller symmetric group # S_n, where n is the number of generators supported. # # The code that follows checks that the following assumptions hold: #     * All generators have order 2 #     * All generators share a common element # # We then know that this group is isomorphic to S_n, # and therefore its order is n!. # Check that all generators are order 2 and have length-1 cycle tuples. for g in gens: if g.order() != 2: return None if len(g.cycle_tuples()) != 1: return None # Find the common element. g0 = gens.cycle_tuples() g1 = gens.cycle_tuples() a, b = g0 if a not in g1 and b not in g1: return None if a in g1: elem = a else: elem = b # Count the number of unique elements in the generators. unique = set() for g in gens: a, b = g.cycle_tuples() if a != elem and b != elem: return None unique.add(a) unique.add(b) # Compute the order. return factorial(len(unique)) def order(self): """ Return the number of elements of this group. """ if not self.gens() or self.gens() == [self(1)]: return Integer(1) subgroup_order = self._order() if subgroup_order is not None: return subgroup_order return Integer(self._gap_().Size()) def random_element(self):