diff --git a/doc/ref/grpfp.xml b/doc/ref/grpfp.xml index ce276f6df0..602594bf13 100644 --- a/doc/ref/grpfp.xml +++ b/doc/ref/grpfp.xml @@ -282,7 +282,7 @@ gap> f := FreeGroup( "a", "b" ); gap> g := f / [ f.1^2, f.2^3, (f.1*f.2)^5 ]; gap> h := IsomorphismPermGroup( g ); -[ a, b ] -> [ (1,2)(3,5), (2,3,4) ] +[ a, b ] -> [ (1,2)(4,5), (2,3,4) ] gap> u:=Subgroup(g,[g.1*g.2]);;rt:=RightTransversal(g,u); RightTransversal(,Group([ a*b ])) diff --git a/lib/ghomfp.gd b/lib/ghomfp.gd index 61c33352fc..42f412b24e 100644 --- a/lib/ghomfp.gd +++ b/lib/ghomfp.gd @@ -357,3 +357,10 @@ DeclareGlobalFunction("LargerQuotientBySubgroupAbelianization"); ## <#/GAPDoc> ## DeclareGlobalFunction("ProcessEpimorphismToNewFpGroup"); + +############################################################################# +## +#M InducedRepFpGroup(, ) +## +## induce def. on up to the full group +DeclareGlobalFunction("InducedRepFpGroup"); diff --git a/lib/ghomfp.gi b/lib/ghomfp.gi index d0f9558ce8..d1c08cd35a 100644 --- a/lib/ghomfp.gi +++ b/lib/ghomfp.gi @@ -504,7 +504,7 @@ end); #M InducedRepFpGroup(, ) ## ## induce def. on up to the full group -BindGlobal("InducedRepFpGroup",function(thom,s) +InstallGlobalFunction(InducedRepFpGroup,function(thom,s) local t,w,c,q,chom,tg,hi,u; w:=FamilyObj(s)!.wholeGroup; diff --git a/lib/grp.gd b/lib/grp.gd index 860ae8862b..9a93b0dc9c 100644 --- a/lib/grp.gd +++ b/lib/grp.gd @@ -4347,13 +4347,14 @@ DeclareAttribute( "IsomorphismFpGroup", IsGroup ); ## 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 39 +## #I the image group has 2 gens and 5 rels of total length 52 ## [ (1,2), (1,2,3,4,5) ] -> [ F1, F2 ] ## gap> fp := Image( iso ); ## ## gap> RelatorsOfFpGroup( fp ); -## [ F1^2, F2^5, (F2^-1*F1)^4, (F1*F2*F1*F2^-1)^3, (F2*F1*F2^-2*F1*F2)^2 -## ] +## [ 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 ] ## ]]> ##

## The main task of the function @@ -4380,9 +4381,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 20 rels of total length 418 +## #I the image group has 3 gens and 21 rels of total length 559 ## gap> iso := IsomorphismFpGroupByGenerators( M12, gens );; -## #I the image group has 3 gens and 20 rels of total length 526 +## #I the image group has 3 gens and 21 rels of total length 548 ## ]]> ##

## Also in the case of a permutation group G, the function @@ -4431,7 +4432,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 135 rels of total length 2938 +## #I the image group has 3 gens and 176 rels of total length 3821 ## ]]> ##

## Though the option method := "regular" is only checked in the case @@ -4453,7 +4454,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 10 rels of total length 132 +## #I the image group has 2 gens and 8 rels of total length 88 ## gap> iso := IsomorphismFpGroupByGenerators( G, gens : ## > method := "regular");; ## #I the image group has 2 gens and 6 rels of total length 56 diff --git a/lib/grp.gi b/lib/grp.gi index 20ecee1c1a..74425b7bb3 100644 --- a/lib/grp.gi +++ b/lib/grp.gi @@ -168,11 +168,16 @@ local r,i,j,u,f,q,n,lim,sel,nat,ok,mi; od; f:=FreeGroup(r); ok:=false; - if IsPerfectGroup(g) then + if not IsSolvableGroup(g) then if n=false then n:=ShallowCopy(NormalSubgroups(g)); - # all perfect groups of order <15360 *are* 2-generated - lim:=15360; + if IsPerfectGroup(g) then + # all perfect groups of order <15360 *are* 2-generated + lim:=15360; + else + # all groups of order <8 *are* 2-generated + lim:=8; + fi; n:=Filtered(n,x->IndexNC(g,x)>=lim and Size(x)>1); SortBy(n,x->-Size(x)); mi:=MinimalInclusionsGroups(n); diff --git a/lib/grpfp.gi b/lib/grpfp.gi index eff13fec0f..e250e5a53a 100644 --- a/lib/grpfp.gi +++ b/lib/grpfp.gi @@ -3989,7 +3989,7 @@ InstallGlobalFunction(IsomorphismPermGroupOrFailFpGroup, function(arg) local mappow, G, max, p, gens, rels, comb, i, l, m, H, t, gen, silent, sz, t1, bad, trial, b, bs, r, nl, o, u, rp, eo, rpo, e, e2, sc, j, z, - timerFunc; + timerFunc,amax,iso,useind; timerFunc := GET_TIMER_FROM_ReproducibleBehaviour(); @@ -4101,36 +4101,70 @@ local mappow, G, max, p, gens, rels, comb, i, l, m, H, t, gen, silent, sz, max:=sz*10; fi; + # Do not die on large coset table + amax:=max; + if max>10^4*sz then + max:=10^3*sz; + fi; + + useind:=false; t1:=timerFunc(); - bad:=[]; - i:=1; - while Size(H)IsSubset(i,trial)) then - Info(InfoFpGroup,1,"Try subgroup ",trial); - t:=CosetTableFromGensAndRels(gens,rels,trial:silent:=true,max:=max ); - if t<>fail 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 - SetSize(H,sz); - else - StabChain(H,rec(limit:=sz)); - fi; - else - # note that this subset fails a coset enumeration - Add(bad,Set(trial)); + while maxIsSubset(i,trial)) then + Info(InfoFpGroup,1,"Try subgroup ",trial," with ",max); + t:=CosetTableFromGensAndRels(gens,rels,trial:silent:=true,max:=max ); + if t<>fail 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 + SetSize(H,sz); + else + StabChain(H,rec(limit:=sz)); + fi; + + + # try to use induced rep + if Size(H)1 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); + if t<>fail then + t:=iso*t; + iso:=InducedRepFpGroup(t,Source(iso)); + H:=Group(List(GeneratorsOfGroup(G), + x->ImagesRepresentative(iso,x))); + StabChain(H,rec(limit:=sz)); + if IsAbelian(H) then + t:=MinimalFaithfulPermutationRepresentation(H); + H:=Group(List(GeneratorsOfGroup(H), + x->ImagesRepresentative(t,x))); + StabChain(H,rec(limit:=sz)); + fi; + useind:=true; + fi; + fi; + else + # note that this subset fails a coset enumeration + Add(bad,Set(trial)); + fi; fi; - fi; - i:=i+1; + i:=i+1; + od; + max:=Minimum(amax,max*10); od; if Size(H)=Size(H) then + p:=SmallerDegreePermutationRepresentation(H); + else + p:=SmallerDegreePermutationRepresentation(H:cheap); + fi; # tell the family that we can now compare elements SetCanEasilyCompareElements(FamilyObj(One(G)),true); SetCanEasilySortElements(FamilyObj(One(G)),true); diff --git a/lib/grplatt.gi b/lib/grplatt.gi index 2700efc517..8e5d871ea2 100644 --- a/lib/grplatt.gi +++ b/lib/grplatt.gi @@ -1354,7 +1354,7 @@ end); BindGlobal("RepsPerfSimpSub",function(G,simple) local badsizes,n,un,cl,r,i,l,u,bw,cnt,gens,go,imgs,bg,bi,emb,nu,k,j, - D,params,might,bo; + D,params,might,bo,pls; if IsSolvableGroup(G) then return [TrivialSubgroup(G)]; elif Size(SolvableRadical(G))>1 and (IsPermGroup(G) or IsMatrixGroup(G)) then @@ -1394,7 +1394,8 @@ local badsizes,n,un,cl,r,i,l,u,bw,cnt,gens,go,imgs,bg,bi,emb,nu,k,j, fi; Info(InfoLattice,1,"Searching perfect groups up to size ",Maximum(un)); - if ForAny(un,i->i>10^6) then + pls:=Maximum(SizesPerfectGroups()); + if ForAny(un,i->i>pls) then Error("the perfect residuum is too large"); fi; diff --git a/lib/oprtglat.gi b/lib/oprtglat.gi index 56328f0726..ae35f2af20 100644 --- a/lib/oprtglat.gi +++ b/lib/oprtglat.gi @@ -135,8 +135,8 @@ function(G,dom,all) savemem:=ValueOption("savemem"); n:=Length(dom); if n>20 and ForAll(dom,x->IsSubset(G,x)) - and NrMovedPoints(G)>1000 - and NrMovedPoints(G)*1000>Size(G) then + and NrMovedPoints(G)>1000 then + #and NrMovedPoints(G)*1000>Size(G) then b:=SmallerDegreePermutationRepresentation(G:cheap); if NrMovedPoints(Range(b))