Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minimal Permutation Degree for Simple and Semi-Simple Groups #5732

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Open
1 change: 1 addition & 0 deletions doc/ref/groups.xml
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ the series without destroying the properties of the series.
<#Include Label="ContainedConjugates">
<#Include Label="ContainingConjugates">
<#Include Label="MinimalFaithfulPermutationDegree">
<#Include Label="MinimalFaithfulPermutationDegreeOfSimpleGroup">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if you install this as a method for MinimalFaithfulPermutationDegree, there isn't much of a reason to document MinimalFaithfulPermutationDegreeOfSimpleGroup, is there? It might be different if it was a helper function that takes a description of the simple group (e.g. the info record) -- then it could be used in other algorithms (without forcing them to create a group just in order to be able to access the data provided by your function).

Of course the documentation for MinimalFaithfulPermutationDegree could be extended to mention that there is special code for simple groups, but I am not sure that this is useful for regular users?

<#Include Label="RepresentativesPerfectSubgroups">
<#Include Label="ConjugacyClassesPerfectSubgroups">
<#Include Label="Zuppos">
Expand Down
25 changes: 25 additions & 0 deletions lib/grplatt.gd
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,31 @@ DeclareOperation("MinimalFaithfulPermutationDegree",[IsGroup and IsFinite]);
DeclareOperation("MinimalFaithfulPermutationRepresentation",
[IsGroup and IsFinite]);

#############################################################################
##
#F MinimalFaithfulPermutationDegreeOfSimpleGroup( <G> )
##
## <#GAPDoc Label="MinimalFaithfulPermutationDegreeOfSimpleGroup">
## <ManSection>
## <Func Name="MinimalFaithfulPermutationDegreeOfSimpleGroup" Arg='G'/>
##
## <Description>
## Return the minimal faithful permutation degree of <A>G</A> based
## on the type of simple group. This is much faster than
## <Ref Oper="MinimalFaithfulPermutationDegree"/>
## but limited to simple groups only.
## <Example><![CDATA[
## gap> MinimalFaithfulPermutationDegreeOfSimpleGroup(PSL(3,3));
## 13
## gap> MinimalFaithfulPermutationDegree(PSL(3,3));
## 13
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareGlobalFunction("MinimalFaithfulPermutationDegreeOfSimpleGroup");

#############################################################################
##
#F DescSubgroupIterator( <G> )
Expand Down
135 changes: 135 additions & 0 deletions lib/grplatt.gi
Original file line number Diff line number Diff line change
Expand Up @@ -3654,6 +3654,141 @@ function(G)
return DoMinimalFaithfulPermutationDegree(G,true);
end);

InstallGlobalFunction(MinimalFaithfulPermutationDegreeOfSimpleGroup,function (G)
pranav-joshi-iitgn marked this conversation as resolved.
Show resolved Hide resolved
local
series, # series of simple groups
parameter, # parameters of G in series
info, # information regarding type of simple group
d, # mostly the dimension of vector space for classical groups
q, # elements in the field over which group is define
m, # first parameter
b,
name,
SporDegs, # The Minimal Permutation Degrees for sporadic groups
deg;

info := IsomorphismTypeInfoFiniteSimpleGroup(G);
series := info.series;

if series = "Spor" then
name := info.shortname;
SporDegs := [
["M11",11],
["M12",12],
["M22",22],
["M23",23],
["M24",24],
["Co1",98280],
["Co2",2300],
["Co3",276],
["McL",275],
["HS",100],
["Suz",1782],
["Fi22",3510],
["Fi23",31671],
["Fi24",306936],
["M",97239461142009186000],
["B",13571955000],
["Th",143127000],
["HN",1140000],
["He",2058],
["J1",266],
["J2",100],
["J3",6156],
["J4",173067389],
["ON",122760],
["Ly",8835156],
["Ru",4060]
];
for deg in SporDegs do
if deg[1] = name then return deg[2]; fi;
od;
pranav-joshi-iitgn marked this conversation as resolved.
Show resolved Hide resolved
else
pranav-joshi-iitgn marked this conversation as resolved.
Show resolved Hide resolved
parameter := info.parameter;
if IsList(parameter) then
q := parameter[2];
m := parameter[1];
else q := parameter; fi;
pranav-joshi-iitgn marked this conversation as resolved.
Show resolved Hide resolved
fi;
if series = "Z" then
return q;
elif series = "A" then # Alt
return q;
elif series = "L" then # PSL
d := m;
if (d = 4 and q = 2) then return 8; fi;
if d = 2 then
if q = 9 then return 6; fi;
if q in [5,7,11] then return q; fi;
fi;
return (q^d-1)/(q-1);
elif series = "2A" then # PSU
d := m + 1;
if d = 3 and q = 5 then return 50; fi;
if d = 3 then return q^3 + 1; fi;
if d = 4 then return (q+1)*(q^3 + 1); fi;
if d mod 2 = 0 and q = 2 then return (2^(d-1)*(2^d - 1))/3; fi;
return ((q^d - (-1)^d)*(q^(d-1) + (-1)^d))/(q^2-1);
elif series = "B" then # P\Omega or O
d := 2*m +1;
if q = 3 and m > 2 then return (3^m)*(3^m - 1)/2; fi;
if q > 4 and m > 2 then return (q^(2*m)-1)/(q-1); fi;
#Special case : B(2,3) ~ 2A(3,2) = PSU(4,2)
if q = 3 and m = 2 then return 27;fi;
# B(2,2) is not a simple group.
#Special case : B(2,q) ~ C(2,q) = PSp(4,q)
if m=2 then return (q^(2*m) -1)/(q-1);fi;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if m=2 then return (q^(2*m) -1)/(q-1);fi;
if m = 2 then return (q^(2*m)-1)/(q-1); fi;

In general it'd be nice if the formatting was somewhat consistent (i.e. sometimes you have if d=4 sometimes if d = 4, etc. etc.)

But this is a very minor point and not that important.

#Special case : B(m,2) ~ C(m,2) = PSp(2*m,2)
if q = 2 then return (2^(m-1))*(2^m -1); fi;
elif series = "2B" then # Sz or _2 B^2
if 2^(Log2Int(q)) = q and Log2Int(q) mod 2 = 1 then
pranav-joshi-iitgn marked this conversation as resolved.
Show resolved Hide resolved
return q^2 + 1;
fi;
elif series = "C" then # PSp
d := 2*m;
if d=4 and q=2 then return 6;fi;
if d=4 and q=3 then return 27;fi;
if m>2 and q=2 then return (2^(m-1))*(2^m -1);fi;
if m>1 and q>2 then return (q^d -1)/(q-1);fi;
elif series = "D" then # P\Omega ^+ or O+
d := 2*m;
if m > 3 then
if q < 4 then return q^(m-1)*(q^m -1)/(q-1);
else return (q^(m-1) + 1)*(q^m-1)/(q-1); fi;
fi;
elif series = "2D" then # P\Omega ^- or O-
d := 2*m;
if m > 3 then return (q^m+1)*(q^(m-1)-1)/(q-1);fi;
elif series = "3D" then # ^3 D_4
return (q^8 + q^4 + 1)*(q+1);
elif series = "E" then #E_n(q)
d := m;
if d = 6 then return (q^9 - 1)*(q^8 + q^4 + 1)/(q-1);
elif d = 7 then return (q^14 - 1)*(q^9 + 1)*(q^5 -1)/(q-1);
elif d = 8 then return (q^30 - 1)*(q^12 + 1)*(q^10 + 1)*(q^6 + 1)/(q-1);
fi;
elif series = "2E" then #2E(6,q)
return (q^12 -1)*(q^6 - q^3 + 1)^(q^4 +1)/(q-1);
elif series = "F" then #F(4,q)
return (q^12 -1)*(q^4 + 1)/(q-1);
elif series = "2F" then #2F(4,q)
#special case : 2F4(2) ~ Tits
if q = 2 then return 1600; fi;
return (q^6 + 1)*(q^3 + 1)*(q+1);
elif series = "G" then #G(2,q)
if q = 3 then return 351; fi;
if q = 4 then return 416; fi;
return (q^6 -1)/(q-1);
elif series = "2G" then #2G(2,q)
b := Int(Log(Float(q)) / Log(3.0));
pranav-joshi-iitgn marked this conversation as resolved.
Show resolved Hide resolved
if 3^(b+1) = q then b := b+1; fi; #just a safety net
if q = 3^b and b mod 2 = 1 then return q^3 + 1; fi;
pranav-joshi-iitgn marked this conversation as resolved.
Show resolved Hide resolved
fi;
return Concatenation("Couldn't fit", info.name," aka ",StructureDescriptionForFiniteSimpleGroups(G), "into a type","\n");
end);

InstallMethod(MinimalFaithfulPermutationDegree,"for simple groups",true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the group might not know IsSimple in advance, wouldn't this be better as part of the general MinimalDegree method?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean something like

if IsSimple(G) then
  info := IsomorphismTypeInfoFiniteSimpleGroup(G);
  return MinimalFaithfulPermutationDegreeOfSimpleGroupWithIsomorphismType(info);
fi;

in MinimalFaithfulPermutationDegree itself ?

[IsSimpleGroup and IsFinite],0,MinimalFaithfulPermutationDegreeOfSimpleGroup);

# utility function: Find a subgroup $S$ of $G\le P$, with $G'\le S\le G$ such
# that $[G:S]<=limit$ and that $S\lhd N_P(G)$.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
gap> START_TEST("MinimalFaithfulPermutationDegreeOfSimpleGroup.tst");
gap> checksimple := function(maxsize)
> local i,mu,mu2,info,G;
> i := 1;
> for G in SimpleGroupsIterator(1,maxsize) do
> mu := DoMinimalFaithfulPermutationDegree(G,false);
> mu2 := MinimalFaithfulPermutationDegreeOfSimpleGroup(G);
> if mu2 <> mu then
> info := IsomorphismTypeInfoFiniteSimpleGroup(G);
> return Concatenation("Failed on simple group ",String(i)," i.e. ",info.name,"\n");
> fi;
> i := i + 1;
> od;
> return "Passed";
> end;
function( maxsize ) ... end
gap> checksimple(50000); # first 26 simple groups
"Passed"
gap> LightChecknonabelianSimple := function(maxsize)
> local size,series,info,G,mu,mu2,mu3;
> for info in SIMPLEGPSNONL2 do
> size := info[1];
> if size > maxsize then break; fi;
> series := info[2];
> mu := Last(info);
> if IsString(info[3]) then #Spor
> G := SimpleGroup(info[3]);
> elif Length(info) = 5 then
> if info[4] = 0 then
> G := SimpleGroup(series,info[3]);
> else
> G := SimpleGroup(series,info[3],info[4]);
> fi;
> else
> Print(info,"\n");
> continue;
> fi;
> mu2 := MinimalFaithfulPermutationDegreeOfSimpleGroup(G);
> if mu < mu2 then
> return Concatenation("failed on",String(info),". From table :",String(mu),", Computed :",String(mu2),"\n");
> elif mu > mu2 then
> mu3 := DoMinimalFaithfulPermutationDegree(G,false);
> if mu2 <> mu3 then
> return Concatenation("failed on",String(info),". From MinimalFaithfulPermutationDegree :",String(mu3),", Computed :",String(mu2),"\n");
> fi;
> fi;
> od;
> return "PASS";
> end;
function( maxsize ) ... end
gap> LightChecknonabelianSimple(1000000); # First 19 non abelian simple groups
"PASS"