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
3 changes: 3 additions & 0 deletions lib/grplatt.gd
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,8 @@ DeclareSynonym("EmbeddingConjugates",ContainingConjugates);
## positive integer <M>n=\mu(G)</M> such that <A>G</A> is isomorphic to a
## subgroup of the symmetric group of degree <M>n</M>.
## This can require calculating the whole subgroup lattice.
## In case you know that <A>G</A> is simple, use
## <C>MinimalFaithfulPermutationDegreeOfSimpleGroup</C> instead.
## The operation
## <Ref Oper="MinimalFaithfulPermutationRepresentation"/>
## returns a
Expand All @@ -556,6 +558,7 @@ DeclareSynonym("EmbeddingConjugates",ContainingConjugates);
DeclareOperation("MinimalFaithfulPermutationDegree",[IsGroup and IsFinite]);
DeclareOperation("MinimalFaithfulPermutationRepresentation",
[IsGroup and IsFinite]);
DeclareGlobalFunction("MinimalFaithfulPermutationDegreeOfSimpleGroup");

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

BindGlobal("SporadicGroupMinimalFaithfulPermutationDegrees", rec(
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,
));

BindGlobal("MinimalFaithfulPermutationDegreeOfSimpleGroupWithIsomorphismType",function (info)
Copy link
Contributor

Choose a reason for hiding this comment

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

I would prefer to move all of this into DataAboutSimpleGroup, which already stores a lot of knowledge about the simple groups, if only to keep this data together. The case distinctions for the different classes of groups are already coded there.
As that function can take a group as argument, it implies that the global function MinimalFaithfulPermutationDegreeOfSimpleGroupWithIsomorphismType would not be needed.

# This function is derived from table 4 of this paper :
# https://www.ams.org/journals/tran/2015-367-11/S0002-9947-2015-06293-X/S0002-9947-2015-06293-X.pdf

# `info` is the a record containing information about the type of the simple group,
# like one obtained from `IsomorphismTypeInfoFiniteSimpleGroup`. You need to give the series,
# parameter, and shortname values in the record.
local
series, # series of simple groups
d, # mostly the dimension of vector space for classical groups
q, # elements in the field over which group is defined
m, # first parameter
b; # q = p^b for some prime p

series := info.series;
if series = "Spor" then
return SporadicGroupMinimalFaithfulPermutationDegrees.(info.shortname);
else
pranav-joshi-iitgn marked this conversation as resolved.
Show resolved Hide resolved
if IsList(info.parameter) then
q := info.parameter[2];
m := info.parameter[1];
else
q := info.parameter;
fi;
fi;
if series = "Z" then #Cyclic group of prime order
return q;
elif series = "A" then # Alternating group
return q;
elif series = "L" then # PSL(m,q)
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(m+1,q)
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(2*m+1,q) or O
if q = 3 and m > 2 then return (3^m)*(3^m - 1)/2;
elif q > 4 and m > 2 then return (q^(2*m)-1)/(q-1);
elif q = 3 and m = 2 then return 27; #Special case : B(2,3) ~ 2A(3,2) = PSU(4,2)
elif q = 2 and m = 2 then # B(2,2) is not a simple group.
Error("B(2,2) is not a simple group. This shouldn't be happening.\n");
elif m = 2 then return (q^(2*m) -1)/(q-1); #Special case : B(2,q) ~ C(2,q) = PSp(4,q)
elif q = 2 then return (2^(m-1))*(2^m -1); #Special case : B(m,2) ~ C(m,2) = PSp(2*m,2)
else Error("series B and m,q not of proper form\n"); fi;
elif series = "2B" then # Sz or _2 B^2
b := Log2Int(q);
if 2^b = q and b mod 2 = 1 then return q^2 + 1;
else Error("2B series without q of proper form\n"); fi;
elif series = "C" then # PSp(2*m,q)
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;
Error("series C and m,q are not of proper form\n");
elif series = "D" then # POmega(+1,2*m,q) or O+
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;
else Error("series D and m < 4\n"); fi;
elif series = "2D" then # POmega(-1,2*m,q) or O-
if m > 3 then return (q^m+1)*(q^(m-1)-1)/(q-1);
else Error("series 2D and m < 4\n"); fi;
elif series = "3D" then # ^3 D_4
return (q^8 + q^4 + 1)*(q+1);
elif series = "E" then #E_n(q)
if m = 6 then return (q^9 - 1)*(q^8 + q^4 + 1)/(q-1);
elif m = 7 then return (q^14 - 1)*(q^9 + 1)*(q^5 -1)/(q-1);
elif m = 8 then return (q^30 - 1)*(q^12 + 1)*(q^10 + 1)*(q^6 + 1)/(q-1);
else Error("series E and m is not 6,7 or 8\n");
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)
if q = 2 then return 1600; #special case : 2F4(2) ~ Tits
else return (q^6 + 1)*(q^3 + 1)*(q+1); fi;
elif series = "G" then #G(2,q)
if q = 3 then return 351;
elif q = 4 then return 416;
else return (q^6 -1)/(q-1); fi;
elif series = "2G" then #2G(2,q)
b := PValuation(q,3);
if q = 3^b and b mod 2 = 1 then return q^3 + 1;
else Error("series 2G and q not of proper form\n"); fi;
fi;
Error("series `",series,"` is not valid\n");
end);

InstallGlobalFunction(MinimalFaithfulPermutationDegreeOfSimpleGroup,function(G)
local info;
info := IsomorphismTypeInfoFiniteSimpleGroup(G); #This requires computing Size(G)
return MinimalFaithfulPermutationDegreeOfSimpleGroupWithIsomorphismType(info);
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,129 @@
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> Clean := function(INFO)
> local SporNames,SeriesNames,info,name,q,size;
> info := ShallowCopy(INFO);
> SporNames := [
> ["M11","M(11)"],
> ["M12","M(12)"],
> ["M22","M(22)"],
> ["M23","M(23)"],
> ["M24","M(24)"],
> ["J1","J(1)"],
> ["J2","J(2)"],
> ["J3","J(3)"],
> ["Co2","Co(2)"],
> ["Co3","Co(3)"],
> ["Fi22","Fi(22)"],
> ];
> SeriesNames := [
> ["U","2A"],
> ["S","C"],
> ["Sz","2B"],
> ["O+","D"],
> ["O-","2D"],
> ["O","B"],
> ];
> if IsString(info[3]) then
> for name in SporNames do
> if name[2] = info[3] then
> info[3] := name[1];
> fi;
> od;
> if info[3] = "T" then
> info[2] := "2F";
> info[3] := 2;
> info[4] := 0;
> fi;
> else
> for name in SeriesNames do
> if name[1] = info[2] then
> info[2] := name[2];
> fi;
> if INFO[2] = "U" then info[3] := INFO[3] -1;fi;
> if INFO[2] in ["S","O+","O-"] then info[3] := INFO[3]/2; fi;
> if INFO[2] = "O" then info[3] := (INFO[3] -1)/2; fi;
> if not IsInt(info[3]) then Error("wierd .. ",INFO,"\n"); fi;
> if info[2] = "R" then
> q := info[3];
> size := info[1];
> if size = q^3 * (q^3 + 1) * (q-1) and PrimeDivisors(q) = [3] then
> info[2] := "2G";
> elif size = q^12 * (q^6 + 1) * (q^4 -1) * (q^3+1) * (q-1)
> and PrimeDivisors(q) = [2] then
> info[2] := "2F";
> else
> Error("Couldn't identify");
> fi;
> fi;
> od;
> fi;
> return info;
> end;
function( INFO ) ... end
gap> MakeRecord := function(INFO)
> local info,parameter,series,shortname;
> if IsString(INFO[3]) then
> return rec(
> series := "Spor",
> parameter := INFO[4],
> shortname := INFO[3],
> );
> fi;
> if INFO[4] = 0 then
> parameter := INFO[3];
> else
> parameter := [INFO[3],INFO[4]];
> fi;
> return rec(
> series := INFO[2],
> parameter := parameter,
> );
> end;
function( INFO ) ... end
gap> LightChecknonabelianSimple := function(perfectTill)
> local size,series,INFO,G,mu,mu2,mu3,info;
> for INFO in SIMPLEGPSNONL2 do
> if LENGTH(INFO) <> 5 then continue; fi;
> size := INFO[1];
> series := INFO[2];
> mu := Last(INFO);
> info := MakeRecord(Clean(INFO));
> mu2 := MinimalFaithfulPermutationDegreeOfSimpleGroupWithIsomorphismType(info);
> if mu < mu2 then
> return Concatenation("failed on",String(INFO),". From table :",String(mu),", Computed :",String(mu2),"\n");
> elif size <= perfectTill and mu>mu2 then
> if IsString(INFO[3]) then
> G := SimpleGroup(INFO[3]);
> elif INFO[4] = 0 then
> G := SimpleGroup(INFO[2],INFO[3]);
> else
> G := SimpleGroup(INFO[2],INFO[3],INFO[4]);
> fi;
> 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( perfectTill ) ... end
gap> LightChecknonabelianSimple(10^6);
"PASS"
Loading