home *** CD-ROM | disk | FTP | other *** search
/ Math Solutions 1995 October / Math_Solutions_CD-ROM_Walnut_Creek_October_1995.iso / pc / mac / discrete / lib / permcose.g < prev    next >
Encoding:
Text File  |  1993-05-05  |  14.5 KB  |  496 lines

  1. #############################################################################
  2. ##
  3. #A  permcose.g                  GAP library                         Udo Polis
  4. #A                                                         & Martin Schoenert
  5. ##
  6. #H  @(#)$Id: permcose.g,v 3.2 1993/01/18 18:55:42 martin Rel $
  7. ##
  8. #Y  Copyright 1990-1992,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
  9. ##
  10. ##  This file contains the functions to  work  with  cosets  of subgroups  in
  11. ##  permutation groups.
  12. ##
  13. #H  $Log: permcose.g,v $
  14. #H  Revision 3.2  1993/01/18  18:55:42  martin
  15. #H  added double coset functions
  16. #H
  17. #H  Revision 3.1  1993/01/18  17:39:12  martin
  18. #H  initial revision under RCS (moved from 'permgrp.g')
  19. #H
  20. ##
  21.  
  22.  
  23. #############################################################################
  24. ##
  25. #F  PermGroupOps.RightCoset(<U>,<g>)  . . . . . . . . .  create a right coset
  26. #V  RightCosetPermGroupOps  operations record of right cosets in a perm group
  27. ##
  28. ##  'PermGroupOps.RightCoset' is  the  function to create a   right  coset in
  29. ##  a  permutation group.  It  computes the  smallest  element of   the coset
  30. ##  and  stores <U> together  with  this smallest  element  as representative
  31. ##  in a record, and enters the operations record 'RightCosetGroupOps'.
  32. ##
  33. ##  'RightCosetPermGroupOps'  is the  operations record of   right  cosets in
  34. ##  a  permutation    group.   It   inherits  the   default functions    from
  35. ##  'RightCosetGroupOps', and  overlays   the   two    comparison  functions,
  36. ##  using the  fact   that permutation   group  cosets have    their smallest
  37. ##  element as representative.
  38. ##
  39. PermGroupOps.RightCoset := function ( U, g )
  40.     local   C,          # right coset of <U> and <g>, result
  41.             S,          # stabilizer of <U>
  42.             p;          # miminal image of basepoint of <S> under '<U>\*<g>'
  43.  
  44.     # compute the smallest element of the coset
  45.     if not IsBound( U.smallestBase )  or U.smallestBase <> Base( U )  then
  46.         MakeStabChain( U, U.operations.MovedPoints( U ) );
  47.         U.smallestBase := Base( U );
  48.     fi;
  49.     S := U;
  50.     while S.generators <> []  do
  51.         p := Minimum( OnTuples( S.orbit, g ) );
  52.         while S.orbit[1]^g <> p  do g := S.transversal[p/g] mod g;  od;
  53.         S := S.stabilizer;
  54.     od;
  55.  
  56.     # make the domain
  57.     C := rec( );
  58.     C.isDomain          := true;
  59.     C.isRightCoset      := true;
  60.  
  61.     # enter the identifying information
  62.     C.group             := U;
  63.     C.representative    := g;
  64.     C.smallest          := g;
  65.  
  66.     # enter knowledge
  67.     if IsBound( U.isFinite )  then
  68.         C.isFinite      := U.isFinite;
  69.     fi;
  70.     if IsBound( U.size )  then
  71.         C.size          := U.size;
  72.     fi;
  73.  
  74.     # enter the operations record
  75.     C.operations        := RightCosetPermGroupOps;
  76.  
  77.     # return the coset
  78.     return C;
  79. end;
  80.  
  81. RightCosetPermGroupOps := Copy( RightCosetGroupOps );
  82.  
  83. RightCosetPermGroupOps.\= := function ( C, D )
  84.     local   isEql;
  85.  
  86.     # compare a right coset with minimal representative
  87.     if IsRightCoset( C )  and IsBound( C.smallest )  then
  88.  
  89.         # with another right coset with minimal representative
  90.         if IsRightCoset( D )  and IsBound( D.smallest )  then
  91.             if C.group = D.group  then
  92.                 isEql := C.smallest = D.smallest;
  93.             else
  94.                 isEql := RightCosetGroupOps.\=( C, D );
  95.             fi;
  96.  
  97.         # with a subgroup, which is a special right coset
  98.         elif IsGroup( D )  then
  99.             if C.group = D  then
  100.                 isEql := C.smallest = D.identity;
  101.             else
  102.                 isEql := RightCosetGroupOps.\=( C, D );
  103.             fi;
  104.  
  105.         # with something else
  106.         else
  107.             isEql := RightCosetGroupOps.\=( C, D );
  108.         fi;
  109.  
  110.     # compare a subgroup, which is a special right coset
  111.     elif IsGroup( C )  then
  112.  
  113.         # with a right coset with minimal representative
  114.         if IsRightCoset( D )  and IsBound( D.smallest )  then
  115.             if C = D.group  then
  116.                 isEql := C.identity = D.smallest;
  117.             else
  118.                 isEql := RightCosetGroupOps.\=( C, D );
  119.             fi;
  120.  
  121.         # with something else
  122.         else
  123.             isEql := RightCosetGroupOps.\=( C, D );
  124.         fi;
  125.  
  126.     # compare something else
  127.     else
  128.         isEql := RightCosetGroupOps.\=( C, D );
  129.     fi;
  130.  
  131.     # return the result
  132.     return isEql;
  133. end;
  134.  
  135. RightCosetPermGroupOps.\< := function ( C, D )
  136.     local   isLess;
  137.  
  138.     # compare a right coset with minimal representative
  139.     if IsRightCoset( C )  and IsBound( C.smallest )  then
  140.  
  141.         # with another right coset with minimal representative
  142.         if IsRightCoset( D )  and IsBound( D.smallest )  then
  143.             if C.group = D.group  then
  144.                 isLess := C.smallest < D.smallest;
  145.             else
  146.                 isLess := RightCosetGroupOps.\<( C, D );
  147.             fi;
  148.  
  149.         # with a subgroup, which is a special right coset
  150.         elif IsGroup( D )  then
  151.             if C.group = D  then
  152.                 isLess := C.smallest < D.identity;
  153.             else
  154.                 isLess := RightCosetGroupOps.\<( C, D );
  155.             fi;
  156.  
  157.         # with something else
  158.         else
  159.             isLess := RightCosetGroupOps.\<( C, D );
  160.         fi;
  161.  
  162.     # compare a subgroup, which is a special right coset
  163.     elif IsGroup( C )  then
  164.  
  165.         # with a right coset with minimal representative
  166.         if IsRightCoset( D )  and IsBound( D.smallest )  then
  167.             if C = D.group  then
  168.                 isLess := C.identity < D.smallest;
  169.             else
  170.                 isLess := RightCosetGroupOps.\<( C, D );
  171.             fi;
  172.  
  173.         # with something else
  174.         else
  175.             isLess := RightCosetGroupOps.\<( C, D );
  176.         fi;
  177.  
  178.     # compare something else
  179.     else
  180.         isLess := RightCosetGroupOps.\<( C, D );
  181.     fi;
  182.  
  183.     # return the result
  184.     return isLess;
  185. end;
  186.  
  187.  
  188. #############################################################################
  189. ##
  190. #F  PermGroupOps.RightCosets(<G>,<U>) . . . . . . . . .  cosets of a subgroup
  191. #F                                                     in a permutation group
  192. ##
  193. PermGroupOps.RightCosets := function ( G, U )
  194.     local   C,          # cosets of <U> in <G>, result
  195.             R;          # representative of <U> in <G>
  196.  
  197.     # make sure we have a stabchain for <G> and a compatible for <U>
  198.     MakeStabChain( G );
  199.     MakeStabChain(   U, G.operations.Base( G ) );
  200.     ExtendStabChain( U, G.operations.Base( G ) );
  201.  
  202.     # compute the representatives
  203.     R := G.operations.RightCosetRepsStab( G, U );
  204.  
  205.     # and the cosets
  206.     C := List( R, g -> Coset( U, g ) );
  207.  
  208.     # reduce the stabilizer chain of <U> again
  209.     ReduceStabChain( U );
  210.  
  211.     # return the list of cosets
  212.     return C;
  213. end;
  214.  
  215. PermGroupOps.RightCosetRepsStab := function ( G, U )
  216.     local   R,          # representatives for <U> in <G>, result
  217.             r,          # one candidate for <R>
  218.             S,          # representatives for <U>.stab in <G>.stab
  219.             s,          # index into <S>
  220.             T,          # representatives for <G>.stab in <G>
  221.             t,          # index into <T>
  222.             i;          # loop variable
  223.  
  224.     # if <U> is trivial, then the elements of <G>/<U> are the elements of <G>
  225.     if U.generators = []  then
  226.  
  227.         R := PermGroupOps.ElementsStab( G );
  228.  
  229.     # otherwise
  230.     else
  231.  
  232.         # compute a transversal for <U>.stab in <G>.stab
  233.         S := PermGroupOps.RightCosetRepsStab( G.stabilizer, U.stabilizer );
  234.  
  235.         # initializer the new transversal with this
  236.         R := ShallowCopy( S );
  237.  
  238.         # run through the representatives of '<G>.stab' in <G>
  239.         T := [];
  240.         T[G.orbit[1]] := G.identity;
  241.         t := 2;
  242.         while Length(R) < Length(S)*Length(G.orbit)/Length(U.orbit)  do
  243.             T[G.orbit[t]] := T[ G.orbit[t] ^ G.transversal[G.orbit[t]] ]
  244.                              / G.transversal[G.orbit[t]];
  245.  
  246.             # run through the representatives of '<U>.stab' in '<G>.stab'
  247.             s := 1;
  248.             while s <= Length(S)
  249.               and Length(R) < Length(S)*Length(G.orbit)/Length(U.orbit)  do
  250.  
  251.                 # compute $r in S * T$
  252.                 r := S[s] * T[G.orbit[t]];
  253.  
  254.                 # test $r$
  255.                 i := 1;
  256.                 while i < t  and not G.orbit[i]/r in U.orbit  do
  257.                     i := i + 1;
  258.                 od;
  259.  
  260.                 # if $r$ is new add if to the transversal
  261.                 if i = t  then
  262.                     Add( R, r );
  263.                 fi;
  264.  
  265.                 s := s + 1;
  266.             od;
  267.  
  268.             t := t + 1;
  269.         od;
  270.     fi;
  271.  
  272.     # return the list of representatives
  273.     return R;
  274. end;
  275.  
  276.  
  277. #############################################################################
  278. ##
  279. #F  InfoCoset1  . . . . . . . . . . . . . . . information for coset functions
  280. ##
  281. if not IsBound(InfoCoset1)  then InfoCoset1:=Ignore; fi;
  282.  
  283.  
  284. #############################################################################
  285. ##
  286.  
  287. #F  PermGroupOps.DoubeCosets  . . . . .  double cosets for permutation groups
  288. ##
  289. PermGroupOps.DoubleCosets := CalcDoubleCosets;
  290.  
  291.  
  292. #############################################################################
  293. ##
  294. #F  AscendingChain(<G>,<U>) . . . . . . .  chain of subgroups G=G_1>...>G_n=U
  295. ##
  296. PermGroupOps.AscendingChain := function(G,s)
  297.   local np,a,b,c;
  298.   np:=Difference(PermGroupOps.MovedPoints(G),PermGroupOps.MovedPoints(s));
  299.   MakeStabChain(G,np);
  300.   c:=[];
  301.   a:=G;
  302.   while Size(a)>1 and a.orbit[1] in np do
  303.     Add(c,a);
  304.     b:=a.stabilizer;
  305.     if b.generators=[] then
  306.       a:=TrivialSubgroup(G);
  307.     else
  308.       a:=Subgroup(Parent(G),b.generators);
  309.       #a.orbit:=b.orbit;
  310.       #a.transversal:=b.transversal;
  311.       #a.stabilizer:=b.stabilizer;
  312.     fi;
  313.   od;
  314.   if c=[] then
  315.     c:=[G];
  316.   fi;
  317.   Add(c,s);
  318.   return PermRefinedChain(G,Reversed(c));
  319.   #return Concatenation(CalcAscendingChain(a,s),Reversed(c));
  320. end;
  321.  
  322.  
  323. #############################################################################
  324. ##
  325. #F  PermRefinedChain(<G>,<c>) . . . . . . . . . . . . . .  refine chain links
  326. ##
  327. ##  <c> is an ascending chain in the Group <G>. The task of this routine is
  328. ##  to refine c, i.e. if there is a "link" U>L in c with [U:L] too big,
  329. ##  this procedure tries to find Subgroups G_0,...,G_n of G; such that 
  330. ##  U=G_0>...>G_n=L. This is done by extending L inductively: Since normal
  331. ##  steps can help in further calculations, the routine first tries to
  332. ##  extend to the normalizer in U. If the subgroup is self-normalizing,
  333. ##  the group is extended via a random element. If this results in a step
  334. ##  too big, it is repeated several times to find hopefully a small
  335. ##  extension!
  336. ##
  337. PermRefinedChain := function(G,cc)
  338. local bound,a,b,c,cnt,r,i,j,bb,ranfl;
  339.   bound:=10*LogInt(Size(G),10)*Maximum(Factors(Size(G)));
  340.   c:=[];  
  341.   for i in [2..Length(cc)] do  
  342.     Add(c,cc[i-1]);
  343.     if Index(cc[i],cc[i-1]) > bound then
  344.       # c:=Concatenation(c,RefinedChainLink(G,cc[i],cc[i-1]));
  345.       a:=cc[i-1];
  346.       while Index(cc[i],a)>bound do
  347.     # try extension via normalizer
  348.     b:=Normalizer(cc[i],a);
  349.     if b<>a then
  350.      # extension by normalizer surely is a normal step
  351.       a.normalStep:=true;
  352.       bb:=b;
  353.         else
  354.       bb:=cc[i];
  355.       a.normalStep:=false;
  356.         fi;
  357.     if b=a then
  358.       b:=Normalizer(cc[i],Centre(a));
  359.     fi;
  360.     if b=a or Index(b,a)>bound then
  361.       cnt:=8+2^(LogInt(Index(bb,a),5)+2);
  362.       repeat
  363.         if Index(bb,a)<3000 then
  364.           b:=Extension(bb,a);
  365.           if b=false then
  366.         b:=bb;
  367.           fi;
  368.           cnt:=0;
  369.         else
  370.         # larger indices may take more tests...
  371.           InfoCoset1("#W Random\n");
  372.           ranfl:=false;
  373.           repeat
  374.         r:=Random(bb);
  375.           until not(r in a);
  376.           if a.normalStep then
  377.         b:=Closure(a,r);
  378.               else
  379.         # self normalizing subgroup: thus every element not in <a>
  380.              # will surely map one generator out
  381.             j:=0;
  382.         repeat
  383.           j:=j+1;
  384.                 until not(a.generators[j]^r in a);
  385.         r:=a.generators[j]^r;
  386.  
  387.         #b:=Closure(a,r);
  388.         b:=Subgroup(Parent(a),Union(a.generators,[r]));
  389.                 MakeStabChainRandom(b);
  390.         ranfl:=true;
  391.           fi;
  392.           if Size(b)<Size(bb) then
  393.         if ranfl then
  394.           # force correct Schreier Sims
  395.           b:=Closure(a,r);
  396.                 fi;
  397.         bb:=b;
  398.         InfoCoset1("#I improvement found\n");
  399.           fi;
  400.           cnt:=cnt-1;
  401.         fi;
  402.       until Index(bb,a)<=bound or cnt<1;
  403.     fi;
  404.     a:=b;
  405.     if a<>cc[i] then #not upper level
  406.       Add(c,a);
  407.     fi;
  408.       od;
  409.     fi;
  410.   od;
  411.   Add(c,cc[Length(cc)]);
  412.   return c;
  413. end;
  414.  
  415.  
  416. #############################################################################
  417. ##
  418. #F  PermGroupOps.CanonicalCosetElement(<U>,<g>) . . . . .  CCE for permgroups
  419. ##
  420. PermGroupOps.CanonicalCosetElement := function(U,g)
  421.   # prepare special base for CCE
  422.   if not IsBound( U.smallestBase )  or U.smallestBase <> Base( U )  then
  423.       MakeStabChain( U, U.operations.MovedPoints( U ) );
  424.       U.smallestBase := Base( U );
  425.   fi;
  426.   return MainEntryCCEPermGroup( Parent(U), U, g );
  427. end;
  428.  
  429.  
  430. #############################################################################
  431. ##
  432. #F  PermGroupOps.OnCanonicalCosetElements(<G>,<U>)  create operation function
  433. #F                                                    for CCEs for permgroups
  434. ##
  435. ##  this routine returns a *function*, that can be used like OnPoints.
  436. ##
  437. PermGroupOps.OnCanonicalCosetElements := function(G,U)
  438.   return function(a,b)
  439.        # prepare special base for CCE
  440.        if not IsBound( U.smallestBase ) or U.smallestBase <> Base( U) then
  441.          MakeStabChain( U, U.operations.MovedPoints( U ) );
  442.              U.smallestBase := Base( U );
  443.        fi;
  444.        return MainEntryCCEPermGroup(G,U,a*b);
  445.      end;
  446. end;
  447.  
  448.  
  449. #############################################################################
  450. ##
  451. #F  MainEntryCCEPermGroup( <G>, <U>, <g> )  . . . . . . .  cce for permgroups
  452. ##
  453. ##  Main part of the computation of a canonical coset representative in a
  454. ##  PermGroup. This is done, by factoring with the strong generators, that
  455. ##  move points the same way, as the coset representative. The routine
  456. ##  supposes, that an appropriate base has been set up by the calling
  457. ##  routine.
  458. ##
  459. MainEntryCCEPermGroup := function(G,U,g)
  460.   local   p,    # miminal image of basepoint of <S> under '<U>\*<g>'
  461.           i,img;
  462.  
  463.   while U.generators <> []  do
  464.     # calculate p := Minimum( OnTuples( U.orbit, g ) );
  465.     p := "infinity";
  466.     for i in U.orbit do
  467.       img:=i^g;
  468.       if img<p then
  469.     p:=img;
  470.       fi;
  471.     od;
  472.     while U.orbit[1]^g <> p  do g := U.transversal[p/g] mod g;  od;
  473.     U := U.stabilizer;
  474.   od;
  475.   return g;
  476. end;
  477.  
  478. PermGroupOps.MainEntryCCE := MainEntryCCEPermGroup;
  479.  
  480.  
  481. #############################################################################
  482. ##
  483. #E  Emacs . . . . . . . . . . . . . . . . . . . . . . . local emacs variables
  484. ##
  485. ##  Local Variables:
  486. ##  mode:               outline
  487. ##  outline-regexp:     "#A\\|#F\\|#V\\|#E\\|#R"
  488. ##  fill-column:        73
  489. ##  fill-prefix:        "##  "
  490. ##  eval:               (hide-body)
  491. ##  End:
  492. ##
  493.  
  494.  
  495.  
  496.