Skip to content

Commit

Permalink
ENHANCE: Performance improvements to automorphism group computations.
Browse files Browse the repository at this point in the history
Includes improvements to `SmallGeneratingSet` for perm groups.
  • Loading branch information
hulpke committed Apr 23, 2018
1 parent b1956b8 commit c4514ae
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 10 deletions.
6 changes: 5 additions & 1 deletion lib/autsr.gi
Original file line number Diff line number Diff line change
Expand Up @@ -941,7 +941,11 @@ local d,a,map,possibly,cG,cH,nG,nH,i,j,sel,u,v,asAutomorphism,K,L,conj,e1,e2,
u:=ClosureGroup(i,K);
v:=ClosureGroup(i,L);
if u<>v then
gens:=SmallGeneratingSet(api);
if IsSolvableGroup(api) then
gens:=Pcgs(api);
else
gens:=SmallGeneratingSet(api);
fi;
pre:=List(gens,x->PreImagesRepresentative(iso,x));
map:=RepresentativeAction(SubgroupNC(a,pre),u,v,asAutomorphism);
if map=fail then
Expand Down
42 changes: 33 additions & 9 deletions lib/grpperm.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1892,10 +1892,20 @@ end);
InstallMethod(SmallGeneratingSet,"random and generators subset, randsims",true,
[IsPermGroup],0,
function (G)
local i, j, U, gens,o,v,a,sel,min;
local i, j, U, gens,o,v,a,sel,min,orb,orp,ok;

# remove obvious redundancies
gens := ShallowCopy(Set(GeneratorsOfGroup(G)));

# try pc methods first. The solvability test should not exceed cost, nor
# the number of points.
if #Length(MovedPoints(G))<50000 and
#((HasIsSolvableGroup(G) and IsSolvableGroup(G)) or IsAbelian(G))
IsSolvableGroup(G)
and Length(gens)>3 then
return MinimalGeneratingSet(G);
fi;

# remove obvious redundancies
o:=List(gens,Order);
SortParallel(o,gens,function(a,b) return a>b;end);
sel:=Filtered([1..Length(gens)],x->o[x]>1);
Expand All @@ -1920,26 +1930,32 @@ local i, j, U, gens,o,v,a,sel,min;
od;
gens:=gens{sel};

# try pc methods first
if Length(MovedPoints(G))<1000 and HasIsSolvableGroup(G)
and IsSolvableGroup(G) and Length(gens)>3 then
return MinimalGeneratingSet(G);
fi;

# store orbit data
orb:=Set(List(Orbits(G,MovedPoints(G)),Set));
orp:=Filtered([1..Length(orb)],x->IsPrimitive(Action(G,orb[x])));

min:=2;
if Length(gens)>2 then
# minimal: AbelianInvariants
min:=Maximum(List(Collected(Factors(Size(G)/Size(DerivedSubgroup(G)))),x->x[2]));
if min=Length(GeneratorsOfGroup(G)) then return GeneratorsOfGroup(G);fi;
i:=Maximum(2,min);
while i<=min+1 and i<Length(gens) do
# try to find a small generating system by random search
j:=1;
while j<=5 and i<Length(gens) do
U:=Subgroup(G,List([1..i],j->Random(G)));
ok:=true;
# first test orbits
if ok then
ok:=Length(orb)=Length(Orbits(U,MovedPoints(U))) and
ForAll(orp,x->IsPrimitive(U,orb[x]));
fi;


StabChainOptions(U).random:=100; # randomized size
#Print("A:",i,",",j," ",Size(G)/Size(U),"\n");
if Size(U)=Size(G) then
if ok and Size(U)=Size(G) then
gens:=Set(GeneratorsOfGroup(U));
fi;
j:=j+1;
Expand All @@ -1955,6 +1971,14 @@ local i, j, U, gens,o,v,a,sel,min;
while i <= Length(gens) and Length(gens)>min do
# random did not improve much, try subsets
U:=Subgroup(G,gens{Difference([1..Length(gens)],[i])});

ok:=true;
# first test orbits
if ok then
ok:=Length(orb)=Length(Orbits(U,MovedPoints(U))) and
ForAll(orp,x->IsPrimitive(U,orb[x]));
fi;

StabChainOptions(U).random:=100; # randomized size
#Print("B:",i," ",Size(G)/Size(U),"\n");
if Size(U)<Size(G) then
Expand Down

0 comments on commit c4514ae

Please sign in to comment.