Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  simple.gi   Sprache: unbekannt

 
#############################################################################
##
##  This file is part of GAP, a system for computational discrete algebra.
##  This file's authors include Alexander Hulpke.
##
##  Copyright of GAP belongs to its developers, whose names are too numerous
##  to list here. Please refer to the COPYRIGHT file for details.
##
##  SPDX-License-Identifier: GPL-2.0-or-later
##
##  This file contains basic constructions for simple groups of bounded size,
##  if necessary by calling the `atlasrep' package.
##

# data for simple groups of order up to 10^18 that are not L_2(q)
# for some of the groups entry #5 indicates the smallest permutation degree
BindGlobal("SIMPLEGPSNONL2",
  MakeImmutable(
  [[60,"A",5,0,5],[360,"A",6,0,6],[2520,"A",7,0,7],
    [5616,"L",3,3,13],[6048,"U",3,3,28],
    [7920,"Spor","M(11)",0,11],[20160,"A",8,0,8],
    [20160,"L",3,4,21],[25920,"S",4,3,40],
    [29120,"Sz",8,0,65],[62400,"U",3,4,65],
    [95040,"Spor","M(12)",0,12],[126000,"U",3,5,126],
    [175560,"Spor","J(1)",0,266],[181440,"A",9,0,9],
    [372000,"L",3,5,31],[443520,"Spor","M(22)",0,22],
    [604800,"Spor","J(2)",0,100],[979200,"S",4,4,85],
    [1451520,"S",6,2,63],[1814400,"A",10,0,10],
    [1876896,"L",3,7,57],[3265920,"U",4,3,280],
    [4245696,"G",2,3,351],[4680000,"S",4,5,156],
    [5515776,"U",3,8,513],[5663616,"U",3,7,344],
    [6065280,"L",4,3,40],[9999360,"L",5,2,31],
    [10200960,"Spor","M(23)",0,23],[13685760,"U",5,2,165],
    [16482816,"L",3,8,73],[17971200,"Spor","T",0,1600],
    [19958400,"A",11,0,11],[32537600,"Sz",32,0,1025],
    [42456960,"L",3,9,91],[42573600,"U",3,9,730],
    [44352000,"Spor","HS",0,100],[50232960,"Spor","J(3)",0,6156],
    [70915680,"U",3,11,1332],[138297600,"S",4,7,400],
    [174182400,"O+",8,2,120],[197406720,"O-",8,2,119],
    [211341312,"3D",4,2,819],[212427600,"L",3,11,133],
    [239500800,"A",12,0,12],[244823040,"Spor","M(24)",0,24],
    [251596800,"G",2,4,416],[270178272,"L",3,13,183],
    [811273008,"U",3,13,2198],[898128000,"Spor","McL",0,275],
    [987033600,"L",4,4,85],[1018368000,"U",4,4,1105],
    [1056706560,"S",4,8,585],[1425715200,"L",3,16,273],
    [1721606400,"S",4,9,820],[2317678272,"U",3,17,4914],
    [3113510400,"A",13,0,13],[4030387200,"Spor","He",0,2058],
    [4279234560,"U",3,16,4097],[4585351680,"S",6,3,364],
    [4585351680,"O",7,3,351],[5644682640,"L",3,19,381],
    [5859000000,"G",2,5,3906],[6950204928,"L",3,17,307],
    [7254000000,"L",4,5,156],[9196830720,"U",6,2,672],
    [10073444472,"R",27,0,19684],[12860654400,"S",4,11,1464],
    [14742000000,"U",4,5,3276],[16938986400,"U",3,19,6860],
    [20158709760,"L",6,2,63],[26056457856,"U",3,23,12168],
    [34093383680,"Sz",128,0,16385],[43589145600,"A",14,0,14],
    [47377612800,"S",8,2,255],[50778000000,"L",3,25,651],
    [68518981440,"S",4,13,2380],[78156525216,"L",3,23,553],
    [145926144000,"Spor","Ru",0,4060],[152353500000,"U",3,25,15626]
    ,[166557358800,"U",3,29,24390],[237783237120,"L",5,3,121],
    [258190571520,"U",5,3,2440],[282027786768,"L",3,27,757],
    [282056445216,"U",3,27,19684],[283991644800,"L",3,31,993],
    [366157135872,"U",3,32,32769],
    [448345497600,"Spor","Suz",0,1782],
    [460815505920,"Spor","ON",0,122760],
    [495766656000,"Spor","Co(3)",0,276],[499631102880,"L",3,29,871]
    ,[653837184000,"A",15,0,15],[664376138496,"G",2,7],
    [852032133120,"U",3,31,29792],[1004497044480,"S",4,17,5220],
    [1095199948800,"S",4,16,4369],[1098404364288,"L",3,32,1057],
    [1165572172800,"U",4,7,17200],[1169948144736,"L",3,37,1407],
    [2317591180800,"L",4,7,400],[2660096970720,"U",3,41,68922],
    [3057017889600,"S",4,19,7240],[3509983020816,"U",3,37,50654],
    [3893910661872,"L",3,43,1893],[4106059776000,"S",6,4,1365],
    [4329310519296,"G",2,8],[4952179814400,"O+",8,3,1080],
    [7933578895872,"U",3,47,103824],[7980059337600,"L",3,41,1723],
    [10151968619520,"O-",8,3,1066],[10461394944000,"A",16,0,16],
    [11072935641600,"L",3,49,2451],[11682025843488,"U",3,43],
    [20560831566912,"3D",4,3,26572],[20674026236160,"S",4,23,12720]
    ,[20745981365616,"U",3,53],[22594320403200,"G",2,9],
    [23499295948800,"O+",10,2,496],[23800278205248,"L",3,47,2257],
    [25015379558400,"O-",10,2,495],[33219371640000,"U",3,49],
    [34558531338240,"L",4,8,585],[34693789777920,"U",4,8],
    [35115786567680,"Sz",512,0,262145],
    [42305421312000,"Spor","Co(2)",0,2300],
    [47607300000000,"S",4,25,16276],[48929657263200,"U",3,59],
    [50759843097600,"L",4,9,820],[53443952640000,"U",5,4],
    [62237108003616,"L",3,53,2863],[63884982751200,"L",3,61,3783],
    [64561751654400,"Spor","Fi(22)",0,3510],
    [93801727918080,"L",3,64,4161],[101798586432000,"U",4,9],
    [102804157834560,"S",4,27,20440],
    [135325289783376,"L",3,67,4557],[146787542351760,"L",3,59,3541]
    ,[163849992929280,"L",7,2,127],[177843714048000,"A",17,0,17]
    ,[191656636992240,"U",3,61],[210103196385600,"S",4,29,25260],
    [215209078277760,"U",3,71],[227787103272960,"U",7,2],
    [228501000000000,"S",6,5,3906],[228501000000000,"O",7,5,3906],
    [258492255436800,"L",5,4,341],[268768894995072,"L",3,73,5403],
    [273030912000000,"Spor","HN",0,1140000],
    [281407330713600,"U",3,64],[376611192619200,"G",2,11],
    [405978568998816,"U",3,67],[409387254681600,"S",4,31,30784],
    [505620881962560,"L",3,79,6321],[645623627090400,"L",3,71,5113]
    ,[750656410078176,"U",3,83],[806310830350368,"U",3,73],
    [1036388695478400,"U",4,11],[1124799322521600,"S",4,32,33825],
    [1312032469255200,"U",3,89],[1516868799014400,"U",3,79],
    [1852734273062400,"L",3,81,6643],[1852741245568320,"U",3,81],
    [2069665112592000,"L",4,11,1464],
    [2251961353296816,"L",3,83,6973],
    [2402534664555840,"S",4,37,52060],
    [2612197345314816,"L",3,97,9507],[3201186852864000,"A",18,0,18]
    ,[3311126603366400,"F",4,2,69888],
    [3609172015066800,"U",3,101],[3914077489672896,"G",2,13],
    [3936086241056640,"L",3,89,8011],
    [4222165056643872,"L",3,103,10713],[5726791697419872,"U",3,107],
    [6641311310615520,"L",3,109,11991],
    [6707334818822400,"S",4,41,70644],[7836609208799616,"U",3,97],
    [8860792800073536,"U",3,113],[10799893897531200,"S",4,43,81400],
    [10827495027060000,"L",3,101,10303],
    [12666518353227648,"U",3,103],[12714519233969280,"L",4,13,2380],
    [15315521833180800,"L",3,121,14763],
    [17180347043675088,"L",3,107,11557],
    [19866953531250000,"U",3,125],[19923964701735600,"U",3,109],
    [21032402889738240,"L",6,3,364],
    [22557001777261056,"L",3,127,16257],[22837472432087040,"U",6,3],
    [24017743449686016,"U",3,128],[24815256521932800,"S",10,2,1023],
    [25452197883665280,"U",4,13],[26287655087416320,"S",4,47,106080]
    ,[26582341554402816,"L",3,113,12883],
    [28908396044367840,"U",3,131],
    [36011213418659840,"Sz",2048,0,4194305],
    [39879509765760000,"S",4,49,120100],
    [41363788790194272,"U",3,137],[45946617370848480,"U",3,121],
    [46448800925370480,"L",3,139,19461],
    [49825657439340552,"R",243,0],
    [51765179004000000,"Spor","Ly",0,8835156],
    [56653740000000000,"L",5,5],[57604365000000000,"U",5,5],
    [59600799562500000,"L",3,125],[60822550204416000,"A",19,0],
    [65784756654489600,"S",8,3],[65784756654489600,"O",9,3],
    [67010895544320000,"O+",8,4],[67536471195648000,"O-",8,4],
    [67671071404425216,"U",3,127],[67802350642790400,"3D",4,4],
    [71776114783027200,"G",2,16],[72053161633775616,"L",3,128],
    [80974721219670000,"U",3,149],[86725110978620400,"L",3,131],
    [87412594259315520,"S",4,53],[90089701905420000,"L",3,151],
    [90745943887872000,"Spor","Th",0,143127000],
    [123043374372144096,"L",3,157],[124091269852276608,"L",3,137],
    [139346506548429600,"U",3,139],[166097514629752272,"L",3,163],
    [167795197370551296,"G",2,17],[201648518295622272,"U",3,167],
    [221797724414797440,"L",3,169],[242924016786074400,"L",3,149],
    [255484940347310400,"S",4,59],[267444174893824656,"U",3,173],
    [270269262714825600,"U",3,151],[273457218604953600,"S",6,7],
    [273457218604953600,"O",7,7],[351309192845176800,"U",3,179],
    [356575576421678400,"S",4,61],[369130313886677616,"U",3,157],
    [383967100578952800,"L",3,181],[498292774007829408,"U",3,163],
    [590382996204625920,"U",3,191],[604945295112210528,"L",3,167],
    [641690334200143872,"L",3,193],[665393448951722400,"U",3,169],
    [712975930219192320,"L",4,17],[756131656307437872,"U",3,197],
    [796793353927300800,"G",2,19],[802332214764045216,"L",3,173],
    [819770591880266400,"L",3,199],[911215823217986880,"S",4,67]]
    ));

# call atlasrep, possibly with extra parameters, but only if atlasrep is available
BindGlobal("DoAtlasrepGroup",function(params)
local g;
  if IsPackageMarkedForLoading("atlasrep","")<>true then
    Error("`atlasrep' package must be available to construct group ",params[1]);
  fi;
  g:=CallFuncList(ValueGlobal("AtlasGroup"),params);
  if not IsGroup(g) then
     Error("The AtlasRep package could not load a group with parameters ",params);
  fi;
  SetName(g,params[1]);
  if not '.' in params[1] then
    SetIsSimpleGroup(g,true);
  fi;
  return g;
end);

BindGlobal("ChevalleyG",function(q)
local p,f,z,G,o;
  # Generators probably due to Don Taylor, communicated by Derek Holt
  p:=Factors(q);
  if Length(Set(p))>1 then Error("<q> must be prime power");fi;
  p:=p[1];
  f:=GF(q);
  z:=PrimitiveRoot(f);
  o:=One(f);

  # first generator differs for q=2,p=3
  if q=2 then
    G:=Group(
        o*[[1,1,0,0,0,0,0],
        [0,1,0,0,0,0,0],
        [0,0,1,1,1,0,0],
        [0,0,0,1,0,0,0],
        [0,0,0,0,1,0,0],
        [0,0,0,0,0,1,1],
        [0,0,0,0,0,0,1]],
        o*[[0,0,1,0,0,0,0],
        [1,0,0,0,0,0,0],
        [0,0,0,0,0,1,0],
        [0,0,0,1,0,0,0],
        [0,1,0,0,0,0,0],
        [0,0,0,0,0,0,1],
        [0,0,0,0,1,0,0]]);
  elif p=3 then
    G:=Group(
    o*[[z^2,0,0,0,0,0,0],
      [0,z,0,0,0,0,0],
      [0,0,z,0,0,0,0],
      [0,0,0,1,0,0,0],
      [0,0,0,0,z^(q-2),0,0],
      [0,0,0,0,0,z^(q-2),0],
      [0,0,0,0,0,0,z^(q-3)]],
      o*[[0,0,1,0,0,0,0],
      [2,0,1,0,0,1,0],
      [0,0,0,0,0,1,0],
      [0,0,0,2,0,2,0],
      [0,2,0,2,0,1,1],
      [0,0,0,0,0,0,1],
      [0,0,0,0,1,0,1]]
    );
  else
    G:=Group(
     o*[[z,0,0,0,0,0,0],
      [0,z^(q-2),0,0,0,0,0],
      [0,0,z^2,0,0,0,0],
      [0,0,0,1,0,0,0],
      [0,0,0,0,z^(q-3),0,0],
      [0,0,0,0,0,z,0],
      [0,0,0,0,0,0,z^(q-2)]],
      o*[[p-1,0,1,0,0,0,0],
      [p-1,0,0,0,0,0,0],
      [0,p-1,0,p-1,0,1,0],
      [0,p-2,0,p-1,0,0,0],
      [0,p-1,0,0,0,0,0],
      [0,0,0,0,1,0,1],
      [0,0,0,0,1,0,0]]);
  fi;

  SetSize(G,q^6*(q^6-1)*(q^2-1));
  return G;
end);

# generators from
# Howlett, R. B.(5-SYD-SM); Rylands, L. J.; Taylor, D. E.(5-SYD-SM)
# Matrix generators for exceptional groups of Lie type.
# J. Symbolic Comput. 31 (2001), no. 4, 429–445.
# Note that Magma uses slightly different generators
BindGlobal("Chevalley3D4",function(q)
local f,mu,m1,m2,x,n,o;
  f:=GF(q^3);
  o:=One(f);
  mu:=PrimitiveRoot(f);
  m1:=DiagonalMat([mu^(q^2),mu^(-q^2),mu^(q+1),mu^(q-1),
                   mu^(-q+1),mu^(-q-1),mu^(q^2),mu^(-q^2)]);
  x:=IdentityMat(8,f);
  x[1,2]:=o;
  x[3,4]:=o;
  x[3,5]:=o;
  x[3,6]:=o;
  x[4,6]:=o;
  x[5,6]:=o;
  x[7,8]:=o;
  n:=NullMat(8,8,f);
  n[1,3]:=o;
  n[2,1]:=-o;
  n[3,7]:=o;
  n[4,5]:=-o;
  n[5,4]:=-o;
  n[6,2]:=-o;
  n[7,8]:=o;
  n[8,6]:=o;
  m2:=x*n;
  x:=Group(m1,m2);
  SetName(x,Concatenation("3D4(",String(q),")"));
  SetSize(x,q^12*(q^8+q^4+1)*(q^6-1)*(q^2-1));
  return x;
end);

InstallGlobalFunction(SimpleGroup,function(arg)
local brg,str,p,a,param,g,s,small,plus,sets;
  if IsRecord(arg[1]) then
    p:=arg[1];
    if p.series="Spor" then
      brg:=p.parameter[1];
      if '=' in brg then
        brg:=brg{[1..Position(brg,'=')-1]};
      fi;
      while Last(brg)=' ' do
        brg:=brg{[1..Length(brg)-1]};
      od;
      brg:=[brg];
    else
      brg:=Concatenation([p.series],p.parameter);
    fi;
  else
    brg:=arg;
  fi;
  str:=brg[1];
  # Case x(y gets replaced by x,y for x,y digits
  p:=Position(str,'(');
  if p>1 and p<Length(str) and str[p-1] in CHARS_DIGITS and str[p+1] in CHARS_DIGITS
    then
    str:=Concatenation(str{[1..p-1]},",",str{[p+1..Length(str)]});
  fi;

  # the weird F3+ name
  if UppercaseString(str)="F3+" then str:="FI24'";fi;

  # blanks,parentheses,_,^,' do not contribute to parsing
  a:=" ()_^'";
  str:=UppercaseString(Filtered(str,x->not x in a));

  # are there parameters in the string?
  # skip leading numbers for indicating 2/3 twist
  if Length(str)>1 then
    p:=PositionProperty(str{[2..Length(str)]},
      x->x in CHARS_DIGITS or x in "+-");
    if p<>fail then p:=p+1;fi;
  else
    p:=PositionProperty(str{[1..Length(str)]},
      x->x in CHARS_DIGITS or x in "+-");
  fi;
  param:=[];
  if p<>fail then
    a:=str{[p..Length(str)]};
    str:=str{[1..p-1]};

    # special case `O+' or `O-'
    if '+' in a or '-' in a then
      p:=Position(a,'+');
      if p<>fail then
        plus:=1;
      else
        p:=Position(a,'-');
        plus:=-1;
      fi;
      if Length(a)=1 then
        # deal with "O+" class
        Add(a,'1');
      elif Length(a)>=p+1 and a[p+1]='1' and a[p+2]=',' then
        # gave O(+1,8,2) or so
        plus:=fail;
      fi;
      if plus<>fail then
        if p=1 then
          # leading +-, possibly with comma
          a:=a{[2..Length(a)]};
          if a="1" then a:="";fi;
          if Length(a)>1 and a[1]=',' then
            a:=a{[2..Length(a)]};
          fi;
        else
          # internal +-
          a[p]:=',';
        fi;
      fi;

    else
      plus:=fail;
    fi;

    if Length(a)>0 then
      p:=Position(a,',');
      while p<>fail do
        s:=a{[1..p-1]};
        if s[1]='+' then
          s:=s{[2..Length(s)]};
        fi;
        Add(param,Int(s));
        a:=a{[p+1..Length(a)]};
        p:=Position(a,',');
      od;
      if a[1]='+' then
        a:=a{[2..Length(a)]};
      fi;
      Add(param,Int(a));
    fi;

    if plus<>fail then
      param:=Concatenation([plus],param);
    fi;

  fi;
  param:=Concatenation(param,brg{[2..Length(brg)]});
  if ForAny(param,x->not IsInt(x)) then
    Error("parameters must be integral");
  fi;

  # replace Lie names with classical/discoverer equivalents if possible

  # now parse the name. Is it sporadic, alternating, suzuki, or ree?
  if Length(param)<=1 then
    if str="A" or str="ALT" then
      if Length(param)=1 and param[1]>4 then
        g:=AlternatingGroup(param[1]);
        SetName(g,Concatenation("A",String(param[1])));
        SetIsNonabelianSimpleGroup(g,true);
        return g;
      else
        Error("illegal parameter for alternating groups");
      fi;

    elif (str="M" and Length(param)=0) or str="FG" then
      Error("Monster not yet supported");
    elif (str="B" or str="BM") and Length(param)=0 then
      return DoAtlasrepGroup(["B"]);
    elif str="M" or str="MATHIEU" then
      if Length(param)=1 and param[1] in [11,12,22,23,24] then
        g:=MathieuGroup(param[1]);
        SetName(g,Concatenation("M",String(param[1])));
        return g;
      else
        Error("illegal parameter for Mathieu groups");
      fi;

    elif str="J" or str="JANKO" then
      if Length(param)=1 and param[1] in [1..4] then
        if param[1]=1 then
          g:=PrimitiveGroup(266,1);
        elif param[1]=2 then
          g:=PrimitiveGroup(100,1);
        else
          g:=[,,"J3","J4"];
          g:=DoAtlasrepGroup([g[param[1]]]);
        fi;
        SetIsNonabelianSimpleGroup(g,true);
        return g;
      else
        Error("illegal parameter for Janko groups");
      fi;

    elif str="CO" or str="." or str="CONWAY" then
      if Length(param)=1 and param[1] in [1..3] then
        if param[1]=3 then
          g:=PrimitiveGroup(276,3);
        elif param[1]=2 then
          g:=PrimitiveGroup(2300,1);
        else
          g:=DoAtlasrepGroup(["Co1"]);
        fi;
        SetIsNonabelianSimpleGroup(g,true);
        return g;
      else
        Error("illegal parameter for Conway groups");
      fi;

    elif str="FI" or str="FISCHER" then
      if Length(param)=1 and param[1] in [22,23,24] then
        s:=Concatenation("Fi",String(param[1]));
        if param[1] = 24 then Append(s,"'"); fi;
        g:=DoAtlasrepGroup([s]);
        SetIsNonabelianSimpleGroup(g,true);
        return g;
      else
        Error("illegal parameter for Fischer groups");
      fi;
    elif str="SUZ" or str="SZ" or str="SUZUKI" then
      if Length(param)=0 and str="SUZ" then
        g:=PrimitiveGroup(1782,1);
        SetIsNonabelianSimpleGroup(g,true);
        return g;
      elif Length(param)=1 and param[1]>7 and
        PrimeDivisors(param[1])=[2] and IsOddInt(LogInt(param[1],2)) then
        g:=SuzukiGroup(IsPermGroup,param[1]);
        SetName(g,Concatenation("Sz(",String(param),")"));
        SetIsNonabelianSimpleGroup(g,true);
        return g;
      else
        Error("illegal parameter for Suzuki groups");
      fi;
    elif str="R" or str="REE" or str="2G" then
      if Length(param)=1 and param[1]>26 and
        PrimeDivisors(param[1])=[3] and IsOddInt(LogInt(param[1],3)) then
        g:=ReeGroup(IsMatrixGroup,param[1]);
        SetName(g,Concatenation("Ree(",String(param[1]),")"));
        SetIsNonabelianSimpleGroup(g,true);
        return g;
      else
        Error("illegal parameter for Ree groups");
      fi;

    elif str="ON" then
      return DoAtlasrepGroup(["ON"]);
    elif str="HE" then
      return PrimitiveGroup(2058,1);
    elif str="HS" then
      return PrimitiveGroup(100,3);
    elif str="HN" then
      return DoAtlasrepGroup(["HN"]);
    elif str="LY" then
      return DoAtlasrepGroup(["Ly"]);
    elif str="MC" or str="MCL" then
      return PrimitiveGroup(275,1);
    elif str="TH" then
      return DoAtlasrepGroup(["Th"]);
    elif str="RU" then
      return DoAtlasrepGroup(["Ru"]);
    elif str="B" then
      return DoAtlasrepGroup(["B"]);
    elif str="T" then
      g:=PrimitiveGroup(1600,20);
      s:=Size(g);
      g:=Group(GeneratorsOfGroup(g));
      SetSize(g,s);
      SetName(g,"2F(4,2)'");
      SetIsNonabelianSimpleGroup(g,true);
      return g;
    fi;
  fi;

  # now the name is ``classical''. and the second parameter a prime power
  if not IsPrimePowerInt(param[Maximum(2,Length(param))]) then
    Error("field order must be a prime power");
  fi;

  small:=false;
  s:=fail;
  if str="L" or str="SL" or str="PSL" then
    if param = [2,2] or param = [2,3] then
        Error("illegal parameter for linear groups");
    fi;
    g:=PSL(param[1],param[2]);
    s:=Concatenation("PSL(",String(param[1]),",",String(param[2]),")");
  elif str="U" or str="SU" or str="PSU" then
    if param in [ [2,2], [2,3], [3,2] ] then
      Error("illegal parameter for unitary groups");
    fi;
    g:=PSU(param[1],param[2]);
    s:=Concatenation("PSU(",String(param[1]),",",String(param[2]),")");
    small:=true;
  elif str="S" or str="SP" or str="PSP" then
    if param in [ [2,2], [2,3], [4,2] ] then
      Error("illegal parameter for symplectic groups");
    fi;
    g:=PSp(param[1],param[2]);
    s:=Concatenation("PSp(",String(param[1]),",",String(param[2]),")");
    small:=true;
  elif str="O" or str="SO" or str="PSO" then
    if Length(param)=2 and IsOddInt(param[1]) then
      if param[1] < 3 or (param[1] = 3 and param[2] <= 3) then
        Error("illegal parameter for orthogonal groups");
      fi;
      g:=SO(param[1],param[2]);
      g:=Action(g,NormedRowVectors(GF(param[2])^param[1]),OnLines);
      s:=DerivedSubgroup(g);
      if s<>g and IsBound(g!.actionHomomorphism) then
        s!.actionHomomorphism:=ActionHomomorphism(
          PreImage(g!.actionHomomorphism,s),
          HomeEnumerator(UnderlyingExternalSet(g!.actionHomomorphism)),
          OnLines,"surjective");
      fi;
      g:=s;
      s:=Concatenation("O(",String(param[1]),",",String(param[2]),")");
      small:=true;
    elif Length(param)=3 and param[1]=1 and IsEvenInt(param[2]) then
      if param[2] < 6 then
        Error("illegal parameter for orthogonal groups");
      fi;
      g:=SO(1,param[2],param[3]);
      g:=Action(g,NormedRowVectors(GF(param[3])^param[2]),OnLines);
      g:=DerivedSubgroup(g);
      s:=Concatenation("O+(",String(param[2]),",",String(param[3]),")");
      small:=true;
    elif Length(param)=3 and param[1]=-1 and IsEvenInt(param[2]) then
      if param[2] < 4 then
        Error("illegal parameter for orthogonal groups");
      fi;
      g:=SO(-1,param[2],param[3]);
      g:=Action(g,NormedRowVectors(GF(param[3])^param[2]),OnLines);
      g:=DerivedSubgroup(g);
      s:=Concatenation("O-(",String(param[2]),",",String(param[3]),")");
      small:=true;
    else
      Error("wrong dimension/parity for O");
    fi;

  elif str="D" then
    return SimpleGroup("O",1,param[1]*2,param[2]);
  elif str="E" then
    if Length(param)<2 or not param[1] in [6,7,8] then
      Error("E(n,q) needs n=6,7,8");
    fi;
    s:=Concatenation("E",String(param[1]),"(",String(param[2]),")");
    g:=DoAtlasrepGroup([s]);

  elif str="F" then
    if Length(param)>1 and param[1]<>4 then
      Error("F(n,q) needs n=4");
    fi;
    a:=param[Length(param)];
    if a=2 then
      g:=DoAtlasrepGroup(["F4(2)"]);
    else
      Error("Can't do yet");
    fi;
    s:=Concatenation("F_4(",String(a),")");

  elif str="G" then
    if Length(param)>1 and param[1]<>2 then
      Error("G(n,q) needs n=2");
    fi;
    a:=param[Length(param)];
    if a=2 then return SimpleGroup("U",3,3);
    elif a=3 then
      g:=PrimitiveGroup(351,7);
    elif a=4 then
      g:=PrimitiveGroup(416,7);
    else
      g:=ChevalleyG(a);
      g:=Action(g,
           Set(Orbit(g,One(DefaultFieldOfMatrixGroup(g))*[1,0,0,0,0,0,0],
             OnLines)),
          OnLines);
    fi;
    s:=Concatenation("G_2(",String(a),")");

  elif str="3D" then
    if Length(param)>1 and param[1]<>4 then
      Error("3D(n,q) needs n=4");
    fi;
    a:=param[Length(param)];
    if a=2 then
      g:=PrimitiveGroup(819,5);
    elif a=3 then
      g:=DoAtlasrepGroup(["3D4(3)"]);
    else
      return Chevalley3D4(a);
    fi;
    s:=Concatenation("3D4(",String(a),")");

  elif str="2E" then
    if Length(param)>1 and param[1]<>6 then
      Error("2E(n,q) needs n=6");
    fi;
    a:=param[Length(param)];
    s:=Concatenation("2E6(",String(a),")");
    g:=DoAtlasrepGroup([s]);

  else
    Error("Can't handle type ",str);
  fi;
  if small then
    a:=ShallowCopy(Orbits(g,MovedPoints(g)));
    if Length(a)>1 then
      SortParallel(List(a,Length),a);
      if IsBound(g!.actionHomomorphism) then
        # pull back
        p:=UnderlyingExternalSet(g!.actionHomomorphism);
        a:=Action(Source(g!.actionHomomorphism),HomeEnumerator(p){a[1]},
             FunctionAction(p));
      else
        a:=Action(g,a[1]);
      fi;
      SetSize(a,Size(g));
      g:=a;
    fi;

    a:=Blocks(g,MovedPoints(g));
    if Length(a)>1 then
      if IsBound(g!.actionHomomorphism) then
        # pull back
        p:=UnderlyingExternalSet(g!.actionHomomorphism);
        sets:=Set(List(a,x->HomeEnumerator(p){x}));
        p:=FunctionAction(p);
        a:=Action(Source(g!.actionHomomorphism),sets,
             function(set,g)
               return Set(List(set,x->p(x,g)));
             end);
      else
        a:=Action(g,a,OnSets);
      fi;
      SetSize(a,Size(g));
      g:=a;
    fi;

  fi;
  if s<>fail and not HasName(g) then
    SetName(g,s);
  fi;
  SetIsNonabelianSimpleGroup(g,true);
  return g;

end);

BindGlobal("SizeL2Q",q->q*(q-1)*(q+1)*Gcd(2,q)/2);

# deal with irregular order for L2(2^a)
# return [usedegree, nexta, stackvalue]
BindGlobal("NextL2Q",function(a,stack)
local NextL2PrimePowerInt;

  NextL2PrimePowerInt:=function(a)
    repeat
      a:=a+1;
    # L2(q) for q=4,5,9 duplicates others
    until IsPrimePowerInt(a) and not a in [4,5,9];
    return a;
  end;

  a:=NextL2PrimePowerInt(a);
  if stack<>fail then
    if SizeL2Q(stack)<SizeL2Q(a) then
      return [stack,a-1,fail];
    else
      return [a,a,stack];
    fi;
  elif IsEvenInt(a) and SizeL2Q(a)>SizeL2Q(NextL2PrimePowerInt(a)) then
    stack:=a;
    a:=NextL2PrimePowerInt(a);
    return [a,a,stack];
  else
    return [a,a,fail];
  fi;
end);

BindGlobal("LOADSIMPLE2",function()
local a;
  if not IsBound(SIMPLEGPSNONL2[248]) then
    MakeReadWriteGlobal("SIMPLEGPSNONL2");
    a:=ReadAsFunction(Filename(List(GAPInfo.RootPaths,Directory),
      "grp/simple2.g"));
    SIMPLEGPSNONL2:=Immutable(Concatenation(SIMPLEGPSNONL2,a()));
    MakeReadOnlyGlobal("SIMPLEGPSNONL2");
  fi;
end);

BindGlobal("NextIterator_SimGp",function(it)
local a,l,pos,g,b;
  if it!.done then return fail;fi;
  a:=it!.b;
  if a>=1316848669 then
    # 1316848669 is the first prime power whose L2 order is beyond the
    # simple2 list
    Error("List of simple groups only available up to order",
      SIMPLE_GROUPS_ITERATOR_RANGE);
  fi;
  l:=SizeL2Q(a);
  pos:=it!.pos;
  if pos>=245  then LOADSIMPLE2(); fi;
  if l<SIMPLEGPSNONL2[pos][1] and not it!.nopsl2 then
    # next is a L2
    g:=SimpleGroup("L",2,a);
    a:=NextL2Q(it!.a,it!.stack);
    it!.a:=a[2];
    it!.b:=a[1];
    it!.stack:=a[3];
  else
    # next is from the list
    a:=SIMPLEGPSNONL2[pos];
    it!.pos:=pos+1;

    if a[2]="Spor" then
      g:=SimpleGroup(a[3]);
    else
      if a[4]=0 then
        b:=a{[2,3]}; # 0 is filler
      else
        b:=a{[2..4]};
      fi;
      g:=CallFuncList(SimpleGroup,b);
    fi;
    # safety check
    if Size(g)<>a[1] then
      Error("order inconsistency");
    fi;
  fi;

  #Print("pos=",it!.pos," b=",it!.b,"\n");

  it!.done:=SIMPLEGPSNONL2[it!.pos][1]>it!.ende
    and (SizeL2Q(it!.b)>it!.ende or it!.nopsl2);

  return g;
end);

BindGlobal("IsDoneIterator_SimGp",function(it)
  return it!.done;
end);

InstallGlobalFunction(SimpleGroupsIterator,function(arg)
  local a,b,stack,ende,start,pos,nopsl2;
  ende:=infinity;
  if Length(arg)=0 then
    start:=60;
  else
    start:=Maximum(60,arg[1]);
    if Length(arg)>1 then
      ende:=arg[2];
    fi;
  fi;
  nopsl2:=ValueOption("NOPSL2")=true or ValueOption("nopsl2")=true;

  # find relevant L2 order
  a:=RootInt(start,3)-1;
  stack:=fail;
  repeat
    a:=NextL2Q(a,stack);
    b:=a[1];
    stack:=a[3];
    a:=a[2];
  until SizeL2Q(b)>=start;
  if start>=10^18 then LOADSIMPLE2(); fi;
  pos:=First([1..Length(SIMPLEGPSNONL2)],x->SIMPLEGPSNONL2[x][1]>=start);
  return IteratorByFunctions(rec(
    IsDoneIterator:=IsDoneIterator_SimGp,
    NextIterator:=NextIterator_SimGp,
    ShallowCopy:=iter -> rec( a:=iter!.a,
      b:=iter!.b, ende:=iter!.ende,
      stack:=ShallowCopy(iter!.stack), pos:=iter!.pos,
      nopsl2:=iter!.nopsl2,
      done:=iter!.done),
    a:=a,
    b:=b,
    ende:=ende,
    stack:=stack,
    pos:=pos,
    nopsl2:=nopsl2,
    # if nopsl2 then the l2size is irrelevant
    done:=(SizeL2Q(b)>ende or nopsl2) and SIMPLEGPSNONL2[pos][1]>ende
  ));

end);

InstallGlobalFunction(ClassicalIsomorphismTypeFiniteSimpleGroup,function(G)
local t,r;
  if IsGroup(G) then
    t:=IsomorphismTypeInfoFiniteSimpleGroup(G);
  else
    t:=G;
  fi;
  r:=rec();
  if t.series in ["Z","A"] then
    r.series:=t.series;
    r.parameter:=[t.parameter];
  elif t.series in ["L","E"] then
    r.series:=t.series;
    r.parameter:=t.parameter;
  elif t.series="Spor" then
    r.series:=t.series;
    # stupid naming of J2
    if Length(t.name)>5 and t.name{[1..5]}="HJ = " then
      r.parameter:=["J2"];
    else
      r.parameter:=[t.name];
    fi;
  elif t.series="B" then
    r.series:="O";
    r.parameter:=[t.parameter[1]*2+1,t.parameter[2]];
  elif t.series="C" then
    r.series:="S";
    r.parameter:=[t.parameter[1]*2,t.parameter[2]];
  elif t.series="D" then
    r.series:="O+";
    r.parameter:=[t.parameter[1]*2,t.parameter[2]];
  elif t.series="F" then
    r.series:="F";
    r.parameter:=[4,t.parameter];
  elif t.series="G" then
    r.series:="G";
    r.parameter:=[2,t.parameter];
  elif t.series="2A" then
    r.series:="U";
    r.parameter:=[t.parameter[1]+1,t.parameter[2]];
  elif t.series="2B" then
    r.series:="Sz";
    r.parameter:=[t.parameter];
  elif t.series="2D" then
    r.series:="O-";
    r.parameter:=[t.parameter[1]*2,t.parameter[2]];
  elif t.series="3D" then
    r.series:="3D";
    r.parameter:=[4,t.parameter];
  elif t.series="2E" then
    r.series:="2E";
    r.parameter:=[6,t.parameter];
  elif t.series="2F" then
    if t.parameter=2 then
      r.series:="Spor";
      r.parameter:=["T"];
    else
      r.series:="2F";
      r.parameter:=[t.parameter];
    fi;
  elif t.series="2G" then
    r.series:="2G";
    r.parameter:=[t.parameter];
  fi;
  return r;
end);

InstallMethod(DataAboutSimpleGroup,true,[IsGroup],0,
function(G)
local id;
  id:=IsomorphismTypeInfoFiniteSimpleGroup(G);
  return DataAboutSimpleGroup(id);
end);

# Tables for outer automorphisms from Bray/Holt/Roney-Dougal p. 36/37 [BHRD2013]
BindGlobal("OuterAutoSimplePres",function(class,n,q)
local p,e,f,rels,gp;
  class:=UppercaseString(class);
  p:=SmallestPrimeDivisor(q);
  e:=LogInt(q,p);
  if class="L" and n=2 then
    f:=FreeGroup("d","f");
    rels:=StringFormatted("d{}=f{}=[d,f]=1",Gcd(q-1,2),e);
  elif class="L" and n>=3 then
    f:=FreeGroup("d","g","f");
    rels:=StringFormatted("d{}=g2=f{}=[g,f]=1,d^g=D,d^f=d{}",Gcd(q-1,n),e,p);
  elif class="U" and n>=3 then
    f:=FreeGroup("d","g","f");
    rels:=StringFormatted("d{}=g2=1,f{}=g,d^g=D,d^f=d{}",Gcd(q+1,n),e,p);
  elif class="S" and n>=2 and (n<>4 or p<>2) then
    f:=FreeGroup("d","f");
    rels:=StringFormatted("d{}=f{}=[d,f]=1",Gcd(q-1,2),e);
  elif class="S" and n=4 and p=2 then
    f:=FreeGroup("g","f");
    rels:=StringFormatted("g2=f,f{}=1",e);
  elif (class="O" or class="O0" or class="OO") and n>=3 then
    # special case of characteristic 2 -- copy S status
    if p=2 then
      f:=FreeGroup("d","f");
      rels:=StringFormatted("d{}=f{}=[d,f]=1",Gcd(q-1,2),e);
    else
      f:=FreeGroup("d","f");
      rels:=StringFormatted("d2=f{}=[d,f]=1",e);
    fi;
  elif class="O+" and n>=6 and IsEvenInt(n) and n<>8 and p=2 then
    f:=FreeGroup("g","f");
    rels:=StringFormatted("g2=f{}=[g,f]=1",e);
  elif class="O+" and n=8 and p=2 then
    f:=FreeGroup("t","g","f");
    rels:=StringFormatted("t^3=g2=(gt)2=f{}=[t,f]=[g,f]=1",e);
  elif class="O-" and n>=4 and IsEvenInt(n) and p=2 then
    f:=FreeGroup("g","f");
    rels:=StringFormatted("g2,f{}=g",e);
  elif class="O+" and n=8 and IsOddInt(p) then
    f:=FreeGroup("p","t","g","d","f");
    rels:=StringFormatted(
      "p2=t3=g2=(gt)2=d2=1,d^t=p,p^dp,(dg)2=p,f{}=[d,f]=[t,f]=[g,f]=1",e);
  elif class="O+" and n>=12 and n mod 4=0 and IsOddInt(q) then
    f:=FreeGroup("p","g","d","f");
    rels:=StringFormatted("p2=g2=d2=1,(dg)2=p,f{}=[d,f]=[g,f]=1",e);
  elif class="O+" and n>=6 and n mod 4=2 and q mod 4=1 then
    f:=FreeGroup("p","g","d","f");
    rels:=StringFormatted("p2=g2=1,d2=p,d^g=D,f{}=[g,f]=1,d^f=d{}",e,p);
  elif class="O+" and n>=6 and n mod 4=2 and q mod 4=3 then
    f:=FreeGroup("g","d","f");
    rels:=StringFormatted("g2=d2=[d,g]=f{}=[g,f]=[d,f]=1",e);
  elif class="O-" and n>=4 and (n mod 4=0 or q mod 4=1) and IsOddInt(q) then
    f:=FreeGroup("g","d","f");
    rels:=StringFormatted("g2=d2=[d,g]=[d,f]=1,f{}=g",e);
  elif class="O-" and n>=4 and n mod 4=2 and q mod 4=3 then
    f:=FreeGroup("p","g","d","f");
    rels:=StringFormatted("p2=g2=1,d2=p,d^g=D,f{}=[g,f]=[d,f]=1",e);
  else
    return fail;
  fi;
  gp:=f/ParseRelators(f,rels);
  SetReducedMultiplication(gp);
  Size(gp);
  return gp;
end);

InstallOtherMethod(DataAboutSimpleGroup,true,[IsRecord],0,
function(id)
local nam,e,efactors,par,expo,prime,result,aut,i,classical,classaut,shortname,
      multElabel;

  shortname:=function(gp)
  local s;
    if IsCyclic(gp) then
      return String(Size(gp));
    elif IdGroup(gp)=[4,2] then
      return "2^2";
    elif IdGroup(gp)=[6,1] then
      return "3.2";
    elif IdGroup(gp)=[8,3] then
      return "2^2.2";
    elif IdGroup(gp)=[9,2] then
      return "3^2";
    elif IdGroup(gp)=[18,3] then
      return "3^2.2";
    elif Size(gp)<=31 or Size(gp) in [33..47] then
      s:=StructureDescription(gp);
      s:=Filtered(s,x->not x in "C ");
      if Length(s)>3 and s{[Length(s)-2..Length(s)]}="xS3" then
        s:=Concatenation(s{[1..Length(s)-3]},".3.2");
      fi;
      return s;
    else
      Error("name not yet found");
    fi;
  end;

  multElabel:=function()
  local a,b,j;
    for a in e do
      b:=Filtered(e,x->x[2]=a[2]);
      if Length(b)>1 then
        for j in [1..Length(b)] do
          b[j][2]:=Concatenation(b[j][2],"_",String(j));
        od;
      fi;
    od;
    Sort(e);
  end;

  # fix O5 to SP4
  if id.series="B" and id.parameter[1]=2 then
    id:=rec(name:=id.name,series:="C",parameter:=id.parameter,
      shortname:=Concatenation("S4(",String(id.parameter[2]),")"));
  fi;

  # fix

  if IsBound(id.parameter) then
    par:=id.parameter;
    if IsList(par) then
      prime:=Factors(par[2])[1];
      expo:=LogInt(par[2],prime);
    else
      prime:=Factors(par)[1];
      expo:=LogInt(par,prime);
    fi;
  fi;

  efactors:=fail;
  classaut:=fail;
  e:=fail;

  classical:=fail;
  if id.series="Spor" then
    nam:=id.name;
    # deal wirth stupid names in identification

    if nam in ["M(11)","M(12)","M(22)","M(23)","M(24)","J(1)","J(3)",
               "J(4)","Co(3)","Co(2)","Fi(22)","Fi(23)"] then
      nam:=Filtered(nam,x->x<>'(' and x<>')');
    elif nam="HJ = J(2) = F(5-)" then
      nam:="J2";
    elif nam="He = F(7)" then
      nam:="He";
    elif nam="Fi(24) = F(3+)" then
      nam:="F3+";
    elif nam="Mc" then
      nam:="McL";
    elif nam="HN = F(5) = F = F(5+)" then
      nam:="HN";
    elif nam="Th = F(3) = E = F(3/3)" then
      nam:="Th";
    elif nam="Co(1) = F(2-)" then
      nam:="Co1";
    elif nam="B = F(2+)" then
      nam:="B";
    elif nam="M = F(1)" then
      nam:="M";
    fi;
    if nam in ["M12","M22","HS","McL","He","Fi22","F3+","HN","Suz","ON",
               "J2","J3"] then
      e:=[[2,"2"]];
    else
      e:=[];
    fi;
  elif id.series="A" then
    nam:=Concatenation("A",String(par));
    if par=6 then
      e:=[[2,"2_1"],[2,"2_2"],[2,"2_3"],[4,"2^2"]];
    else
      e:=[[2,"2"]];
    fi;
  elif id.series="L" then
    classical:=["L",par[1],par[2]];
    nam:=Concatenation("L",String(par[1]),"(",String(par[2]),")");
    if par[1]=2 then
      efactors:=[Gcd(2,par[2]-1),expo,1];
    else
      efactors:=[Gcd(par[1],par[2]-1),expo,2];
    fi;
  elif id.series="2A" then
    classical:=["U",par[1]+1,par[2]];
    nam:=Concatenation("U",String(par[1]+1),"(",String(par[2]),")");
    efactors:=[Gcd(par[1]+1,par[2]+1),2*expo,1];
  elif id.series="B" then
    classical:=["O",2*par[1]+1,par[2]];
    if IsEvenInt(par[2]) then
      nam:=Concatenation("S",String(2*par[1]),"(",String(par[2]),")");
    else
      nam:=Concatenation("O",String(2*par[1]+1),"(",String(par[2]),")");
    fi;
    if par[1]=2 and par[2]=3 then
      nam:="U4(2)"; # library name
    fi;
    if par[1]=2 and prime=2 then
      efactors:=[Gcd(2,par[2]-1),expo,2];
    else
      efactors:=[Gcd(2,par[2]-1),expo,1];
    fi;
  elif id.series="2B" then
    nam:=Concatenation("Sz(",String(par),")");
    efactors:=[1,expo,1];
  elif id.series="C" then
    classical:=["S",2*par[1],par[2]];
    nam:=Concatenation("S",String(par[1]*2),"(",String(par[2]),")");
    if par[1]=2 and prime=2 then
      efactors:=[Gcd(2,par[2]-1),expo,2];
    else
      efactors:=[Gcd(2,par[2]-1),expo,1];
    fi;
  elif id.series="D" then
    classical:=["O+",2*par[1],par[2]];
    nam:=Concatenation("O",String(par[1]*2),"+(",String(par[2]),")");
    if par[1]=4 then
      efactors:=[Gcd(2,par[2]-1)^2,expo,6];
    elif IsEvenInt(par[1]) then
      efactors:=[Gcd(2,par[2]-1)^2,expo,2];
    else
      efactors:=[Gcd(4,par[2]^par[1]-1),expo,2];
    fi;
  elif id.series="2D" then
    classical:=["O-",2*par[1],par[2]];
    nam:=Concatenation("O",String(par[1]*2),"-(",String(par[2]),")");

    efactors:=[Gcd(4,par[2]^par[1]+1),2*expo,1];

  elif id.series="F" then
    nam:=Concatenation("F4(",String(par),")");
    if prime=2 then
      efactors:=[1,expo,2];
      # outer automorphism group is cyclic
      classaut:=CyclicGroup(2*expo);
    else
      efactors:=[1,expo,1];
    fi;

  elif id.series="G" then
    nam:=Concatenation("G2(",String(par),")");
    if prime=3 then
      efactors:=[1,expo,2];
      # outer automorphism group is cyclic
      classaut:=CyclicGroup(2*expo);
    else
      efactors:=[1,expo,1];
    fi;

  elif id.series="3D" then
    nam:=Concatenation("3D4(",String(par),")");
    efactors:=[1,3*expo,1];
  elif id.series="2G" then
    nam:=Concatenation("R(",String(par),")");
    efactors:=[1,expo,1];
  elif id.series="2F" and id.parameter=2 then
    # special case for tits' group before sorting out further 2F4's
    nam:="2F4(2)'";
    e:=[[2,"2"]];
  else
    Info(InfoWarning,1,"simple group tom nonidentified/not yet done");
    nam:=fail;
    e:=fail;
  fi;

  aut:=fail;
  if classical<>fail then
    classaut:=OuterAutoSimplePres(classical[1],classical[2],classical[3]);
    if classaut<>fail then
      if efactors<>fail and Size(classaut)<>Product(efactors) then
        Error("outer automorphism efactor fail");
      fi;
      if IdGroup(classaut)=[4,2] then
        # subgroup classes V4
        e:=[[2,"2_1"],[2,"2_2"],[2,"2_3"],[4,"2^2"]];
      elif IdGroup(classaut)=[6,1] then
        # subgroup classes S_3
        e:=[  [ 2, "2" ], [ 3, "3" ], [ 6, "3.2" ] ];
      elif IdGroup(classaut)=[12,4] then
        # subgroup classes 2\times S_3 (since S3 cannot act on C2)
        e:=[ [ 2, "2_1" ], [ 2, "2_2" ], [ 2, "2_3" ], [ 3, "3" ],
             [ 4, "2^2" ], [ 6, "3.2_1" ], [ 6, "3.2_2" ], [ 6, "6" ],
             [ 12, "3.2^2" ] ];
      elif IdGroup(classaut)=[24,12] then
        # subgroup classes S_4
        e:=[  [ 2, "2_1" ],[ 2, "2_2" ], [ 3, "3" ],
              [ 4, "4" ], [ 4, "(2^2)_{111}" ], [4,"(2^2)_{122}"],
              [ 6, "3.2" ], [ 8, "D8" ], [ 12, "A4" ],
              [ 24, "S4" ] ];
      else
        e:=List(ConjugacyClassesSubgroups(classaut),Representative);
        e:=Filtered(e,x->Size(x)>1);
        e:=List(e,x->[Size(x),shortname(x)]);
        multElabel();
      fi;
    fi;
  elif e=fail and efactors<>fail then

# outer automorphism group -- also being described through efactors.
# Atlas of Finite Groups (Chapter 3, Section 3) says:
#
#The outer automorphism group is a semidirect product (in this order) of
#groups of orders d (diagonal automorphisms), f (field automorphisms), and g
#(graph automorphisms modulo field automorphisms), except that for
#B_2(2^f), G_2(3^f), F_4(2^f)
# Note that B2 is handled as C2 -- symplectic

    if not IsGroup(classaut) then
      if Number(efactors,x->x>1)>1 then
        Error("Code currently does not support more than one efactor,\n",
          "Group could be nonabelian");
      fi;
      classaut:=AbelianGroup(efactors);
    fi;
    e:=List(ConjugacyClassesSubgroups(classaut),Representative);
    e:=Filtered(e,x->Size(x)>1);
    e:=List(e,x->[Size(x),shortname(x)]);
    multElabel();
  fi;
  if e=fail then Error("eh?");fi;

  if aut=fail then
    if Length(e)=0 then
      aut:=[1,"1"];
    else
      aut:=Maximum(e);
    fi;
  fi;

  result:=rec(idSimple:=id,
              tomName:=nam,
              allExtensions:=e,
              fullAutGroup:=aut,
              classicalId:=ClassicalIsomorphismTypeFiniteSimpleGroup(id));
  if classaut<>fail then
    result.outerAutomorphismGroup:=classaut;
  fi;
  if efactors<>fail then result.efactors:=efactors;fi;

  return result;
end);

InstallGlobalFunction(SufficientlySmallDegreeSimpleGroupOrder,function(n)
local a;
  if n<168 then return 5;fi;
  a:=Filtered(SIMPLEGPSNONL2,x->x[1]=n);
  # we have degree data up to order 2^55
  if n<=2^55 and Length(a)=0 then
    # L2 case
    return 2*RootInt(n,3);
  elif Length(a)>0 and ForAll(a,x->Length(x)>4) then
    return Maximum(List(a,x->x[5]));
  fi;
  # we don't know a smallest degree
  a:=2^Number(Factors(n),x->x=2);
  return n/a; # 2-Sylow index
end);

InstallGlobalFunction("EpimorphismFromClassical",function(G)
local H,d,id,hom,field,C,dom,orbs;
  if not IsSimpleGroup(G) then
    H:=PerfectResiduum(G);
  else
    H:=G;
  fi;
  id:=ValueOption("forcetype");
  if id=fail then
    d:=DataAboutSimpleGroup(H);
    id:=d.idSimple;
  fi;
  if not id.series in ["L","2A","C","D","2D","B"] then
    return fail;
  fi;

  # TODO: Recognize subgroups of almost
  if G<>H then
    return fail;
  fi;

  field:=id.parameter[2];
  if id.series="2A" then
    field:=field^2;
  fi;

  # the source group we are expecting
  if id.series="L" then
    C:=SL(id.parameter[1],id.parameter[2]);
  elif id.series="C" then
    C:=SP(2*id.parameter[1],id.parameter[2]);
  elif id.series="2A" then
    C:=SU(id.parameter[1]+1,id.parameter[2]);
  elif id.series="D" then
    C:=SO(1,2*id.parameter[1],id.parameter[2]);
    C:=DerivedSubgroup(C);
  elif id.series="2D" then
    C:=SO(-1,2*id.parameter[1],id.parameter[2]);
    C:=DerivedSubgroup(C);
  elif id.series="B" then
    C:=SO(0,2*id.parameter[1]+1,id.parameter[2]);
    C:=DerivedSubgroup(C);
  else
    Error("not yet done");
  fi;

  # was the fgroup created as ``P...''?
  if IsBound(G!.actionHomomorphism) then
    hom:=G!.actionHomomorphism;
    if IsMatrixGroup(Source(hom)) and Image(hom)=G and Size(Source(hom))/Size(G)<field then
      # test that the source is really the group we want
      if GeneratorsOfGroup(C)=GeneratorsOfGroup(Source(hom))
        or Source(hom)=C then
          return hom;
      #else
#       Print("different source -- ID\n");
      fi;
    fi;
  fi;


  # build isom
  dom:=NormedRowVectors(DefaultFieldOfMatrixGroup(C)^DimensionOfMatrixGroup(C));
  hom:=ActionHomomorphism(C,dom,OnLines,"surjective");
  orbs:=Orbits(Image(hom),MovedPoints(Image(hom)));
  if Length(orbs)>1 then
    # reduce domain
    orbs:=ShallowCopy(orbs);
    SortBy(orbs,Length);
    dom:=dom{Set(orbs[1])};
    hom:=ActionHomomorphism(C,dom,OnLines,"surjective");
  fi;

  if Size(Image(hom))<>Size(G) then
    Error("inconsistent image");
  fi;

  if # catch if one group is with memory
     RepresentationsOfObject(One(Image(hom)))=
     RepresentationsOfObject(One(G))
     and Image(hom)=G then
    d:=IdentityMapping(G);
  else
    # only force isomorphism if we really want it -- e.g. maximal subgroups
    if ValueOption("classicepiuseiso")<>true then
      return fail;
    fi;
    # Image(hom) is the better group to search in, e.g. classes.
    d:=Image(hom);
    d!.actionHomomorphism:=hom;
    # option to avoid infinite recursion
    d:=IsomorphismGroups(G,Image(hom):classicepiuseiso:=false);
  fi;
  if d=fail then
    Error("inconsistent image 2");
  fi;
  return hom*RestrictedInverseGeneralMapping(d);

end);

[ Dauer der Verarbeitung: 0.39 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge