| 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 are transpositions (i.e., permutations |
| 1335 | # that switch two elements and leave everything else fixed), |
| 1336 | # * All generators share a common element. |
| 1337 | # |
| 1338 | # We then know that this group is isomorphic to S_n, |
| 1339 | # and therefore its order is n!. |
| 1340 | |
| 1341 | # Check that all generators are order 2 and have length-1 cycle tuples. |
| 1342 | for g in gens: |
| 1343 | if g.order() != 2: |
| 1344 | return None |
| 1345 | if len(g.cycle_tuples()) != 1: |
| 1346 | return None |
| 1347 | # Find the common element. |
| 1348 | g0 = gens[0].cycle_tuples()[0] |
| 1349 | g1 = gens[1].cycle_tuples()[0] |
| 1350 | a, b = g0 |
| 1351 | if a not in g1 and b not in g1: |
| 1352 | return None |
| 1353 | if a in g1: |
| 1354 | elem = a |
| 1355 | else: |
| 1356 | elem = b |
| 1357 | # Count the number of unique elements in the generators. |
| 1358 | unique = set() |
| 1359 | for g in gens: |
| 1360 | a, b = g.cycle_tuples()[0] |
| 1361 | if a != elem and b != elem: |
| 1362 | return None |
| 1363 | unique.add(a) |
| 1364 | unique.add(b) |
| 1365 | # Compute the order. |
| 1366 | return factorial(len(unique)) |
| 1367 | |