From 7d29977d6d320eabc09d67dc9266f699a9c8dce0 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Fri, 29 Sep 2023 07:57:43 -0600 Subject: [PATCH] ENHANCE: FittingFreeLiftSetup (#5510) Use cachedFFS to build new map if applicable. Store new FFHoms in Pool Reduce generator number of subgroups, also in maxsub code. Better preimage under ffhom for fitting free. (Otherwise use orbits first to see whether kernel elements are required, before calculating orders.) Avoid trivial images slowing down setup for permhom Avoid hom on trivial subgroup w/o parent --- lib/fitfree.gi | 44 +++++++++++++++++++++++++++++--------------- lib/ghomperm.gi | 44 +++++++++++++++++++++++++++++++++++++------- lib/grp.gd | 7 +++---- lib/maxsub.gi | 18 +++++++----------- lib/permdeco.gi | 29 ++++++++++++++++++++++++++++- 5 files changed, 104 insertions(+), 38 deletions(-) diff --git a/lib/fitfree.gi b/lib/fitfree.gi index 23e96fb7cb..3234fadd5d 100644 --- a/lib/fitfree.gi +++ b/lib/fitfree.gi @@ -149,9 +149,10 @@ local ffs,pcisom,rest,kpc,k,x,ker,r,pool,i,xx,pregens,iso; r:=Concatenation(k!.depthsInParent,[Length(ffs.pcgs)+1]); fi; + AddNaturalHomomorphismsPool(U,ker,rest); r:=rec(parentffs:=ffs, rest:=rest, - ker:=ker, + radical:=ker, pcgs:=k, serdepths:=List(ffs.depths,y->First([1..Length(r)],x->r[x]>=y)) ); @@ -183,7 +184,7 @@ local ffs,cache,rest,ker,k,r; r:=[1..Length(k)]; r:=rec(parentffs:=ffs, rest:=rest, - ker:=ker, + radical:=ker, pcgs:=k, serdepths:=List(ffs.depths,y->First([1..Length(r)],x->r[x]>=y)) ); @@ -204,7 +205,7 @@ local ffs,cache,rest,ker,k,r; end); InstallGlobalFunction(SubgroupByFittingFreeData,function(G,gens,imgs,ipcgs) -local ffs,hom,U,rest,ker,r,p,l,i,depths,pcisom; +local ffs,hom,U,rest,ker,r,p,l,i,depths,pcisom,subsz,pcimgs; ffs:=FittingFreeLiftSetup(G); # get back to initial group -- dont induce of induce @@ -251,7 +252,21 @@ local ffs,hom,U,rest,ker,r,p,l,i,depths,pcisom; SetIndicesEANormalSteps(ipcgs,l); fi; - U:=SubgroupNC(G,Concatenation(gens,ipcgs)); + pcimgs:=List(ipcgs,x->ImagesRepresentative(ffs.pcisom,x)); + + ker:=SubgroupNC(G,List(MinimalGeneratingSet(Group(pcimgs,One(Range(ffs.pcisom)))), + x->PreImagesRepresentative(ffs.pcisom,x))); + SetPcgs(ker,ipcgs); + if Length(ipcgs)=0 then + SetSize(ker,1); + else + SetPcgs(ker,ipcgs); + SetSize(ker,Product(RelativeOrders(ipcgs))); + fi; + subsz:=Size(Group(imgs,One(Image(ffs.factorhom))))*Size(ker); + + U:=SubgroupNC(G,Concatenation(gens,GeneratorsOfGroup(ker))); + SetSize(U,subsz); gens:=Concatenation(gens,ipcgs); imgs:=Concatenation(imgs,List(ipcgs,x->One(Range(hom)))); @@ -269,16 +284,8 @@ local ffs,hom,U,rest,ker,r,p,l,i,depths,pcisom; SetRecogDecompinfoHomomorphism(rest,RecogDecompinfoHomomorphism(hom)); fi; - ker:=SubgroupNC(G,ipcgs); - if Length(ipcgs)=0 then - SetSize(ker,1); - else - SetPcgs(ker,ipcgs); - SetSize(ker,Product(RelativeOrders(ipcgs))); - fi; SetKernelOfMultiplicativeGeneralMapping(rest,ker); - SetSize(U,Size(Group(imgs,One(Image(ffs.factorhom))))*Size(ker)); if Length(ipcgs)=0 then r:=[Length(ffs.pcgs)+1]; @@ -290,7 +297,7 @@ local ffs,hom,U,rest,ker,r,p,l,i,depths,pcisom; fi; r:=rec(parentffs:=ffs, rest:=rest, - ker:=ker, + radical:=ker, pcgs:=ipcgs, serdepths:=List(ffs.depths,y->First([1..Length(r)],x->r[x]>=y)) ); @@ -302,9 +309,15 @@ local ffs,hom,U,rest,ker,r,p,l,i,depths,pcisom; if ipcgs=MappingGeneratorsImages(ffs.pcisom)[1] then pcisom:=ffs.pcisom; else - pcisom:=List(ipcgs,x->ImagesRepresentative(ffs.pcisom,x)); + pcisom:=pcimgs; + if Length(ipcgs)>0 then + # work around error for special trivial group. + r:=Group(ipcgs,OneOfPcgs(ipcgs)); + else + r:=SubgroupNC(G,ipcgs); + fi; RUN_IN_GGMBI:=true; - pcisom:=GroupHomomorphismByImagesNC(Group(ipcgs,OneOfPcgs(ipcgs)), + pcisom:=GroupHomomorphismByImagesNC(r, SubgroupNC(Range(ffs.pcisom),pcisom), ipcgs,pcisom); RUN_IN_GGMBI:=false; @@ -317,6 +330,7 @@ local ffs,hom,U,rest,ker,r,p,l,i,depths,pcisom; factorhom:=rest ); SetFittingFreeLiftSetup(U,r); + AddNaturalHomomorphismsPool(U,ker,rest); fi; return U; diff --git a/lib/ghomperm.gi b/lib/ghomperm.gi index c2a8c5468e..630dd63da4 100644 --- a/lib/ghomperm.gi +++ b/lib/ghomperm.gi @@ -18,23 +18,47 @@ InstallMethod( PreImagesSet, CollFamRangeEqFamElms, [ IsPermGroupHomomorphism, IsGroup ], function( map, elms ) -local genpreimages, pre,kg,sz; +local genpreimages, pre,kg,sz,ol,orb,pos,dom,one; genpreimages:=GeneratorsOfMagmaWithInverses( elms ); - if Length(genpreimages)>0 and CanEasilyCompareElements(genpreimages[1]) then - # remove identities - genpreimages:=Filtered(genpreimages,i->i<>One(i)); - fi; genpreimages:= List(genpreimages, gen -> PreImagesRepresentative( map, gen ) ); if fail in genpreimages then TryNextMethod(); fi; + + if HasFittingFreeLiftSetup(Source(map)) and + IsIdenticalObj(map,FittingFreeLiftSetup(Source(map)).factorhom) then + dom:=FittingFreeLiftSetup(Source(map)); + pre:=SubgroupByFittingFreeData(Source(map),genpreimages, + GeneratorsOfMagmaWithInverses(elms),dom.pcgs); + return pre; + fi; + + if Length(genpreimages)>0 and CanEasilyCompareElements(genpreimages[1]) then + # remove identities + genpreimages:=Filtered(genpreimages,i->i<>One(i)); + fi; + + one:=One(Source(map)); if HasSize( elms ) then sz:=Size( KernelOfMultiplicativeGeneralMapping( map ) ) * Size( elms ); kg:=GeneratorsOfGroup(KernelOfMultiplicativeGeneralMapping( map ) ); - if Length(kg)>2 then Add(genpreimages,Random(kg));fi; + ol:=Concatenation(genpreimages,kg); + dom:=MovedPoints(ol); + ol:=Length(Orbits(Group(ol,one),dom)); pre:=SubgroupNC(Source(map),genpreimages); + orb:=List(Orbits(pre,dom),Set); + pos:=0; + while Length(orb)>ol do + repeat + pos:=pos+1; + until ForAny(orb,x->OnSets(x,kg[pos])<>x); + Add(genpreimages,kg[pos]); + pre:=SubgroupNC(Source(map),genpreimages); + orb:=List(Orbits(pre,dom),Set); + od; + StabChainOptions(pre).limit:=sz; while Size(pre)not i in pre)); @@ -664,6 +688,7 @@ BindGlobal("DoSCMPermGpHom",function(arg) dict, short, FillTransversalShort, + ntran, # positions of non-identity generators BuildOrb, AddToStbO, maxstor, @@ -901,12 +926,16 @@ BindGlobal("DoSCMPermGpHom",function(arg) size := Length( S.orbit ); # create new elements until we have reached the size + + ntran:=Filtered([1..Length(mapi[1])],x->not IsOne(mapi[1][x])); + # catch all trivial case + if Length(ntran)=0 then ntran:=[1..Length(mapi[1])];fi; while size <> gsize do # try random elements elm := rnd[rni]; img := rne[rni]; - i := Random( 1, Length( mapi[1] ) ); + i := Random(ntran); rnd[rni] := rnd[rni] * mapi[1][i]; rne[rni] := rne[rni] * mapi[2][i]; rni := rni mod two + 1; @@ -1443,6 +1472,7 @@ InstallMethod( CoKernelOfMultiplicativeGeneralMapping, true, [ IsPermGroupGeneralMappingByImages and IsToPermGroupGeneralMappingByImages ], 0, function( hom ) + Size(Source(hom)); Size(Range(hom)); # force sizes for RSS StabChainPermGroupToPermGroupGeneralMappingByImages( hom ); return CoKernelOfMultiplicativeGeneralMapping( hom ); end ); diff --git a/lib/grp.gd b/lib/grp.gd index f1d8e8d677..d4cf7a50ee 100644 --- a/lib/grp.gd +++ b/lib/grp.gd @@ -1255,8 +1255,7 @@ DeclareAttribute( "ConjugacyClasses", IsGroup ); ## ConjugacyClassesMaximalSubgroups(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 ] +## Group( [ (3,4), (1,3)(2,4) ] )^G, Group( [ (3,4), (2,4,3) ] )^G ] ## ]]> ## ## @@ -1302,8 +1301,8 @@ DeclareAttribute( "MaximalSubgroups", IsGroup ); ## of G. ## MaximalSubgroupClassReps(g); -## [ 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) ]) ] +## [ Group([ (2,4,3), (1,4)(2,3), (1,3)(2,4) ]), +## Group([ (3,4), (1,3)(2,4) ]), Group([ (3,4), (2,4,3) ]) ] ## ]]> ## ## diff --git a/lib/maxsub.gi b/lib/maxsub.gi index 5b841ec003..8c3f425801 100644 --- a/lib/maxsub.gi +++ b/lib/maxsub.gi @@ -69,15 +69,6 @@ function( G, fampcgs,pcgs,fphom,words,wordgens,wordimgs) group := G, factorfphom:=fphom ); - # giving generators enforces a bad presentation - #generators := GeneratorsOfGroup( G ) ); - -#for gen in -# List(GeneratorsOfGroup(Range(fphom)),x->PreImagesRepresentative(fphom,x)) do -# gen:=(List(pcgs,y->ExponentsOfPcElement(pcgs,y^gen))); -# Print(gen,"\n"); -#od; -#Error("EH"); OCOneCocycles( ocr, false ); if not IsBound( ocr.complement ) then return []; fi; @@ -189,6 +180,11 @@ BindGlobal("MaximalSubgroupClassesSol",function(G) f:=ff.factorhom; mgi:=MappingGeneratorsImages(ff.factorhom); sel:=Filtered([1..Length(mgi[2])],x->not IsOne(mgi[2][x])); + if 4^Length(sel)>Size(Range(ff.factorhom)) then + f:=SmallGeneratingSet(Image(ff.factorhom)); + mgi:=[List(f,x->PreImagesRepresentative(ff.factorhom,x)),f]; + sel:=[1..Length(mgi[1])]; + fi; gensG:=mgi[1]{sel}; # fp group and word representation for gensG @@ -903,7 +899,7 @@ local G,types,ff,maxes,lmax,q,d,dorb,dorbt,i,dorbc,dorba,dn,act,comb,smax,soc, # eliminate those containing the socle lmax:=Filtered(lmax,x->not IsSubset(x,soc)); Info(InfoLattice,1,Length(lmax)," type 2 maxes"); -for mm in lmax do mm!.type:="2";od; + for mm in lmax do mm!.type:="2";od; Append(maxes,lmax); fi; @@ -913,7 +909,7 @@ for mm in lmax do mm!.type:="2";od; lmax:=MaxesType3(act[1],Image(act[2],q),act[3],act[4],act[5],true); Info(InfoLattice,1,Length(lmax)," type 3b maxes"); lmax:=List(lmax,x->PreImage(act[2],x)); -for mm in lmax do mm!.type:="3b";od; + for mm in lmax do mm!.type:="3b";od; Append(maxes,lmax); fi; diff --git a/lib/permdeco.gi b/lib/permdeco.gi index eaa4dd6c85..ec2b56098a 100644 --- a/lib/permdeco.gi +++ b/lib/permdeco.gi @@ -22,7 +22,34 @@ local pcgs,r,hom,A,iso,p,i,depths,ords,b,mo,pc,limit,good,new,start,np; if Size(r)=1 then hom:=IdentityMapping(G); else - hom:=NaturalHomomorphismByNormalSubgroup(G,r); + hom:=fail; + if IsBound(G!.cachedFFS) then + A:=First(G!.cachedFFS,x->IsSubset(x[1]!.radical,r)); + if A<>fail then + hom:=A[2].rest; + pcgs:=A[2].pcgs; + pc:=CreateIsomorphicPcGroup(pcgs,true,false); + iso := GroupHomomorphismByImagesNC( r, pc, pcgs, GeneratorsOfGroup( pc )); + r:=rec(inducedfrom:=A[1], + radical:=r, + factorhom:=hom, + depths:=Set(A[2].serdepths), #Set as factors might vanish + pcisom:=iso, + pcgs:=pcgs); + return r; + fi; + A:=First(G!.cachedFFS,x->IsSubset(r,x[1]!.radical)); + if A<>fail then + b:=Image(A[2].rest); + b:=NaturalHomomorphismByNormalSubgroupNC(b,RadicalGroup(b)); + hom:=A[2]!.rest*b; + SetKernelOfMultiplicativeGeneralMapping(hom,r); + AddNaturalHomomorphismsPool(G,r,hom); + fi; + fi; + if hom=fail then + hom:=NaturalHomomorphismByNormalSubgroup(G,r); + fi; fi; A:=Image(hom);