Skip to content

Commit

Permalink
Merge pull request #896 from hulpke/additions: Further enhancements t…
Browse files Browse the repository at this point in the history
…o group automorphisms

This PR contains a number of improvements and additions for testing of group isomorphism, respectively calculation of automorphism groups. It has been tested over several months and is merged to avoid too much divergence between master and development branches.

The main effect of this change should be a significantly improved performance for group isomorphism/automorphisms.

The main changes are:

- The automorphism based isomorphism test is also used for solvable groups, unless they can be generated by few elements.
- To this end, the automorphism group calculation allows the (internal) specification of characteristic (or to-be-stabilized) subgroups.
- When calculating subspace stabilizers in GL, write down a generating set instead of performing an orbit/stabilizer calculation.
- Improvements of heuristics in the code which represents factor groups as permutation groups and determines smaller degree permutation representations, to avoid falling into certain long-runtime traps. Code may utilize maximal subgroups.
- A dedicated test file
  • Loading branch information
hulpke authored Nov 23, 2016
2 parents 2908745 + 1c9c9fa commit 9e38dd1
Show file tree
Hide file tree
Showing 21 changed files with 1,345 additions and 185 deletions.
118 changes: 87 additions & 31 deletions lib/autsr.gi
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#############################################################################
##
#W auttf.gi GAP library Alexander Hulpke
#W autsr.gi GAP library Alexander Hulpke
#W Soley Jonsdottir
##
##
Expand Down Expand Up @@ -149,7 +149,12 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs,
b,fratsim,AQ,OQ,Zm,D,innC,bas,oneC,imgs,C,maut,innB,tmpAut,imM,a,A,B,
cond,sub,AQI,AQP,AQiso,rf,res,resperm,proj,Aperm,Apa,precond,ac,
comiso,extra,mo,rada,makeaqiso,ind,lastperm,actbase,somechar,stablim,
scharorb,asAutom,jorb,jorpo,substb;
scharorb,asAutom,jorb,jorpo,substb,isBadPermrep,ma;

# criterion for when to force degree reduction
isBadPermrep:=function(g)
return NrMovedPoints(g)^2>Size(g)*Index(g,DerivedSubgroup(g));
end;

asAutom:=function(sub,hom) return Image(hom,sub);end;

Expand All @@ -170,20 +175,23 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs,
AQP:=Image(AQiso,AQ);
# force degree down
a:=Size(AQP);
AQP:=Group(SmallGeneratingSet(AQP));
AQP:=Group(SmallGeneratingSet(AQP),One(AQP));
SetSize(AQP,a);
a:=SmallerDegreePermutationRepresentation(AQP:cheap);
if NrMovedPoints(Image(a))<NrMovedPoints(AQP) then
Info(InfoMorph,3,"Permdegree reduced ",
NrMovedPoints(AQP),"->",NrMovedPoints(Image(a)));
AQiso:=AQiso*a;
b:=Image(a,AQP);
if Length(GeneratorsOfGroup(b))>Length(GeneratorsOfGroup(AQP)) then
b:=Group(List(GeneratorsOfGroup(AQP),x->ImagesRepresentative(a,x)));
SetSize(b,Size(AQP));
if isBadPermrep(AQP) then
a:=SmallerDegreePermutationRepresentation(AQP:cheap);
if NrMovedPoints(Image(a))<NrMovedPoints(AQP) then
Info(InfoMorph,3,"Permdegree reduced ",
NrMovedPoints(AQP),"->",NrMovedPoints(Image(a)));
AQiso:=AQiso*a;
b:=Image(a,AQP);
if Length(GeneratorsOfGroup(b))>Length(GeneratorsOfGroup(AQP)) then
b:=Group(List(GeneratorsOfGroup(AQP),x->ImagesRepresentative(a,x)));
SetSize(b,Size(AQP));
fi;
AQP:=b;
fi;
AQP:=b;
fi;

end;

stablim:=function(gp,cond,lim)
Expand Down Expand Up @@ -313,6 +321,8 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs,
Q:=Image(hom,G);
fi;

ma:=MaximalSubgroupClassesSol(G);

AQ:=AutomorphismGroupFittingFree(Q:someCharacteristics:=fail);
AQI:=InnerAutomorphismsAutomorphismGroup(AQ);
lastperm:=fail;
Expand All @@ -329,19 +339,41 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs,
hom:=NaturalHomomorphismByNormalSubgroup(G,N);
Q:=Image(hom,G);
# degree reduction called for?
if Size(N)>1 and IsPermGroup(Q) and NrMovedPoints(Q)^2>Size(Q) then
if Size(N)>1 and isBadPermrep(Q) then
#if NrMovedPoints(Q)>15000 then Error("egad!");fi;
q:=SmallerDegreePermutationRepresentation(Q);
Info(InfoMorph,3,"reduced permrep Q ",NrMovedPoints(Q)," -> ",
NrMovedPoints(Range(q)));
hom:=hom*q;
Q:=Image(hom,G);
fi;

# inherit radical factor map
q:=GroupHomomorphismByImagesNC(Q,Range(ff.factorhom),
List(GeneratorsOfGroup(G),x->ImagesRepresentative(hom,x)),
List(GeneratorsOfGroup(G),x->ImagesRepresentative(ff.factorhom,x)));
b:=Image(hom,ff.radical);
SetRadicalGroup(Q,b);
AddNaturalHomomorphismsPool(Q,b,q);

# Use known maximals for Frattini
for j in ma do
D:=Image(hom,j);
if not IsSubset(D,b) then
b:=Core(Q,NormalIntersection(b,D));
fi;
od;
SetIsNilpotentGroup(b,true);
SetFrattiniSubgroup(Q,b);

# M-factor
Mim:=Image(hom,M);
MPcgs:=Pcgs(Mim);
q:=GroupHomomorphismByImagesNC(Q,OQ,
List(GeneratorsOfGroup(G),x->ImagesRepresentative(hom,x)),
List(GeneratorsOfGroup(G),x->ImagesRepresentative(lhom,x)));
AddNaturalHomomorphismsPool(Q,Mim,q);

mo:=GModuleByMats(LinearActionLayer(GeneratorsOfGroup(Q),MPcgs),GF(RelativeOrders(MPcgs)[1]));
# is the extension split?
ocr:=OneCocycles(Q,Mim);
Expand Down Expand Up @@ -543,7 +575,7 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs,
# desperately try to grab some further generators
#stablim(sub,cond,10000)=false then

#if Size(sub)/Size(Aperm)>100000 then Error("HundredK"); fi;
#if Size(sub)/Size(Aperm)>1000000 then Error("Million"); fi;
sub:=SubgroupProperty(sub,cond,Aperm);

Aperm:=Group(Apa,());
Expand Down Expand Up @@ -597,19 +629,34 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs,
then

if rada=fail then
ind:=IsomorphismPcGroup(r);
rada:=AutomorphismGroup(Image(ind,r):someCharacteristics:=fail,actbase:=fail);
# we only consider those homomorphism that stabilize the series we use
for k in List(ser,x->Image(ind,x)) do
if ForAny(GeneratorsOfGroup(rada),x->Image(x,k)<>k) then
Info(InfoMorph,3,"radical automorphism stabilizer");
NiceMonomorphism(rada:autactbase:=fail,someCharacteristics:=fail);
rada:=Stabilizer(rada,k,asAutom);
fi;
od;
# move back to bad degree
rada:=Group(List(GeneratorsOfGroup(rada),
x-> InducedAutomorphism(InverseGeneralMapping(ind),x)));
if IsElementaryAbelian(r) and Size(r)>1 then
B:=Pcgs(r);
rf:=GF(RelativeOrders(B)[1]);
ind:=Filtered(ser,x->IsSubset(r,x) and Size(x)>1 and Size(x)<Size(r));
ind:=List(ind,x->List(GeneratorsOfGroup(x),y->ExponentsOfPcElement(B,y)));
ind:=List(ind,x->x*One(rf));
ind:=SpaceAndOrbitStabilizer(Length(B),rf,ind,[]);
rada:=List(GeneratorsOfGroup(ind),x->
GroupHomomorphismByImagesNC(r,r,B,List(x,y->PcElementByExponents(B,List(y,Int)))));
rada:=Group(rada);
SetIsGroupOfAutomorphismsFiniteGroup(rada,true);
NiceMonomorphism(rada:autactbase:=fail,someCharacteristics:=fail);
else
ind:=IsomorphismPcGroup(r);
rada:=AutomorphismGroup(Image(ind,r):someCharacteristics:=fail,actbase:=fail);
# we only consider those homomorphism that stabilize the series we use
for k in List(ser,x->Image(ind,x)) do
if ForAny(GeneratorsOfGroup(rada),x->Image(x,k)<>k) then
Info(InfoMorph,3,"radical automorphism stabilizer");
NiceMonomorphism(rada:autactbase:=fail,someCharacteristics:=fail);
rada:=Stabilizer(rada,k,asAutom);
fi;
od;
# move back to bad degree
rada:=Group(List(GeneratorsOfGroup(rada),
x-> InducedAutomorphism(InverseGeneralMapping(ind),x)));

fi;
fi;

rf:=Image(hom,r);
Expand Down Expand Up @@ -674,18 +721,25 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs,

if Length(u)>0 then
C:=MappingGeneratorsImages(AQiso);
if C[2]<>GeneratorsOfGroup(AQP) then
C:=[List(GeneratorsOfGroup(AQP),
x->PreImagesRepresentative(AQiso,x)),
GeneratorsOfGroup(AQP)];
fi;
for j in u do
if IsList(j) then
# stabilizer set of subgroups
jorb:=Orbit(AQP,j[1],C[2],C[1],asAutom);
jorb:=ShallowCopy(Orbit(AQP,j[1],C[2],C[1],asAutom));
jorpo:=[Position(jorb,j[1]),Position(jorb,j[2])];
if jorpo[2]=fail then
Append(jorb,Orbit(AQP,j[1],C[2],C[1],asAutom));
jorpo[2]:=Position(jorb,j[2]);
fi;
if Length(jorb)>Length(j) then
B:=ActionHomomorphism(AQP,jorb,C[2],C[1],asAutom);
substb:=PreImage(B,Stabilizer(Image(B),Set(jorpo),OnSets));
substb:=Group(List(C[2],x->ImagesRepresentative(B,x)),());
substb:=Stabilizer(substb,Set(jorpo),OnSets);
substb:=PreImage(B,substb);
Info(InfoMorph,2,"Stabilize characteristic orbit ",Size(j[1]),
" :",Size(AQP)/Size(substb) );
else
Expand Down Expand Up @@ -753,6 +807,8 @@ local d,a,map,possibly,cG,cH,nG,nH,i,j,sel,u,v,asAutomorphism,K,L,conj,e1,e2,
end;

# go through factors of characteristic series to keep orbits short.
AutomorphismGroup(G:someCharacteristics:=fail);
AutomorphismGroup(H:someCharacteristics:=fail);
cG:=CharacteristicSubgroupsLib(G);
nG:=[];
cH:=ShallowCopy(CharacteristicSubgroupsLib(H));
Expand Down Expand Up @@ -780,7 +836,7 @@ local d,a,map,possibly,cG,cH,nG,nH,i,j,sel,u,v,asAutomorphism,K,L,conj,e1,e2,
x->possibly(cH[i],cH[x])));
v:=TrivialSubgroup(H);
for j in sel do
u:=ClosureGroup(v,cH[j]);
v:=ClosureGroup(v,cH[j]);
od;
if Size(u)<>Size(v) then
return fail;
Expand Down
39 changes: 36 additions & 3 deletions lib/factgrp.gi
Original file line number Diff line number Diff line change
Expand Up @@ -314,10 +314,32 @@ local G,pool,p,comb,i,c,perm,l,isi,N,discard,ab;
if Length(arg)>1 then
N:=arg[2];
p:=Filtered(p,i->IsSubset(pool.ker[i],N));
if Length(p)=0 then
return;
fi;
SortParallel(List(pool.ker{p},Size),p);
if Size(pool.ker[p[1]])=Size(N) and Length(p)>3 then
# N in pool
c:=pool.cost[p[1]];
p:=Filtered(p,x->pool.cost[x]<c);
fi;
else
N:=fail;
fi;

# minimal ones
c:=Filtered([1..Length(p)],
x->not ForAny([1..x-1],y->IsSubset(pool.ker[p[x]],pool.ker[p[y]])));
c:=p{c};
if Size(Intersection(pool.ker{c}))>Size(N) then
# cannot reach N
return;
elif Length(p)>20 or Size(N)=1 then
p:=c; # use only minimal ones if there is lots
fi;

#if Length(p)>20 then Error("hier!");fi;

# do the abelians extra.
p:=Filtered(p,x->not HasAbelianFactorGroup(G,pool.ker[x]));

Expand Down Expand Up @@ -523,7 +545,7 @@ end);
BADINDEX:=1000; # the index that is too big
GenericFindActionKernel:=function(arg)
local G, N, knowi, goodi, simple, uc, zen, cnt, pool, ise, v, bv, badi,
totalcnt, interupt, u, nu, cor, zzz,bigperm,perm,badcores;
totalcnt, interupt, u, nu, cor, zzz,bigperm,perm,badcores,max,i;

G:=arg[1];
N:=arg[2];
Expand Down Expand Up @@ -635,7 +657,7 @@ totalcnt, interupt, u, nu, cor, zzz,bigperm,perm,badcores;
fi;
totalcnt:=totalcnt+1;
if KnownNaturalHomomorphismsPool(G,N) and
Minimum(Index(G,v),knowi)<20000
Minimum(Index(G,v),knowi)<100000
and 5*totalcnt>Minimum(Index(G,v),knowi,1000) then
# interupt if we're already quite good
interupt:=true;
Expand Down Expand Up @@ -673,7 +695,7 @@ totalcnt, interupt, u, nu, cor, zzz,bigperm,perm,badcores;
if Size(cor)>Size(N) and IsSubset(cor,N) and not cor in badcores then
Add(badcores,cor);
fi;
# store known information(we do't act, just store the subgroup.
# store known information(we do't act, just store the subgroup).
# Thus this is fairly cheap
pool.dotriv:=true;
zzz:=AddNaturalHomomorphismsPool(G,cor,u,Index(G,u));
Expand All @@ -686,6 +708,17 @@ totalcnt, interupt, u, nu, cor, zzz,bigperm,perm,badcores;
zzz:=DegreeNaturalHomomorphismsPool(G,N);

Info(InfoFactor,3," ext ",cnt,": ",Index(G,u)," best degree:",zzz);
if Size(cor)>Size(N) and Index(G,u)*2<knowi and
ValueOption("inmax")=fail then
max:=Filtered(MaximalSubgroupClassReps(u:inmax,cheap),
x->IndexNC(G,x)<knowi and IsSubset(x,N));
for i in max do
cor:=Core(G,i);
AddNaturalHomomorphismsPool(G,cor,i,Index(G,i));
od;
zzz:=DegreeNaturalHomomorphismsPool(G,N);
Info(InfoFactor,3," Maxes: ",Length(max)," best degree:",zzz);
fi;
else
zzz:=DegreeNaturalHomomorphismsPool(G,N);
fi;
Expand Down
20 changes: 12 additions & 8 deletions lib/grpffmat.gi
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ InstallMethod( IsNaturalGL,
0,

function( grp )
return Size( grp ) = Size( GL( DimensionOfMatrixGroup( grp ),
Size( FieldOfMatrixGroup( grp ) ) ) );
return MTX.IsAbsolutelyIrreducible(
GModuleByMats(GeneratorsOfGroup(grp),DefaultFieldOfMatrixGroup(grp))) and
Size( grp ) = Size( GL( DimensionOfMatrixGroup( grp ),
Size( FieldOfMatrixGroup( grp ) ) ) );
end );

InstallMethod( IsNaturalSL,
Expand All @@ -101,12 +103,14 @@ InstallMethod( IsNaturalSL,
0,

function( grp )
local gen, d, f;
f := FieldOfMatrixGroup( grp );
d := DimensionOfMatrixGroup( grp );
gen := GeneratorsOfGroup( grp );
return ForAll(gen, x-> DeterminantMat(x) = One(f))
and Size(grp) = Size(SL(d, Size(f)));
local gen, d, f;
f := FieldOfMatrixGroup( grp );
d := DimensionOfMatrixGroup( grp );
gen := GeneratorsOfGroup( grp );
return MTX.IsAbsolutelyIrreducible(
GModuleByMats(GeneratorsOfGroup(grp),DefaultFieldOfMatrixGroup(grp))) and
ForAll(gen, x-> DeterminantMat(x) = One(f))
and Size(grp) = Size(SL(d, Size(f)));
end );


Expand Down
9 changes: 7 additions & 2 deletions lib/grplatt.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1091,7 +1091,12 @@ InstallGlobalFunction(LatticeViaRadical,function(arg)

if pcgs=false then
lmpc:=ModuloPcgs(ser[i-1],nts[j]);
npcgs:=ModuloPcgs(nts[j],ser[i]);
if Size(nts[j])=1 and Size(ser[i])=1 then
# avoid degenerate case
npcgs:=Pcgs(nts[j]);
else
npcgs:=ModuloPcgs(nts[j],ser[i]);
fi;
else
if IsTrivial(nts[j]) then
lmpc:=pcgs[i-1];
Expand Down Expand Up @@ -2321,7 +2326,7 @@ local rt,op,a,l,i,j,u,max,subs;
return rec(subgroups:=List(a,i->ClosureGroup(U,rt{i})),inclusions:=max);
end);

InstallMethod(IntermediateSubgroups,"blocks for coset operation",
InstallMethod(IntermediateSubgroups,"using maximal subgroups",
IsIdenticalObj, [IsGroup,IsGroup],
1, # better than previous if index larger
function(G,U)
Expand Down
1 change: 1 addition & 0 deletions lib/grppc.gi
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ InstallMethod( SubgroupByPcgs, "subgroup with pcgs",
function( G, pcgs )
local U;
U := SubgroupNC( G, AsList( pcgs ) );
SetSize(U,Product(RelativeOrders(pcgs)));
SetPcgs( U, pcgs );
SetGroupOfPcgs (pcgs, U);
# home pcgs will be inherited
Expand Down
3 changes: 3 additions & 0 deletions lib/grppcaut.gd
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@
#Y Copyright (C) 2002 The GAP Group
##

DeclareGlobalFunction("SpaceAndOrbitStabilizer");

#############################################################################
##
#P IsFrattiniFree
##
DeclareProperty( "IsFrattiniFree", IsGroup );


DeclareGlobalFunction("AutomorphismGroupNilpotentGroup");
DeclareGlobalFunction("AutomorphismGroupSolvableGroup");
DeclareGlobalFunction("AutomorphismGroupFrattFreeGroup");
Expand Down
Loading

0 comments on commit 9e38dd1

Please sign in to comment.