############################################################################# ## ## 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. ##
# 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))>1then Error("<q> must be prime power");fi;
p:=p[1];
f:=GF(q);
z:=PrimitiveRoot(f);
o:=One(f);
# 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)>1then
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)=1then # 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=1then # 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)>0then
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)<=1then if str="A" or str="ALT"then if Length(param)=1 and param[1]>4then
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)=0then
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]=1then
g:=PrimitiveGroup(266,1); elif param[1]=2then
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]=3then
g:=PrimitiveGroup(276,3); elif param[1]=2then
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] = 24then 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;
# 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] < 6then
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] < 4then
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]<>4then
Error("F(n,q) needs n=4"); fi;
a:=param[Length(param)]; if a=2then
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]<>2then
Error("G(n,q) needs n=2"); fi;
a:=param[Length(param)]; if a=2then return SimpleGroup("U",3,3); elif a=3then
g:=PrimitiveGroup(351,7); elif a=4then
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]<>4then
Error("3D(n,q) needs n=4"); fi;
a:=param[Length(param)]; if a=2then
g:=PrimitiveGroup(819,5); elif a=3then
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]<>6then
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)>1then
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)>1then 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;
# 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!.donethen return fail;fi;
a:=it!.b; if a>=1316848669then # 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>=245then 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]=0then
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);
InstallGlobalFunction(SimpleGroupsIterator,function(arg)
local a,b,stack,ende,start,pos,nopsl2;
ende:=infinity; if Length(arg)=0then
start:=60; else
start:=Maximum(60,arg[1]); if Length(arg)>1then
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^18then 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=2then
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=2then
f:=FreeGroup("d","f");
rels:=StringFormatted("d{}=f{}=[d,f]=1",Gcd(q-1,2),e); elif class="L" and n>=3then
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>=3then
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=2then
f:=FreeGroup("g","f");
rels:=StringFormatted("g2=f,f{}=1",e); elif (class="O" or class="O0" or class="OO") and n>=3then # special case of characteristic 2 -- copy S status if p=2then
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=2then
f:=FreeGroup("g","f");
rels:=StringFormatted("g2=f{}=[g,f]=1",e); elif class="O+" and n=8 and p=2then
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=2then
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=1then
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=3then
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=3then
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)>1then 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]=2then
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=6then
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]=2then
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]=3then
nam:="U4(2)"; # library name fi; if par[1]=2 and prime=2then
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=2then
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]=4then
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=2then
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=3then
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=2then # 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;
# 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)>1then
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)=0then
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<168then 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)=0then # 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;
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);
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.72 Sekunden
(vorverarbeitet am 2026-10-12)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.