Skip to content

Commit

Permalink
Enhance coset enumeration to make it work in more cases (#5770)
Browse files Browse the repository at this point in the history
  • Loading branch information
hulpke authored Aug 20, 2024
1 parent f873785 commit 414a824
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 118 deletions.
2 changes: 1 addition & 1 deletion doc/ref/grpfp.xml
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ gap> f := FreeGroup( "a", "b" );
gap> g := f / [ f.1^2, f.2^3, (f.1*f.2)^5 ];
<fp group on the generators [ a, b ]>
gap> h := IsomorphismPermGroup( g );
[ a, b ] -> [ (1,2)(4,5), (2,3,4) ]
[ a, b ] -> [ (2,4)(5,6), (1,2,3)(4,5,6) ]
gap> u:=Subgroup(g,[g.1*g.2]);;rt:=RightTransversal(g,u);
RightTransversal(<fp group of size 60 on the generators
[ a, b ]>,Group([ a*b ]))
Expand Down
14 changes: 5 additions & 9 deletions lib/grp.gd
Original file line number Diff line number Diff line change
Expand Up @@ -4358,14 +4358,10 @@ DeclareAttribute( "IsomorphismFpGroup", IsGroup );
## <Example><![CDATA[
## gap> SetInfoLevel( InfoFpGroup, 1 );
## gap> iso := IsomorphismFpGroupByGenerators( g, [ (1,2), (1,2,3,4,5) ] );
## #I the image group has 2 gens and 5 rels of total length 52
## #I the image group has 2 gens and 5 rels of total length 39
## [ (1,2), (1,2,3,4,5) ] -> [ F1, F2 ]
## gap> fp := Image( iso );
## <fp group of size 120 on the generators [ F1, F2 ]>
## gap> RelatorsOfFpGroup( fp );
## [ F1^2, (F1*F2^-1)^4, (F2^-2*F1*F2^-3)^2,
## F2^-1*(F2^-1*F1)^2*F2^2*(F1*F2^-1)^2*F2^-1*F1*F2*F1,
## (F1*F2^-2)^2*F2^-1*F1*F2^3*F1*F2^-3 ]
## ]]></Example>
## <P/>
## The main task of the function
Expand All @@ -4392,9 +4388,9 @@ DeclareAttribute( "IsomorphismFpGroup", IsGroup );
## (1,12)(2,11)(3,6)(4,8)(5,9)(7,10) ])
## gap> gens := GeneratorsOfGroup( M12 );;
## gap> iso := IsomorphismFpGroupByGenerators( M12, gens );;
## #I the image group has 3 gens and 21 rels of total length 559
## #I the image group has 3 gens and 24 rels of total length 669
## gap> iso := IsomorphismFpGroupByGenerators( M12, gens );;
## #I the image group has 3 gens and 21 rels of total length 548
## #I the image group has 3 gens and 20 rels of total length 414
## ]]></Example>
## <P/>
## Also in the case of a permutation group <A>G</A>, the function
Expand Down Expand Up @@ -4443,7 +4439,7 @@ DeclareAttribute( "IsomorphismFpGroup", IsGroup );
## #I the image group has 3 gens and 11 rels of total length 92
## gap> iso := IsomorphismFpGroupByGenerators( M12, gens :
## > method := "fast" );;
## #I the image group has 3 gens and 176 rels of total length 3821
## #I the image group has 3 gens and 136 rels of total length 3170
## ]]></Example>
## <P/>
## Though the option <C>method := "regular"</C> is only checked in the case
Expand All @@ -4465,7 +4461,7 @@ DeclareAttribute( "IsomorphismFpGroup", IsGroup );
## [ [ 0, 1, 0, 0, 0 ], [ 0, 0, 1, 0, 0 ], [ 0, 0, 0, 1, 0 ],
## [ 1, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 1 ] ] ]
## gap> iso := IsomorphismFpGroupByGenerators( G, gens );;
## #I the image group has 2 gens and 8 rels of total length 88
## #I the image group has 2 gens and 11 rels of total length 120
## gap> iso := IsomorphismFpGroupByGenerators( G, gens :
## > method := "regular");;
## #I the image group has 2 gens and 6 rels of total length 56
Expand Down
4 changes: 3 additions & 1 deletion lib/grp.gi
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,9 @@ local r,i,j,u,f,q,n,lim,sel,nat,ok,mi;
if n=false or i<=Length(n)+1 then
# still try group
q:=GQuotients(f,g:findall:=false);
if Length(q)>0 then return r;fi; # found
if Length(q)>0 then return List(GeneratorsOfGroup(f),
x->ImagesRepresentative(q[1],x)) ;fi; # found

fi;
r:=r+1;
until false;
Expand Down
121 changes: 70 additions & 51 deletions lib/grpfp.gi
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# gaplint: disable = analyse-lvars
#############################################################################
##
## This file is part of GAP, a system for computational discrete algebra.
Expand Down Expand Up @@ -3892,8 +3893,7 @@ end);
##
#M Size( <G> ) . . . . . . . . . . . . . size of a finitely presented group
##
InstallMethod(Size, "for finitely presented groups", true,
[ IsSubgroupFpGroup and IsGroupOfFamily ], 0,
BindGlobal("SIZE_FP_FROM_CYCLIC_INDEX",
function( G )
local fgens, # generators of the free group
rels, # relators of <G>
Expand Down Expand Up @@ -3942,6 +3942,8 @@ local fgens, # generators of the free group

end );

InstallMethod(Size, "for finitely presented groups", true,
[ IsSubgroupFpGroup and IsGroupOfFamily ], 0, SIZE_FP_FROM_CYCLIC_INDEX);

#############################################################################
##
Expand Down Expand Up @@ -3978,7 +3980,7 @@ end);
##
InstallGlobalFunction(IsomorphismPermGroupOrFailFpGroup,
function(arg)
local mappow, G, max, p, gens, rels, comb, i, l, m, H, t, gen, sz,
local mappow, G, max, p, gens, rels, comb, i, l, m, H, HH, t, gen, sz,
t1, bad, trial, b, bs, r, nl, o, u, rp, eo, rpo, e, e2, sc, j, z,
timerFunc,amax,iso,useind;

Expand Down Expand Up @@ -4042,57 +4044,70 @@ local mappow, G, max, p, gens, rels, comb, i, l, m, H, t, gen, sz,

H:=[]; # indicate pseudo-size 0
if not HasSize(G) then
Info(InfoFpGroup,1,"First compute size via cyclic subgroup");
t:=FinIndexCyclicSubgroupGenerator(G,max);
if t<>fail then
gen:=t[1];
Unbind(t);
t := NEWTC_CosetEnumerator( FreeGeneratorsOfFpGroup(G),
RelatorsOfFpGroup(G),[gen],true,false:
cyclic:=true,limit:=1+max,quiet:=true );
fi;

if t=fail then
# we cannot get the size within the permitted limits -- give up
return fail;
fi;
e:=NEWTC_CyclicSubgroupOrder(t);
if e=0 then
SetSize(G,infinity);
return fail;
fi;
sz:=e*t.index;
sz:=SIZE_FP_FROM_CYCLIC_INDEX(G);
SetSize(G,sz);
Info(InfoFpGroup,1,"found size ",sz);
if sz>200*t.index then
# try the corresponding perm rep
p:=t.ct{t.offset+[1..Length(FreeGeneratorsOfFpGroup(G))]};
Unbind(t);

for j in [1..Length(p)] do
p[j]:=PermList(p[j]);
od;
H:= GroupByGenerators( p );
# compute stabilizer chain with size info.
StabChain(H,rec(limit:=sz));
if Size(H)<sz then
# don't try this again
comb:=Filtered(comb,i->i<>[gen]);
fi;
else
# for memory reasons it might be better to try other perm rep first
Unbind(t);
fi;

elif Size(G)=infinity then
fi;
if Size(G)=infinity then
return fail;
fi;

sz:=Size(G);

if sz*10>max then
max:=sz*10;
fi;

# do we have a cyclic subgroup by which we can enumerate?
if HasCyclicSubgroupFpGroup(G) then
trial:=GeneratorsOfGroup(CyclicSubgroupFpGroup(G));
trial:=List(trial,UnderlyingElement);
Info(InfoFpGroup,1,"Try subgroup ",trial," with ",max);
t:=CosetTableFromGensAndRels(gens,rels,trial:silent:=true,max:=max );
if t<>fail and IndexCosetTab(t)>1 then
p:=t{[1,3..Length(t)-1]};
Unbind(t);
for j in [1..Length(p)] do
p[j]:=PermList(p[j]);
od;
H:= GroupByGenerators( p );

StabChain(H,rec(limit:=sz));

Info(InfoFpGroup,1,"found index ",NrMovedPoints(H)," size ",Size(H));

if Size(H)<sz then
# not good -- induce abelian rep
iso:=IsomorphismFpGroup(SubgroupNC(G,
List(trial,x->ElementOfFpGroup(FamilyObj(One(G)),x))
):silent:=true,max:=2*max);
if iso<>fail then

HH:=Range(iso);
SetSize(HH,sz/NrMovedPoints(H));

# p:=GroupHomomorphismByImagesNC(G,H,GeneratorsOfGroup(G),
# GeneratorsOfGroup(H));
# ker:=SubgroupNC(HH,List(GeneratorsOfGroup(Kernel(p)),x->
# ImagesRepresentative(iso,x)));
#
# # try to find a subgroup not containing `ker`
# we know that the subgroup is cyclic, thus abelian. so no test needed
# if not IsSubset(DerivedSubgroup(HH),ker) then
t:=MaximalAbelianQuotient(HH);
t:=t*MinimalFaithfulPermutationRepresentation(Range(t));
t:=InducedRepFpGroup(iso*t,Source(iso));
H:=Group(MappingGeneratorsImages(t)[2]);
StabChain(H,rec(limit:=sz));
fi;
# fi;

fi;


fi;

fi;

# Do not die on large coset table
amax:=max;
if max>10^4*sz then
Expand All @@ -4108,17 +4123,19 @@ local mappow, G, max, p, gens, rels, comb, i, l, m, H, t, gen, sz,
i:=1;
while Size(H)<sz and i<=Length(comb) do
trial:=comb[i];
if not ForAny(bad,i->IsSubset(i,trial)) then
if not ForAny(bad,i->IsSubset(trial,i)) then
Info(InfoFpGroup,1,"Try subgroup ",trial," with ",max);
t:=CosetTableFromGensAndRels(gens,rels,trial:silent:=true,max:=max );
if t<>fail then
if t<>fail and IndexCosetTab(t)>1 then
Info(InfoFpGroup,1,"has index ",IndexCosetTab(t));

p:=t{[1,3..Length(t)-1]};
Unbind(t);
for j in [1..Length(p)] do
p[j]:=PermList(p[j]);
od;
H:= GroupByGenerators( p );

# compute stabilizer chain with size info.
if Length(trial)=0 then
# regular is faithful
Expand All @@ -4127,14 +4144,16 @@ local mappow, G, max, p, gens, rels, comb, i, l, m, H, t, gen, sz,
StabChain(H,rec(limit:=sz));
fi;


# try to use induced rep
if Size(H)<sz and Size(H)>1 then
if Size(H)<sz and NrMovedPoints(H)<1000 then

iso:=IsomorphismFpGroup(SubgroupNC(G,
List(trial,x->ElementOfFpGroup(FamilyObj(One(G)),x))
):silent:=true,max:=2*max);
H:=Range(iso);
t:=IsomorphismPermGroupOrFailFpGroup(H,max);
HH:=Range(iso);
SetSize(HH,sz/NrMovedPoints(H));

t:=IsomorphismPermGroupOrFailFpGroup(HH,max);
if t<>fail then
t:=iso*t;
iso:=InducedRepFpGroup(t,Source(iso));
Expand Down
86 changes: 44 additions & 42 deletions lib/sgpres.gi
Original file line number Diff line number Diff line change
Expand Up @@ -3514,7 +3514,7 @@ end );
# -1: No relators
InstallGlobalFunction(NEWTC_PresentationMTC,function(arg)
local DATA,rels,i,j,w,f,r,s,fam,ri,a,offset,rset,re,stack,pres,
subnum,bad,warn,parameter,str;
subnum,parameter,str,wordefs;

DATA:=arg[1];
if Length(arg)=1 then
Expand Down Expand Up @@ -3605,9 +3605,11 @@ local DATA,rels,i,j,w,f,r,s,fam,ri,a,offset,rset,re,stack,pres,
fi;

# add definitions of secondary generators
wordefs:=[];
for i in [subnum+1..DATA.secount] do
r:=WordProductLetterRep(DATA.secondary[i],[-i]);
Add(rels,r);
wordefs[i]:=r;
od;

if ForAll(str,IsString) and DATA.secount >=Length(str) then
Expand All @@ -3630,49 +3632,49 @@ local DATA,rels,i,j,w,f,r,s,fam,ri,a,offset,rset,re,stack,pres,
TzSearch(pres);
TzOptions(pres).lengthLimit:=pres!.tietze[TZ_TOTAL]+1;
fi;
#TzGoGo(pres);
TzOptions(pres).eliminationsLimit:=5;
TzGoElim(pres,subnum);
TzGoElim(pres,subnum,wordefs);
if IsEvenInt(parameter) and Length(GeneratorsOfPresentation(pres))>subnum then
warn:=true;
# Help Tietze with elimination
bad:=Reversed(List(GeneratorsOfPresentation(pres)
{[subnum+1..Length(GeneratorsOfPresentation(pres))]},
x->LetterRepAssocWord(x)[1]));
for i in bad do
r:=DATA.secondary[i];
re:=true;
while re do
s:=[];
re:=false;
for j in r do
if AbsInt(j)>subnum then
re:=true;
if j>0 then
Append(s,DATA.secondary[j]);
else
Append(s,-Reversed(DATA.secondary[-j]));
fi;
else
Add(s,j);
fi;
od;
Info(InfoFpGroup,2,"Length =",Length(s));
r:=s;
if warn and Length(s)>100*Sum(rels,Length) then
warn:=false;
Error(
"Trying to eliminate all auxiliary generators might cause the\n",
"size of the presentation to explode. Proceed at risk!");
fi;
od;
r:=AssocWordByLetterRep(fam,Concatenation(r,[-i]));
AddRelator(pres,r);
#TzSearch(pres); Do *not* search, as this might kill the relator we
#just added.
TzEliminate(pres,i);
od;
Assert(0,Length(GeneratorsOfPresentation(pres))=subnum);
Error("did not eliminate properly");
# warn:=true;
# # Help Tietze with elimination
# bad:=Reversed(List(GeneratorsOfPresentation(pres)
# {[subnum+1..Length(GeneratorsOfPresentation(pres))]},
# x->LetterRepAssocWord(x)[1]));
# for i in bad do
# r:=DATA.secondary[i];
# re:=true;
# while re do
# s:=[];
# re:=false;
# for j in r do
# if AbsInt(j)>subnum then
# re:=true;
# if j>0 then
# Append(s,DATA.secondary[j]);
# else
# Append(s,-Reversed(DATA.secondary[-j]));
# fi;
# else
# Add(s,j);
# fi;
# od;
# Info(InfoFpGroup,2,"Length =",Length(s));
# r:=s;
# if warn and Length(s)>100*Sum(rels,Length) then
# warn:=false;
# Error(
# "Trying to eliminate all auxiliary generators might cause the\n",
# "size of the presentation to explode. Proceed at risk!");
# fi;
# od;
# r:=AssocWordByLetterRep(fam,Concatenation(r,[-i]));
# AddRelator(pres,r);
# #TzSearch(pres); Do *not* search, as this might kill the relator we
# #just added.
# TzEliminate(pres,i);
# od;
# Assert(0,Length(GeneratorsOfPresentation(pres))=subnum);

fi;
r:=List(GeneratorsOfPresentation(pres){[1..subnum]},
Expand Down
Loading

0 comments on commit 414a824

Please sign in to comment.