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

FIX: (Maximal) subgroups computation. #2488

Merged
merged 2 commits into from
Jun 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 32 additions & 28 deletions lib/csetgrp.gi
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ end);
## the operation of G on the Right Cosets of U.
##
InstallGlobalFunction( IntermediateGroup, function(G,U)
local o,b,img,G1,c,m,hardlimit,gens,t,k,intersize;
local o,b,img,G1,c,m,mt,hardlimit,gens,t,k,intersize;

if U=G then
return fail;
Expand All @@ -221,34 +221,38 @@ local o,b,img,G1,c,m,hardlimit,gens,t,k,intersize;
return fail; # avoid infinite recursion
fi;

# use maximals
m:=MaximalSubgroupClassReps(G:cheap,intersize:=intersize);

m:=Filtered(m,x->Size(x) mod Size(U)=0 and Size(x)>Size(U));
SortBy(m,x->Size(G)/Size(x));

gens:=SmallGeneratingSet(U);
for c in m do
if Index(G,c)<50000 then
t:=RightTransversal(G,c:noascendingchain); # conjugates
for k in t do
if ForAll(gens,x->k*x/k in c) then
Info(InfoCoset,2,"Found Size ",Size(c),"\n");
# U is contained in c^k
return c^k;
# use maximals, use `Try` as we call with limiting options
IsNaturalAlternatingGroup(G);
IsNaturalSymmetricGroup(G);
Copy link
Member

Choose a reason for hiding this comment

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

The above two lines are new. I assume they are meant to ensure better methods are applied, if possible? I.e. an optimization, but not a vital part of the fix? (Just trying to understand).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. But this optimization is checked for in manual and test examples.

m:=TryMaximalSubgroupClassReps(G:cheap,intersize:=intersize,nolattice);
if m<>fail and Length(m)>0 then
Copy link
Member

Choose a reason for hiding this comment

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

Was the nolattice option added here on purpose? Just wondering, as I don't see this part of the change mentioned in the commit message.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes.


m:=Filtered(m,x->Size(x) mod Size(U)=0 and Size(x)>Size(U));
SortBy(m,x->Size(G)/Size(x));

gens:=SmallGeneratingSet(U);
for c in m do
if Index(G,c)<50000 then
t:=RightTransversal(G,c:noascendingchain); # conjugates
for k in t do
if ForAll(gens,x->k*x/k in c) then
Info(InfoCoset,2,"Found Size ",Size(c),"\n");
# U is contained in c^k
return c^k;
fi;
od;
else
t:=DoConjugateInto(G,c,U,true:intersize:=intersize,onlyone:=true);
if t<>fail and t<>[] then
Info(InfoCoset,2,"Found Size ",Size(c),"\n");
return c^(Inverse(t));
fi;
od;
else
t:=DoConjugateInto(G,c,U,true:intersize:=intersize,onlyone:=true);
if t<>fail and t<>[] then
Info(InfoCoset,2,"Found Size ",Size(c),"\n");
return c^(Inverse(t));
fi;
fi;
od;
od;

Info(InfoCoset,2,"Found no intermediate subgroup ",Size(G)," ",Size(U));
return fail;
Info(InfoCoset,2,"Found no intermediate subgroup ",Size(G)," ",Size(U));
return fail;
fi;

# old code -- obsolete

Expand Down Expand Up @@ -824,7 +828,7 @@ local c, flip, maxidx, refineChainActionLimit, cano, tryfct, p, r, t,
fi;
end;

for i in MaximalSubgroupClassReps(G:cheap) do
for i in TryMaximalSubgroupClassReps(G:cheap) do
if Index(G,i)<maxidx(c) and Index(G,i)<badlimit then
p:=Intersection(a,i);
if Index(a,p)<uplimit then
Expand All @@ -846,7 +850,7 @@ local c, flip, maxidx, refineChainActionLimit, cano, tryfct, p, r, t,

if maxidx(c)>10*actlimit then

r:=ShallowCopy(MaximalSubgroupClassReps(a:cheap));
r:=ShallowCopy(TryMaximalSubgroupClassReps(a:cheap));
r:=Filtered(r,x->Index(a,x)<uplimit);

Sort(r,function(a,b) return Size(a)<Size(b);end);
Expand Down
2 changes: 1 addition & 1 deletion lib/factgrp.gi
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ totalcnt, interupt, u, nu, cor, zzz,bigperm,perm,badcores,max,i;
# only affine ones are needed, rest will have wrong kernel
max:=DoMaxesTF(u,["1"]:inmax,cheap);
else
max:=MaximalSubgroupClassReps(u:inmax,cheap);
max:=TryMaximalSubgroupClassReps(u:inmax,cheap);
fi;
max:=Filtered(max,x->IndexNC(G,x)<knowi and IsSubset(x,N));
for i in max do
Expand Down
4 changes: 2 additions & 2 deletions lib/gpprmsya.gi
Original file line number Diff line number Diff line change
Expand Up @@ -2409,7 +2409,7 @@ local G,max,dom,n,A,S,issn,p,i,j,m,k,powdec,pd,gps,v,invol,sel,mf,l,prim;
return max;
end);

InstallMethod( MaximalSubgroupClassReps, "symmetric", true,
InstallMethod( TryMaximalSubgroupClassReps, "symmetric", true,
[ IsNaturalSymmetricGroup and IsFinite], OVERRIDENICE,
function ( G )
local m;
Expand All @@ -2421,7 +2421,7 @@ local m;
fi;
end);

InstallMethod( MaximalSubgroupClassReps, "alternating", true,
InstallMethod( TryMaximalSubgroupClassReps, "alternating", true,
[ IsNaturalAlternatingGroup and IsFinite], OVERRIDENICE,
function ( G )
local m;
Expand Down
13 changes: 9 additions & 4 deletions lib/grp.gd
Original file line number Diff line number Diff line change
Expand Up @@ -1158,8 +1158,9 @@ DeclareAttribute( "ConjugacyClasses", IsGroup );
## <Ref Func="MaximalSubgroupClassReps"/>.
## <Example><![CDATA[
## gap> ConjugacyClassesMaximalSubgroups(g);
## [ AlternatingGroup( [ 1 .. 4 ] )^G, Group( [ (1,2,3), (1,2) ] )^G,
## Group( [ (1,2), (3,4), (1,3)(2,4) ] )^G ]
## [ Group( [ (2,4,3), (1,4)(2,3), (1,3)(2,4) ] )^G,
## Group( [ (3,4), (1,4)(2,3), (1,3)(2,4) ] )^G,
## Group( [ (3,4), (2,4,3) ] )^G ]
## ]]></Example>
## </Description>
## </ManSection>
Expand Down Expand Up @@ -1205,16 +1206,20 @@ DeclareAttribute( "MaximalSubgroups", IsGroup );
## of <A>G</A>.
## <Example><![CDATA[
## gap> MaximalSubgroupClassReps(g);
## [ Alt( [ 1 .. 4 ] ), Group([ (1,2,3), (1,2) ]), Group([ (1,2), (3,4),
## (1,3)(2,4) ]) ]
## [ Group([ (2,4,3), (1,4)(2,3), (1,3)(2,4) ]), Group([ (3,4), (1,4)
## (2,3), (1,3)(2,4) ]), Group([ (3,4), (2,4,3) ]) ]
## ]]></Example>
## </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareAttribute("MaximalSubgroupClassReps",IsGroup);

# utility attribute: Allow use with limiting options, so could hold `fail'.
DeclareAttribute("TryMaximalSubgroupClassReps",IsGroup,"mutable");

# utility function in maximal subgroups code
DeclareGlobalFunction("TryMaxSubgroupTainter");
DeclareGlobalFunction("DoMaxesTF");
DeclareGlobalFunction("MaxesAlmostSimple");

Expand Down
47 changes: 47 additions & 0 deletions lib/grp.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1357,6 +1357,53 @@ end);
##
#M MaximalSubgroups( <G> )
##
InstallMethod(MaximalSubgroupClassReps,"default, catch dangerous options",

This comment was marked as resolved.

This comment was marked as resolved.

true,[IsGroup],0,
function(G)
local H,a,m,i,l;
# easy case, go without options
if not HasTryMaximalSubgroupClassReps(G) then
return TryMaximalSubgroupClassReps(G:
# as if options were unset
cheap:=fail,intersize:=fail,inmax:=fail,nolattice:=fail);
fi;

# hard case -- `Try` is stored
if not IsBound(G!.maxsubtrytaint) or G!.maxsubtrytaint=false then
# stored and untainted, just go on
return TryMaximalSubgroupClassReps(G);
fi;

# compute anew for new group to avoid taint
H:=Group(GeneratorsOfGroup(G));
for i in [Size,IsNaturalAlternatingGroup,IsNaturalSymmetricGroup] do
if Tester(i)(G) then Setter(i)(H,i(G));fi;
Copy link
Member

Choose a reason for hiding this comment

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

So how do we ensure that these three attributes are the only relevant ones for computations of maximal subgroups? What about e.g. IsSolvableGroup? Or information about stabilizer chains, etc. etc.?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They are currently the only two for which special methods for maximal subgroups are installed.

od;
m:=TryMaximalSubgroupClassReps(H:
cheap:=false,intersize:=false,inmax:=false,nolattice:=false);
l:=[];
for i in m do
a:=SubgroupNC(G,GeneratorsOfGroup(i));
if HasSize(i) then SetSize(a,Size(i));fi;
Add(l,a);
od;

# now we know list is untained, store
SetTryMaximalSubgroupClassReps(G,l);
return l;

end);

InstallMethod(TryMaximalSubgroupClassReps,"fetch known correct data",true,
[IsGroup and HasMaximalSubgroupClassReps],SUM_FLAGS,
MaximalSubgroupClassReps);

InstallGlobalFunction(TryMaxSubgroupTainter,function(G)
if ForAny(["cheap","intersize","inmax","nolattice"],
x->not ValueOption(x) in [fail,false]) then
G!.maxsubtrytaint:=true;
fi;
end);

#############################################################################
##
Expand Down
30 changes: 17 additions & 13 deletions lib/grplatt.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1767,10 +1767,12 @@ end);
#F MaximalSubgroupClassReps(<G>) . . . . reps of conjugacy classes of
#F maximal subgroups
##
InstallMethod(MaximalSubgroupClassReps,"using lattice",true,[IsGroup],0,
InstallMethod(TryMaximalSubgroupClassReps,"using lattice",true,[IsGroup],0,
function (G)
local maxs,lat;

TryMaxSubgroupTainter(G);
if ValueOption("nolattice")=true then return fail;fi;
#AH special AG treatment
if not HasIsSolvableGroup(G) and IsSolvableGroup(G) then
return MaximalSubgroupClassReps(G);
Expand Down Expand Up @@ -2345,6 +2347,7 @@ InstallMethod(IntermediateSubgroups,"using maximal subgroups",
1, # better than previous if index larger
function(G,U)
local uind,subs,incl,i,j,k,m,gens,t,c,p,conj,bas,basl,r;

if (not IsFinite(G)) and Index(G,U)=infinity then
TryNextMethod();
fi;
Expand All @@ -2359,11 +2362,13 @@ local uind,subs,incl,i,j,k,m,gens,t,c,p,conj,bas,basl,r;
gens:=SmallGeneratingSet(U);
while i<=Length(subs) do
if conj[i]<>fail then
m:=MaximalSubgroupClassReps(subs[conj[i][1]]); # fetch attribute
m:=TryMaximalSubgroupClassReps(subs[conj[i][1]]:nolattice); # fetch
if m=fail then TryNextMethod();fi;
m:=List(m,x->x^conj[i][2]);
else
# find all maximals containing U
m:=MaximalSubgroupClassReps(subs[i]);
m:=TryMaximalSubgroupClassReps(subs[i]:nolattice);
if m=fail then TryNextMethod();fi;
fi;
m:=Filtered(m,x->IndexNC(subs[i],U) mod IndexNC(subs[i],x)=0);

Expand Down Expand Up @@ -2814,11 +2819,10 @@ InstallGlobalFunction("SubgroupsTrivialFitting",function(G)
ValueOption(NO_PRECOMPUTED_DATA_OPTION)<>true then
Info(InfoPerformance,2,"Using Table of Marks Library");
go:=ImagesSource(tom[1]);
tom:=tom[2];
Info(InfoLattice,1, "Fetching subgroups of simple ",
Identifier(tom)," from table of marks");
len:=LengthsTom(tom);
sub:=List([1..Length(len)],x->RepresentativeTom(tom,x));
Identifier(tom[2])," from table of marks");
len:=LengthsTom(tom[2]);
Copy link
Member

Choose a reason for hiding this comment

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

This looks plausible to me, thanks.

Quick remark on the commit message: It contains the string "partially fixes #2586" -- GitHub sees that, but only the "fixes #2586" bit, it doesn't care about the "partially". As a result, if this commit gets merged, GitHub will close issue #2586.

One workaround is to rephrase this to e.g. fixes issue #2586 (I think). Well, or we wait for you to also fix the second bug, then closing the issue is fine, after all ;-)

sub:=List([1..Length(len)],x->PreImage(tom[1],RepresentativeTom(tom[2],x)));
return sub;
fi;
fi;
Expand Down Expand Up @@ -2846,14 +2850,15 @@ InstallGlobalFunction("SubgroupsTrivialFitting",function(G)
tom:=TomDataAlmostSimpleRecognition(i);
if tom<>fail then
go:=ImagesSource(tom[1]);
tom:=tom[2];
if tom<>fail and
if tom[2]<>fail and
ValueOption(NO_PRECOMPUTED_DATA_OPTION)<>true then
Info(InfoPerformance,2,"Using Table of Marks Library");
Info(InfoLattice,1, "Fetching subgroups of simple ",
Identifier(tom)," from table of marks");
len:=LengthsTom(tom);
sub:=List([1..Length(len)],x->RepresentativeTom(tom,x));
Identifier(tom[2])," from table of marks");
len:=LengthsTom(tom[2]);
# different than above -- no preimage. We're setting subgroups
# of go
sub:=List([1..Length(len)],x->RepresentativeTom(tom[2],x));
sub:=List(sub,x->ConjugacyClassSubgroups(go,x));
SetConjugacyClassesSubgroups(go,sub);
fi;
Expand All @@ -2864,7 +2869,6 @@ InstallGlobalFunction("SubgroupsTrivialFitting",function(G)
fi;
Add(gold,go);


p:=Length(types);
fi;
Add(iso,IsomorphismGroups(i,gold[p]));
Expand Down
15 changes: 14 additions & 1 deletion lib/grpnice.gi
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,20 @@ GroupSeriesMethodByNiceMonomorphism( LowerCentralSeriesOfGroup,
##
#M MaximalSubgroupClassReps( <G> )
##
SubgroupsMethodByNiceMonomorphism( MaximalSubgroupClassReps, [ IsGroup ] );
InstallOtherMethod( TryMaximalSubgroupClassReps,
"handled by nice monomorphism, transfer tainter", true, [IsGroup], 0,
function( G )
local nice, img, sub,i;
TryMaxSubgroupTainter(G);
nice := NiceMonomorphism(G);
img := ShallowCopy(TryMaximalSubgroupClassReps( NiceObject(G) ));
for i in [1..Length(img)] do
sub := GroupByNiceMonomorphism( nice, img[i] );
SetParent( sub, G );
img[i]:=sub;
od;
return img;
end );


#############################################################################
Expand Down
5 changes: 3 additions & 2 deletions lib/grppcatr.gi
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ end;
MAXSUBS_BY_PCGS:=function( G )
local spec, first, max, i, new;

TryMaxSubgroupTainter(G);
spec := SpecialPcgs(G);
first := LGFirst( spec );
max := [];
Expand All @@ -384,15 +385,15 @@ end;
##
#M MaximalSubgroupClassReps( <G> )
##
InstallMethod( MaximalSubgroupClassReps,
InstallMethod( TryMaximalSubgroupClassReps,
"pcgs computable groups using special pcgs",
true,
[ IsGroup and CanEasilyComputePcgs and IsFinite ],
0,
MAXSUBS_BY_PCGS);

#fallback
InstallMethod( MaximalSubgroupClassReps,
InstallMethod( TryMaximalSubgroupClassReps,
"pcgs computable groups using special pcgs",
true,
[ IsGroup and IsSolvableGroup and IsFinite ],
Expand Down
4 changes: 4 additions & 0 deletions lib/maxsub.gi
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,7 @@ local G,types,ff,maxes,lmax,q,d,dorb,dorbt,i,dorbc,dorba,dn,act,comb,smax,soc,
a1emb,a2emb,anew,wnew,e1,e2,emb,a1,a2,mm;

G:=arg[1];
TryMaxSubgroupTainter(G);

# which kinds of maxes do we want to get
if Length(arg)>1 then
Expand Down Expand Up @@ -991,6 +992,9 @@ end);
InstallMethod(MaximalSubgroupClassReps,"TF method",true,
[IsGroup and IsFinite and CanComputeFittingFree],OVERRIDENICE,DoMaxesTF);

InstallMethod(TryMaximalSubgroupClassReps,"TF method",true,
[IsGroup and IsFinite and CanComputeFittingFree],OVERRIDENICE,DoMaxesTF);

#InstallMethod(MaximalSubgroupClassReps,"perm group",true,
# [IsPermGroup and IsFinite],0,DoMaxesTF);

Expand Down
3 changes: 2 additions & 1 deletion lib/pcgsperm.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1430,10 +1430,11 @@ end);
##
## method for solvable perm groups -- it is cheaper to translate to a pc
## group
InstallMethod( MaximalSubgroupClassReps,"solvable perm group",true,
InstallMethod( TryMaximalSubgroupClassReps,"solvable perm group",true,
[ IsPermGroup and CanEasilyComputePcgs and IsFinite ], 0,
function(G)
local hom,m;
TryMaxSubgroupTainter(G);
hom:=IsomorphismPcGroup(G);
m:=MaximalSubgroupClassReps(Image(hom));
List(m,Size); # force
Expand Down
28 changes: 28 additions & 0 deletions tst/testbugfix/2018-05-24-IntermediateSubgroups.tst
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# test for MaximalSubgroupClassReps with options (reported through
# observation by S.Alavi with IntermediateGroup
# More complicated to construct w/o AtlasSubgroup to ensure the 325 points
# action, as it is too slow otherwise.
# Also construct the smaller subgroup
# s1 directly. Finally do not slow down with assertions that don't need
# testing here

gap> START_TEST("noassert");
gap> SetAssertionLevel(0);;
gap> g:=SU(IsPermGroup,4,4);;
gap> sy:=SylowSubgroup(g,2);;
gap> n:=Filtered(NormalSubgroups(sy),x->IsAbelian(x) and Size(x)=256);;
gap> sub:=Normalizer(g,n[1]);;
gap> g:=Action(g,RightTransversal(g,sub),OnRight);;
gap> NrMovedPoints(g);Size(g);
325
1018368000
gap> s:=Stabilizer(g,1);;
gap> s1:=Complementclasses(s,RadicalGroup(s));;
gap> s1:=s1[1];;Size(s1);
4080
gap> n1:= Normalizer( g, s1 );; Size( n1 );
24480
gap> int:=IntermediateGroup(g,s1);;
gap> IsGroup(int);
true
gap> STOP_TEST("noassert");
Loading