From 69c0d4caa98b851839c0caa36493fede14d5811f Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Thu, 4 Aug 2016 15:11:57 +0200 Subject: [PATCH 01/15] ENHANCE: Cannon/Holt automorphism group algorithm in basic implementation. (rename to SR to make Eamonn happy) Use SR method by default if radical >1 --- lib/autsr.gi | 371 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/morpheus.gi | 2 + lib/read5.g | 1 + 3 files changed, 374 insertions(+) create mode 100644 lib/autsr.gi diff --git a/lib/autsr.gi b/lib/autsr.gi new file mode 100644 index 0000000000..d83d1430af --- /dev/null +++ b/lib/autsr.gi @@ -0,0 +1,371 @@ +############################################################################# +## +#W auttf.gi GAP library Alexander Hulpke +#W Soley Jonsdottir +## +## +#Y Copyright (C) 2016 The GAP Group +## +## This file contains an implementation of the Cannon/Holt automorphism +## group algorithm. + +BindGlobal("AGTFPrepareAutomLift",function(G,pcgs,nat) +local ocr, fphom, fpg, free, len, dim, tmp, L0, S, R, rels, mat, r, RS, i, g, v; + + ocr:=rec(group:=G,modulePcgs:=pcgs); + fphom:=IsomorphismFpGroup(G); + ocr.identity := One(ocr.modulePcgs[1]); + fpg:=FreeGeneratorsOfFpGroup(Range(fphom)); + ocr.factorpres:=[fpg,RelatorsOfFpGroup(Range(fphom))]; + ocr.generators:=List(GeneratorsOfGroup(Range(fphom)), + i->PreImagesRepresentative(fphom,i)); + OCAddMatrices(ocr,ocr.generators); + OCAddRelations(ocr,ocr.generators); + OCAddSumMatrices(ocr,ocr.generators); + OCAddToFunctions(ocr); + + ocr.module:=GModuleByMats( + LinearActionLayer(G,ocr.generators,ocr.modulePcgs),ocr.field); + ocr.moduleauts:=MTX.ModuleAutomorphisms(ocr.module); + + ocr.factorgens:=List(ocr.generators,i->Image(nat,i)); + free:=FreeGroup(Length(ocr.generators),"f"); + ocr.free:=free; + ocr.decomp:=GroupGeneralMappingByImages(Image(nat,G),free, + ocr.factorgens,GeneratorsOfGroup(free)); + + # Initialize system. + len:=Length(ocr.generators); + dim:=Length(pcgs); + tmp := ocr.moduleMap( ocr.identity ); + L0 := Concatenation( List( [ 1 .. len ], x -> tmp ) ); + ConvertToVectorRep(L0,ocr.field); + S := List( [ 1 .. len * dim ], x -> L0 ); + R := ListWithIdenticalEntries( len * dim,Zero( ocr.field ) ); + ConvertToVectorRep(R,ocr.field); + + rels:=ocr.relators; + mat:=List([1..len*dim],x->[]); + for i in mat do + ConvertToVectorRep(i,ocr.field); + od; + for i in [1..Length(rels)] do + Info(InfoCoh,2," relation ", i, " (",Length(rels),")"); + r:=1; + for g in [1..len] do + RS:=OCEquationMatrix(ocr,rels[i],g); + for v in RS do + Append(mat[r],v); + r:=r+1; + od; + od; + od; + ocr.matrix:=mat; + return ocr; +end); + +############################################################################# +## +#F OCEquationVectorAutom(,,) +## +BindGlobal("OCEquationVectorAutom",function(ocr,r,genimages) +local n,i; + + # If has an entry 'conjugated' the records is no relator for a + # presentation,but belongs to relation + # (g_i n_i) ^ s_j = + # which is used to determinate normal complements. [i,j] is bound to + # . + if IsBound(r.conjugated) then + Error("not yet implemented"); + fi; + n:=ocr.identity; + + for i in [1 .. Length(r.generators)] do + n:=n*genimages[r.generators[i]]^r.powers[i]; + od; + + Assert(1,n in GroupByGenerators(NumeratorOfModuloPcgs(ocr.modulePcgs))); + + return ShallowCopy(ocr.moduleMap(n)); + +end); + +BindGlobal("AGTFAutomLift",function(ocr,nat,fhom,miso) + local v, rels, genimages, v1, psim, w, s, t, l, hom, i, e, j,ep,phom; + + v:=[]; + rels:=ocr.relators; + genimages:=List(ocr.factorgens,i->MappedWord( + ImagesRepresentative(ocr.decomp,Image(fhom,i)), + GeneratorsOfGroup(ocr.free), + ocr.generators)); + for i in [1..Length(rels)] do + v1:=OCEquationVectorAutom(ocr,rels[i],genimages); + Add(v,v1); + od; + + #for ep in Enumerator(ocr.moduleauts) do + phom:=IsomorphismPermGroup(ocr.moduleauts); + for ep in Enumerator(Image(phom)) do + e:=PreImagesRepresentative(phom,ep); + psim:=e*miso; + psim:=psim^-1; + w:=-List(v,i->i*psim); + s:=SolutionMat(ocr.matrix,Concatenation(w)); + if s<>fail then + psim:=psim^-1; + t:=[]; + ConvertToVectorRep(t,ocr.field); + l:=Length(ocr.modulePcgs); + for i in [1..Length(genimages)] do + v1:=s{[(i-1)*l+1..(i*l)]}*psim; + for j in [1..Length(v1)] do + t[(i-1)*l+j]:=v1[j]; + od; + od; + s:=ocr.cocycleToList(t); + for i in [1..Length(genimages)] do + genimages[i]:=genimages[i]*s[i]; + od; + # later use NC version + hom:=GroupHomomorphismByImagesNC(ocr.group,ocr.group, + ocr.generators,genimages); + Assert(2,IsBijective(hom)); + return hom; + fi; + od; + return fail; + +end); + +# main automorphism method -- currently still using factor groups, but +# nevertheless faster.. +BindGlobal("AutomGrpSR",function(G) +local ff,r,d,ser,u,v,i,j,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,comiso,extra,mo; + + ff:=FittingFreeLiftSetup(G); + r:=ff.radical; + # find series through r + + # derived and then primes and then elementary abelian + d:=Reversed(DerivedSeriesOfGroup(r)); + + ser:=[TrivialSubgroup(G)]; + for i in d{[2..Length(d)]} do + u:=ser[Length(ser)]; + for p in Set(Factors(Size(i)/Size(u))) do + bd:=PValuation(Size(i)/Size(u),p); # max p-exponent + u:=ClosureSubgroup(u,SylowSubgroup(i,p)); + v:=ser[Length(ser)]; + while not HasElementaryAbelianFactorGroup(u,v) do + gens:=Filtered(GeneratorsOfGroup(u),x->not x in v); + e:=List(gens,x->First([1..bd],a->x^(p^a) in v)); + e:=p^(Maximum(e)-1); + for j in gens do + v:=ClosureSubgroup(v,j^e); + od; + Add(ser,v); + od; + Add(ser,u); + od; + od; + + ser:=Reversed(ser); + i:=1; + hom:=ff.factorhom; + Q:=Image(hom,G); + AQ:=AutomorphismGroupFittingFree(Q); + AQI:=InnerAutomorphismsAutomorphismGroup(AQ); + while i",Size(ser[i+1])); + M:=ser[i]; + N:=ser[i+1]; + hom:=NaturalHomomorphismByNormalSubgroup(G,N); + Q:=Image(hom,G); + 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); + split:=ocr.isSplitExtension; + if not split then + # test: Semisimple and Frattini + b:=MTX.BasisRadical(mo); + fratsim:=Length(b)=0; + if not fratsim then + b:=List(b,x->PreImagesRepresentative(hom,PcElementByExponents(MPcgs,x))); + for j in b do + N:=ClosureSubgroup(N,b); + od; + # insert + for j in [Length(ser),Length(ser)-1..i+1] do + ser[j+1]:=ser[j]; + od; + ser[i+1]:=N; + Info(InfoMorph,2,"insert1"); + else + # Frattini? + fratsim:=IsSubset(FrattiniSubgroup(Q),Mim); + if not fratsim then + N:=Intersection(FrattiniSubgroup(Q),Mim); + # insert + for j in [Length(ser),Length(ser)-1..i+1] do + ser[j+1]:=ser[j]; + od; + ser[i+1]:=PreImage(hom,N); + Info(InfoMorph,2,"insert2"); + fi; + fi; + fi; + until split or fratsim; + + # Use cocycles + b:=BasisVectors(Basis(ocr.oneCocycles)); + + # find D + Zm:=PreImage(q,Centre(OQ)); + D:=Centralizer(Zm,Mim); + + innC:=List(GeneratorsOfGroup(D),d->InnerAutomorphism(Q,d)); + + D:=List(innC,inn->List(ocr.generators,o->Image(inn,o))); + D:=List(D,d->List([1..Length(ocr.generators)],i->ocr.generators[i]^-1*d[i])); + D:=List(D,d->ocr.listToCocycle(d)); + TriangulizeMat(D); + D:=Filtered(D,x->x<>0*x); + + b:=BaseSteinitzVectors(b,D).factorspace; + + C:=[]; + if Size(Group(ocr.generators))ocr.generators[i]*oneC[i]); + oneC:=GroupHomomorphismByImagesNC(Q,Q,Concatenation(ocr.generators,extra),Concatenation(imgs,extra)); + Assert(2,IsBijective(oneC)); + Add(C,oneC); + od; + + B:=[]; + AQiso:=IsomorphismPermGroup(AQ); + AQP:=Image(AQiso,AQ); + + if split then + maut:=MTX.ModuleAutomorphisms(mo); + # find noninner of B + innB:=List(SmallGeneratingSet(Zm),z->InnerAutomorphism(Q,z)); + innB:=Group(One(DefaultFieldOfMatrixGroup(maut))* + List(innB,inn->List(MPcgs,m->ExponentsOfPcElement(MPcgs,Image(inn,m))))); + + tmpAut:=SubgroupNC(maut,Filtered(GeneratorsOfGroup(maut),aut->not aut in innB)); + + gens:=GeneratorsOfGroup(ocr.complement); + for a in GeneratorsOfGroup(tmpAut) do + imM:=List(a,i->PcElementByExponents(MPcgs,i)); + imM:=GroupHomomorphismByImagesNC(Q,Q,Concatenation(MPcgs,gens),Concatenation(imM,gens)); + Assert(2,IsBijective(imM)); + Add(B,imM); + od; + + # test condition for lifting, also add corresponding automorphism + comiso:=GroupHomomorphismByImagesNC(ocr.complement,OQ,gens,List(gens,x->ImagesRepresentative(q,x))); + + cond:=function(perm) + local aut,newgens,mo2,iso,a; + aut:=PreImagesRepresentative(AQiso,perm); + newgens:=List(GeneratorsOfGroup(Q), + x->PreImagesRepresentative(q,Image(aut,ImagesRepresentative(q,x)))); + mo2:=GModuleByMats(LinearActionLayer(newgens,MPcgs),mo.field); + iso:=MTX.IsomorphismModules(mo,mo2); + if iso=fail then + return false; + else + # build associated auto + + a:=GroupHomomorphismByImagesNC(Q,Q,Concatenation(gens,MPcgs), + Concatenation(List(gens,x->PreImagesRepresentative(comiso, + ImagesRepresentative(aut,ImagesRepresentative(comiso,x)))), + List(MPcgs,x->PcElementByExponents(MPcgs, + (ExponentsOfPcElement(MPcgs,x)*One(mo.field))*iso )))); + Assert(2,IsBijective(a)); + Add(A,a); + return true; + fi; + end; + + else + # there is no B in the nonsplit case + B:=[]; + + ocr:=AGTFPrepareAutomLift( Q, MPcgs, q ); + + cond:=function(perm) + local aut,newgens,mo2,iso,a; + aut:=PreImagesRepresentative(AQiso,perm); + newgens:=List(GeneratorsOfGroup(Q), + x->PreImagesRepresentative(q,Image(aut,ImagesRepresentative(q,x)))); + mo2:=GModuleByMats(LinearActionLayer(newgens,MPcgs),mo.field); + iso:=MTX.IsomorphismModules(mo,mo2); + if iso=fail then + return false; + else + # build associated auto + + a:=AGTFAutomLift(ocr,q,aut,iso); + if a=fail then + return false; + else + Add(A,a); + return true; + fi; + fi; + end; + + fi; + + # find A using the set condition + A:=[]; + sub:=SubgroupProperty(AQP,cond, + SubgroupNC(AQP,List(GeneratorsOfGroup(AQI),x->ImagesRepresentative(AQiso,x)))); + Info(InfoMorph,2,"Lift Index ",Size(AQP)/Size(sub)); + + # now make the new automorphism group + innB:=List(SmallGeneratingSet(Q),x->InnerAutomorphism(Q,x)); + gens:=ShallowCopy(innB); + Append(gens,C); + Append(gens,B); + Append(gens,A); + + A:=Group(gens); + SetIsAutomorphismGroup(A,true); + SetIsGroupOfAutomorphismsFiniteGroup(A,true); + SetIsFinite(A,true); + + AQI:=SubgroupNC(A,innB); + SetInnerAutomorphismsAutomorphismGroup(A,AQI); + + AQ:=A; + + + i:=i+1; + od; + + return AQ; + +end); + diff --git a/lib/morpheus.gi b/lib/morpheus.gi index c6626d2197..d2074b8a78 100644 --- a/lib/morpheus.gi +++ b/lib/morpheus.gi @@ -1929,6 +1929,8 @@ local A; elif Size(RadicalGroup(G))=1 and IsPermGroup(G) then # essentially a normalizer when suitably embedded A:=AutomorphismGroupFittingFree(G); + elif Size(RadicalGroup(G))>1 then + A:=AutomGrpSR(G); else A:=AutomorphismGroupMorpheus(G); fi; diff --git a/lib/read5.g b/lib/read5.g index 9064433d17..12012181e0 100644 --- a/lib/read5.g +++ b/lib/read5.g @@ -198,6 +198,7 @@ ReadLib( "schursym.gi"); # files dealing with nice monomorphism ReadLib( "grpnice.gi" ); +ReadLib( "autsr.gi" ); ReadLib( "morpheus.gi" ); ReadLib( "grplatt.gi" ); ReadLib( "oprtglat.gi" ); From 96ad592362b664ac5f24a0d1f07713630d519fb6 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Thu, 11 Aug 2016 13:08:28 +0100 Subject: [PATCH 02/15] ENHANCE: Added `RefinedSubnormalSeries` and `CharacteristicSubgroups` Method for characteristic subgroups is pathetic filtering amongst normal subgroups. Also added `CharacteristicFactorsOfGroup` in basic version. --- lib/grp.gd | 42 ++++++++++++++++++++++++++++++++++++++++++ lib/grp.gi | 41 +++++++++++++++++++++++++++++++++++++++++ lib/grpnames.gd | 19 +++++++++++++++++++ lib/grpnames.gi | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+) diff --git a/lib/grp.gd b/lib/grp.gd index ee141eb319..1a2ab7f9c6 100644 --- a/lib/grp.gd +++ b/lib/grp.gd @@ -921,6 +921,25 @@ DeclareOperation( "ChiefSeriesUnderAction", [ IsGroup, IsGroup ] ); ## DeclareOperation( "ChiefSeriesThrough", [ IsGroup, IsList ] ); +############################################################################# +## +#F RefinedSubnormalSeries( , ) +## +## <#GAPDoc Label="RefinedSubnormalSeries"> +## +## +## +## +## If ser is a subnormal series of a group G, and n is a +## normal subgroup, this function returns the series obtained by refining with +## n, that is closures and intersections are inserted at the appropriate +## place. +## +## +## <#/GAPDoc> +## +DeclareGlobalFunction( "RefinedSubnormalSeries" ); + ############################################################################# ## @@ -1783,6 +1802,29 @@ DeclareAttribute( "MinimalNormalSubgroups", IsGroup ); ## DeclareAttribute( "NormalSubgroups", IsGroup ); +############################################################################# +## +#A CharacteristicSubgroups( ) +## +## <#GAPDoc Label="CharacteristicSubgroups"> +## +## +## +## +## returns a list of all characteristic subgroups of G, that is +## subgroups that are invariant under all automorphisms. +## g:=SymmetricGroup(4);;NormalSubgroups(g); +## [ Sym( [ 1 .. 4 ] ), Group([ (2,4,3), (1,4)(2,3), (1,3)(2,4) ]), +## Group([ (1,4)(2,3), (1,3)(2,4) ]), Group(()) ] +## ]]> +##

+## +## +## <#/GAPDoc> +## +DeclareAttribute( "CharacteristicSubgroups", IsGroup ); + ############################################################################# ## diff --git a/lib/grp.gi b/lib/grp.gi index 7660f20106..30f656be22 100644 --- a/lib/grp.gi +++ b/lib/grp.gi @@ -642,6 +642,40 @@ InstallMethod( ChiefSeries, G -> ChiefSeriesUnderAction( G, G ) ); +############################################################################# +## +#M RefinedSubnormalSeries( , ) +## +InstallGlobalFunction("RefinedSubnormalSeries",function(ser,sub) +local new,i,c; + new:=[]; + i:=1; + if not IsSubset(ser[1],sub) then + sub:=Intersection(ser[1],sub); + fi; + while IsSubset(ser[i],sub) do + Add(new,ser[i]); + i:=i+1; + od; + while not IsSubset(sub,ser[i]) do + c:=ClosureGroup(sub,ser[i]); + Add(new,c); + Add(new,ser[i]); + sub:=Intersection(sub,ser[i]); + i:=i+1; + od; + if Size(sub)Size(ser[i]) then + Add(new,sub); + fi; + while i<=Length(ser) do + Add(new,ser[i]); + i:=i+1; + od; + return new; +end); + + + ############################################################################# ## #M CommutatorFactorGroup( ) . . . . commutator factor group of a group @@ -4965,6 +4999,13 @@ function(G,U) return AsList(ConjugacyClassSubgroups(G,U)); end); +############################################################################# +## +#M CharacteristicSubgroups( ) +## +InstallMethod(CharacteristicSubgroups,"use automorphisms",true,[IsGroup], + G->Filtered(NormalSubgroups(G),x->IsCharacteristicSubgroup(G,x))); + InstallTrueMethod( CanComputeSize, HasSize ); InstallMethod( CanComputeIndex,"by default impossible unless identical", diff --git a/lib/grpnames.gd b/lib/grpnames.gd index 29ebe72274..a5ea1d359f 100644 --- a/lib/grpnames.gd +++ b/lib/grpnames.gd @@ -130,6 +130,25 @@ DeclareOperation( "NormalComplementNC", [IsGroup, IsGroup]); ## DeclareAttribute( "DirectFactorsOfGroup", IsGroup ); +############################################################################# +## +#A CharacteristicFactorsOfGroup( ) . decomposition into a direct product +## +## <#GAPDoc Label="CharacteristicFactorsOfGroup"> +## +## +## +## +## For a finite group this function returns a list +## of characteristic subgroups [G1, .., Gr] such +## that G = G1 x .. x Gr and none of the Gi +## is a direct product of characteristic subgroups. +## +## +## <#/GAPDoc> +## +DeclareAttribute( "CharacteristicFactorsOfGroup", IsGroup ); + ############################################################################# ## #F DirectFactorsOfGroupFromList( , , ) diff --git a/lib/grpnames.gi b/lib/grpnames.gi index fbf04c772e..14ff50412d 100644 --- a/lib/grpnames.gi +++ b/lib/grpnames.gi @@ -458,6 +458,45 @@ InstallMethod(DirectFactorsOfGroup, "generic method", true, return DirectFactorsOfGroupFromList(G, Ns, MinNs); end); +InstallMethod(CharacteristicFactorsOfGroup, "generic method", true, + [ IsGroup ], 0, +function(G) +local Ns,MinNs,sel,a,sz,j,gs,g,N; + + Ns := ShallowCopy(CharacteristicSubgroups(G)); + SortBy(Ns,Size); + MinNs:=[]; + sel:=[2..Length(Ns)-1]; + while Length(sel)>0 do + a:=sel[1]; + sz:=Size(Ns[a]); + RemoveSet(sel,sel[1]); + Add(MinNs,Ns[a]); + for j in ShallowCopy(sel) do + if Size(Ns[j])>sz and Size(Ns[j]) mod sz=0 and IsSubset(Ns[j],Ns[a]) then + RemoveSet(sel,j); + fi; + od; + od; + + if Length(MinNs)= 1 then + # size of MinNs is an upper bound to the number of components + return [ G ]; + fi; + + gs := [ ]; + for N in MinNs do + g := First(GeneratorsOfGroup(N), g -> g<>One(N)); + if g <> fail then + AddSet(gs, g); + fi; + od; + # normal subgroup containing all minimal subgroups cannot have complement + Ns := Filtered(Ns, N -> not IsSubset(N, gs)); + + return DirectFactorsOfGroupFromList(G, Ns, MinNs); +end); + InstallGlobalFunction( DirectFactorsOfGroupFromList, function ( G, NList, MinList ) From afd35585f1d112a45358c3445aaae3d0d5331a13 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Thu, 11 Aug 2016 14:18:27 +0100 Subject: [PATCH 03/15] ENHANCE: Refine series with some characteristic subgroups. Use radical automorphisms (more efficient solvable/pgroup routines) to potentially reduce search through large GL's in next step Add Assertion in RefinedSeries --- lib/autsr.gi | 118 ++++++++++++++++++++++++++++++++++++++++++++++++--- lib/grp.gi | 15 ++++--- 2 files changed, 123 insertions(+), 10 deletions(-) diff --git a/lib/autsr.gi b/lib/autsr.gi index d83d1430af..c8120fe32d 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -142,15 +142,65 @@ end); # main automorphism method -- currently still using factor groups, but # nevertheless faster.. BindGlobal("AutomGrpSR",function(G) -local ff,r,d,ser,u,v,i,j,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,comiso,extra,mo; +local ff,r,d,ser,u,v,i,j,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, + comiso,extra,mo,rada,makeaqiso,ind,lastperm; + + makeaqiso:=function(); + AQiso:=IsomorphismPermGroup(AQ); + AQP:=Image(AQiso,AQ); + # force degree down + a:=Size(AQP); + AQP:=Group(SmallGeneratingSet(AQP)); + SetSize(AQP,a); + a:=SmallerDegreePermutationRepresentation(AQP:cheap); + if NrMovedPoints(Image(a))",NrMovedPoints(Image(a))); + AQiso:=AQiso*a; + AQP:=Image(a,AQP); + fi; + end; ff:=FittingFreeLiftSetup(G); r:=ff.radical; # find series through r # derived and then primes and then elementary abelian - d:=Reversed(DerivedSeriesOfGroup(r)); + d:=ValueOption("series"); + if d=fail then + d:=DerivedSeriesOfGroup(r); + # refine + d:=RefinedSubnormalSeries(d,Centre(r)); + for i in Set(Factors(Size(r))) do + u:=PCore(r,i); + d:=RefinedSubnormalSeries(d,u); + j:=1; + repeat + v:=Agemo(u,i,j); + if Size(v)>1 then + d:=RefinedSubnormalSeries(d,v); + fi; + j:=j+1; + until Size(v)=1; + j:=1; + repeat + v:=Omega(u,i,j); + if Size(v)Size(d[x])<>Size(d[x+1]))); + + d:=Reversed(d); + else + d:=ShallowCopy(d); + SortBy(d,Size); # in case reversed order.... + fi; ser:=[TrivialSubgroup(G)]; for i in d{[2..Length(d)]} do @@ -172,12 +222,15 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs,b,frat od; od; + rada:=fail; + ser:=Reversed(ser); i:=1; hom:=ff.factorhom; Q:=Image(hom,G); AQ:=AutomorphismGroupFittingFree(Q); AQI:=InnerAutomorphismsAutomorphismGroup(AQ); + lastperm:=fail; while ifail then + AQiso:=lastperm; + AQP:=Image(AQiso,AQ); + else + makeaqiso(); + + fi; if split then maut:=MTX.ModuleAutomorphisms(mo); @@ -361,6 +420,55 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs,b,frat AQ:=A; + # do we use induced radical automorphisms to help next step? + if Size(KernelOfMultiplicativeGeneralMapping(hom))>1 and + # potentially large GL + Size(GL(Length(MPcgs),RelativeOrders(MPcgs)[1]))>10^10 and + # automorphism size really grew from B/C-bit + Size(A)/Size(AQP)*Index(AQP,sub)>10^10 + then + if rada=fail then + rada:=AutomorphismGroup(r); + fi; + rf:=Image(hom,r); + Info(InfoMorph,2,"Use radical automorphisms for reduction"); + + makeaqiso(); + B:=MappingGeneratorsImages(AQiso); + C:=List(B[1],x-> + GroupHomomorphismByImagesNC(rf,rf,GeneratorsOfGroup(rf), + List(GeneratorsOfGroup(rf),y->ImagesRepresentative(x,y)))); + res:=Group(C); + SetIsFinite(res,true); + SetIsGroupOfAutomorphismsFiniteGroup(res,true); + + ind:=List(GeneratorsOfGroup(rada),x-> + GroupHomomorphismByImagesNC(rf,rf,GeneratorsOfGroup(rf), + List(GeneratorsOfGroup(rf),y->ImagesRepresentative(hom,ImagesRepresentative(x,PreImagesRepresentative(hom,y)))))); + ind:=SubgroupNC(res,ind); + #SetIsFinite(ind,true); + #SetIsAutomorphismGroup(ind,true); + #SetIsGroupOfAutomorphismsFiniteGroup(ind,true); + + if Size(ind)*100ImagesRepresentative(resperm,x))); + C:=PreImage(proj,Image(resperm,ind)); + C:=List(SmallGeneratingSet(C),x->PreImagesRepresentative(AQiso,x)); + AQ:=Group(C); + SetIsFinite(AQ,true); + SetIsGroupOfAutomorphismsFiniteGroup(AQ,true); + makeaqiso(); + fi; + + lastperm:=AQiso; + else + lastperm:=fail; + fi; + i:=i+1; od; diff --git a/lib/grp.gi b/lib/grp.gi index 30f656be22..c0410abaa0 100644 --- a/lib/grp.gi +++ b/lib/grp.gi @@ -653,24 +653,29 @@ local new,i,c; if not IsSubset(ser[1],sub) then sub:=Intersection(ser[1],sub); fi; - while IsSubset(ser[i],sub) do + while i<=Length(ser) and IsSubset(ser[i],sub) do Add(new,ser[i]); i:=i+1; od; - while not IsSubset(sub,ser[i]) do + while i<=Length(ser) and not IsSubset(sub,ser[i]) do c:=ClosureGroup(sub,ser[i]); - Add(new,c); - Add(new,ser[i]); + if Size(new[Length(new)])>Size(c) then + Add(new,c); + fi; + if Size(new[Length(new)])>Size(ser[i]) then + Add(new,ser[i]); + fi; sub:=Intersection(sub,ser[i]); i:=i+1; od; - if Size(sub)Size(ser[i]) then + if Size(sub)Size(ser[i]) then Add(new,sub); fi; while i<=Length(ser) do Add(new,ser[i]); i:=i+1; od; + Assert(1,ForAll([1..Length(new)-1],x->Size(new[x])<>Size(new[x+1]))); return new; end); From db2e6645b615e147051cdf5c2f70bd1cd0236e3f Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Thu, 11 Aug 2016 17:16:58 +0100 Subject: [PATCH 04/15] ENHANCE: Added `PatheticIsomorphism' for test based on Aut(G\times H) This is slow and overkill, but in the case of many generators still better than morpheus... --- lib/autsr.gi | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/autsr.gi b/lib/autsr.gi index c8120fe32d..ee5d3c8299 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -477,3 +477,21 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, end); +# pathetic isomorphism test, based on the automorphism group of GxH. This is +# only of use as long as we don't yet have a Cannon/Holt version of +# isomorphism available and there are many generators +BindGlobal("PatheticIsomorphism",function(G,H) +local d,a,map; + d:=DirectProduct(G,H); + a:=AutomorphismGroup(d); + map:=RepresentativeAction(a,Image(Embedding(d,1)), + Image(Embedding(d,2)), + function(sub,hom) + return Image(hom,sub); + end); + if map=fail then return fail;fi; + return GroupHomomorphismByImagesNC(G,H,GeneratorsOfGroup(G), + List(GeneratorsOfGroup(G),x->PreImagesRepresentative(Embedding(d,2), + Image(map,Image(Embedding(d,1),x))))); +end); + From 3497509f41a150f6d8e7703f9e397d8651c5ef7d Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Fri, 12 Aug 2016 10:44:29 +0100 Subject: [PATCH 05/15] ENHANCE: Further property tests in isomorphism, used PatheticIsomorphism if many generators. Add Test. --- lib/morpheus.gi | 13 ++++++++++- tst/teststandard/grpperm.tst | 45 ++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/lib/morpheus.gi b/lib/morpheus.gi index d2074b8a78..0504fe23a1 100644 --- a/lib/morpheus.gi +++ b/lib/morpheus.gi @@ -2019,8 +2019,19 @@ local m; and IsSolvableGroup(G) and Size(G) <= 2000 then return IsomorphismSolvableSmallGroups(G,H); fi; - elif Length(ConjugacyClasses(G))<>Length(ConjugacyClasses(H)) then + elif AbelianInvariants(G)<>AbelianInvariants(H) then return fail; + elif Collected(List(ConjugacyClasses(G), + x->[Order(Representative(x)),Size(x)])) + <>Collected(List(ConjugacyClasses(H), + x->[Order(Representative(x)),Size(x)])) then + return fail; + fi; + + if Length(AbelianInvariants(G))>3 and Size(RadicalGroup(G))>1 then + # In place until a proper implementation of Cannon/Holt automorphism is + # made available. + return PatheticIsomorphism(G,H); fi; m:=Morphium(G,H,false); diff --git a/tst/teststandard/grpperm.tst b/tst/teststandard/grpperm.tst index 61aba8818d..4c3d6bb452 100644 --- a/tst/teststandard/grpperm.tst +++ b/tst/teststandard/grpperm.tst @@ -177,6 +177,51 @@ gap> g:=TransitiveGroup(12,250);; gap> hom:=IsomorphismPcGroup(g);; gap> Length(ConjugacyClassesByHomomorphicImage(g,hom)); 65 +gap> gp1:=Group( +> (1,23,6,64,38)(2,42,18,19,11)(3,7,30,49,50)(4,14,20,45,46)(5,9,21,41,58,34, +> 17,29,48,44)(8,26,40,43,33)(10,22,59,60,32)(12,24,53,74,76)(13,31,55,81,77, +> 61,25,52,75,83)(15,27,51,78,79)(16,28,47,68,71,62,36,56,70,69)(35,57,82,92, +> 91,37,54,80,90,93)(66,72)(85,86)(88,94)(95,96)(97,98,100,102,104)(99,101, +> 103,105,106), (1,32,11,3)(2,10,23,7)(4,15,33,12)(5,13,34,61)(6,38,42,19)(8, +> 27,14,24)(9,25,17,31)(16,35,62,37)(18,63,64,39)(20,46,26,43)(21,44,29, +> 58)(22,60,30,50)(28,54,36,57)(40,67,45,65)(41,66,48,72)(47,69,56,71)(49,84, +> 59,73)(51,79,53,76)(52,77,55,83)(68,85,70,86)(74,89,78,87)(75,88,81,94)(80, +> 91,82,93)(90,95,92,96)(97,98)(99,101)(102,104)(105,106), +> (4,33)(8,14)(12,15)(16,62)(20,26)(24,27)(28,36)(35,37)(40,45)(43,46)(47, +> 56)(51,53)(54,57)(65,67)(68,70)(69,71)(74,78)(76,79)(80,82)(85,86)(87, +> 89)(90,92)(91,93)(95,96), (1,4)(2,8)(3,12)(5,16)(6,20)(7,24)(9,28)(10, +> 27)(11,33)(13,35)(14,23)(15,32)(17,36)(18,40)(19,43)(21,47)(22,51)(25, +> 54)(26,42)(29,56)(30,53)(31,57)(34,62)(37,61)(38,46)(39,65)(41,68)(44, +> 69)(45,64)(48,70)(49,74)(50,76)(52,80)(55,82)(58,71)(59,78)(60,79)(63, +> 67)(66,85)(72,86)(73,87)(75,90)(77,91)(81,92)(83,93)(84,89)(88,95)(94,96), +> (1,5)(2,9)(3,13)(4,16)(6,21)(7,25)(8,28)(10,31)(11,34)(12,35)(14,36)(15, +> 37)(17,23)(18,41)(19,44)(20,47)(22,52)(24,54)(26,56)(27,57)(29,42)(30, +> 55)(32,61)(33,62)(38,58)(39,66)(40,68)(43,69)(45,70)(46,71)(48,64)(49, +> 75)(50,77)(51,80)(53,82)(59,81)(60,83)(63,72)(65,85)(67,86)(73,88)(74, +> 90)(76,91)(78,92)(79,93)(84,94)(87,95)(89,96));; +gap> gp2:=Group( +> (4,16)(5,20)(8,14)(9,18)(12,15)(13,39)(23,29)(24,32)(27,30)(28,35)(42,47)(43, +> 50)(45,48)(46,60)(54,56)(55,58)(65,67)(66,72)(74,78)(75,81)(76,79)(77, +> 83)(87,89)(88,94), (1,2,6,21,40,11,26,44,64,22)(3,10,34,61,53,36,7,25,52, +> 62)(4,14,23,47,48)(5,9,24,43,60,20,18,32,50,46)(8,29,42,45,16)(12,27,56,74, +> 76)(13,35,58,81,77,39,28,55,75,83)(15,30,54,78,79)(17,33,49,69,71)(19,31, +> 51,68,70)(37,57,82,90,92)(38,59,80,91,93)(41,63)(66,72)(73,84)(88,94), +> (1,4,11,16)(2,8,26,14)(3,12,36,15)(5,19,20,17)(6,23,44,29)(7,27,10,30)(9,33, +> 18,31)(13,38,39,37)(21,42,64,47)(22,45,40,48)(24,51,32,49)(25,54,34,56)(28, +> 59,35,57)(41,65,63,67)(43,69,50,68)(46,71,60,70)(52,74,61,78)(53,76,62, +> 79)(55,82,58,80)(66,86,72,85)(73,87,84,89)(75,91,81,90)(77,93,83,92)(88,96, +> 94,95), (1,5)(2,9)(3,13)(4,17)(6,24)(7,28)(8,31)(10,35)(11,20)(12,37)(14, +> 33)(15,38)(16,19)(18,26)(21,43)(22,46)(23,49)(25,55)(27,57)(29,51)(30, +> 59)(32,44)(34,58)(36,39)(40,60)(41,66)(42,68)(45,70)(47,69)(48,71)(50, +> 64)(52,75)(53,77)(54,80)(56,82)(61,81)(62,83)(63,72)(65,85)(67,86)(73, +> 88)(74,90)(76,92)(78,91)(79,93)(84,94)(87,95)(89,96), +> (1,36,11,3)(2,10,26,7)(4,15,16,12)(5,39,20,13)(6,40,44,22)(8,30,14,27)(9,35, +> 18,28)(17,38,19,37)(21,63,64,41)(23,48,29,45)(24,60,32,46)(25,62,34,53)(31, +> 59,33,57)(42,67,47,65)(43,72,50,66)(49,71,51,70)(52,84,61,73)(54,79,56, +> 76)(55,83,58,77)(68,86,69,85)(74,89,78,87)(75,94,81,88)(80,93,82,92)(90,96, +> 91,95));; +gap> IsomorphismGroups(gp1,gp2)<>fail; +true gap> STOP_TEST( "grpperm.tst", 1814420000); ############################################################################# From d3fc5594e5006384d3402d19befb77ddda171e2e Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Sat, 13 Aug 2016 09:58:20 +0100 Subject: [PATCH 06/15] ENHANCE: Ensure radical factor is not inheriting stupidly large degree. --- lib/autsr.gi | 12 ++++++++++++ lib/permdeco.gi | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/lib/autsr.gi b/lib/autsr.gi index ee5d3c8299..da588cc8d6 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -148,6 +148,7 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, comiso,extra,mo,rada,makeaqiso,ind,lastperm; makeaqiso:=function(); + Info(InfoMorph,3,"Permrep of AQ ",Size(AQ)); AQiso:=IsomorphismPermGroup(AQ); AQP:=Image(AQiso,AQ); # force degree down @@ -228,6 +229,17 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, i:=1; hom:=ff.factorhom; Q:=Image(hom,G); + if IsPermGroup(Q) and NrMovedPoints(Q)/Size(Q)*Size(Socle(Q)) + >SufficientlySmallDegreeSimpleGroupOrder(Size(Q)) then + # just in case the radical factor hom is inherited. + Q:=SmallerDegreePermutationRepresentation(Q); + Info(InfoMorph,3,"Radical factor degree reduced ",NrMovedPoints(Range(hom)), + " -> ",NrMovedPoints(Range(Q))); + hom:=hom*Q; + Q:=Image(hom,G); + fi; + + AQ:=AutomorphismGroupFittingFree(Q); AQI:=InnerAutomorphismsAutomorphismGroup(AQ); lastperm:=fail; diff --git a/lib/permdeco.gi b/lib/permdeco.gi index 9497ea20b0..b50043173a 100644 --- a/lib/permdeco.gi +++ b/lib/permdeco.gi @@ -20,6 +20,15 @@ local pcgs,r,hom,A,iso,p,i; else hom:=NaturalHomomorphismByNormalSubgroup(G,r); fi; + + A:=Image(hom); + if IsPermGroup(A) and NrMovedPoints(A)/Size(A)*Size(Socle(A)) + >SufficientlySmallDegreeSimpleGroupOrder(Size(A)) then + A:=SmallerDegreePermutationRepresentation(A); + Info(InfoGroup,3,"Radical factor degree reduced ",NrMovedPoints(Image(hom)), + " -> ",NrMovedPoints(Image(A))); + hom:=hom*A; + fi; pcgs := TryPcgsPermGroup( G,r, false, false, true ); if not IsPcgs( pcgs ) then From 25f245b332bdc0af646440c7952f905d42c66b3f Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Sat, 13 Aug 2016 10:41:46 +0100 Subject: [PATCH 07/15] WORKAROUND: Temporarily rename CharacteristicSubgroups to CharacteristicSubgroupsLib to avoid complaints when loading CRISP. Moved a test which for some reason takes very long in later place This causes timeouts in travis test. --- lib/grp.gd | 8 ++++---- lib/grp.gi | 4 ++-- lib/grpnames.gi | 2 +- tst/teststandard/bugfix.tst | 16 ++++++++-------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/grp.gd b/lib/grp.gd index 1a2ab7f9c6..e2ea71b241 100644 --- a/lib/grp.gd +++ b/lib/grp.gd @@ -1804,11 +1804,11 @@ DeclareAttribute( "NormalSubgroups", IsGroup ); ############################################################################# ## -#A CharacteristicSubgroups( ) +#A CharacteristicSubgroupsLib( ) ## -## <#GAPDoc Label="CharacteristicSubgroups"> +## <#GAPDoc Label="CharacteristicSubgroupsLib"> ## -## +## ## ## ## returns a list of all characteristic subgroups of G, that is @@ -1823,7 +1823,7 @@ DeclareAttribute( "NormalSubgroups", IsGroup ); ## ## <#/GAPDoc> ## -DeclareAttribute( "CharacteristicSubgroups", IsGroup ); +DeclareAttribute( "CharacteristicSubgroupsLib", IsGroup ); ############################################################################# diff --git a/lib/grp.gi b/lib/grp.gi index c0410abaa0..68dca10344 100644 --- a/lib/grp.gi +++ b/lib/grp.gi @@ -5006,9 +5006,9 @@ end); ############################################################################# ## -#M CharacteristicSubgroups( ) +#M CharacteristicSubgroupsLib( ) ## -InstallMethod(CharacteristicSubgroups,"use automorphisms",true,[IsGroup], +InstallMethod(CharacteristicSubgroupsLib,"use automorphisms",true,[IsGroup], G->Filtered(NormalSubgroups(G),x->IsCharacteristicSubgroup(G,x))); InstallTrueMethod( CanComputeSize, HasSize ); diff --git a/lib/grpnames.gi b/lib/grpnames.gi index 14ff50412d..a94b947b02 100644 --- a/lib/grpnames.gi +++ b/lib/grpnames.gi @@ -463,7 +463,7 @@ InstallMethod(CharacteristicFactorsOfGroup, "generic method", true, function(G) local Ns,MinNs,sel,a,sz,j,gs,g,N; - Ns := ShallowCopy(CharacteristicSubgroups(G)); + Ns := ShallowCopy(CharacteristicSubgroupsLib(G)); SortBy(Ns,Size); MinNs:=[]; sel:=[2..Length(Ns)-1]; diff --git a/tst/teststandard/bugfix.tst b/tst/teststandard/bugfix.tst index ddc6472025..e9b5b8b59f 100644 --- a/tst/teststandard/bugfix.tst +++ b/tst/teststandard/bugfix.tst @@ -10,6 +10,14 @@ gap> DeclareGlobalVariable("foo73"); gap> InstallValue(foo73,true); Error, InstallValue: value cannot be immediate, boolean or character +# Reported by Sohail Iqbal on 2008/10/15, added by AK on 2010/10/03 +gap> f:=FreeGroup("s","t");; s:=f.1;; t:=f.2;; +gap> g:=f/[s^4,t^4,(s*t)^2,(s*t^3)^2];; +gap> CharacterTable(g); +CharacterTable( ) +gap> Length(Irr(g)); +10 + ## Check if ConvertToMatrixRepNC works properly. BH ## gap> mat := [[1,0,1,1],[0,1,1,1]]*One(GF(2)); @@ -1779,14 +1787,6 @@ gap> y:= [ [ Z(3)^0, 0*Z(3) ], [ 0*Z(3), Z(9) ] ];; gap> IsConjugate( G, x, y ); true -# Reported by Sohail Iqbal on 2008/10/15, added by AK on 2010/10/03 -gap> f:=FreeGroup("s","t");; s:=f.1;; t:=f.2;; -gap> g:=f/[s^4,t^4,(s*t)^2,(s*t^3)^2];; -gap> CharacterTable(g); -CharacterTable( ) -gap> Length(Irr(g)); -10 - # 2010/10/06 (TB) gap> EU(7,2); -1 From 25909ad92cbd0886c5138ce4f0633567967722d4 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Mon, 15 Aug 2016 11:22:33 -0600 Subject: [PATCH 08/15] ENHANCE: Avoid Agemo if subgroup is trivial --- lib/autsr.gi | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/lib/autsr.gi b/lib/autsr.gi index da588cc8d6..d5ee7f1005 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -176,23 +176,25 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, d:=RefinedSubnormalSeries(d,Centre(r)); for i in Set(Factors(Size(r))) do u:=PCore(r,i); - d:=RefinedSubnormalSeries(d,u); - j:=1; - repeat - v:=Agemo(u,i,j); - if Size(v)>1 then - d:=RefinedSubnormalSeries(d,v); - fi; - j:=j+1; - until Size(v)=1; - j:=1; - repeat - v:=Omega(u,i,j); - if Size(v)1 then + d:=RefinedSubnormalSeries(d,u); + j:=1; + repeat + v:=Agemo(u,i,j); + if Size(v)>1 then + d:=RefinedSubnormalSeries(d,v); + fi; + j:=j+1; + until Size(v)=1; + j:=1; + repeat + v:=Omega(u,i,j); + if Size(v)Size(d[x])<>Size(d[x+1]))); From 515e2d98123752af4b1acaa4792ed044e73557c2 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Tue, 16 Aug 2016 15:59:59 -0600 Subject: [PATCH 09/15] ENHANCE: Performance improvements to `PatheticIsomorphism` Use characteristic factors to first map in factor groups (shorter orbits) Use direct product structure to obtain better permrep for automorphism group. FIX: Do not drag autactbase into solvable case. --- lib/autsr.gi | 144 +++++++++++++++++++++++++++++++++++++++++++----- lib/morpheus.gi | 13 ++++- 2 files changed, 140 insertions(+), 17 deletions(-) diff --git a/lib/autsr.gi b/lib/autsr.gi index d5ee7f1005..3f765014ce 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -145,11 +145,21 @@ BindGlobal("AutomGrpSR",function(G) local ff,r,d,ser,u,v,i,j,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, - comiso,extra,mo,rada,makeaqiso,ind,lastperm; + comiso,extra,mo,rada,makeaqiso,ind,lastperm,actbase; + + actbase:=ValueOption("autactbase"); makeaqiso:=function(); + if HasIsomorphismPermGroup(AQ) then + AQiso:=IsomorphismPermGroup(AQ); + elif HasNiceMonomorphism(AQ) and IsPermGroup(Range(NiceMonomorphism(AQ))) then + AQiso:=NiceMonomorphism(AQ); + elif actbase<>fail then + AQiso:=IsomorphismPermGroup(AQ:autactbase:=List(actbase,x->Image(hom,x))); + else + AQiso:=IsomorphismPermGroup(AQ); + fi; Info(InfoMorph,3,"Permrep of AQ ",Size(AQ)); - AQiso:=IsomorphismPermGroup(AQ); AQP:=Image(AQiso,AQ); # force degree down a:=Size(AQP); @@ -424,6 +434,9 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, Append(gens,B); Append(gens,A); + for j in gens do + SetIsBijective(j,true); + od; A:=Group(gens); SetIsAutomorphismGroup(A,true); SetIsGroupOfAutomorphismsFiniteGroup(A,true); @@ -431,8 +444,11 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, AQI:=SubgroupNC(A,innB); SetInnerAutomorphismsAutomorphismGroup(A,AQI); - AQ:=A; + # use the actbase for order computations + if actbase<>fail then + Size(A:autactbase:=List(actbase,x->Image(hom,x))); + fi; # do we use induced radical automorphisms to help next step? if Size(KernelOfMultiplicativeGeneralMapping(hom))>1 and @@ -459,6 +475,7 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, ind:=List(GeneratorsOfGroup(rada),x-> GroupHomomorphismByImagesNC(rf,rf,GeneratorsOfGroup(rf), List(GeneratorsOfGroup(rf),y->ImagesRepresentative(hom,ImagesRepresentative(x,PreImagesRepresentative(hom,y)))))); + Size(ind:autactbase:=fail); # disable autactbase transfer ind:=SubgroupNC(res,ind); #SetIsFinite(ind,true); #SetIsAutomorphismGroup(ind,true); @@ -466,7 +483,7 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, if Size(ind)*100ImagesRepresentative(resperm,x))); @@ -495,17 +512,116 @@ end); # only of use as long as we don't yet have a Cannon/Holt version of # isomorphism available and there are many generators BindGlobal("PatheticIsomorphism",function(G,H) -local d,a,map; +local d,a,map,possibly,cG,cH,nG,nH,i,j,sel,u,v,asAutomorphism,K,L,conj,e1,e2, + iso,api,good,gens,pre; + possibly:=function(a,b) + if Size(a)<>Size(b) then + return false; + fi; + if AbelianInvariants(a)<>AbelianInvariants(b) then + return false; + fi; + if Size(a)<1000 and Size(a)<>512 and IdGroup(a)<>IdGroup(b) then + return false; + fi; + return true; + end; + + asAutomorphism:=function(sub,hom) + return Image(hom,sub); + end; + + # go through factors of characteristic series to keep orbits short. + cG:=CharacteristicSubgroupsLib(G); + nG:=[]; + cH:=ShallowCopy(CharacteristicSubgroupsLib(H)); + if Length(cG)<>Length(cH) then + return fail; + fi; + SortBy(cH,Size); + nH:=[]; + i:=1; + good:=[1..Length(cH)]; + while i<=Length(cH) do + if i in good and Size(cH[i])>1 and Size(cH[i])possibly(cG[x],cH[i])); + if Length(sel)=0 then + return fail; + elif Length(sel)=1 then + Add(nG,cG[sel[1]]); + Add(nH,cH[i]); + else + u:=TrivialSubgroup(G); + for j in sel do + u:=ClosureGroup(u,cG[j]); + od; + sel:=Concatenation([i],Filtered([i+1..Length(cH)], + x->possibly(cH[i],cH[x]))); + v:=TrivialSubgroup(H); + for j in sel do + u:=ClosureGroup(v,cH[j]); + od; + if Size(u)<>Size(v) then + return fail; + fi; + good:=Difference(good,sel); + if Size(u)5000 then + # K:=SmallerDegreePermutationRepresentation(api); + # Info(InfoMorph,2,"Permdegree reduced ", +# NrMovedPoints(api),"->",NrMovedPoints(Image(K))); +# iso:=iso*K; +# api:=Image(iso); +# fi; + + # now work in reverse through the characteristic factors + conj:=One(a); + K:=Image(e1,G); + L:=Image(e2,H); + Add(cG,TrivialSubgroup(d)); + for i in cG do + u:=ClosureGroup(i,K); + v:=ClosureGroup(i,L); + if u<>v then + gens:=SmallGeneratingSet(api); + pre:=List(gens,x->PreImagesRepresentative(iso,x)); + map:=RepresentativeAction(SubgroupNC(a,pre),u,v,asAutomorphism); + if map=fail then + return fail; + fi; + conj:=conj*map; + K:=Image(map,K); + + u:=Stabilizer(api,v,gens,pre,asAutomorphism); + Info(InfoMorph,1,"Factor ",Size(d)/Size(i),": ", + "reduce by ",Size(api)/Size(u)); + api:=u; + fi; + od; + return GroupHomomorphismByImagesNC(G,H,GeneratorsOfGroup(G), - List(GeneratorsOfGroup(G),x->PreImagesRepresentative(Embedding(d,2), - Image(map,Image(Embedding(d,1),x))))); + List(GeneratorsOfGroup(G),x->PreImagesRepresentative(e2, + Image(conj,Image(e1,x))))); end); diff --git a/lib/morpheus.gi b/lib/morpheus.gi index 0504fe23a1..63c8b50579 100644 --- a/lib/morpheus.gi +++ b/lib/morpheus.gi @@ -234,7 +234,8 @@ end); ## # try to find a small faithful action for an automorphism group InstallGlobalFunction(AssignNiceMonomorphismAutomorphismGroup,function(au,g) -local hom, allinner, gens, c, ran, r, cen, img, dom, u, subs, orbs, cnt, br, bv, v, val, o, i, comb, best; +local hom, allinner, gens, c, ran, r, cen, img, dom, u, subs, orbs, cnt, br, bv, +v, val, o, i, comb, best,actbase; hom:=fail; allinner:=HasIsAutomorphismGroup(au) and IsAutomorphismGroup(au); @@ -378,10 +379,14 @@ local hom, allinner, gens, c, ran, r, cen, img, dom, u, subs, orbs, cnt, br, bv, fi; od; else + actbase:=ValueOption("autactbase"); + if actbase=fail then + actbase:=[g]; + fi; repeat cnt:=cnt+1; repeat - r:=Random(g); + r:=Random(Random(actbase)); until not r in u; # force prime power order if not IsPrimePowerInt(Order(r)) then @@ -1924,7 +1929,9 @@ local A; if HasIsFrattiniFree(G) and IsFrattiniFree(G) then A:=AutomorphismGroupFrattFreeGroup(G); else - A:=AutomorphismGroupSolvableGroup(G); + # currently autactbase does not work well, as the representation might + # change. + A:=AutomorphismGroupSolvableGroup(G:autactbase:=fail); fi; elif Size(RadicalGroup(G))=1 and IsPermGroup(G) then # essentially a normalizer when suitably embedded From 6765f080d8886fa420af3153461b082727839331 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Mon, 22 Aug 2016 20:48:03 -0600 Subject: [PATCH 10/15] ENHANCE: More use of radical automorphism group Use only compatible radical automorphisms. Further prevention of invalid option passing. Refine subnormal series with given characteristic subs. --- lib/autsr.gi | 171 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 150 insertions(+), 21 deletions(-) diff --git a/lib/autsr.gi b/lib/autsr.gi index 3f765014ce..18a1e49ee8 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -142,10 +142,10 @@ end); # main automorphism method -- currently still using factor groups, but # nevertheless faster.. BindGlobal("AutomGrpSR",function(G) -local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, +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, - comiso,extra,mo,rada,makeaqiso,ind,lastperm,actbase; + cond,sub,AQI,AQP,AQiso,rf,res,resperm,proj,Aperm,Apa,precond,ac, + comiso,extra,mo,rada,makeaqiso,ind,lastperm,actbase,somechar; actbase:=ValueOption("autactbase"); @@ -153,7 +153,7 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, if HasIsomorphismPermGroup(AQ) then AQiso:=IsomorphismPermGroup(AQ); elif HasNiceMonomorphism(AQ) and IsPermGroup(Range(NiceMonomorphism(AQ))) then - AQiso:=NiceMonomorphism(AQ); + AQiso:=NiceMonomorphism(AQ:autactbase:=fail); elif actbase<>fail then AQiso:=IsomorphismPermGroup(AQ:autactbase:=List(actbase,x->Image(hom,x))); else @@ -184,6 +184,12 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, d:=DerivedSeriesOfGroup(r); # refine d:=RefinedSubnormalSeries(d,Centre(r)); + somechar:=ValueOption("someCharacteristics"); + if somechar<>fail then + for i in somechar do + d:=RefinedSubnormalSeries(d,i); + od; + fi; for i in Set(Factors(Size(r))) do u:=PCore(r,i); if Size(u)>1 then @@ -252,10 +258,11 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, fi; - AQ:=AutomorphismGroupFittingFree(Q); + AQ:=AutomorphismGroupFittingFree(Q:someCharacteristics:=fail); AQI:=InnerAutomorphismsAutomorphismGroup(AQ); lastperm:=fail; while iSize(Source(x))=Size(Q))); # ensure that the step is OK lhom:=hom; OQ:=Q; @@ -368,11 +375,17 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, # test condition for lifting, also add corresponding automorphism comiso:=GroupHomomorphismByImagesNC(ocr.complement,OQ,gens,List(gens,x->ImagesRepresentative(q,x))); + precond:=fail; + mo:=GModuleByMats(LinearActionLayer(gens,MPcgs),mo.field); cond:=function(perm) local aut,newgens,mo2,iso,a; + if perm in Aperm then + return true; + fi; aut:=PreImagesRepresentative(AQiso,perm); - newgens:=List(GeneratorsOfGroup(Q), - x->PreImagesRepresentative(q,Image(aut,ImagesRepresentative(q,x)))); + newgens:=List(gens,x->PreImagesRepresentative(comiso, + ImagesRepresentative(aut,ImagesRepresentative(comiso,x)))); + mo2:=GModuleByMats(LinearActionLayer(newgens,MPcgs),mo.field); iso:=MTX.IsomorphismModules(mo,mo2); if iso=fail then @@ -381,12 +394,13 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, # build associated auto a:=GroupHomomorphismByImagesNC(Q,Q,Concatenation(gens,MPcgs), - Concatenation(List(gens,x->PreImagesRepresentative(comiso, - ImagesRepresentative(aut,ImagesRepresentative(comiso,x)))), + Concatenation(newgens, List(MPcgs,x->PcElementByExponents(MPcgs, (ExponentsOfPcElement(MPcgs,x)*One(mo.field))*iso )))); Assert(2,IsBijective(a)); Add(A,a); + Add(Apa,perm); + Aperm:=ClosureGroup(Aperm,perm); return true; fi; end; @@ -397,8 +411,23 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, ocr:=AGTFPrepareAutomLift( Q, MPcgs, q ); + precond:=function(perm) + local aut,newgens,mo2,iso,a; + if perm in Aperm then + return true; + fi; + aut:=PreImagesRepresentative(AQiso,perm); + newgens:=List(GeneratorsOfGroup(Q), + x->PreImagesRepresentative(q,Image(aut,ImagesRepresentative(q,x)))); + mo2:=GModuleByMats(LinearActionLayer(newgens,MPcgs),mo.field); + return MTX.IsomorphismModules(mo,mo2)<>fail; + end; + cond:=function(perm) local aut,newgens,mo2,iso,a; + if perm in Aperm then + return true; + fi; aut:=PreImagesRepresentative(AQiso,perm); newgens:=List(GeneratorsOfGroup(Q), x->PreImagesRepresentative(q,Image(aut,ImagesRepresentative(q,x)))); @@ -411,9 +440,13 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, a:=AGTFAutomLift(ocr,q,aut,iso); if a=fail then + #Print("test failed\n"); return false; else Add(A,a); + Add(Apa,perm); + Aperm:=ClosureGroup(Aperm,perm); + #Print("test succeeded\n"); return true; fi; fi; @@ -423,8 +456,67 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, # find A using the set condition A:=[]; - sub:=SubgroupProperty(AQP,cond, - SubgroupNC(AQP,List(GeneratorsOfGroup(AQI),x->ImagesRepresentative(AQiso,x)))); + Apa:=[]; + # note: we do not include AQI here, so might need to add later + Aperm:=SubgroupNC(AQP,List(GeneratorsOfGroup(AQI), + x->ImagesRepresentative(AQiso,x))); + + # try to find some further generators + if Size(AQP)/Size(Aperm)>100 then + for j in Pcgs(RadicalGroup(AQP)) do + cond(j); + od; + for j in GeneratorsOfGroup(AQP) do + cond(j); + od; + fi; + + sub:=AQP; + #if Size(KernelOfMultiplicativeGeneralMapping(hom))=1 then + # Error("trigger"); + #fi; + if precond<>fail and not ForAll(GeneratorsOfGroup(sub),precond) then + sub:=SubgroupProperty(sub,precond,Aperm); + fi; + sub:=SubgroupProperty(sub,cond,Aperm); + + + #if Size(AQP)/Size(Aperm)>1000 then + # ac:=AscendingChain(AQP,Aperm); + # List(Union(List(ac,GeneratorsOfGroup)),cond); # try generators... + # if Size(Aperm)>Size(ac[1]) then +# ac:=Unique(List(ac,x->ClosureGroup(Aperm,x))); +# fi; +# for j in [2..Length(ac)] do +# if Size(ac[j])/Size(Aperm)<10000 then +# sub:=SubgroupProperty(ac[j],cond,Aperm); +# Info(InfoMorph,3,"IteratedSearch ",j," :",Size(ac[j])/Size(Aperm), +# " Good ",Size(sub)/Size(ac[j-1])," Not:",Size(ac[j])/Size(sub)); +# else +# sub:=Aperm; +# fi; +# +# if Size(sub)>Size(ac[j-1]) then +# for k in [j+1..Length(ac)] do +# ac[k]:=ClosureGroup(ac[k],sub); +# od; +# fi; +# od; +# Error("hooray"); +# fi; + + Aperm:=Group(Apa,()); + j:=1; + while Size(Aperm)1 and - # potentially large GL - Size(GL(Length(MPcgs),RelativeOrders(MPcgs)[1]))>10^10 and - # automorphism size really grew from B/C-bit - Size(A)/Size(AQP)*Index(AQP,sub)>10^10 + Size(A)>10^8 + #( + ## potentially large GL + #Size(GL(Length(MPcgs),RelativeOrders(MPcgs)[1]))>10^10 and + ## automorphism size really grew from B/C-bit + ##Size(A)/Size(AQP)*Index(AQP,sub)>10^10) ) then + + # hook for using existing characteristics to reduce for next step + #if somechar<>fail then + # u:=Filtered(Unique(List(somechar,x->Image(hom,x))),x->Size(x)>1); + # Error("ZZZ"); + #fi; + if rada=fail then - rada:=AutomorphismGroup(r); + ind:=SmallerDegreePermutationRepresentation(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"); + rada:=Stabilizer(rada,k,function(sub,hom) + return Image(hom,sub);end); + fi; + od; + if Source(ind)<>Range(ind) then + # move back to bad degree + rada:=Group(List(GeneratorsOfGroup(rada), + x-> InducedAutomorphism(InverseGeneralMapping(ind),x))); + fi; fi; + + + + + rf:=Image(hom,r); Info(InfoMorph,2,"Use radical automorphisms for reduction"); @@ -472,11 +593,19 @@ local ff,r,d,ser,u,v,i,j,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, SetIsFinite(res,true); SetIsGroupOfAutomorphismsFiniteGroup(res,true); - ind:=List(GeneratorsOfGroup(rada),x-> - GroupHomomorphismByImagesNC(rf,rf,GeneratorsOfGroup(rf), - List(GeneratorsOfGroup(rf),y->ImagesRepresentative(hom,ImagesRepresentative(x,PreImagesRepresentative(hom,y)))))); - Size(ind:autactbase:=fail); # disable autactbase transfer + ind:=[]; + for j in GeneratorsOfGroup(rada) do + k:=GroupHomomorphismByImagesNC(rf,rf, + GeneratorsOfGroup(rf), + List(GeneratorsOfGroup(rf), + y->ImagesRepresentative(hom,ImagesRepresentative(j, + PreImagesRepresentative(hom,y))))); + Assert(2,IsBijective(k)); + Add(ind,k); + od; + ind:=SubgroupNC(res,ind); + Size(ind:autactbase:=fail); # disable autactbase transfer #SetIsFinite(ind,true); #SetIsAutomorphismGroup(ind,true); #SetIsGroupOfAutomorphismsFiniteGroup(ind,true); @@ -584,7 +713,7 @@ local d,a,map,possibly,cG,cH,nG,nH,i,j,sel,u,v,asAutomorphism,K,L,conj,e1,e2, od; K:=[Image(e1,G),Image(e2,H)]; - a:=AutomorphismGroup(d:autactbase:=K); + a:=AutomorphismGroup(d:autactbase:=K,someCharacteristics:=cG); iso:=IsomorphismPermGroup(a:autactbase:=K); api:=Image(iso); #if NrMovedPoints(api)>5000 then From fc3e59d63bb175270bd78e9c1fc255f78c03446a Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Thu, 25 Aug 2016 08:33:02 -0600 Subject: [PATCH 11/15] ENHANCE: Hooks for iterative SubgroupProperty. Fix initialization in permrep for automorphism. Rename TF to SR --- lib/autsr.gi | 102 ++++++++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 45 deletions(-) diff --git a/lib/autsr.gi b/lib/autsr.gi index 18a1e49ee8..e47b6a02e5 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -9,7 +9,7 @@ ## This file contains an implementation of the Cannon/Holt automorphism ## group algorithm. -BindGlobal("AGTFPrepareAutomLift",function(G,pcgs,nat) +BindGlobal("AGSRPrepareAutomLift",function(G,pcgs,nat) local ocr, fphom, fpg, free, len, dim, tmp, L0, S, R, rels, mat, r, RS, i, g, v; ocr:=rec(group:=G,modulePcgs:=pcgs); @@ -91,7 +91,7 @@ local n,i; end); -BindGlobal("AGTFAutomLift",function(ocr,nat,fhom,miso) +BindGlobal("AGSRAutomLift",function(ocr,nat,fhom,miso) local v, rels, genimages, v1, psim, w, s, t, l, hom, i, e, j,ep,phom; v:=[]; @@ -145,7 +145,7 @@ BindGlobal("AutomGrpSR",function(G) 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; + comiso,extra,mo,rada,makeaqiso,ind,lastperm,actbase,somechar,stablim; actbase:=ValueOption("autactbase"); @@ -174,6 +174,43 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, fi; end; + stablim:=function(gp,cond,lim) + local no,same,sz,ac,i,sub; + same:=true; + repeat + sz:=Size(Aperm); + if Size(gp)/Size(Aperm)>lim then + no:=Normalizer(gp,Aperm); + if Size(no)>Size(Aperm) and Size(no)lim then + ac:=AscendingChain(gp,Aperm); + List(Union(List(ac,GeneratorsOfGroup)),cond); # try generators... + if Size(Aperm)>sz then + ac:=Unique(List(ac,x->ClosureGroup(Aperm,x))); + fi; + + i:=First([Length(ac),Length(ac)-1..1],x->Size(ac[x])/sz<=lim); + sub:=ac[i]; + else + sub:=gp; + fi; + if Size(sub)>Size(Aperm) and not IsSubset(no,sub) then + SubgroupProperty(sub,cond,Aperm); + fi; + same:=Size(Aperm)=sz; + if not same then + Info(InfoMorph,3,"stablim improves by ",Size(Aperm)/sz, + " remaining ",Size(gp)/Size(Aperm)); + fi; + until same; + return sub=gp; + end; + ff:=FittingFreeLiftSetup(G); r:=ff.radical; # find series through r @@ -409,7 +446,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, # there is no B in the nonsplit case B:=[]; - ocr:=AGTFPrepareAutomLift( Q, MPcgs, q ); + ocr:=AGSRPrepareAutomLift( Q, MPcgs, q ); precond:=function(perm) local aut,newgens,mo2,iso,a; @@ -437,8 +474,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, return false; else # build associated auto - - a:=AGTFAutomLift(ocr,q,aut,iso); + a:=AGSRAutomLift(ocr,q,aut,iso); if a=fail then #Print("test failed\n"); return false; @@ -478,32 +514,11 @@ 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 precond<>fail and not ForAll(GeneratorsOfGroup(sub),precond) then sub:=SubgroupProperty(sub,precond,Aperm); fi; - sub:=SubgroupProperty(sub,cond,Aperm); - - #if Size(AQP)/Size(Aperm)>1000 then - # ac:=AscendingChain(AQP,Aperm); - # List(Union(List(ac,GeneratorsOfGroup)),cond); # try generators... - # if Size(Aperm)>Size(ac[1]) then -# ac:=Unique(List(ac,x->ClosureGroup(Aperm,x))); -# fi; -# for j in [2..Length(ac)] do -# if Size(ac[j])/Size(Aperm)<10000 then -# sub:=SubgroupProperty(ac[j],cond,Aperm); -# Info(InfoMorph,3,"IteratedSearch ",j," :",Size(ac[j])/Size(Aperm), -# " Good ",Size(sub)/Size(ac[j-1])," Not:",Size(ac[j])/Size(sub)); -# else -# sub:=Aperm; -# fi; -# -# if Size(sub)>Size(ac[j-1]) then -# for k in [j+1..Length(ac)] do -# ac[k]:=ClosureGroup(ac[k],sub); -# od; -# fi; -# od; -# Error("hooray"); -# fi; + # desperately try to grab some further generators + #stablim(sub,cond,10000)=false then + if Size(sub)/Size(Aperm)>100000 then Error("HundredK"); fi; + sub:=SubgroupProperty(sub,cond,Aperm); Aperm:=Group(Apa,()); j:=1; @@ -553,34 +568,31 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, ##Size(A)/Size(AQP)*Index(AQP,sub)>10^10) ) then - # hook for using existing characteristics to reduce for next step - #if somechar<>fail then - # u:=Filtered(Unique(List(somechar,x->Image(hom,x))),x->Size(x)>1); - # Error("ZZZ"); + # # hook for using existing characteristics to reduce for next step + # if somechar<>fail then + # u:=Filtered(Unique(List(somechar,x->Image(hom,x))),x->Size(x)>1); +# if ForAny(u,s->ForAny(GeneratorsOfGroup(AQ),h->Image(h,s)<>s)) then + #Error("ZZZ"); + #fi; #fi; if rada=fail then - ind:=SmallerDegreePermutationRepresentation(r); + 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,function(sub,hom) return Image(hom,sub);end); fi; od; - if Source(ind)<>Range(ind) then - # move back to bad degree - rada:=Group(List(GeneratorsOfGroup(rada), - x-> InducedAutomorphism(InverseGeneralMapping(ind),x))); - fi; + # move back to bad degree + rada:=Group(List(GeneratorsOfGroup(rada), + x-> InducedAutomorphism(InverseGeneralMapping(ind),x))); fi; - - - - rf:=Image(hom,r); Info(InfoMorph,2,"Use radical automorphisms for reduction"); From 5d62d85090da16f7a72cc7553f3a1fbfd6fa8ff2 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Thu, 25 Aug 2016 14:43:43 -0600 Subject: [PATCH 12/15] ENHANCE: Use stabilization of characteristic subgroups to reduce work. In isomorphism test feed in subgroups that must be stabilized by Aut(G)\wr 2, as we don't need the full Aut(GxG) --- lib/autsr.gi | 106 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 85 insertions(+), 21 deletions(-) diff --git a/lib/autsr.gi b/lib/autsr.gi index e47b6a02e5..bde4b056df 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -149,7 +149,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, actbase:=ValueOption("autactbase"); - makeaqiso:=function(); + makeaqiso:=function() + local a,b; if HasIsomorphismPermGroup(AQ) then AQiso:=IsomorphismPermGroup(AQ); elif HasNiceMonomorphism(AQ) and IsPermGroup(Range(NiceMonomorphism(AQ))) then @@ -167,10 +168,15 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, SetSize(AQP,a); a:=SmallerDegreePermutationRepresentation(AQP:cheap); if NrMovedPoints(Image(a))",NrMovedPoints(Image(a))); AQiso:=AQiso*a; - AQP:=Image(a,AQP); + 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; end; @@ -293,7 +299,6 @@ 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:=hom*Q; Q:=Image(hom,G); fi; - AQ:=AutomorphismGroupFittingFree(Q:someCharacteristics:=fail); AQI:=InnerAutomorphismsAutomorphismGroup(AQ); @@ -310,6 +315,14 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, N:=ser[i+1]; 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 + q:=SmallerDegreePermutationRepresentation(Q); + Info(InfoMorph,3,"reduced permrep Q ",NrMovedPoints(Q)," -> ", + NrMovedPoints(Range(q))); + hom:=hom*q; + Q:=Image(hom,G); + fi; Mim:=Image(hom,M); MPcgs:=Pcgs(Mim); q:=GroupHomomorphismByImagesNC(Q,OQ, @@ -386,10 +399,9 @@ 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 lastperm<>fail then AQiso:=lastperm; - AQP:=Image(AQiso,AQ); + AQP:=Group(List(GeneratorsOfGroup(AQ),x->ImagesRepresentative(AQiso,x))); else makeaqiso(); - fi; if split then @@ -517,7 +529,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, # 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)>100000 then Error("HundredK"); fi; sub:=SubgroupProperty(sub,cond,Aperm); Aperm:=Group(Apa,()); @@ -553,10 +566,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, AQI:=SubgroupNC(A,innB); SetInnerAutomorphismsAutomorphismGroup(A,AQI); AQ:=A; - # use the actbase for order computations - if actbase<>fail then - Size(A:autactbase:=List(actbase,x->Image(hom,x))); - fi; + makeaqiso(); + + # use the actbase for order computations + #if actbase<>fail then + # Size(A:autactbase:=List(actbase,x->Image(hom,x))); + #fi; # do we use induced radical automorphisms to help next step? if Size(KernelOfMultiplicativeGeneralMapping(hom))>1 and @@ -568,14 +583,6 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, ##Size(A)/Size(AQP)*Index(AQP,sub)>10^10) ) then - # # hook for using existing characteristics to reduce for next step - # if somechar<>fail then - # u:=Filtered(Unique(List(somechar,x->Image(hom,x))),x->Size(x)>1); -# if ForAny(u,s->ForAny(GeneratorsOfGroup(AQ),h->Image(h,s)<>s)) then - #Error("ZZZ"); - #fi; - #fi; - if rada=fail then ind:=IsomorphismPcGroup(r); rada:=AutomorphismGroup(Image(ind,r):someCharacteristics:=fail,actbase:=fail); @@ -604,6 +611,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, res:=Group(C); SetIsFinite(res,true); SetIsGroupOfAutomorphismsFiniteGroup(res,true); + Size(res:autactbase:=fail); # disable autactbase transfer ind:=[]; for j in GeneratorsOfGroup(rada) do @@ -636,12 +644,39 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, makeaqiso(); fi; + # # hook for using existing characteristics to reduce for next step + if somechar<>fail then + u:=Filtered(Unique(List(somechar,x->Image(hom,x))),x->Size(x)>1); + u:=Filtered(u,s->ForAny(GeneratorsOfGroup(AQ),h->Image(h,s)<>s)); + if Length(u)>0 then + SortBy(u,Size); + C:=MappingGeneratorsImages(AQiso); + for j in u do + C:=Stabilizer(AQP,j,C[2],C[1], + function(sub,hom) return Image(hom,sub);end); + Info(InfoMorph,1,"Stabilize characteristic subgroup ",Size(j), + " :",Size(AQP)/Size(C) ); + B:=Size(C); + C:=SmallGeneratingSet(C); + AQP:=Group(C); + SetSize(AQP,B); + C:=[List(C,x->PreImagesRepresentative(AQiso,x)),C]; + od; + AQ:=Group(C[1]); + SetIsFinite(AQ,true); + SetIsGroupOfAutomorphismsFiniteGroup(AQ,true); + SetSize(AQ,Size(AQP)); + #AQP:=Group(C[2]); # ensure small gen set + #SetSize(AQP,Size(AQ)); + makeaqiso(); + fi; + fi; + lastperm:=AQiso; else lastperm:=fail; fi; - i:=i+1; od; @@ -720,9 +755,38 @@ local d,a,map,possibly,cG,cH,nG,nH,i,j,sel,u,v,asAutomorphism,K,L,conj,e1,e2, e2:=Embedding(d,2); # combine images of characteristic factors, reverse order cG:=[]; - for i in [Length(nG),Length(nG)-1..1] do + nG:=Reversed(nG); + nH:=Reversed(nH); + for i in [1..Length(nG)] do Add(cG,ClosureGroup(Image(e1,nG[i]),Image(e2,nH[i]))); od; + nG:=Concatenation([TrivialSubgroup(G)],nG); + nH:=Concatenation([TrivialSubgroup(H)],nH); + + for i in [2..Length(nG)] do + K:=Filtered([1..Length(nG)],x->Size(nG[x])*2=Size(nG[i]) + and IsSubset(nG[i],nG[x])); + if Length(K)>0 then + K:=K[1]; + # We are seeking an isomorphism, not the full automorphism group of + # GxG. It is thus sufficient, if we find the subgroup Aut(G)\wr 2. + + + # We now found that G and H have two characteristic subgroups Anot x in nG[K])) + *Image(e2,First(GeneratorsOfGroup(nH[i]),x->not x in nH[K])))); + + fi; + od; K:=[Image(e1,G),Image(e2,H)]; a:=AutomorphismGroup(d:autactbase:=K,someCharacteristics:=cG); From aae03ab5a82d902c9f5c69a1d87ec1a43e17b0c4 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Tue, 16 Aug 2016 20:56:41 -0600 Subject: [PATCH 13/15] ENHANCE: New method for `IntermediateSubgroups` using maximal subgroups --- lib/grplatt.gi | 63 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/lib/grplatt.gi b/lib/grplatt.gi index f8b5e507cc..432390f410 100644 --- a/lib/grplatt.gi +++ b/lib/grplatt.gi @@ -2306,9 +2306,70 @@ 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", + IsIdenticalObj, [IsGroup,IsGroup], + 1, # better than previous if index larger +function(G,U) +local uind,subs,incl,i,j,k,m,gens,t,c,p; + if (not IsFinite(G)) and Index(G,U)=infinity then + TryNextMethod(); + fi; + uind:=IndexNC(G,U); + if uind<200 then + TryNextMethod(); + fi; + subs:=[G]; #subgroups so far + incl:=[]; + i:=1; + gens:=SmallGeneratingSet(U); + while i<=Length(subs) do + # find all maximals containing U + m:=MaximalSubgroupClassReps(subs[i]); + m:=Filtered(m,x->IndexNC(subs[i],U) mod IndexNC(subs[i],x)=0); + Info(InfoLattice,1,"Subgroup ",i,", Order ",Size(subs[i]),": ",Length(m), + " maxes"); + for j in m do + t:=RightTransversal(subs[i],Normalizer(subs[i],j)); # conjugates + for k in t do + if ForAll(gens,x->k*x/k in j) then + # U is contained in j^k + c:=j^k; + Assert(1,IsSubset(c,U)); + #is it U? + if uind=IndexNC(G,c) then + Add(incl,[0,i]); + else + # is it new? + p:=PositionProperty(subs,x->IndexNC(G,x)=IndexNC(G,c) and + ForAll(GeneratorsOfGroup(c),y->y in x)); + if p<>fail then + Add(incl,[p,i]); + else + Add(subs,c); + Add(incl,[Length(subs),i]); + fi; + fi; + fi; + od; + od; + i:=i+1; + od; + # rearrange + c:=List(subs,x->IndexNC(x,U)); + p:=Sortex(c); + subs:=Permuted(subs,p); + subs:=subs{[1..Length(subs)-1]}; # remove whole group + for i in incl do + if i[1]>0 then i[1]:=i[1]^p; fi; + if i[2]>0 then i[2]:=i[2]^p; fi; + od; + Sort(incl); + return rec(inclusions:=incl,subgroups:=subs); +end); + InstallMethod(IntermediateSubgroups,"normal case", IsIdenticalObj, [IsGroup,IsGroup], - 1,# better than the previous method + 2,# better than the previous methods function(G,N) local hom,F,cl,cls,lcl,sub,sel,unsel,i,j,rmNonMax; if not IsNormal(G,N) then From 9e44af6f05924fa25f39c4deccbdbc7f386cad82 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Fri, 26 Aug 2016 09:39:27 -0600 Subject: [PATCH 14/15] Fix: res and ind might not be subset of each other. Thus create common parent for niceo Fix variable use --- lib/autsr.gi | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/lib/autsr.gi b/lib/autsr.gi index bde4b056df..5d877e657c 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -605,13 +605,9 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, makeaqiso(); B:=MappingGeneratorsImages(AQiso); - C:=List(B[1],x-> + res:=List(B[1],x-> GroupHomomorphismByImagesNC(rf,rf,GeneratorsOfGroup(rf), List(GeneratorsOfGroup(rf),y->ImagesRepresentative(x,y)))); - res:=Group(C); - SetIsFinite(res,true); - SetIsGroupOfAutomorphismsFiniteGroup(res,true); - Size(res:autactbase:=fail); # disable autactbase transfer ind:=[]; for j in GeneratorsOfGroup(rada) do @@ -624,18 +620,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, Add(ind,k); od; - ind:=SubgroupNC(res,ind); - Size(ind:autactbase:=fail); # disable autactbase transfer - #SetIsFinite(ind,true); - #SetIsAutomorphismGroup(ind,true); - #SetIsGroupOfAutomorphismsFiniteGroup(ind,true); + C:=Group(Concatenation(res,ind)); # to guarantee common parent + SetIsFinite(C,true); + SetIsGroupOfAutomorphismsFiniteGroup(C,true); + Size(C:autactbase:=fail,someCharacteristics:=fail); # disable autactbase transfer + res:=SubgroupNC(C,res); + ind:=SubgroupNC(C,ind); + # this should now go via the niceo of C + Size(ind:autactbase:=fail,someCharacteristics:=fail); + Size(res:autactbase:=fail,someCharacteristics:=fail); + ind:=Intersection(res,ind); # only those we care about if Size(ind)*100ImagesRepresentative(resperm,x))); + B[2],List(GeneratorsOfGroup(res),x->ImagesRepresentative(resperm,x))); C:=PreImage(proj,Image(resperm,ind)); C:=List(SmallGeneratingSet(C),x->PreImagesRepresentative(AQiso,x)); AQ:=Group(C); From 93c0cbdffb3e016058a54a536f3e5c6cb005b63a Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Sun, 28 Aug 2016 19:35:01 -0600 Subject: [PATCH 15/15] ENHANCE: For isomorphism, stabilizer orbits of characteristic subgroups --- lib/autsr.gi | 78 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 15 deletions(-) diff --git a/lib/autsr.gi b/lib/autsr.gi index 5d877e657c..2ad6b36237 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -141,11 +141,17 @@ end); # main automorphism method -- currently still using factor groups, but # nevertheless faster.. + +# option somechar may be a list of characterstic subgroups, or a record with +# component subgroups, orbits BindGlobal("AutomGrpSR",function(G) 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; + comiso,extra,mo,rada,makeaqiso,ind,lastperm,actbase,somechar,stablim, + scharorb,asAutom,jorb,jorpo,substb; + + asAutom:=function(sub,hom) return Image(hom,sub);end; actbase:=ValueOption("autactbase"); @@ -227,8 +233,15 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, d:=DerivedSeriesOfGroup(r); # refine d:=RefinedSubnormalSeries(d,Centre(r)); + scharorb:=fail; somechar:=ValueOption("someCharacteristics"); if somechar<>fail then + if IsRecord(somechar) then + if IsBound(somechar.orbits) then + scharorb:=somechar.orbits; + fi; + somechar:=somechar.subgroups; + fi; for i in somechar do d:=RefinedSubnormalSeries(d,i); od; @@ -591,8 +604,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, 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,function(sub,hom) - return Image(hom,sub);end); + rada:=Stabilizer(rada,k,asAutom); fi; od; # move back to bad degree @@ -631,7 +643,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, Size(res:autactbase:=fail,someCharacteristics:=fail); ind:=Intersection(res,ind); # only those we care about - if Size(ind)*100fail then u:=Filtered(Unique(List(somechar,x->Image(hom,x))),x->Size(x)>1); u:=Filtered(u,s->ForAny(GeneratorsOfGroup(AQ),h->Image(h,s)<>s)); + SortBy(u,Size); + Info(InfoMorph,1,"Forced characteristics ",List(u,Size)); + + if scharorb<>fail then + # these are subgroups for which certain orbits must be stabilized. + C:=List(Reversed(scharorb),x->List(x,y->Image(hom,y))); + C:=Filtered(C,x->Size(x[1])>1 and Size(x[1])Size(x[1]))); + Append(u,C); + fi; + if Length(u)>0 then - SortBy(u,Size); C:=MappingGeneratorsImages(AQiso); for j in u do - C:=Stabilizer(AQP,j,C[2],C[1], - function(sub,hom) return Image(hom,sub);end); - Info(InfoMorph,1,"Stabilize characteristic subgroup ",Size(j), - " :",Size(AQP)/Size(C) ); - B:=Size(C); - C:=SmallGeneratingSet(C); - AQP:=Group(C); - SetSize(AQP,B); - C:=[List(C,x->PreImagesRepresentative(AQiso,x)),C]; + if IsList(j) then + # stabilizer set of subgroups + jorb:=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)); + Info(InfoMorph,2,"Stabilize characteristic orbit ",Size(j[1]), + " :",Size(AQP)/Size(substb) ); + else + substb:=AQP; + fi; + + + else + substb:=Stabilizer(AQP,j,C[2],C[1],asAutom); + Info(InfoMorph,2,"Stabilize characteristic subgroup ",Size(j), + " :",Size(AQP)/Size(substb) ); + fi; + if Size(substb)PreImagesRepresentative(AQiso,x)),substb]; + fi; + od; AQ:=Group(C[1]); SetIsFinite(AQ,true); @@ -790,7 +834,11 @@ local d,a,map,possibly,cG,cH,nG,nH,i,j,sel,u,v,asAutomorphism,K,L,conj,e1,e2, od; K:=[Image(e1,G),Image(e2,H)]; - a:=AutomorphismGroup(d:autactbase:=K,someCharacteristics:=cG); + # we also fix the *pairs* of the characteristic subgroups as orbits. Again + # this must happen in Aut(G)\wr 2, and reduces the size of the group. + a:=AutomorphismGroup(d:autactbase:=K,someCharacteristics:= + rec(subgroups:=cG, + orbits:=List([1..Length(nG)],x->[Image(e1,nG[x]),Image(e2,nH[x])]))); iso:=IsomorphismPermGroup(a:autactbase:=K); api:=Image(iso); #if NrMovedPoints(api)>5000 then