From f7e68975ae74faa8ec5f2c74ff50dcf58974f4cb Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Thu, 1 Sep 2016 15:12:18 -0600 Subject: [PATCH 01/35] FIX: Ensure generating sets remain consistent. Conflicts: lib/autsr.gi --- lib/autsr.gi | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/autsr.gi b/lib/autsr.gi index 2ad6b36237..6968764c0a 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -543,7 +543,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, # 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)>1000000 then Error("Million"); fi; sub:=SubgroupProperty(sub,cond,Aperm); Aperm:=Group(Apa,()); @@ -674,6 +674,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 Length(u)>0 then C:=MappingGeneratorsImages(AQiso); + if C[2]<>GeneratorsOfGroup(AQP) then + C:=[List(GeneratorsOfGroup(AQP), + x->PreImagesRepresentative(AQiso,x)), + GeneratorsOfGroup(AQP)]; + fi; for j in u do if IsList(j) then # stabilizer set of subgroups @@ -685,7 +690,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, 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)); + substb:=Group(List(C[2],x->ImagesRepresentative(B,x)),()); + substb:=Stabilizer(substb,Set(jorpo),OnSets); + substb:=PreImage(B,substb); Info(InfoMorph,2,"Stabilize characteristic orbit ",Size(j[1]), " :",Size(AQP)/Size(substb) ); else From 064b2834dbe8cdd618e1426d3d32aeb662f7e26f Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Thu, 1 Sep 2016 15:12:18 -0600 Subject: [PATCH 02/35] FIX: Corrections to new automorphism code Ensure generating sets remain consistent. Fixed variable name in copied code bit Conflicts: lib/autsr.gi --- lib/autsr.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/autsr.gi b/lib/autsr.gi index 6968764c0a..db52708ecc 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -787,7 +787,7 @@ local d,a,map,possibly,cG,cH,nG,nH,i,j,sel,u,v,asAutomorphism,K,L,conj,e1,e2, x->possibly(cH[i],cH[x]))); v:=TrivialSubgroup(H); for j in sel do - u:=ClosureGroup(v,cH[j]); + v:=ClosureGroup(v,cH[j]); od; if Size(u)<>Size(v) then return fail; From bac63b489b0375a35b404568e64f39ea3cb429f1 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Mon, 5 Sep 2016 07:33:56 -0600 Subject: [PATCH 03/35] ENHANCE: Allow use of PC representation for pc automorphism group --- lib/grppcext.gi | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/grppcext.gi b/lib/grppcext.gi index ed8754429d..b16234adff 100644 --- a/lib/grppcext.gi +++ b/lib/grppcext.gi @@ -567,13 +567,22 @@ end); InstallGlobalFunction(EXReducePermutationActionPairs,function(r) local hom, sel, u, gens, i; - hom:=SmallerDegreePermutationRepresentation(r.permgroup); - if NrMovedPoints(Image(hom))Image(hom,i)); if IsBound(r.isomorphism) then r.isomorphism:=InverseGeneralMapping(hom)*r.isomorphism; fi; + else + hom:=SmallerDegreePermutationRepresentation(r.permgroup); + if NrMovedPoints(Image(hom))Image(hom,i)); + if IsBound(r.isomorphism) then + r.isomorphism:=InverseGeneralMapping(hom)*r.isomorphism; + fi; + fi; fi; # try to reduce nr. of generators sel:=[]; From 420b25e97a9a17d66d9368bc4a8493308e63476e Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Mon, 5 Sep 2016 07:34:42 -0600 Subject: [PATCH 04/35] ENHANCE: Broader criterion for use of PatheticIsomorphism --- lib/morpheus.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/morpheus.gi b/lib/morpheus.gi index 63c8b50579..591811424a 100644 --- a/lib/morpheus.gi +++ b/lib/morpheus.gi @@ -2035,7 +2035,7 @@ local m; return fail; fi; - if Length(AbelianInvariants(G))>3 and Size(RadicalGroup(G))>1 then + if (Length(AbelianInvariants(G))>2 or Length(SmallGeneratingSet(G))>2) and Size(RadicalGroup(G))>1 then # In place until a proper implementation of Cannon/Holt automorphism is # made available. return PatheticIsomorphism(G,H); From 522a69e01b5ffbf66b480846defebf2a762b3d8b Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Mon, 5 Sep 2016 07:35:08 -0600 Subject: [PATCH 05/35] ENHANCE: Start to allow specification of characteristics in pc automorphisms --- lib/grppcaut.gi | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/grppcaut.gi b/lib/grppcaut.gi index ad1852bdb1..da60ca720c 100644 --- a/lib/grppcaut.gi +++ b/lib/grppcaut.gi @@ -873,8 +873,17 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) local spec, weights, first, m, pcgsU, F, pcgsF, A, i, s, n, p, H, pcgsH, pcgsN, N, epi, mats, M, autos, ocr, elms, e, list, imgs, auto, tmp, hom, gens, P, C, B, D, pcsA, rels, iso, xset, - gensA, new,as; + gensA, new,as,somechar,someorb,asAuto; + asAuto:=function(sub,hom) return Image(hom,sub);end; + + somechar:=ValueOption("someCharacteristics"); + if somechar<>fail then + someorb:=somechar.orbits; + somechar:=somechar.subgroups; + else + someorb:=fail; + fi; # get LG series spec := SpecialPcgs(G); weights := LGWeights( spec ); @@ -1036,6 +1045,21 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) SetSize( A, tmp ); fi; fi; + + if somechar<>fail then + B:=List(somechar,x->SubgroupNC(H,List(GeneratorsOfGroup(x),x->PcElementByExponents(pcgsH,ExponentsOfPcElement(spec,x){[1..Length(pcgsH)]})))); + B:=Unique(B); + B:=Filtered(B,x->ForAny(GeneratorsOfGroup(A),y->x<>asAuto(x,y))); + if Length(B)>0 then + SortBy(B,Size); + tmp:=Size(A); + for e in B do + A:=Stabilizer(A,e,asAuto); + od; + Info(InfoAutGrp,2,"given chars reduce by ",tmp/Size(A)); + fi; + fi; + od; # the last step From 5c284fd19cca4b8988bafff23f6569188d637c57 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Thu, 8 Sep 2016 13:28:26 -0600 Subject: [PATCH 06/35] ENHANCE: Increase hardcoded domain size limit for reducing down from GL. Utilize a given `autactbase' to help with pc group automorphisms. --- lib/grppcaut.gi | 35 ++++++++++++++++++++++++++++------- lib/morpheus.gi | 2 +- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/lib/grppcaut.gi b/lib/grppcaut.gi index da60ca720c..dcf5ece443 100644 --- a/lib/grppcaut.gi +++ b/lib/grppcaut.gi @@ -552,7 +552,7 @@ NormalizingReducedGL := function( spec, s, n, M ) S := B; # in case that we cannot compute a perm rep of pgl - if p^d > 10000 then + if p^d > 100000 then return S; fi; @@ -873,16 +873,18 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) local spec, weights, first, m, pcgsU, F, pcgsF, A, i, s, n, p, H, pcgsH, pcgsN, N, epi, mats, M, autos, ocr, elms, e, list, imgs, auto, tmp, hom, gens, P, C, B, D, pcsA, rels, iso, xset, - gensA, new,as,somechar,someorb,asAuto; + gensA, new,as,somechar,someorb,asAutom,autactbase; - asAuto:=function(sub,hom) return Image(hom,sub);end; + asAutom:=function(sub,hom) return Image(hom,sub);end; + autactbase:=ValueOption("autactbase"); + PushOptions(rec(autactbase:=fail)); # remove this option from concern somechar:=ValueOption("someCharacteristics"); if somechar<>fail then - someorb:=somechar.orbits; + scharorb:=somechar.orbits; somechar:=somechar.subgroups; else - someorb:=fail; + scharorb:=fail; fi; # get LG series spec := SpecialPcgs(G); @@ -1049,16 +1051,34 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) if somechar<>fail then B:=List(somechar,x->SubgroupNC(H,List(GeneratorsOfGroup(x),x->PcElementByExponents(pcgsH,ExponentsOfPcElement(spec,x){[1..Length(pcgsH)]})))); B:=Unique(B); - B:=Filtered(B,x->ForAny(GeneratorsOfGroup(A),y->x<>asAuto(x,y))); + B:=Filtered(B,x->ForAny(GeneratorsOfGroup(A),y->x<>asAutom(x,y))); if Length(B)>0 then SortBy(B,Size); tmp:=Size(A); + if autactbase<>fail then + e:=List(autactbase,x->SubgroupNC(H,List(GeneratorsOfGroup(x),x->PcElementByExponents(pcgsH,ExponentsOfPcElement(spec,x){[1..Length(pcgsH)]})))); + NiceMonomorphism(A:autactbase:=e); + fi; for e in B do - A:=Stabilizer(A,e,asAuto); + A:=Stabilizer(A,e,asAutom); od; Info(InfoAutGrp,2,"given chars reduce by ",tmp/Size(A)); fi; fi; + # as yet disabled + if false and scharorb<>fail then + # these are subgroups for which certain orbits must be stabilized. + B:=List(Reversed(scharorb),x->List(x,x->Group(List(GeneratorsOfGroup(x), + y->PcElementByExponents(pcgsH,ExponentsOfPcElement(spec,y){ + [1..Length(pcgsH)]} )),One(H)))); + B:=Filtered(B,x->Size(x[1])>1 and Size(x[1])Length(e) then + Error("eng"); + fi; + od; + fi; od; @@ -1080,6 +1100,7 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) od; B := GroupByGenerators( autos ); SetSize( B, Size(A) ); + PopOptions(); # undo the added `fail' return B; end); diff --git a/lib/morpheus.gi b/lib/morpheus.gi index 591811424a..a266035fb9 100644 --- a/lib/morpheus.gi +++ b/lib/morpheus.gi @@ -1931,7 +1931,7 @@ local A; else # currently autactbase does not work well, as the representation might # change. - A:=AutomorphismGroupSolvableGroup(G:autactbase:=fail); + A:=AutomorphismGroupSolvableGroup(G); fi; elif Size(RadicalGroup(G))=1 and IsPermGroup(G) then # essentially a normalizer when suitably embedded From 828452819a26c08c2b3ded5891617f10f5812559 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Sat, 10 Sep 2016 20:36:25 -0600 Subject: [PATCH 07/35] ENHANCE: Added functions to have small steps in module series on top/bottom --- lib/meataxe.gi | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/lib/meataxe.gi b/lib/meataxe.gi index 0a8b04e249..c951d91d87 100644 --- a/lib/meataxe.gi +++ b/lib/meataxe.gi @@ -3190,6 +3190,65 @@ mats:=m.generators; end; SMTX.BasesCompositionSeries:=SMTX_BasesCompositionSeries; +# composition series with small steps +SMTX_BasesCSSmallDimUp:=function(m) +local cf,dim,b,den,sub,i,s,q,found,qb; + cf:=List(SMTX.CollectedFactors(m),x->[x[1],x[2]]); # so we can overwrite + SortBy(cf,x->x[1].dimension); + dim:=m.dimension; + b:= IdentityMat(SMTX.Dimension(m),SMTX.Field(m) ); + ConvertToMatrixRep(b); + den:=0; + sub:=[[]]; + q:=m; + while den0 then # can we still get this module? + s:=MTX.Homomorphisms(cf[i][1],q); + if Length(s)>0 then + # found one + cf[i][2]:=cf[i][2]-1; + found:=true; + s:=s[1]; + if Length(s)=q.dimension then + # on top + Add(sub,TriangulizedMat(b)); + den:=dim; + else + TriangulizeMat(s); + qb:=b{[den+1..Length(b)]}; # basis + qb:=List(s,x->x*qb); + qb:=Concatenation(b{[1..den]},qb); + qb:=TriangulizedMat(qb); + Add(sub,qb); + s:=SMTX.InducedAction(q,s,3); + b:=Concatenation(b{[1..den]},s[3]*b{[den+1..Length(b)]}); + den:=den+Length(qb); + q:=s[2]; + den:=Length(qb); + fi; + fi; + fi; + i:=i+1; + od; + od; + return sub; +end; +SMTX.BasesCSSmallDimUp:=SMTX_BasesCSSmallDimUp; + +SMTX_BasesCSSmallDimDown:=function(m) +local d,sub; + d:=MTX.DualModule(m); + sub:=SMTX_BasesCSSmallDimUp(d); + return Concatenation([[]], + Reversed(List(sub{[2..Length(sub)-1]},x->SMTX.DualizedBasis(m,x))), + [IdentityMat(m.dimension,m.field)]); + +end; +SMTX.BasesCSSmallDimDown:=SMTX_BasesCSSmallDimDown; + SMTX_BasesSubmodules:=function(m) local cf,u,i,j,f,cl,min,neu,sq,sb,fb,k,nmin,F; F:=SMTX.Field(m); From d51b7971d234b468b16aed351e7e9b1a97f7d3d2 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Sun, 11 Sep 2016 08:58:40 -0600 Subject: [PATCH 08/35] ENHANCE: SmallGeneratingSet behaves better in cases of huge generator numbers. Instead of abelian invariants use factors of index of G'. --- lib/grpperm.gi | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/grpperm.gi b/lib/grpperm.gi index cf7c301ace..3d3caf79a3 100644 --- a/lib/grpperm.gi +++ b/lib/grpperm.gi @@ -1831,7 +1831,7 @@ end ); InstallMethod(SmallGeneratingSet,"random and generators subset, randsims",true, [IsPermGroup],0, function (G) -local i, j, U, gens,o,v,a,sel; +local i, j, U, gens,o,v,a,sel,min; # remove obvious redundancies gens := ShallowCopy(Set(GeneratorsOfGroup(G))); @@ -1865,14 +1865,19 @@ local i, j, U, gens,o,v,a,sel; return MinimalGeneratingSet(G); fi; + + min:=2; if Length(gens)>2 then - i:=2; - while i<=3 and ix[2])); + i:=Maximum(2,min); + while i<=min+1 and iRandom(G))); - StabChain(U,rec(random:=1)); + StabChainOptions(U).random:=100; # randomized size +#Print("A:",i,",",j," ",Size(G)/Size(U),"\n"); if Size(U)=Size(G) then gens:=Set(GeneratorsOfGroup(U)); fi; @@ -1881,13 +1886,16 @@ local i, j, U, gens,o,v,a,sel; i:=i+1; od; fi; + i := 1; if not IsAbelian(G) then i:=i+1; fi; - while i < Length(gens) do + while i <= Length(gens) and Length(gens)>min do # random did not improve much, try subsets U:=Subgroup(G,gens{Difference([1..Length(gens)],[i])}); + StabChainOptions(U).random:=100; # randomized size +#Print("B:",i," ",Size(G)/Size(U),"\n"); if Size(U) Date: Sun, 11 Sep 2016 08:59:40 -0600 Subject: [PATCH 09/35] ENHANCE: Use better series, projective action on vectors. Also ensure that automorphism group is automorphismgroup and fix comment. Two small fixes in ordering if there is trivial orbit on lines --- lib/autsr.gi | 2 +- lib/grppcaut.gi | 52 +++++++++++++++++++++++++++++++++++++------------ 2 files changed, 41 insertions(+), 13 deletions(-) diff --git a/lib/autsr.gi b/lib/autsr.gi index db52708ecc..63e8e1d293 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -1,6 +1,6 @@ ############################################################################# ## -#W auttf.gi GAP library Alexander Hulpke +#W autsr.gi GAP library Alexander Hulpke #W Soley Jonsdottir ## ## diff --git a/lib/grppcaut.gi b/lib/grppcaut.gi index dcf5ece443..ea46b5cc10 100644 --- a/lib/grppcaut.gi +++ b/lib/grppcaut.gi @@ -52,7 +52,10 @@ InducedActionFactor := function( mats, fac, low ) end; VectorStabilizerByFactors:=function(group,gens,mats,shadows,vec) - local PrunedBasis, f, lim, mo, dim, bas, newbas, dims, q, bp, ind, affine, acts, nv, stb, idx, idxh, incstb, incperm, notinc, free, freegens, stabp, stabm, dict, orb, tp, tm, p, img, sch, incpermstop, sz, sel, nbas, offset, i; + local PrunedBasis, f, lim, mo, dim, bas, newbas, dims, q, bp, ind, affine, + acts, nv, stb, idx, idxh, incstb, incperm, notinc, free, freegens, stabp, + stabm, dict, orb, tp, tm, p, img, sch, incpermstop, sz, sel, nbas, offset, + i,action,lineflag; PrunedBasis:=function(p) local b,q,i; @@ -73,7 +76,7 @@ VectorStabilizerByFactors:=function(group,gens,mats,shadows,vec) lim:=2; mo:=GModuleByMats(mats,f); dim:=mo.dimension; - bas:=PrunedBasis(MTX.BasesCompositionSeries(mo)); + bas:=PrunedBasis(MTX.BasesCSSmallDimDown(mo)); # form new basis of space newbas:=ShallowCopy(bas[2]); @@ -92,6 +95,8 @@ VectorStabilizerByFactors:=function(group,gens,mats,shadows,vec) vec:=vec*q; bp:=Length(dims)-1; + action:=false; + lineflag:=true; while bp>=1 do ind:=[dims[bp]+1..dims[bp+1]]; q:=[dims[bp+1]+1..dim]; @@ -100,11 +105,25 @@ VectorStabilizerByFactors:=function(group,gens,mats,shadows,vec) ind:=[dims[bp]+1..dim]; else affine:=List(mats,i->vec{q}*(i{q}{ind})); + if ForAll(affine,IsZero) then + affine:=false; + fi; fi; Info(InfoMatOrb,2,"Acting dimension ",ind); acts:=List(mats,x->ImmutableMatrix(f,x{ind}{ind})); nv:=vec{ind}; - + + if affine=false then + if lineflag and Size(mo.field)>2 then + action:=OnLines; + nv:=NormedRowVector(nv); + else + action:=OnRight; + fi; + else + action:=false; + fi; + if (affine=false and ForAny([1..Length(acts)],i->nv*acts[i]<>nv)) or (affine<>false and ForAny([1..Length(acts)],i->nv*acts[i]+affine[i]<>nv)) then @@ -120,15 +139,18 @@ VectorStabilizerByFactors:=function(group,gens,mats,shadows,vec) stabp:=[]; stabm:=[]; dict:=NewDictionary(nv,true,f^Length(nv)); + + MakeImmutable(nv); orb:=[nv]; AddDictionary(dict,nv,1); tp:=[One(group)]; tm:=[One(free)]; p:=1; + while incstb and p<=Length(orb) do for i in [1..Length(gens)] do - if affine=false then - img:=orb[p]*acts[i]; + if action<>false then + img:=action(orb[p],acts[i]); else img:=orb[p]*acts[i]+affine[i]; fi; @@ -192,14 +214,14 @@ VectorStabilizerByFactors:=function(group,gens,mats,shadows,vec) p:=p+1; od; #sz:=Maximum(Difference(DivisorsInt(sz),[sz])); - if Length(orb)<=idxh then + if Length(orb)<=idxh and Length(orb)false then + img:=action(orb[p],acts[i]); else img:=orb[p]*acts[i]+affine[i]; fi; @@ -248,7 +270,7 @@ VectorStabilizerByFactors:=function(group,gens,mats,shadows,vec) gens:=stabp; mats:=List(stabm,i->MappedWord(i,freegens,mats)); shadows:=List(stabm,i->MappedWord(i,freegens,shadows)); - if AssertionLevel()>0 then + if AssertionLevel()>0 and action=false or action=OnRight then ind:=[dims[bp]+1..dim]; acts:=List(mats,x->ImmutableMatrix(f,x{ind}{ind})); nv:=vec{ind}; @@ -262,7 +284,7 @@ VectorStabilizerByFactors:=function(group,gens,mats,shadows,vec) acts:=List(mats,x->ImmutableMatrix(f,x{ind}{ind})); mo:=GModuleByMats(acts,f); #if not MTX.IsIrreducible(mo) then - nbas:=PrunedBasis(MTX.BasesCompositionSeries(mo)); + nbas:=PrunedBasis(MTX.BasesCSSmallDimDown(mo)); offset:=Length(nbas)-bp; if offset>0 then #nbas:=nbas{[2..Length(nbas)]}; @@ -297,7 +319,12 @@ VectorStabilizerByFactors:=function(group,gens,mats,shadows,vec) fi; fi; - bp:=bp-1; + if action<>OnLines then + bp:=bp-1; + lineflag:=true; + else + lineflag:=false; + fi; od; Assert(1,ForAll(mats,i->vec*i=vec)); return rec(stabilizer:=group, @@ -873,7 +900,7 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) local spec, weights, first, m, pcgsU, F, pcgsF, A, i, s, n, p, H, pcgsH, pcgsN, N, epi, mats, M, autos, ocr, elms, e, list, imgs, auto, tmp, hom, gens, P, C, B, D, pcsA, rels, iso, xset, - gensA, new,as,somechar,someorb,asAutom,autactbase; + gensA, new,as,somechar,scharorb,asAutom,autactbase; asAutom:=function(sub,hom) return Image(hom,sub);end; @@ -1054,6 +1081,7 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) B:=Filtered(B,x->ForAny(GeneratorsOfGroup(A),y->x<>asAutom(x,y))); if Length(B)>0 then SortBy(B,Size); + SetIsGroupOfAutomorphismsFiniteGroup(A,true); tmp:=Size(A); if autactbase<>fail then e:=List(autactbase,x->SubgroupNC(H,List(GeneratorsOfGroup(x),x->PcElementByExponents(pcgsH,ExponentsOfPcElement(spec,x){[1..Length(pcgsH)]})))); From 6049305be6d14489adeb0c686cf750874ee0943b Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Sun, 11 Sep 2016 11:55:00 -0600 Subject: [PATCH 10/35] New test file Modify assertions that were not any longer valid. Required blank lines in test file --- lib/grppcaut.gi | 4 +- tst/teststandard/grpauto.tst | 77 ++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 tst/teststandard/grpauto.tst diff --git a/lib/grppcaut.gi b/lib/grppcaut.gi index ea46b5cc10..2c5afc25ed 100644 --- a/lib/grppcaut.gi +++ b/lib/grppcaut.gi @@ -270,7 +270,7 @@ VectorStabilizerByFactors:=function(group,gens,mats,shadows,vec) gens:=stabp; mats:=List(stabm,i->MappedWord(i,freegens,mats)); shadows:=List(stabm,i->MappedWord(i,freegens,shadows)); - if AssertionLevel()>0 and action=false or action=OnRight then + if AssertionLevel()>0 and (action=false or action=OnRight) then ind:=[dims[bp]+1..dim]; acts:=List(mats,x->ImmutableMatrix(f,x{ind}{ind})); nv:=vec{ind}; @@ -310,7 +310,7 @@ VectorStabilizerByFactors:=function(group,gens,mats,shadows,vec) bp:=bp+offset; fi; - if AssertionLevel()>0 then + if AssertionLevel()>0 and (action=false or action=OnRight) then ind:=[dims[bp]+1..dim]; acts:=List(mats,x->ImmutableMatrix(f,x{ind}{ind})); nv:=vec{ind}; diff --git a/tst/teststandard/grpauto.tst b/tst/teststandard/grpauto.tst new file mode 100644 index 0000000000..9d8a56ddd6 --- /dev/null +++ b/tst/teststandard/grpauto.tst @@ -0,0 +1,77 @@ +############################################################################# +## +#W grpauto.tst GAP tests Alexander Hulpke +#W Max Horn +## +## +#Y Copyright (C) 2016 +## +## Warning: Later tests need more than the default memory allocation + + +gap> START_TEST("grpauto.tst"); + +# +# hard-iso +# +gap> G:=PcGroupCode(589146814442329838036024080610343654876506937853710969\ +> 448924603190236492427673556989072961847,11664);; +gap> H:=PcGroupCode(801562094435225650939080918450186172844860829657513982\ +> 80193370111859863168020375597783858966368416055,11664);; +gap> IsomorphismGroups(G,H); +fail +gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; +false + +# +# hard-iso2 +# +gap> G:=PcGroupCode(409374400436488159632156475187687419052272443300404477\ +> 8304456449542618727,11664);; +gap> H:=PcGroupCode(409362703022669659121228158166302826716273465648729361\ +> 3630709080224464487,11664);; +gap> K:=PcGroupCode(409374400436488159632788450059215346119864636722303267\ +> 1585655861072658023,11664);; +gap> IsomorphismGroups(G,H); +fail +gap> IsomorphismGroups(G,K); +fail +gap> IsomorphismGroups(H,K); +fail +gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; +false + +# +# hard-iso3 +# +gap> G:=PcGroupCode( +> 47230783805023816758284073850775753212570866553716206981615555,20000);; +gap> H:=PcGroupCode( +> 2361539190251190837914203692538788582942691934753704906691,20000);; +gap> IsomorphismGroups(G,H); +fail +gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; +false + +# +# from here on needs 4GB +# +# hard-iso4 +# +gap> G:=PcGroupCode( +> 741231213963541373679312045151639276850536621925972119311,11664);; +gap> H:=PcGroupCode( +> 888658311993669104086576972570546890038187728096037768975,11664);; +gap> IsomorphismGroups(G,H); +fail +gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; +false + + + + +gap> STOP_TEST( "grpauto.tst", 1814420000); + +############################################################################# +## +#E From a082308329a282c9902ede67209c45f8af10523c Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Mon, 12 Sep 2016 13:23:12 -0600 Subject: [PATCH 11/35] Cheap version of `SmallerDegree' in PC-extension code. --- lib/grppcext.gi | 2 +- tst/teststandard/grpauto.tst | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/grppcext.gi b/lib/grppcext.gi index b16234adff..79b5f93446 100644 --- a/lib/grppcext.gi +++ b/lib/grppcext.gi @@ -575,7 +575,7 @@ local hom, sel, u, gens, i; r.isomorphism:=InverseGeneralMapping(hom)*r.isomorphism; fi; else - hom:=SmallerDegreePermutationRepresentation(r.permgroup); + hom:=SmallerDegreePermutationRepresentation(r.permgroup:cheap); if NrMovedPoints(Image(hom))Image(hom,i)); diff --git a/tst/teststandard/grpauto.tst b/tst/teststandard/grpauto.tst index 9d8a56ddd6..cd48ae3aed 100644 --- a/tst/teststandard/grpauto.tst +++ b/tst/teststandard/grpauto.tst @@ -53,6 +53,20 @@ fail gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; false +# +# maximalAbelian took memory +# +gap> G:=PcGroupCode( +> 4241001241648612707217598260832611111859648363850009814061412466747, +> 18144);; +gap> H:=PcGroupCode( +> 8452751797183492013365034036870074746315874486014489856228688347195, +> 18144);; +gap> IsomorphismGroups(G,H); +fail +gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; +false + # # from here on needs 4GB # @@ -72,6 +86,3 @@ false gap> STOP_TEST( "grpauto.tst", 1814420000); -############################################################################# -## -#E From 9558273c226b16cffeb93e4da14e294a4069f9d6 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Tue, 13 Sep 2016 14:45:23 -0600 Subject: [PATCH 12/35] ENHANCE: Use characteristic subgroup classes to split large group on module. Both on top level and for lower modules. --- lib/grppcaut.gi | 105 +++++++++++++++++++++++++++++------ lib/grppcext.gi | 22 ++++---- tst/teststandard/grpauto.tst | 12 ++++ 3 files changed, 113 insertions(+), 26 deletions(-) diff --git a/lib/grppcaut.gi b/lib/grppcaut.gi index 2c5afc25ed..f6dc481421 100644 --- a/lib/grppcaut.gi +++ b/lib/grppcaut.gi @@ -900,10 +900,17 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) local spec, weights, first, m, pcgsU, F, pcgsF, A, i, s, n, p, H, pcgsH, pcgsN, N, epi, mats, M, autos, ocr, elms, e, list, imgs, auto, tmp, hom, gens, P, C, B, D, pcsA, rels, iso, xset, - gensA, new,as,somechar,scharorb,asAutom,autactbase; + gensA, new,as,somechar,scharorb,asAutom,autactbase, + quotimg,eN,field; asAutom:=function(sub,hom) return Image(hom,sub);end; + # image of subgroup in quotient by pcgs + quotimg:=function(F,pcgs,U) + return SubgroupNC(F,List(GeneratorsOfGroup(U), + x->PcElementByExponents(pcgs,ExponentsOfPcElement(spec,x){[1..Length(pcgs)]}))); + end; + autactbase:=ValueOption("autactbase"); PushOptions(rec(autactbase:=fail)); # remove this option from concern somechar:=ValueOption("someCharacteristics"); @@ -929,6 +936,35 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) dimension := first[2]-1, generators := [] ); B := NormalizingReducedGL( spec, 1, first[2], M ); + + if somechar<>fail then + C:=List(somechar,x->quotimg(F,FamilyPcgs(F),x)); + C:=List(C,x->[x]); + if scharorb<>fail then + Append(C,List(scharorb,x->List(x,x->quotimg(F,FamilyPcgs(F),x)))); + fi; + C:=Filtered(C,x->Size(x[1])>1 and Size(x[1])List(SmallGeneratingSet(x), + x->ExponentsOfPcElement(FamilyPcgs(F),x)*One(field))); + C:=List(C,x->OnSubspacesByCanonicalBasis(x,One(B))); + xset:=Orbit(B,C[1],OnSubspacesByCanonicalBasis); + C:=Filtered(C,x->x in xset); + if Length(xset)>Length(C) then + hom:=ActionHomomorphism(B,xset,OnSubspacesByCanonicalBasis, + "surjective"); + C:=List(C,x->Position(xset,x)); + + e:=Size(B); + B:=PreImage(hom,Stabilizer(Image(hom),C,OnSets)); + Info(InfoAutGrp,2,"characteristics reduce ",e, + " to ",Size(B)); + fi; + od; + fi; A := AutomorphismGroupElAbGroup( F, B ); SetIsGroupOfAutomorphismsFiniteGroup(A,true); @@ -949,7 +985,11 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) ocr := rec( group := H, generators := pcgsH ); # we will modify the generators later! + pcgsN := InducedPcgsByPcSequenceNC( pcgsH, pcgsH{[s..n-1]} ); + eN:=SubgroupNC(G,InducedPcgsByPcSequenceNC( spec, spec{[s..m]})); + field:=GF(RelativeOrders(pcgsN)[1]); + ocr.modulePcgs := pcgsN; ocr.generators:=ocr.generators mod NumeratorOfModuloPcgs(pcgsN); @@ -962,14 +1002,50 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) mats := LinearOperationLayer( H, pcgsH{[1..s-1]}, pcgsN ); M := GModuleByMats( mats, GF( p ) ); - # compatible / inducible pairs + # compatible / inducible pairs + Info( InfoAutGrp, 2,"compute reduced gl "); + B := NormalizingReducedGL( spec, s, n, M ); + # A and B will not be used later, so it is no problem to + # replace them by other groups with fewer generators + B:=SubgroupNC(B,SmallGeneratingSet(B)); + + if somechar<>fail then + e:=Product(RelativeOrders(pcgsN)); + D:=List(somechar,x->quotimg(H,pcgsH,Intersection(x,eN))); + D:=List(D,x->[x]); + # do something ... + + if scharorb<>fail then + Append(D,List(scharorb, + x->List(x,x->quotimg(H,pcgsH,Intersection(x,eN))))); + fi; + + D:=Filtered(D,x->Size(x[1])>1 and Size(x[1])List(SmallGeneratingSet(x), + x->ExponentsOfPcElement(pcgsH,x){[s..n-1]}*One(field))); + C:=List(C,x->OnSubspacesByCanonicalBasis(x,One(B))); + xset:=Orbit(B,C[1],OnSubspacesByCanonicalBasis); + C:=Filtered(C,x->x in xset); + if Length(xset)>Length(C) then + hom:=ActionHomomorphism(B,xset,OnSubspacesByCanonicalBasis, + "surjective"); + C:=List(C,x->Position(xset,x)); + + e:=Size(B); + B:=PreImage(hom,Stabilizer(Image(hom),C,OnSets)); + Info(InfoAutGrp,2,"characteristics reduce ",e, + " to ",Size(B)); + fi; + od; + fi; + if weights[s][2] = 1 then - Info( InfoAutGrp, 2,"compute reduced gl "); - B := NormalizingReducedGL( spec, s, n, M ); + #Info( InfoAutGrp, 2,"compute reduced gl "); + #B := NormalizingReducedGL( spec, s, n, M ); - # A and B will not be used later, so it is no problem to - # replace them by other groups with fewer generators - B:=SubgroupNC(B,SmallGeneratingSet(B)); if HasPcgs(A) and Length(Pcgs(A))fail then - B:=List(somechar,x->SubgroupNC(H,List(GeneratorsOfGroup(x),x->PcElementByExponents(pcgsH,ExponentsOfPcElement(spec,x){[1..Length(pcgsH)]})))); + B:=List(somechar,x->quotimg(H,pcgsH,x)); B:=Unique(B); B:=Filtered(B,x->ForAny(GeneratorsOfGroup(A),y->x<>asAutom(x,y))); if Length(B)>0 then @@ -1084,7 +1158,7 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) SetIsGroupOfAutomorphismsFiniteGroup(A,true); tmp:=Size(A); if autactbase<>fail then - e:=List(autactbase,x->SubgroupNC(H,List(GeneratorsOfGroup(x),x->PcElementByExponents(pcgsH,ExponentsOfPcElement(spec,x){[1..Length(pcgsH)]})))); + e:=List(autactbase,x->quotimg(H,pcgsH,x)); NiceMonomorphism(A:autactbase:=e); fi; for e in B do @@ -1093,12 +1167,11 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) Info(InfoAutGrp,2,"given chars reduce by ",tmp/Size(A)); fi; fi; + # as yet disabled if false and scharorb<>fail then # these are subgroups for which certain orbits must be stabilized. - B:=List(Reversed(scharorb),x->List(x,x->Group(List(GeneratorsOfGroup(x), - y->PcElementByExponents(pcgsH,ExponentsOfPcElement(spec,y){ - [1..Length(pcgsH)]} )),One(H)))); + B:=List(Reversed(scharorb),x->List(x,x->quotimg(H,pcgsH,x))); B:=Filtered(B,x->Size(x[1])>1 and Size(x[1])1 then + repeat u:=Group(()); - gens:=[]; - for i in GeneratorsOfGroup(agp) do - if Size(u) IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; false +# +# Full GL on module needs to be reduced +# +gap> G:=PcGroupCode(1083775118752032412701115313901099867559962870543, +> 11664);; +gap> H:=PcGroupCode(542004979975587406537467217880858737939706807055, +> 11664);; +gap> IsomorphismGroups(G,H); +fail +gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; +false + # # from here on needs 4GB # From 1ab7ddd3a12bf4606d97eaef4a8f0797e1dfe3fe Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Thu, 15 Sep 2016 13:27:02 -0600 Subject: [PATCH 13/35] ENHANCE: AutomorphismWreathembedding only if S_n-normalizer is transitive (to avoid bad blowup) --- lib/morpheus.gi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/morpheus.gi b/lib/morpheus.gi index a266035fb9..eb2ebf7667 100644 --- a/lib/morpheus.gi +++ b/lib/morpheus.gi @@ -156,6 +156,16 @@ local gens, inn,out, nonperm, syno, orb, orbi, perms, free, rep, i, maxl, gen, i:=i+1; od; + if not IsTransitive(syno,MovedPoints(syno)) then + return fail; + # # characteristic product? + # w:=Orbits(syno,MovedPoints(syno)); + # n:=List(w,x->Stabilizer(g,Difference(MovedPoints(g),x),OnTuples)); + # if ForAll(n,x->ForAll(GeneratorsOfGroup(au),y->Image(y,x)=x)) then + # Error("WR5"); + # fi; + fi; + cen:=Centralizer(syno,g); Info(InfoMorph,2,"|syno|=",Size(syno)," |cen|=",Size(cen)); if Size(cen)>1 then From 87adf1abf84291978ba58eb6bfa04925f2aaa01c Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Thu, 15 Sep 2016 14:45:29 -0600 Subject: [PATCH 14/35] ENHANCE: Avoid subspace orbit already being too long. --- lib/grppcaut.gi | 49 ++++++++++++++++++++++++++++++++---- tst/teststandard/grpauto.tst | 22 ++++++++++++++++ 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/lib/grppcaut.gi b/lib/grppcaut.gi index f6dc481421..3a61e001d5 100644 --- a/lib/grppcaut.gi +++ b/lib/grppcaut.gi @@ -896,12 +896,38 @@ end; ## #F AutomorphismGroupSolvableGroup( G ) ## + +# shoul db emore generic -- test whether orbit length exceeds limit +BindGlobal("OrbitIsLonger",function(acts,pnt,act,lim) +local orb,d,gen,i,p,D; + # try to find a domain + D:=DomainForAction(pnt,acts,act); + pnt:=Immutable(pnt); + d:=NewDictionary(pnt,false,D); + orb := [ pnt ]; + AddDictionary(d,pnt); + for p in orb do + for gen in acts do + i:=act(p,gen); + MakeImmutable(i); + if not KnowsDictionary(d,i) then + Add( orb, i ); + if Length(orb)>lim then + return true; + fi; + AddDictionary(d,i); + fi; + od; + od; + return false; +end); + InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) local spec, weights, first, m, pcgsU, F, pcgsF, A, i, s, n, p, H, pcgsH, pcgsN, N, epi, mats, M, autos, ocr, elms, e, list, imgs, auto, tmp, hom, gens, P, C, B, D, pcsA, rels, iso, xset, gensA, new,as,somechar,scharorb,asAutom,autactbase, - quotimg,eN,field; + quotimg,eN,field,act; asAutom:=function(sub,hom) return Image(hom,sub);end; @@ -951,11 +977,24 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) C:=List(C,x->List(SmallGeneratingSet(x), x->ExponentsOfPcElement(FamilyPcgs(F),x)*One(field))); C:=List(C,x->OnSubspacesByCanonicalBasis(x,One(B))); - xset:=Orbit(B,C[1],OnSubspacesByCanonicalBasis); - C:=Filtered(C,x->x in xset); + + if Length(C)=1 and + ForAny(GeneratorsOfGroup(B), + x->ForAny(C[1],y->SolutionMat(C[1],y*x)=fail)) + and OrbitIsLonger(GeneratorsOfGroup(B), + OnSubspacesByCanonicalBasis(C[1],One(B)), + OnSubspacesByCanonicalBasis,Size(F)*2/3) + then + C:=NormedVectors(VectorSpace(field,C[1])); + act:=OnLines; + xset:=Union(Orbits(B,C,act)); + else + act:=OnSubspacesByCanonicalBasis; + xset:=Orbit(B,C[1],act); + C:=Filtered(C,x->x in xset); + fi; if Length(xset)>Length(C) then - hom:=ActionHomomorphism(B,xset,OnSubspacesByCanonicalBasis, - "surjective"); + hom:=ActionHomomorphism(B,xset,act,"surjective"); C:=List(C,x->Position(xset,x)); e:=Size(B); diff --git a/tst/teststandard/grpauto.tst b/tst/teststandard/grpauto.tst index cc93e50157..5c47c89f62 100644 --- a/tst/teststandard/grpauto.tst +++ b/tst/teststandard/grpauto.tst @@ -78,6 +78,28 @@ gap> IsomorphismGroups(G,H); fail gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; false +gap> G:=PcGroupCode(731609193963915469349479836674438288113664000126400, +> 15744);; +gap> H:=PcGroupCode(11518455149767885147152053318976713124993564672000126400, +> 15744);; +gap> IsomorphismGroups(G,H); +fail +gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; +false + +# +# Too hard work for permiso +# +gap> G:=Group((1,3,8,21,37,43,36,35)(2,6,15,30,41,29,19,4)(5,7,18,34,46, +> 32,38,25)(9,23,39,28,27,42,12,14)(10,26,17,20,24,33,13,11)(16,31,45,48, +> 44,47,40,22)(50,53)(51,52)(55,56)(57,58), (1,4,11,28,37,30,20,14) +> (2,3,9,24,41,43,27,10)(5,13,26,31,46,17,33,47)(6,16,32,15,29,44,7,19) +> (8,22,38,21,36,48,18,35)(12,23,40,25,39,42,45,34)(49,51)(50,52)(54,55) +> (56,57),(1,2,5,12,26)(3,7,17,6,14)(4,10,25,35,42)(8,20,9,18,15) +> (11,27,38,19,36)(13,29,28,43,32)(21,23,30,24,34)(33,37,41,46,39) +> (49,50,52,51,53));; +gap> Size(AutomorphismGroup(G)); +2880000 # # from here on needs 4GB From 40d6617c3b843264616f9990ab96a22c98a20b85 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Thu, 22 Sep 2016 13:37:53 -0600 Subject: [PATCH 15/35] ENHANCE: Improved subspace stabilizer in case of full GL. --- lib/grpffmat.gi | 20 ++-- lib/grppcaut.gi | 194 +++++++++++++++++++++++------------ tst/teststandard/grpauto.tst | 9 ++ 3 files changed, 152 insertions(+), 71 deletions(-) diff --git a/lib/grpffmat.gi b/lib/grpffmat.gi index 043a97ce2d..23c11239cb 100644 --- a/lib/grpffmat.gi +++ b/lib/grpffmat.gi @@ -90,8 +90,10 @@ InstallMethod( IsNaturalGL, 0, function( grp ) - return Size( grp ) = Size( GL( DimensionOfMatrixGroup( grp ), - Size( FieldOfMatrixGroup( grp ) ) ) ); + return MTX.IsAbsolutelyIrreducible( + GModuleByMats(GeneratorsOfGroup(grp),DefaultFieldOfMatrixGroup(grp))) and + Size( grp ) = Size( GL( DimensionOfMatrixGroup( grp ), + Size( FieldOfMatrixGroup( grp ) ) ) ); end ); InstallMethod( IsNaturalSL, @@ -101,12 +103,14 @@ InstallMethod( IsNaturalSL, 0, function( grp ) - local gen, d, f; - f := FieldOfMatrixGroup( grp ); - d := DimensionOfMatrixGroup( grp ); - gen := GeneratorsOfGroup( grp ); - return ForAll(gen, x-> DeterminantMat(x) = One(f)) - and Size(grp) = Size(SL(d, Size(f))); +local gen, d, f; + f := FieldOfMatrixGroup( grp ); + d := DimensionOfMatrixGroup( grp ); + gen := GeneratorsOfGroup( grp ); + return MTX.IsAbsolutelyIrreducible( + GModuleByMats(GeneratorsOfGroup(grp),DefaultFieldOfMatrixGroup(grp))) and + ForAll(gen, x-> DeterminantMat(x) = One(f)) + and Size(grp) = Size(SL(d, Size(f))); end ); diff --git a/lib/grppcaut.gi b/lib/grppcaut.gi index 3a61e001d5..950a79c714 100644 --- a/lib/grppcaut.gi +++ b/lib/grppcaut.gi @@ -897,7 +897,7 @@ end; #F AutomorphismGroupSolvableGroup( G ) ## -# shoul db emore generic -- test whether orbit length exceeds limit +# should be more generic -- test whether orbit length exceeds limit BindGlobal("OrbitIsLonger",function(acts,pnt,act,lim) local orb,d,gen,i,p,D; # try to find a domain @@ -922,6 +922,64 @@ local orb,d,gen,i,p,D; return false; end); +# another function that should be more general and has space for improvement. +BindGlobal("SubspaceStabilizerMatrixGroup",function(G,bas) +local f,act,xset,stb,hom,n,m,l,i; + n:=DimensionOfMatrixGroup(G); + if Length(bas)=0 or ForAll(GeneratorsOfGroup(G), + x->ForAll(bas,y->SolutionMat(bas,y*x)<>fail)) then + # space is fixed + return G; + fi; + bas:=OnSubspacesByCanonicalBasis(bas,One(G)); # canonical form + f:=DefaultFieldOfMatrixGroup(G); + if IsNaturalGL(G) then + # write down stabilizer + l:=Length(bas); + act:=BaseSteinitzVectors(IdentityMat(n,f), + bas); + act:=Concatenation(bas,act.factorspace); + stb:=[]; + # subspace + for i in GeneratorsOfGroup(GL(l,f)) do + m:=IdentityMat(n,f); + m{[1..l]}{[1..l]}:=i; + Add(stb,m); + od; + # factor + for i in GeneratorsOfGroup(GL(n-l,f)) do + m:=IdentityMat(n,f); + m{[l+1..n]}{[l+1..n]}:=i; + Add(stb,m); + od; + # mixer + m:=IdentityMat(n,f); + m[l+1][1]:=One(f); + Add(stb,m); + stb:=List(stb,x->x^act); # base change + stb:=Group(stb); + SetSize(stb,Size(GL(l,f))*Size(GL(n-l,f))*Size(f)^(l*(n-l))); + Info(InfoMatOrb,2,"reduced full GL by ",Size(G)/Size(stb)); + return stb; + fi; + if not OrbitIsLonger(GeneratorsOfGroup(G),bas,OnSubspacesByCanonicalBasis, + Size(f)^QuoInt(Length(bas[1]),2)) then + #just plain + act:=OnSubspacesByCanonicalBasis; + xset:=Orbit(G,bas,act); + stb:=[Position(xset,bas)]; + else + act:=OnLines; + stb:=NormedVectors(VectorSpace(f,bas)); + xset:=Union(Orbits(G,stb,act)); + stb:=Set(List(stb,x->Position(xset,x))); + fi; + hom:=ActionHomomorphism(G,xset,act,"surjective"); + act:=PreImage(hom,Stabilizer(Image(hom),stb,OnSets)); + Info(InfoMatOrb,2,"reduce ",Size(G), " to ",Size(act)); + return act; +end); + InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) local spec, weights, first, m, pcgsU, F, pcgsF, A, i, s, n, p, H, pcgsH, pcgsN, N, epi, mats, M, autos, ocr, elms, e, list, imgs, @@ -964,46 +1022,46 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) B := NormalizingReducedGL( spec, 1, first[2], M ); if somechar<>fail then + field:=DefaultFieldOfMatrixGroup(B); C:=List(somechar,x->quotimg(F,FamilyPcgs(F),x)); - C:=List(C,x->[x]); + C:=List(C,x->List(SmallGeneratingSet(x), + x->ExponentsOfPcElement(FamilyPcgs(F),x)*One(field))); + C:=Filtered(C,x->Length(x)>0); + C:=List(C,x->Filtered(OnSubspacesByCanonicalBasis(x,One(B)), + y->not IsZero(y))); + C:=Unique(C); + for D in C do + B:=SubspaceStabilizerMatrixGroup(B,D); + od; if scharorb<>fail then - Append(C,List(scharorb,x->List(x,x->quotimg(F,FamilyPcgs(F),x)))); + C:=List(scharorb,x->List(x,x->quotimg(F,FamilyPcgs(F),x))); + C:=Filtered(C,x->Size(x[1])>1 and Size(x[1])List(SmallGeneratingSet(x), + x->ExponentsOfPcElement(FamilyPcgs(F),x)*One(field))); + C:=List(C,x->OnSubspacesByCanonicalBasis(x,One(B))); + + if Length(C)=1 then + B:=SubspaceStabilizerMatrixGroup(B,C[1]); + else + act:=OnSubspacesByCanonicalBasis; + xset:=Orbit(B,C[1],act); + C:=Filtered(C,x->x in xset); + if Length(xset)>Length(C) then + hom:=ActionHomomorphism(B,xset,act,"surjective"); + C:=List(C,x->Position(xset,x)); + e:=Size(B); + B:=PreImage(hom,Stabilizer(Image(hom),C,OnSets)); + Info(InfoAutGrp,2,"characteristics reduce ",e, + " to ",Size(B)); + fi; + fi; + od; fi; - C:=Filtered(C,x->Size(x[1])>1 and Size(x[1])List(SmallGeneratingSet(x), - x->ExponentsOfPcElement(FamilyPcgs(F),x)*One(field))); - C:=List(C,x->OnSubspacesByCanonicalBasis(x,One(B))); - - if Length(C)=1 and - ForAny(GeneratorsOfGroup(B), - x->ForAny(C[1],y->SolutionMat(C[1],y*x)=fail)) - and OrbitIsLonger(GeneratorsOfGroup(B), - OnSubspacesByCanonicalBasis(C[1],One(B)), - OnSubspacesByCanonicalBasis,Size(F)*2/3) - then - C:=NormedVectors(VectorSpace(field,C[1])); - act:=OnLines; - xset:=Union(Orbits(B,C,act)); - else - act:=OnSubspacesByCanonicalBasis; - xset:=Orbit(B,C[1],act); - C:=Filtered(C,x->x in xset); - fi; - if Length(xset)>Length(C) then - hom:=ActionHomomorphism(B,xset,act,"surjective"); - C:=List(C,x->Position(xset,x)); - - e:=Size(B); - B:=PreImage(hom,Stabilizer(Image(hom),C,OnSets)); - Info(InfoAutGrp,2,"characteristics reduce ",e, - " to ",Size(B)); - fi; - od; fi; + A := AutomorphismGroupElAbGroup( F, B ); SetIsGroupOfAutomorphismsFiniteGroup(A,true); @@ -1049,36 +1107,46 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) B:=SubgroupNC(B,SmallGeneratingSet(B)); if somechar<>fail then + field:=GF(RelativeOrders(pcgsN)[1]); e:=Product(RelativeOrders(pcgsN)); - D:=List(somechar,x->quotimg(H,pcgsH,Intersection(x,eN))); - D:=List(D,x->[x]); - # do something ... - - if scharorb<>fail then - Append(D,List(scharorb, - x->List(x,x->quotimg(H,pcgsH,Intersection(x,eN))))); - fi; + C:=List(somechar,x->quotimg(H,pcgsH,Intersection(x,eN))); - D:=Filtered(D,x->Size(x[1])>1 and Size(x[1])List(SmallGeneratingSet(x), + C:=List(C,x->List(SmallGeneratingSet(x), x->ExponentsOfPcElement(pcgsH,x){[s..n-1]}*One(field))); - C:=List(C,x->OnSubspacesByCanonicalBasis(x,One(B))); - xset:=Orbit(B,C[1],OnSubspacesByCanonicalBasis); - C:=Filtered(C,x->x in xset); - if Length(xset)>Length(C) then - hom:=ActionHomomorphism(B,xset,OnSubspacesByCanonicalBasis, - "surjective"); - C:=List(C,x->Position(xset,x)); - - e:=Size(B); - B:=PreImage(hom,Stabilizer(Image(hom),C,OnSets)); - Info(InfoAutGrp,2,"characteristics reduce ",e, - " to ",Size(B)); - fi; + C:=Filtered(C,x->Length(x)>0); + C:=List(C,x->Filtered(OnSubspacesByCanonicalBasis(x,One(B)), + y->not IsZero(y))); + C:=Unique(C); + for D in C do + B:=SubspaceStabilizerMatrixGroup(B,D); od; + if scharorb<>fail then + C:=List(scharorb, + x->List(x,x->quotimg(H,pcgsH,Intersection(x,eN)))); + C:=Filtered(C,x->Size(x[1])>1 and Size(x[1])List(SmallGeneratingSet(x), + x->ExponentsOfPcElement(pcgsH,x){[s..n-1]}*One(field))); + C:=List(C,x->OnSubspacesByCanonicalBasis(x,One(B))); + + if Length(C)=1 then + B:=SubspaceStabilizerMatrixGroup(B,C[1]); + else + act:=OnSubspacesByCanonicalBasis; + xset:=Orbit(B,C[1],act); + C:=Filtered(C,x->x in xset); + if Length(xset)>Length(C) then + hom:=ActionHomomorphism(B,xset,act,"surjective"); + C:=List(C,x->Position(xset,x)); + e:=Size(B); + B:=PreImage(hom,Stabilizer(Image(hom),C,OnSets)); + Info(InfoAutGrp,2,"characteristics reduce ",e, + " to ",Size(B)); + fi; + fi; + od; + fi; fi; if weights[s][2] = 1 then diff --git a/tst/teststandard/grpauto.tst b/tst/teststandard/grpauto.tst index 5c47c89f62..9c3aa57b1a 100644 --- a/tst/teststandard/grpauto.tst +++ b/tst/teststandard/grpauto.tst @@ -87,6 +87,15 @@ fail gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; false +gap> G:=PcGroupCode(18738408935379049727906755356708168311565445686261463850856, +> 21952);; +gap> H:=PcGroupCode(18738408935359210460657231881739776911013615108923450662760, +> 21952);; +gap> IsomorphismGroups(G,H); +fail +gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; +false + # # Too hard work for permiso # From 59dcc232b9a3abad9b02db85d9e7182aee53b8d4 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Thu, 22 Sep 2016 17:19:22 -0600 Subject: [PATCH 16/35] Moved test example between files. This resolves #899 --- tst/teststandard/grpauto.tst | 46 ++++++++++++++++++++++++++++++++++++ tst/teststandard/grpperm.tst | 45 ----------------------------------- 2 files changed, 46 insertions(+), 45 deletions(-) diff --git a/tst/teststandard/grpauto.tst b/tst/teststandard/grpauto.tst index 9c3aa57b1a..212b4cd84b 100644 --- a/tst/teststandard/grpauto.tst +++ b/tst/teststandard/grpauto.tst @@ -124,6 +124,52 @@ fail gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; false +# permutation example +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 diff --git a/tst/teststandard/grpperm.tst b/tst/teststandard/grpperm.tst index 4c3d6bb452..61aba8818d 100644 --- a/tst/teststandard/grpperm.tst +++ b/tst/teststandard/grpperm.tst @@ -177,51 +177,6 @@ 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 0502106402a9add428cd165575d954d679bde5ce Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Mon, 26 Sep 2016 13:09:14 -0600 Subject: [PATCH 17/35] FIX: Catch base case trivial/trivial in subgroup lattice which does not translate by niceo when called with an automorphism group. --- lib/grplatt.gi | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/grplatt.gi b/lib/grplatt.gi index 537a4c24c6..a275ba5fa1 100644 --- a/lib/grplatt.gi +++ b/lib/grplatt.gi @@ -1091,7 +1091,12 @@ InstallGlobalFunction(LatticeViaRadical,function(arg) if pcgs=false then lmpc:=ModuloPcgs(ser[i-1],nts[j]); - npcgs:=ModuloPcgs(nts[j],ser[i]); + if Size(nts[j])=1 and Size(ser[i])=1 then + # avoid degenerate case + npcgs:=Pcgs(nts[j]); + else + npcgs:=ModuloPcgs(nts[j],ser[i]); + fi; else if IsTrivial(nts[j]) then lmpc:=pcgs[i-1]; From 25a1bd6321ea32ff6874d6710ce8892861177cc6 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Wed, 28 Sep 2016 08:38:13 -0600 Subject: [PATCH 18/35] Trivial group has empty generating set. --- lib/autsr.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/autsr.gi b/lib/autsr.gi index 63e8e1d293..58d93b4f31 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -170,7 +170,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, AQP:=Image(AQiso,AQ); # force degree down a:=Size(AQP); - AQP:=Group(SmallGeneratingSet(AQP)); + AQP:=Group(SmallGeneratingSet(AQP),One(AQP)); SetSize(AQP,a); a:=SmallerDegreePermutationRepresentation(AQP:cheap); if NrMovedPoints(Image(a)) Date: Tue, 4 Oct 2016 21:48:24 -0600 Subject: [PATCH 19/35] ENHANCE: Instead of stabilizing subspaces repeatedly in GL, write down the subgroup of GL that stabilizes all subspaces (and subspace orbits of length 2). Also Added assertion. --- lib/grppcaut.gi | 388 ++++++++++++++++++++++++++++++----- tst/teststandard/grpauto.tst | 15 +- 2 files changed, 354 insertions(+), 49 deletions(-) diff --git a/lib/grppcaut.gi b/lib/grppcaut.gi index 950a79c714..111f88ee39 100644 --- a/lib/grppcaut.gi +++ b/lib/grppcaut.gi @@ -547,10 +547,11 @@ end; ############################################################################# ## -#F NormalizingReducedGL( spec, s, n, M ) +#F NormalizingReducedGL( spec, s, n, M [,B] ) ## -NormalizingReducedGL := function( spec, s, n, M ) - local G, p, d, field, B, U, hom, pcgs, pcs, rels, w, +NormalizingReducedGL := function(arg) +local spec,s,n,M, + G, p, d, field, B, U, hom, pcgs, pcs, rels, w, S, L, f, P, norm, pcgsN, pcgsM, pcgsF, @@ -558,11 +559,21 @@ NormalizingReducedGL := function( spec, s, n, M ) par, done, i, elm, elms, pcgsH, H, tup, pos, perms, V; + spec:=arg[1]; + s:=arg[2]; + n:=arg[3]; + M:=arg[4]; + G := GroupOfPcgs( spec ); d := M.dimension; field := M.field; p := Characteristic( field ); - B := GL( d, p ); + + if Length(arg)>4 then + B:=arg[5]; + else + B := GL( d, p ); + fi; U := SubgroupNC( B, M.generators ); # the trivial case @@ -980,12 +991,199 @@ local f,act,xset,stb,hom,n,m,l,i; return act; end); +# construct subgroup of GL that stabilizes the spaces given and fixes teh +# listed spaceorbits. + +# auxillary +RedmatSpanningIndices:=function(gens) +local bas,n,one,new,a,b,g; + n:=Length(gens[1]); + one:=One(gens[1]); + new:=[]; + bas:=[]; + while Length(bas)Length(bas)=0 or SolutionMat(bas,x)=fail); + Add(new,Position(one,a)); + Add(bas,a); + # spin + for b in bas do + for g in gens do + a:=b*g; + if SolutionMat(bas,a)=fail then + Add(bas,a); + fi; + od; + od; + od; + return new; +end; + +SpaceAndOrbitStabilizer:=function(n,field,spaces,osporb) +local spaceincl,outvecs,l,sub,yet,i,j,k,s,t,new,incl,min,rans,sofar,done, + gens,one,spl,ngens,m,sz,a,sporb; + + spaceincl:=function(big,small) + return RankMat(Concatenation(big,small))=Length(big); + end; + + outvecs:=function(space,new) + return Filtered(new,x->Length(space)=0 or SolutionMat(space,x)=fail); + end; + + one:=IdentityMat(n,field); + sub:=[]; # space so far + spaces:=List(spaces,x->OnSubspacesByCanonicalBasis(x,one)); + SortBy(spaces,Length); + if not ForAny(spaces,x->Length(x)=n) then + Add(spaces,List(one,ShallowCopy)); + fi; + + osporb:=List(osporb,x->List(x,x->OnSubspacesByCanonicalBasis(x,one))); + sporb:=List(osporb,ShallowCopy); + l:=Length(spaces); + + # inclusion relation, tests + repeat + yet:=0; + done:=[0]; + incl:=List([1..l],x->[0,x]); + new:=[]; + for i in [1..l] do + for j in [i+1..l] do + if spaceincl(spaces[j],spaces[i]) then + AddSet(incl,[i,j]); + else + # check for meet/join closed + s:=SumIntersectionMat(spaces[i],spaces[j]); + for k in s do + if Length(k)>0 and not ForAny(spaces,x->Length(x)=Length(k) and + RankMat(Concatenation(x,k))=Length(x)) then + Add(new,k); + fi; + od; + fi; + od; + od; + if Length(new)>0 then + spaces:=Concatenation(spaces,new); + l:=Length(spaces); + SortBy(spaces,Length); + fi; + until Length(new)=0; + + gens:=[]; + sz:=1; + + while Length(sub)[yet,x] in incl and + ForAll(incl,y->y[1] in done or y[2]<>x)); + rans:=[]; + sofar:=ShallowCopy(sub); + for i in min do + Add(done,i); + if spaceincl(sofar,spaces[i]) then + Error("Not yet done! Fixed subspaces force diagonal action"); + fi; + new:=outvecs(sub,spaces[i]); + Add(rans,[Length(sofar)+1..Length(sofar)+Length(new)]); + Append(sofar,new); + od; + + ngens:=[]; + # now go through each space and add a GL (or GL\wr) in that space + for i in [1..Length(min)] do + spl:=[]; + for j in sporb do + s:=List(j,x->SumIntersectionMat(Concatenation(sub,x), + Concatenation(sub,sofar{rans[i]}))[2]); + s:=Filtered(s,x->Length(x)>Length(sub) and Length(x)< + Length(rans[i])+Length(sub)); + if Length(s)>2 then + Error("sporblen>2 not yet done"); + elif Length(s)=2 then + Add(spl,s); + fi; + od; + if Length(spl)>0 then + spl:=spl[1]; # so far only use one... + # new basis vectors + a:=[]; + for j in spl do + Add(a,outvecs(sub,j)); + od; + if Sum(a,Length)<>Length(rans[i]) then Error("badbasis"); fi; + if Length(a[1])<>Length(a[2]) then Error("differentdim!");fi; + sofar{rans[i]}:=Concatenation(a); + + a:=MatWreathProduct(GL(Length(a[1]),field),SymmetricGroup(Length(a))); + else + # make a GL on the space + a:=GL(Length(rans[i]),field); + fi; + + sz:=sz*Size(a); + for k in GeneratorsOfGroup(a) do + m:=List(one,ShallowCopy); + m{rans[i]}{rans[i]}:=k; + Add(ngens,m); + od; + od; + + if yet>0 then + sz:=sz*Size(field)^(Length(sub)*(Length(sofar)-Length(sub))); + # add generators for the bimodule. + rans:=[1..Length(sub)]; + s:=List(gens,x->x{rans}{rans}); + s:=RedmatSpanningIndices(s); + + rans:=[Length(sub)+1..Length(sofar)]; + t:=List(ngens,x->TransposedMat(x{rans}{rans})); + t:=RedmatSpanningIndices(t); + for i in s do + for j in t do + m:=List(one,ShallowCopy); + m[Length(sub)+j][i]:=One(field); + Add(ngens,m); + od; + od; + fi; + + sub:=sofar; + yet:=First([1..l],x->Length(sub)=Length(spaces[x]) and + spaceincl(sub,spaces[x])); + Add(done,yet); + # remove sporb's that are too small + sporb:=Filtered(sporb,x->not ForAll(x,y->spaceincl(sub,y))); + Append(gens,ngens); + od; + + gens:=List(gens,x->x^sub); + a:=Group(gens); + SetSize(a,sz); + if Length(osporb)>1 then + # we only stabilized one pair so far + for i in osporb do + # assumption: orbit is not too long... (i.e. TODO: improve) + m:=Orbit(a,i[1],OnSubspacesByCanonicalBasis); + if Length(m)>Length(i) then + yet:=ActionHomomorphism(a,m,OnSubspacesByCanonicalBasis,"surjective"); + sub:=Stabilizer(Image(yet),Set(List(i,x->Position(m,x))),OnSets); + a:=PreImage(yet,sub); + fi; + od; + fi; + return a; +end; + + + InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) local spec, weights, first, m, pcgsU, F, pcgsF, A, i, s, n, p, H, pcgsH, pcgsN, N, epi, mats, M, autos, ocr, elms, e, list, imgs, auto, tmp, hom, gens, P, C, B, D, pcsA, rels, iso, xset, gensA, new,as,somechar,scharorb,asAutom,autactbase, - quotimg,eN,field,act; + quotimg,eN,field,act,spaces,sporb; asAutom:=function(sub,hom) return Image(hom,sub);end; @@ -1019,10 +1217,13 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) M := rec( field := GF( weights[1][3] ), dimension := first[2]-1, generators := [] ); - B := NormalizingReducedGL( spec, 1, first[2], M ); + + spaces:=[]; + sporb:=[]; if somechar<>fail then - field:=DefaultFieldOfMatrixGroup(B); + field:=M.field; + B:=IdentityMat(M.dimension,field); C:=List(somechar,x->quotimg(F,FamilyPcgs(F),x)); C:=List(C,x->List(SmallGeneratingSet(x), x->ExponentsOfPcElement(FamilyPcgs(F),x)*One(field))); @@ -1030,9 +1231,7 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) C:=List(C,x->Filtered(OnSubspacesByCanonicalBasis(x,One(B)), y->not IsZero(y))); C:=Unique(C); - for D in C do - B:=SubspaceStabilizerMatrixGroup(B,D); - od; + Append(spaces,C); if scharorb<>fail then C:=List(scharorb,x->List(x,x->quotimg(F,FamilyPcgs(F),x))); C:=Filtered(C,x->Size(x[1])>1 and Size(x[1])List(SmallGeneratingSet(x), x->ExponentsOfPcElement(FamilyPcgs(F),x)*One(field))); C:=List(C,x->OnSubspacesByCanonicalBasis(x,One(B))); - - if Length(C)=1 then - B:=SubspaceStabilizerMatrixGroup(B,C[1]); + if Length(C)=1 and + not ForAny(spaces,x->Length(x)=Length(C[1]) and + RankMat(Concatenation(x,C[1]))=Length(C[1])) then + Add(spaces,C[1]); else - act:=OnSubspacesByCanonicalBasis; - xset:=Orbit(B,C[1],act); - C:=Filtered(C,x->x in xset); - if Length(xset)>Length(C) then - hom:=ActionHomomorphism(B,xset,act,"surjective"); - C:=List(C,x->Position(xset,x)); - e:=Size(B); - B:=PreImage(hom,Stabilizer(Image(hom),C,OnSets)); - Info(InfoAutGrp,2,"characteristics reduce ",e, - " to ",Size(B)); - fi; + Add(sporb,C); fi; od; fi; fi; + # fix the spaces first + B:=SpaceAndOrbitStabilizer(M.dimension,M.field,spaces,sporb); + B := NormalizingReducedGL( spec, 1, first[2], M, B ); + + Assert(2, + ForAll(spaces,x->Length(Orbit(B,x,OnSubspacesByCanonicalBasis)=1))); + Assert(2, + ForAll(sporb,x->Length(Orbit(B,x[1],OnSubspacesByCanonicalBasis)=1) + <=Length(x))); + +# not needed any longer -- fixed +# if somechar<>fail then +# field:=DefaultFieldOfMatrixGroup(B); +# C:=List(somechar,x->quotimg(F,FamilyPcgs(F),x)); +# C:=List(C,x->List(SmallGeneratingSet(x), +# x->ExponentsOfPcElement(FamilyPcgs(F),x)*One(field))); +# C:=Filtered(C,x->Length(x)>0); +# C:=List(C,x->Filtered(OnSubspacesByCanonicalBasis(x,One(B)), +# y->not IsZero(y))); +# C:=Unique(C); +# for D in C do +# B:=SubspaceStabilizerMatrixGroup(B,D); +# od; +# if scharorb<>fail then +# C:=List(scharorb,x->List(x,x->quotimg(F,FamilyPcgs(F),x))); +# C:=Filtered(C,x->Size(x[1])>1 and Size(x[1])List(SmallGeneratingSet(x), +# x->ExponentsOfPcElement(FamilyPcgs(F),x)*One(field))); +# C:=List(C,x->OnSubspacesByCanonicalBasis(x,One(B))); +# +# if Length(C)=1 then +# C:=SubspaceStabilizerMatrixGroup(B,C[1]); +# if B<>C then Error("UGH1");fi; +# B:=C; +# else +# act:=OnSubspacesByCanonicalBasis; +# xset:=Orbit(B,C[1],act); +# C:=Filtered(C,x->x in xset); +# if Length(xset)>Length(C) then +# hom:=ActionHomomorphism(B,xset,act,"surjective"); +# C:=List(C,x->Position(xset,x)); +# e:=Size(B); +# C:=Stabilizer(Image(hom),C,OnSets); +# if C<>Image(hom) then Error("UGH!");fi; +# #B:=PreImage(hom,Stabilizer(Image(hom),C,OnSets)); +# Info(InfoAutGrp,2,"characteristics reduce ",e, +# " to ",Size(B)); +# fi; +# fi; +# od; +# fi; +# fi; + A := AutomorphismGroupElAbGroup( F, B ); SetIsGroupOfAutomorphismsFiniteGroup(A,true); @@ -1101,13 +1347,13 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) # compatible / inducible pairs Info( InfoAutGrp, 2,"compute reduced gl "); - B := NormalizingReducedGL( spec, s, n, M ); - # A and B will not be used later, so it is no problem to - # replace them by other groups with fewer generators - B:=SubgroupNC(B,SmallGeneratingSet(B)); + + spaces:=[]; + sporb:=[]; if somechar<>fail then field:=GF(RelativeOrders(pcgsN)[1]); + B:=IdentityMat(M.dimension,field); e:=Product(RelativeOrders(pcgsN)); C:=List(somechar,x->quotimg(H,pcgsH,Intersection(x,eN))); @@ -1117,9 +1363,7 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) C:=List(C,x->Filtered(OnSubspacesByCanonicalBasis(x,One(B)), y->not IsZero(y))); C:=Unique(C); - for D in C do - B:=SubspaceStabilizerMatrixGroup(B,D); - od; + Append(spaces,C); if scharorb<>fail then C:=List(scharorb, x->List(x,x->quotimg(H,pcgsH,Intersection(x,eN)))); @@ -1129,29 +1373,79 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) C:=List(C,x->List(SmallGeneratingSet(x), x->ExponentsOfPcElement(pcgsH,x){[s..n-1]}*One(field))); C:=List(C,x->OnSubspacesByCanonicalBasis(x,One(B))); - - if Length(C)=1 then - B:=SubspaceStabilizerMatrixGroup(B,C[1]); + if Length(C)=1 and + not ForAny(spaces,x->Length(x)=Length(C[1]) and + RankMat(Concatenation(x,C[1]))=Length(C[1])) then + Add(spaces,C[1]); else - act:=OnSubspacesByCanonicalBasis; - xset:=Orbit(B,C[1],act); - C:=Filtered(C,x->x in xset); - if Length(xset)>Length(C) then - hom:=ActionHomomorphism(B,xset,act,"surjective"); - C:=List(C,x->Position(xset,x)); - e:=Size(B); - B:=PreImage(hom,Stabilizer(Image(hom),C,OnSets)); - Info(InfoAutGrp,2,"characteristics reduce ",e, - " to ",Size(B)); - fi; + Add(sporb,C); fi; + od; fi; fi; + # fix the spaces first + B:=SpaceAndOrbitStabilizer(M.dimension,M.field,spaces,sporb); + + B := NormalizingReducedGL( spec, s, n, M,B ); + # A and B will not be used later, so it is no problem to + # replace them by other groups with fewer generators + B:=SubgroupNC(B,SmallGeneratingSet(B)); + + Assert(2, + ForAll(spaces,x->Length(Orbit(B,x,OnSubspacesByCanonicalBasis)=1))); + Assert(2, + ForAll(sporb,x->Length(Orbit(B,x[1],OnSubspacesByCanonicalBasis)=1) + <=Length(x))); + + # not needed any longer +# if somechar<>fail then +# field:=GF(RelativeOrders(pcgsN)[1]); +# e:=Product(RelativeOrders(pcgsN)); +# C:=List(somechar,x->quotimg(H,pcgsH,Intersection(x,eN))); +# +# C:=List(C,x->List(SmallGeneratingSet(x), +# x->ExponentsOfPcElement(pcgsH,x){[s..n-1]}*One(field))); +# C:=Filtered(C,x->Length(x)>0); +# C:=List(C,x->Filtered(OnSubspacesByCanonicalBasis(x,One(B)), +# y->not IsZero(y))); +# C:=Unique(C); +# for D in C do +# B:=SubspaceStabilizerMatrixGroup(B,D); +# od; +# if scharorb<>fail then +# C:=List(scharorb, +# x->List(x,x->quotimg(H,pcgsH,Intersection(x,eN)))); +# C:=Filtered(C,x->Size(x[1])>1 and Size(x[1])List(SmallGeneratingSet(x), +# x->ExponentsOfPcElement(pcgsH,x){[s..n-1]}*One(field))); +# C:=List(C,x->OnSubspacesByCanonicalBasis(x,One(B))); +# +# if Length(C)=1 then +# B:=SubspaceStabilizerMatrixGroup(B,C[1]); +# else +# act:=OnSubspacesByCanonicalBasis; +# xset:=Orbit(B,C[1],act); +# C:=Filtered(C,x->x in xset); +# if Length(xset)>Length(C) then +# hom:=ActionHomomorphism(B,xset,act,"surjective"); +# C:=List(C,x->Position(xset,x)); +# e:=Size(B); +# B:=PreImage(hom,Stabilizer(Image(hom),C,OnSets)); +# Info(InfoAutGrp,2,"characteristics reduce ",e, +# " to ",Size(B)); +# fi; +# fi; +# od; +# fi; +# fi; + if weights[s][2] = 1 then #Info( InfoAutGrp, 2,"compute reduced gl "); - #B := NormalizingReducedGL( spec, s, n, M ); + #B := MormalizingReducedGL( spec, s, n, M ); if HasPcgs(A) and Length(Pcgs(A)) IsomorphismGroups(G,H); fail gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; false + gap> G:=PcGroupCode(731609193963915469349479836674438288113664000126400, > 15744);; gap> H:=PcGroupCode(11518455149767885147152053318976713124993564672000126400, @@ -96,6 +97,15 @@ fail gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; false +gap> G:=PcGroupCode(49879636940338958988550512603242447645113136854728735, +> 15552);; +gap> H:=PcGroupCode(99756065499714436414025572353196660756647930654752799, +> 15552);; +gap> IsomorphismGroups(G,H); +fail +gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; +false + # # Too hard work for permiso # @@ -110,8 +120,6 @@ gap> G:=Group((1,3,8,21,37,43,36,35)(2,6,15,30,41,29,19,4)(5,7,18,34,46, gap> Size(AutomorphismGroup(G)); 2880000 -# -# from here on needs 4GB # # hard-iso4 # @@ -124,6 +132,9 @@ fail gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; false +# +# from here on needs 4GB +# # permutation example 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, From 5b0d93adac55eece4a6d96521884c01dfcd57be5 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Wed, 5 Oct 2016 11:05:28 -0600 Subject: [PATCH 20/35] FIX: Special cases in subspace stabilizer Fix diagonal case and suplicate spaces in subspace stabilizer. Also avoid characteristic options to be accidentally dragged through. --- lib/autsr.gi | 2 + lib/grppcaut.gi | 114 +++++++++++++++++++++++++++--------------------- 2 files changed, 67 insertions(+), 49 deletions(-) diff --git a/lib/autsr.gi b/lib/autsr.gi index 58d93b4f31..6437e81c79 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -760,6 +760,8 @@ local d,a,map,possibly,cG,cH,nG,nH,i,j,sel,u,v,asAutomorphism,K,L,conj,e1,e2, end; # go through factors of characteristic series to keep orbits short. + AutomorphismGroup(G:someCharacteristics:=fail); + AutomorphismGroup(H:someCharacteristics:=fail); cG:=CharacteristicSubgroupsLib(G); nG:=[]; cH:=ShallowCopy(CharacteristicSubgroupsLib(H)); diff --git a/lib/grppcaut.gi b/lib/grppcaut.gi index 111f88ee39..a5d028ace8 100644 --- a/lib/grppcaut.gi +++ b/lib/grppcaut.gi @@ -1020,19 +1020,20 @@ end; SpaceAndOrbitStabilizer:=function(n,field,spaces,osporb) local spaceincl,outvecs,l,sub,yet,i,j,k,s,t,new,incl,min,rans,sofar,done, - gens,one,spl,ngens,m,sz,a,sporb; + gens,one,spl,ngens,m,sz,a,sporb,notyet; spaceincl:=function(big,small) return RankMat(Concatenation(big,small))=Length(big); end; outvecs:=function(space,new) - return Filtered(new,x->Length(space)=0 or SolutionMat(space,x)=fail); + return BaseSteinitzVectors(new,space).factorspace; end; one:=IdentityMat(n,field); sub:=[]; # space so far - spaces:=List(spaces,x->OnSubspacesByCanonicalBasis(x,one)); + spaces:=Unique(List(spaces,x->OnSubspacesByCanonicalBasis(x,one))); + SortBy(spaces,Length); if not ForAny(spaces,x->Length(x)=n) then Add(spaces,List(one,ShallowCopy)); @@ -1065,69 +1066,77 @@ local spaceincl,outvecs,l,sub,yet,i,j,k,s,t,new,incl,min,rans,sofar,done, od; od; if Length(new)>0 then - spaces:=Concatenation(spaces,new); + new:=List(new,x->OnSubspacesByCanonicalBasis(x,one)); # canonize + spaces:=Set(Concatenation(spaces,new)); l:=Length(spaces); SortBy(spaces,Length); fi; until Length(new)=0; + notyet:=[]; gens:=[]; sz:=1; while Length(sub)[yet,x] in incl and - ForAll(incl,y->y[1] in done or y[2]<>x)); + min:=Filtered([1..l],x->[yet,x] in incl); + min:=Filtered(min,x->not ForAny(min,y->[y,x] in incl)); rans:=[]; sofar:=ShallowCopy(sub); for i in min do - Add(done,i); + AddSet(done,i); if spaceincl(sofar,spaces[i]) then - Error("Not yet done! Fixed subspaces force diagonal action"); + # somewhat diagonal -- stabilize later. + Add(notyet,spaces[i]); + Add(rans,fail); + else + new:=outvecs(sub,spaces[i]); + Add(rans,[Length(sofar)+1..Length(sofar)+Length(new)]); + Append(sofar,new); fi; - new:=outvecs(sub,spaces[i]); - Add(rans,[Length(sofar)+1..Length(sofar)+Length(new)]); - Append(sofar,new); od; ngens:=[]; # now go through each space and add a GL (or GL\wr) in that space for i in [1..Length(min)] do - spl:=[]; - for j in sporb do - s:=List(j,x->SumIntersectionMat(Concatenation(sub,x), - Concatenation(sub,sofar{rans[i]}))[2]); - s:=Filtered(s,x->Length(x)>Length(sub) and Length(x)< - Length(rans[i])+Length(sub)); - if Length(s)>2 then - Error("sporblen>2 not yet done"); - elif Length(s)=2 then - Add(spl,s); - fi; - od; - if Length(spl)>0 then - spl:=spl[1]; # so far only use one... - # new basis vectors - a:=[]; - for j in spl do - Add(a,outvecs(sub,j)); + if rans[i]<>fail then + spl:=[]; + for j in sporb do + s:=List(j,x->SumIntersectionMat(Concatenation(sub,x), + Concatenation(sub,sofar{rans[i]}))[2]); + s:=Filtered(s,x->Length(x)>Length(sub) and Length(x)< + Length(rans[i])+Length(sub)); + if Length(s)>2 then + Error("sporblen>2 not yet done"); + elif Length(s)=2 then + Add(spl,s); + fi; od; - if Sum(a,Length)<>Length(rans[i]) then Error("badbasis"); fi; - if Length(a[1])<>Length(a[2]) then Error("differentdim!");fi; - sofar{rans[i]}:=Concatenation(a); + if Length(spl)>0 then + spl:=spl[1]; # so far only use one... + # new basis vectors + a:=[]; + for j in spl do + Add(a,outvecs(sub,j)); + od; + Assert(1,Sum(a,Length)=Length(rans[i])); + Assert(1,Length(a[1])=Length(a[2])); + sofar{rans[i]}:=Concatenation(a); - a:=MatWreathProduct(GL(Length(a[1]),field),SymmetricGroup(Length(a))); - else - # make a GL on the space - a:=GL(Length(rans[i]),field); + a:=MatWreathProduct(GL(Length(a[1]),field),SymmetricGroup(Length(a))); + else + # make a GL on the space + a:=GL(Length(rans[i]),field); + fi; + + sz:=sz*Size(a); + for k in GeneratorsOfGroup(a) do + m:=List(one,ShallowCopy); + m{rans[i]}{rans[i]}:=k; + Add(ngens,m); + od; fi; - sz:=sz*Size(a); - for k in GeneratorsOfGroup(a) do - m:=List(one,ShallowCopy); - m{rans[i]}{rans[i]}:=k; - Add(ngens,m); - od; od; if yet>0 then @@ -1152,7 +1161,11 @@ local spaceincl,outvecs,l,sub,yet,i,j,k,s,t,new,incl,min,rans,sofar,done, sub:=sofar; yet:=First([1..l],x->Length(sub)=Length(spaces[x]) and spaceincl(sub,spaces[x])); - Add(done,yet); + AddSet(done,yet); + # any others that are included? + for i in Filtered([1..l],x->[x,yet] in incl) do + AddSet(done,i); + od; # remove sporb's that are too small sporb:=Filtered(sporb,x->not ForAll(x,y->spaceincl(sub,y))); Append(gens,ngens); @@ -1161,6 +1174,11 @@ local spaceincl,outvecs,l,sub,yet,i,j,k,s,t,new,incl,min,rans,sofar,done, gens:=List(gens,x->x^sub); a:=Group(gens); SetSize(a,sz); + # are there diagonals we did not deal with? + for i in notyet do + a:=Stabilizer(a,i,OnSubspacesByCanonicalBasis); + od; + if Length(osporb)>1 then # we only stabilized one pair so far for i in osporb do @@ -1257,10 +1275,9 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) B := NormalizingReducedGL( spec, 1, first[2], M, B ); Assert(2, - ForAll(spaces,x->Length(Orbit(B,x,OnSubspacesByCanonicalBasis)=1))); + ForAll(spaces,x->Length(Orbit(B,x,OnSubspacesByCanonicalBasis))=1)); Assert(2, - ForAll(sporb,x->Length(Orbit(B,x[1],OnSubspacesByCanonicalBasis)=1) - <=Length(x))); + ForAll(sporb,x->Length(Orbit(B,x[1],OnSubspacesByCanonicalBasis))<=Length(x))); # not needed any longer -- fixed # if somechar<>fail then @@ -1394,10 +1411,9 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) B:=SubgroupNC(B,SmallGeneratingSet(B)); Assert(2, - ForAll(spaces,x->Length(Orbit(B,x,OnSubspacesByCanonicalBasis)=1))); + ForAll(spaces,x->Length(Orbit(B,x,OnSubspacesByCanonicalBasis))=1)); Assert(2, - ForAll(sporb,x->Length(Orbit(B,x[1],OnSubspacesByCanonicalBasis)=1) - <=Length(x))); + ForAll(sporb,x->Length(Orbit(B,x[1],OnSubspacesByCanonicalBasis))<=Length(x))); # not needed any longer # if somechar<>fail then From 63c0548fff65fbbd668a860e76689e3d7bea4830 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Fri, 7 Oct 2016 09:11:54 -0600 Subject: [PATCH 21/35] ENHANCE: Minor omissions: SubgroupByPcgs, StabilizerOp SubgroupByPcgs sets subgroup order. Method for Dtabilizer that allows feeding in fake domain for hash function --- lib/grppc.gi | 1 + lib/oprt.gi | 8 ++++++-- lib/oprtpcgs.gi | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/grppc.gi b/lib/grppc.gi index f45abd454f..c683f76693 100644 --- a/lib/grppc.gi +++ b/lib/grppc.gi @@ -592,6 +592,7 @@ InstallMethod( SubgroupByPcgs, "subgroup with pcgs", function( G, pcgs ) local U; U := SubgroupNC( G, AsList( pcgs ) ); + SetSize(U,Product(RelativeOrders(pcgs))); SetPcgs( U, pcgs ); SetGroupOfPcgs (pcgs, U); # home pcgs will be inherited diff --git a/lib/oprt.gi b/lib/oprt.gi index 4babbd7487..d5e90babb8 100644 --- a/lib/oprt.gi +++ b/lib/oprt.gi @@ -2833,9 +2833,13 @@ InstallGlobalFunction( Stabilizer, function( arg ) fi; end ); -InstallMethod( StabilizerOp, +InstallOtherMethod( StabilizerOp, "`OrbitStabilizerAlgorithm' with domain",true, - OrbitishReq, 0, + [ IsGroup , IsObject, + IsObject, + IsList, + IsList, + IsFunction ], 0, function( G, D, d, gens, acts, act ) local orbstab; diff --git a/lib/oprtpcgs.gi b/lib/oprtpcgs.gi index 4cc9e2946b..be1747efb4 100644 --- a/lib/oprtpcgs.gi +++ b/lib/oprtpcgs.gi @@ -28,6 +28,7 @@ local orb, # orbit depths:=[]; rel := [ ]; for i in Reversed( [ 1 .. Length( pcgs ) ] ) do + Info(InfoAction,3,"Step ",i,": ",Length(orb)); img := act( pnt, acts[ i ] ); MakeImmutable(img); pos := LookupDictionary( d, img ); From edba015dc2d2995074859b02b904318d640c5466 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Fri, 7 Oct 2016 09:16:17 -0600 Subject: [PATCH 22/35] ENHANCE: Improvements to `CompatiblePairs' Ensure that solvable groups do stabilizer with pcgs. If possible, represent module by list of numbers, not list of matrices, using permutation representation of matrix group. --- lib/grppcext.gd | 15 ++++ lib/grppcext.gi | 189 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 165 insertions(+), 39 deletions(-) diff --git a/lib/grppcext.gd b/lib/grppcext.gd index 2c5507ba67..5b9fa89d38 100644 --- a/lib/grppcext.gd +++ b/lib/grppcext.gd @@ -30,6 +30,21 @@ DeclareInfoClass( "InfoExtReps"); ## DeclareGlobalFunction("MappedPcElement"); +############################################################################# +## +#F TracedPointPcElement( , , , ) +## +## +## +## +## +## returns the image of pt under the permutation image of elm when mapping the pcgs pcgs onto list +## homomorphically. +## +## +## +DeclareGlobalFunction("TracedPointPcElement"); + ############################################################################# ## #F ExtensionSQ( , , , ) diff --git a/lib/grppcext.gi b/lib/grppcext.gi index 13a2827996..e39e918183 100644 --- a/lib/grppcext.gi +++ b/lib/grppcext.gi @@ -64,6 +64,25 @@ InstallGlobalFunction(MappedPcElement,function( elm, pcgs, list ) return new; end); +############################################################################# +## +#F TracedPointPcElement( elm, pcgs, imgs,pt ) +## +InstallGlobalFunction(TracedPointPcElement,function( elm, pcgs, list,pt ) +local vec, i,j; + if Length( list ) = 0 then return pt; fi; + vec := ExponentsOfPcElement( pcgs, elm ); + if Length( list ) < Length( vec ) then return fail; fi; + for i in [1..Length(vec)] do + if vec[i]>0 then + for j in [1..vec[i]] do + pt:=pt^list[i]; + od; + fi; + od; + return pt; +end); + ############################################################################# ## #F ExtensionSQ( C, G, M, c ) @@ -510,7 +529,7 @@ local ag, p1iso, agp, p2iso, DP, p1, p2, gens, genimgs, triso,s,i,u,opt; fi; IsGroupOfAutomorphismsFiniteGroup(ag); p1iso:=IsomorphismPermGroup(ag); - agp:=Range(p1iso); + agp:=Image(p1iso); opt:=rec(limit:=s,random:=1); if HasBaseOfGroup(agp) then opt.knownBase:=BaseOfGroup(agp); @@ -519,7 +538,7 @@ local ag, p1iso, agp, p2iso, DP, p1, p2, gens, genimgs, triso,s,i,u,opt; EraseNaturalHomomorphismsPool(agp); if s>1 then repeat - u:=Group(()); + u:=Group(()); gens:=[]; for i in GeneratorsOfGroup(agp) do if Size(u)Image(hom,i)); @@ -585,27 +608,30 @@ local hom, sel, u, gens, i; r.isomorphism:=InverseGeneralMapping(hom)*r.isomorphism; fi; fi; - fi; - # try to reduce nr. of generators - sel:=[]; - u:=TrivialSubgroup(r.permgroup); - gens:=r.permgens; - for i in Reversed([1..Length(gens)]) do - if not gens[i] in u then - u:=ClosureSubgroupNC(u,gens[i]); - Add(sel,i); - fi; - od; - for i in Reversed(sel) do - if Size(r.permgroup)=Size(Difference(sel,[i])) then - RemoveSet(sel,i); + + # try to reduce nr. of generators + sel:=[]; + u:=TrivialSubgroup(r.permgroup); + gens:=r.permgens; + for i in Reversed([1..Length(gens)]) do + if not gens[i] in u then + u:=ClosureSubgroupNC(u,gens[i]); + Add(sel,i); + fi; + od; + for i in Reversed(sel) do + if Size(r.permgroup)=Size(Difference(sel,[i])) then + RemoveSet(sel,i); + fi; + od; + if Length(sel) PreImagesRepresentative( elm[1], x ) ); - #gens := List( gens, x -> MappedPcElement( x, tup[1], tup[2] ) ); - gens := List( Ggens, x -> PreImagesRepresentative( elm[1], x ) ); - gens := List( gens, x -> MappedPcElement( x, Ggens, tup ) ); - gens := List( gens, x -> x ^ elm[2] ); - return gens; - #return Tuple( [tup[1], gens] ); - end; + if Size(G)>20000 then + # if G is too large we cannot write out elements + elmlist:=fail; + f := function( tup, elm ) + local gens; + #gens := List( tup[1], x -> PreImagesRepresentative( elm[1], x ) ); + #gens := List( gens, x -> MappedPcElement( x, tup[1], tup[2] ) ); + gens := List( Ggens, x -> PreImagesRepresentative( elm[1], x ) ); + gens := List( gens, x -> MappedPcElement( x, Ggens, tup ) ); + gens := List( gens, x -> x ^ elm[2] ); + return gens; + #return Tuple( [tup[1], gens] ); + end; + else + + elmlist:=[]; + + tmp:=List(genimgs,x->x[1]); + preimlist:=List(tmp,x->[x,List(Ggens,y->PreImagesRepresentative(x,y))]); + + f:=function( tup, elm ) + local gens,i,p; + p:=PositionProperty(preimlist,x->IsIdenticalObj(x[1],elm[1])); + if p=fail then + gens := List( Ggens, x -> PreImagesRepresentative( elm[1], x ) ); + else + gens:=preimlist[p][2]; + fi; + gens:=List(gens,x->TracedPointPcElement(x,Ggens,elmlist{tup},baspt)); + gens:=List(gens,x->x^elm[2]); + + return gens; + + # tup:=ShallowCopy(tup); # get memory + # avoid duplicate matrices + # for i in [1..Length(gens)] do + # p:=PositionSorted(elmlist,gens[i]); + # if p<>fail and p<=Length(elmlist) and elmlist[p]=gens[i] then + # tup[i]:=p; + # else + # AddSet(elmlist,gens[i]); + # p:=PositionSorted(elmlist,gens[i]); + # tup[i]:=p; + # fi; + # od; + # return tup; + + end; + + fi; # build tails of the pcgs that are closed under automorphisms pcgs:=Pcgs(G); @@ -765,12 +833,57 @@ InstallGlobalFunction( CompatiblePairs, function( arg ) i->ForAll(GeneratorsOfGroup(A),j->Image(j,i) in u)); Ggens:=InducedPcgsByPcSequence(pcgs,pcgs{idx}); tup:=M.generators{idx}; - tmp := Stabilizer( D, tup,gens,genimgs, f ); + + if elmlist<>fail then + tmp:=List(genimgs,x->x[1]); + preimlist:=List(tmp,x->[x,List(Ggens,y->PreImagesRepresentative(x,y))]); + + # ensure wa also account for action + u:=Group(tup); + elmlist:=Elements(u); + tmp:=GeneratorsOfGroup(u); + i:=1; + while i<=Length(tmp) do + for j in genimgs do + if not tmp[i]^j[2] in elmlist then + u:=ClosureGroup(u,tmp[i]^j[2]); + elmlist:=Elements(u); + tmp:=GeneratorsOfGroup(u); + fi; + od; + i:=i+1; + od; + + baspt:=Position(elmlist,One(u)); + # describe how second part acts on matrices by conjugation + newimgs:=List(genimgs,x->[x[1],Permutation(x[2],elmlist,OnPoints)]); + Assert(1,ForAll(newimgs,x->x[2]<>fail)); + + tup:=List(tup,x->Position(elmlist,x)); + elmlist:=List(elmlist,x->Permutation(x,elmlist,OnRight)); + + pows:=NextPrimeInt(Length(elmlist)-20); # we are likely sparse, so + # not being perfect is not likely to do a hash conflict + pows:=List([0..Length(tup)],x->pows^x); + + tmp:=[D, rec(hashfun:= lst->lst*pows),tup, gens,genimgs, f ]; + + # use `op' to get in the fake domain with the hashfun + tmp := StabilizerOp( D, rec(hashfun:= lst->lst*pows),tup, + gens,newimgs, f ); + else + tmp := Stabilizer( D, tup,gens,genimgs, f ); + fi; + Info( InfoMatOrb, 1, " CompP: ",l,"-tail found orbit of length ", Size(D)/Size(tmp)); if Size(tmp)ImageElm(triso,i)); if translate<>false then translate:=rec(pairgens:=genimgs, @@ -786,8 +899,6 @@ InstallGlobalFunction( CompatiblePairs, function( arg ) fi; until l=1; - #tmp := OrbitStabilizer( D, M.generators,gens,genimgs, f ); - if translate<>false then l:=Size(D); if Length(gens)>3 then From fd406fa01dc96ca02d90d88dabb880e2faadf433 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Fri, 7 Oct 2016 13:12:42 -0600 Subject: [PATCH 23/35] ENHANCE: Avoid SpaceAndOrbitStabilizer being overwhelmed by a huge number of spaces -- in this case, if they are different, they will intersect small. FIX: Correct subspace inclusion -- larger space is not necc. triag. --- lib/grppcaut.gi | 50 ++++++++++++++++++++++++++++++------ tst/teststandard/grpauto.tst | 13 ++++++++++ 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/lib/grppcaut.gi b/lib/grppcaut.gi index a5d028ace8..df8f7140e9 100644 --- a/lib/grppcaut.gi +++ b/lib/grppcaut.gi @@ -1018,12 +1018,23 @@ local bas,n,one,new,a,b,g; return new; end; -SpaceAndOrbitStabilizer:=function(n,field,spaces,osporb) +SpaceAndOrbitStabilizer:=function(n,field,ospaces,osporb) local spaceincl,outvecs,l,sub,yet,i,j,k,s,t,new,incl,min,rans,sofar,done, - gens,one,spl,ngens,m,sz,a,sporb,notyet; + gens,one,spl,ngens,m,sz,a,sporb,notyet,canonicalform,doonedim,spaces; + + # move in function to allow global treatment (or replacement) + canonicalform:=function(space) + if Length(space)=0 then + return space; + else + space:=TriangulizedMat(space); + space:=Filtered(space,x->not IsZero(x)); + return space; + fi; + end; spaceincl:=function(big,small) - return RankMat(Concatenation(big,small))=Length(big); + return canonicalform(big)=canonicalform(Concatenation(big,small)); end; outvecs:=function(space,new) @@ -1032,19 +1043,36 @@ local spaceincl,outvecs,l,sub,yet,i,j,k,s,t,new,incl,min,rans,sofar,done, one:=IdentityMat(n,field); sub:=[]; # space so far - spaces:=Unique(List(spaces,x->OnSubspacesByCanonicalBasis(x,one))); + spaces:=Unique(List(ospaces,canonicalform)); SortBy(spaces,Length); if not ForAny(spaces,x->Length(x)=n) then Add(spaces,List(one,ShallowCopy)); fi; - osporb:=List(osporb,x->List(x,x->OnSubspacesByCanonicalBasis(x,one))); + osporb:=List(osporb,x->List(x,canonicalform)); sporb:=List(osporb,ShallowCopy); l:=Length(spaces); # inclusion relation, tests + doonedim:=true; repeat + if doonedim and Number(spaces,x->Length(x)=1)>=n then + yet:=[]; + new:=[]; + i:=1; + while Length(yet)[0,x]); @@ -1056,9 +1084,9 @@ local spaceincl,outvecs,l,sub,yet,i,j,k,s,t,new,incl,min,rans,sofar,done, else # check for meet/join closed s:=SumIntersectionMat(spaces[i],spaces[j]); + s:=List(s,canonicalform); for k in s do - if Length(k)>0 and not ForAny(spaces,x->Length(x)=Length(k) and - RankMat(Concatenation(x,k))=Length(x)) then + if Length(k)>0 and not ForAny(spaces,x->x=k) then Add(new,k); fi; od; @@ -1066,7 +1094,6 @@ local spaceincl,outvecs,l,sub,yet,i,j,k,s,t,new,incl,min,rans,sofar,done, od; od; if Length(new)>0 then - new:=List(new,x->OnSubspacesByCanonicalBasis(x,one)); # canonize spaces:=Set(Concatenation(spaces,new)); l:=Length(spaces); SortBy(spaces,Length); @@ -1179,6 +1206,13 @@ local spaceincl,outvecs,l,sub,yet,i,j,k,s,t,new,incl,min,rans,sofar,done, a:=Stabilizer(a,i,OnSubspacesByCanonicalBasis); od; + # and any we left? + if doonedim=false then + for i in ospaces do + a:=Stabilizer(a,i,OnSubspacesByCanonicalBasis); + od; + fi; + if Length(osporb)>1 then # we only stabilized one pair so far for i in osporb do diff --git a/tst/teststandard/grpauto.tst b/tst/teststandard/grpauto.tst index ae9cc2b859..10c391f754 100644 --- a/tst/teststandard/grpauto.tst +++ b/tst/teststandard/grpauto.tst @@ -41,6 +41,19 @@ fail gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; false +# +# Many Spaces +# + +gap> G:=PcGroupCode(338681823291028181778801710348121147721184790127576437, +> 29160);; +gap> H:=PcGroupCode(338681822494525443798297952136327929199594863010776437, +> 29160);; +gap> IsomorphismGroups(G,H); +fail +gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; +false + # # hard-iso3 # From b6d8e4125c232ec065abfd927ac9d8ac5bb1ca9e Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Mon, 10 Oct 2016 10:43:21 -0600 Subject: [PATCH 24/35] ENHANCE: Better method for CharacteristicSubgroupsLib for solvable. --- lib/grplatt.gi | 2 +- lib/grppclat.gi | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/grplatt.gi b/lib/grplatt.gi index a275ba5fa1..4acbbb1ca9 100644 --- a/lib/grplatt.gi +++ b/lib/grplatt.gi @@ -2326,7 +2326,7 @@ 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", +InstallMethod(IntermediateSubgroups,"using maximal subgroups", IsIdenticalObj, [IsGroup,IsGroup], 1, # better than previous if index larger function(G,U) diff --git a/lib/grppclat.gi b/lib/grppclat.gi index 46e75ee859..41b34abffc 100644 --- a/lib/grppclat.gi +++ b/lib/grppclat.gi @@ -1193,6 +1193,19 @@ Assert(1,ForAll(bs,i->ForAll(efunc,j->Image(j,i)=i))); end); +############################################################################# +## +#M CharacteristicSubgroupsLib( ) +## +InstallMethod(CharacteristicSubgroupsLib,"solvable, automorphisms",true, + [IsGroup and IsSolvableGroup],0, +function(G) +local A,s; + A:=AutomorphismGroup(G); + s:=SubgroupsSolvableGroup(G,rec(normal:=true,actions:=GeneratorsOfGroup(A))); + return Filtered(s,x->IsCharacteristicSubgroup(G,x)); +end); + ############################################################################# ## #M LatticeSubgroups() . . . . . . . . . . lattice of subgroups From 14535f24f1c3214a6a6e020f7c5411b3884846dc Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Mon, 10 Oct 2016 11:21:47 -0600 Subject: [PATCH 25/35] ENHANCE: Pc automorphisms prepare better for CompatiblePairs Ensure that many tails of the pcgs of a factor group correspond to characteristic subgroups. This way `CompatiblePairs` can reduce the orbit calculation into smaller steps. --- lib/grppcaut.gi | 48 +++++++++++++++++++++++++++++++++++++++++++++--- lib/grppcext.gi | 3 ++- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/lib/grppcaut.gi b/lib/grppcaut.gi index df8f7140e9..76595bf4ee 100644 --- a/lib/grppcaut.gi +++ b/lib/grppcaut.gi @@ -1228,14 +1228,42 @@ local spaceincl,outvecs,l,sub,yet,i,j,k,s,t,new,incl,min,rans,sofar,done, return a; end; - +PcgsCharacteristicTails:=function(G,aut) +local gens,ser,new,pcgs,f,mo,i,j,k,s; + gens:=GeneratorsOfGroup(aut); + ser:=InvariantElementaryAbelianSeries(G,gens); + new:=[G]; + for i in [2..Length(ser)] do + pcgs:=ModuloPcgs(ser[i-1],ser[i]); + f:=GF(RelativeOrders(pcgs)[1]); + mo:=List(gens,x->List(pcgs,y->ExponentsOfPcElement(pcgs,y^x))*One(f)); + mo:=GModuleByMats(mo,f); + for j in + Reversed(Filtered(MTX.BasesCompositionSeries(mo), + x->Length(x)10^10 then + # translate to different pcgs to make tails A-invariant + npcgs:=PcgsCharacteristicTails(F,A); + C:=GroupWithGenerators(npcgs); + SetPcgs(C,npcgs); + Assert(1,Pcgs(C)=npcgs); # ensure no magic took place + as:=GroupHomomorphismByImagesNC(F,Group(M.generators), + Pcgs(F),M.generators); + nM:=rec(field:=M.field,dimension:=M.dimension, + generators:=List(npcgs,x->ImagesRepresentative(as,x))); + C:=CompatiblePairs(C,nM,D); + else + C := CompatiblePairs( F, M, D ); + fi; else #Info( InfoAutGrp, 2,"compute reduced gl "); #B := MormalizingReducedGL( spec, s, n, M ); diff --git a/lib/grppcext.gi b/lib/grppcext.gi index e39e918183..c20ced0a96 100644 --- a/lib/grppcext.gi +++ b/lib/grppcext.gi @@ -831,6 +831,7 @@ local G, M, Mgrp, oper, A, B, D, translate, gens, genimgs, triso, K, K1, u:=SubgroupNC(G,pcgs{idx}); until ForAll(GeneratorsOfGroup(u), i->ForAll(GeneratorsOfGroup(A),j->Image(j,i) in u)); + Ggens:=InducedPcgsByPcSequence(pcgs,pcgs{idx}); tup:=M.generators{idx}; @@ -866,7 +867,7 @@ local G, M, Mgrp, oper, A, B, D, translate, gens, genimgs, triso, K, K1, # not being perfect is not likely to do a hash conflict pows:=List([0..Length(tup)],x->pows^x); - tmp:=[D, rec(hashfun:= lst->lst*pows),tup, gens,genimgs, f ]; + tmp:=[D, rec(hashfun:= lst->lst*pows),tup, gens,newimgs, f ]; # use `op' to get in the fake domain with the hashfun tmp := StabilizerOp( D, rec(hashfun:= lst->lst*pows),tup, From b58b29d21e8db6a4223d0d1b514af1b0663c331f Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Mon, 10 Oct 2016 11:34:53 -0600 Subject: [PATCH 26/35] Another nasty long orbit example --- tst/teststandard/grpauto.tst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tst/teststandard/grpauto.tst b/tst/teststandard/grpauto.tst index 10c391f754..03e3dec168 100644 --- a/tst/teststandard/grpauto.tst +++ b/tst/teststandard/grpauto.tst @@ -119,6 +119,15 @@ fail gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; false +gap> G:=PcGroupCode(332848340429713177703937106393386549730621978799427644\ +> 9522931868718664965834145193694164732290560710717, 15552);; +H:=PcGroupCode(66567520563199644616783412765969002195501090553565952956323\ +> 68577721969603293838088502897313780378654781, 15552);; +gap> IsomorphismGroups(G,H); +fail +gap> IsomorphismGroups(G,PcGroupCode(CodePcGroup(G),Size(G)))=fail; +false + # # Too hard work for permiso # From ab387629bef7e0f4f1b2be75bce7fad9029ba68e Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Mon, 17 Oct 2016 19:21:29 -0600 Subject: [PATCH 27/35] FIX: Make DirectProductElements --- lib/grppcext.gi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/grppcext.gi b/lib/grppcext.gi index c20ced0a96..66f3dc61d9 100644 --- a/lib/grppcext.gi +++ b/lib/grppcext.gi @@ -857,7 +857,8 @@ local G, M, Mgrp, oper, A, B, D, translate, gens, genimgs, triso, K, K1, baspt:=Position(elmlist,One(u)); # describe how second part acts on matrices by conjugation - newimgs:=List(genimgs,x->[x[1],Permutation(x[2],elmlist,OnPoints)]); + newimgs:=List(genimgs, + x->DirectProductElement([x[1],Permutation(x[2],elmlist,OnPoints)])); Assert(1,ForAll(newimgs,x->x[2]<>fail)); tup:=List(tup,x->Position(elmlist,x)); From a8dc14829cac82e35874c6acdc3a621b230a0fbd Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Wed, 19 Oct 2016 13:32:59 -0600 Subject: [PATCH 28/35] Changed heuristic for factor group representation to be less gung-ho on intersections, if there are lots. --- lib/factgrp.gi | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/lib/factgrp.gi b/lib/factgrp.gi index fff63a09c5..03e9be7f50 100644 --- a/lib/factgrp.gi +++ b/lib/factgrp.gi @@ -314,10 +314,32 @@ local G,pool,p,comb,i,c,perm,l,isi,N,discard,ab; if Length(arg)>1 then N:=arg[2]; p:=Filtered(p,i->IsSubset(pool.ker[i],N)); + if Length(p)=0 then + return; + fi; + SortParallel(List(pool.ker{p},Size),p); + if Size(pool.ker[p[1]])=Size(N) and Length(p)>3 then + # N in pool + c:=pool.cost[p[1]]; + p:=Filtered(p,x->pool.cost[x]not ForAny([1..x-1],y->IsSubset(pool.ker[p[x]],pool.ker[p[y]]))); + c:=p{c}; + if Size(Intersection(pool.ker{c}))>Size(N) then + # cannot reach N + return; + elif Length(p)>20 or Size(N)=1 then + p:=c; # use only minimal ones if there is lots + fi; + + #if Length(p)>20 then Error("hier!");fi; + # do the abelians extra. p:=Filtered(p,x->not HasAbelianFactorGroup(G,pool.ker[x])); From 0425a6c132aa942ec453489ad566322c10526ddc Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Sun, 23 Oct 2016 08:49:11 -0600 Subject: [PATCH 29/35] Do not change pcgs if action on pc group is tiny. --- lib/grppcaut.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/grppcaut.gi b/lib/grppcaut.gi index 76595bf4ee..3e42869ca8 100644 --- a/lib/grppcaut.gi +++ b/lib/grppcaut.gi @@ -1539,7 +1539,7 @@ InstallGlobalFunction(AutomorphismGroupSolvableGroup,function( G ) Size(A), " x ",Size(B),", ", Length(GeneratorsOfGroup(D))," generators"); - if Size(D)>10^10 then + if Size(D)>10^10 and Size(A)>4 then # translate to different pcgs to make tails A-invariant npcgs:=PcgsCharacteristicTails(F,A); C:=GroupWithGenerators(npcgs); From 7fa4210a5caa42cd68a2f9afc2600095e0e23d84 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Sun, 23 Oct 2016 10:17:17 -0600 Subject: [PATCH 30/35] ENHANCE: Improvements to factor permutation code Allow degree up to 100000 (computers are bigger now) before hard Use maximal subgroups in trying perm rep. (Do not use maxsub in factor if called from maxsub) FIX: another recursion avoidance. --- lib/factgrp.gi | 17 ++++++++++++++--- lib/maxsub.gi | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/factgrp.gi b/lib/factgrp.gi index 03e9be7f50..b2b635cf11 100644 --- a/lib/factgrp.gi +++ b/lib/factgrp.gi @@ -545,7 +545,7 @@ end); BADINDEX:=1000; # the index that is too big GenericFindActionKernel:=function(arg) local G, N, knowi, goodi, simple, uc, zen, cnt, pool, ise, v, bv, badi, -totalcnt, interupt, u, nu, cor, zzz,bigperm,perm,badcores; +totalcnt, interupt, u, nu, cor, zzz,bigperm,perm,badcores,max,i; G:=arg[1]; N:=arg[2]; @@ -657,7 +657,7 @@ totalcnt, interupt, u, nu, cor, zzz,bigperm,perm,badcores; fi; totalcnt:=totalcnt+1; if KnownNaturalHomomorphismsPool(G,N) and - Minimum(Index(G,v),knowi)<20000 + Minimum(Index(G,v),knowi)<100000 and 5*totalcnt>Minimum(Index(G,v),knowi,1000) then # interupt if we're already quite good interupt:=true; @@ -695,7 +695,7 @@ totalcnt, interupt, u, nu, cor, zzz,bigperm,perm,badcores; if Size(cor)>Size(N) and IsSubset(cor,N) and not cor in badcores then Add(badcores,cor); fi; - # store known information(we do't act, just store the subgroup. + # store known information(we do't act, just store the subgroup). # Thus this is fairly cheap pool.dotriv:=true; zzz:=AddNaturalHomomorphismsPool(G,cor,u,Index(G,u)); @@ -708,6 +708,17 @@ totalcnt, interupt, u, nu, cor, zzz,bigperm,perm,badcores; zzz:=DegreeNaturalHomomorphismsPool(G,N); Info(InfoFactor,3," ext ",cnt,": ",Index(G,u)," best degree:",zzz); + if Size(cor)>Size(N) and Index(G,u)*2IndexNC(G,x) Date: Tue, 25 Oct 2016 19:32:10 -0600 Subject: [PATCH 31/35] ENHANCE: In PcSeries do not induce if the pcgs is being built There are two different situations in which PcSeries is called. The first is a good pcgs and we happen to want the series -- this is the existing code. The second case is that the series is needed to do anything with the pcgs. In this case inducing caused bad recursions. Avoid this. --- lib/pcgscomp.gi | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/pcgscomp.gi b/lib/pcgscomp.gi index 940bb91148..dcd3e3982e 100644 --- a/lib/pcgscomp.gi +++ b/lib/pcgscomp.gi @@ -192,7 +192,7 @@ end ); ## InstallMethod( PcSeries,"construct subgroups", true, [ IsPcgs ], 0, function( pcgs ) - local grp, series, i; +local grp, series, i,hasro; # construct the group generated by #T 1996/10/01 fceller something seems to break for Difference or Set @@ -200,12 +200,20 @@ function( pcgs ) #T seems to work now, 1998/12/09 sam grp := GroupOfPcgs(pcgs); + hasro:=HasRelativeOrders(pcgs); # construct the series series := [ grp ]; for i in [ 2 .. Length(pcgs)+1 ] do + if hasro then + # pcgs is all in place -- use induced pcgs for generators to build + # series after pcgs is at work Add( series, SubgroupByPcgs( grp, InducedPcgsByPcSequenceNC(pcgs,pcgs{[ i .. Length(pcgs) ]} ) )); + else + # pcgs is being built. Don't induce, but just use subgroup. + Add( series, SubgroupNC( grp, pcgs{[ i .. Length(pcgs) ]} ) ); + fi; od; return series; From 87e4e18974d86a6c130fcc7d0b9c49b82e2f1414 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Tue, 1 Nov 2016 09:54:08 -0600 Subject: [PATCH 32/35] FIX: ClosurePermGroup long run In some situations, it seems that ClosurePermGroup can iterate very long time with evrification failing repeatedly. In this situation we now simply force a new stabilizer chain computation from scratch, than trying to bend the (apparently confused) chain in the right way. This is not a beautiful fix but a workaround, albeit one that should have litlle cost implications. --- lib/stbcrand.gi | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/stbcrand.gi b/lib/stbcrand.gi index 32f183bfd5..0d41e28785 100644 --- a/lib/stbcrand.gi +++ b/lib/stbcrand.gi @@ -1525,6 +1525,7 @@ InstallGlobalFunction( ClosureRandomPermGroup, missing, # if a correct base was provided by input, missing # contains those points of it which are not in # constructed base + cnt, # iteration counter correct; # boolean; true if a correct base is given # warning: options.base should be compatible with BaseOfGroup(G) @@ -1647,6 +1648,7 @@ InstallGlobalFunction( ClosureRandomPermGroup, fi; od; + cnt:=0; ready := false; while not ready do if IsBound(options.limit) @@ -1668,6 +1670,15 @@ InstallGlobalFunction( ClosureRandomPermGroup, elif options.random = 1000 then G.restored := SCRRestoredRecord(G); result := VerifySGS( G.restored, missing, correct ); + cnt:=cnt+1; + if cnt>99 then + # in rare cases this loop iterates for a very long time. + # In this case, rather create a new chain, than try to + # fix the problematic one + #Error("infinite loop?"); + return StabChainRandomPermGroup(G.generators,G.identity, + options); + fi; elif options.random > 0 then result := SCRStrongGenTest (G,param,orbits,basesize,base,correct,missing); @@ -1695,6 +1706,7 @@ InstallGlobalFunction( ClosureRandomPermGroup, Unbind(G.restored); SCRMakeStabStrong (G,new,param,orbits, where,basesize,base,correct,missing,true); + #Print("D ",SizeStabChain(G),"\n"); fi; fi; od; From ed9e1716e4c0db638331e222102d8b1bdd9e17dd Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Sat, 5 Nov 2016 15:16:00 +0530 Subject: [PATCH 33/35] ENHANCE: If radical is elementary abelian, use subspace stabilizer code. ENHANCE: Declare `SpaceAndOrbitStabilizer' --- lib/autsr.gi | 41 ++++++++++++++++++++++++++++------------- lib/grppcaut.gd | 3 +++ lib/grppcaut.gi | 4 ++-- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/lib/autsr.gi b/lib/autsr.gi index 6437e81c79..a9b4a71cca 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -597,19 +597,34 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, then if rada=fail then - 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,asAutom); - fi; - od; - # move back to bad degree - rada:=Group(List(GeneratorsOfGroup(rada), - x-> InducedAutomorphism(InverseGeneralMapping(ind),x))); + if IsElementaryAbelian(r) and Size(r)>1 then + B:=Pcgs(r); + rf:=GF(RelativeOrders(B)[1]); + ind:=Filtered(ser,x->IsSubset(r,x) and Size(x)>1 and Size(x)List(GeneratorsOfGroup(x),y->ExponentsOfPcElement(B,y))); + ind:=List(ind,x->x*One(rf)); + ind:=SpaceAndOrbitStabilizer(Length(B),rf,ind,[]); + rada:=List(GeneratorsOfGroup(ind),x-> + GroupHomomorphismByImagesNC(r,r,B,List(x,y->PcElementByExponents(B,List(y,Int))))); + rada:=Group(rada); + SetIsGroupOfAutomorphismsFiniteGroup(rada,true); + NiceMonomorphism(rada:autactbase:=fail,someCharacteristics:=fail); + else + 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,asAutom); + fi; + od; + # move back to bad degree + rada:=Group(List(GeneratorsOfGroup(rada), + x-> InducedAutomorphism(InverseGeneralMapping(ind),x))); + + fi; fi; rf:=Image(hom,r); diff --git a/lib/grppcaut.gd b/lib/grppcaut.gd index 9129fb20cb..ba7f64d34b 100644 --- a/lib/grppcaut.gd +++ b/lib/grppcaut.gd @@ -7,12 +7,15 @@ #Y Copyright (C) 2002 The GAP Group ## +DeclareGlobalFunction("SpaceAndOrbitStabilizer"); + ############################################################################# ## #P IsFrattiniFree ## DeclareProperty( "IsFrattiniFree", IsGroup ); + DeclareGlobalFunction("AutomorphismGroupNilpotentGroup"); DeclareGlobalFunction("AutomorphismGroupSolvableGroup"); DeclareGlobalFunction("AutomorphismGroupFrattFreeGroup"); diff --git a/lib/grppcaut.gi b/lib/grppcaut.gi index 3e42869ca8..c85068e225 100644 --- a/lib/grppcaut.gi +++ b/lib/grppcaut.gi @@ -1018,7 +1018,7 @@ local bas,n,one,new,a,b,g; return new; end; -SpaceAndOrbitStabilizer:=function(n,field,ospaces,osporb) +InstallGlobalFunction(SpaceAndOrbitStabilizer,function(n,field,ospaces,osporb) local spaceincl,outvecs,l,sub,yet,i,j,k,s,t,new,incl,min,rans,sofar,done, gens,one,spl,ngens,m,sz,a,sporb,notyet,canonicalform,doonedim,spaces; @@ -1226,7 +1226,7 @@ local spaceincl,outvecs,l,sub,yet,i,j,k,s,t,new,incl,min,rans,sofar,done, od; fi; return a; -end; +end); PcgsCharacteristicTails:=function(G,aut) local gens,ser,new,pcgs,f,mo,i,j,k,s; From 2f913f79d41e0f9f53a2f37cf16484ca1e9934c4 Mon Sep 17 00:00:00 2001 From: Alexander Hulpke Date: Tue, 8 Nov 2016 21:41:26 +0530 Subject: [PATCH 34/35] ENHANCE: Inherit radical/factor and frattini information for factor group. Relax threshold for new permrep force. FIX: Change reading order to avoid forward declaration Also ensure a maximal subgroups computation for smaller permutation degree stays out of expensive operations. --- lib/autsr.gi | 56 +++++++++++++++++++++++++++++++++++++++----------- lib/factgrp.gi | 2 +- lib/read5.g | 12 +++++------ 3 files changed, 51 insertions(+), 19 deletions(-) diff --git a/lib/autsr.gi b/lib/autsr.gi index a9b4a71cca..343fe95219 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -149,7 +149,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, 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, - scharorb,asAutom,jorb,jorpo,substb; + scharorb,asAutom,jorb,jorpo,substb,isBadPermrep,ma; + + # criterion for when to force degree reduction + isBadPermrep:=function(g) + return NrMovedPoints(g)^2>Size(g)*Index(g,DerivedSubgroup(g)); + end; asAutom:=function(sub,hom) return Image(hom,sub);end; @@ -172,18 +177,21 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs, a:=Size(AQP); AQP:=Group(SmallGeneratingSet(AQP),One(AQP)); SetSize(AQP,a); - a:=SmallerDegreePermutationRepresentation(AQP:cheap); - if NrMovedPoints(Image(a))",NrMovedPoints(Image(a))); - AQiso:=AQiso*a; - 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)); + if isBadPermrep(AQP) then + a:=SmallerDegreePermutationRepresentation(AQP:cheap); + if NrMovedPoints(Image(a))",NrMovedPoints(Image(a))); + AQiso:=AQiso*a; + 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; - AQP:=b; fi; + end; stablim:=function(gp,cond,lim) @@ -313,6 +321,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, Q:=Image(hom,G); fi; + ma:=MaximalSubgroupClassesSol(G); + AQ:=AutomorphismGroupFittingFree(Q:someCharacteristics:=fail); AQI:=InnerAutomorphismsAutomorphismGroup(AQ); lastperm:=fail; @@ -329,19 +339,41 @@ 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:=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 + if Size(N)>1 and isBadPermrep(Q) then + #if NrMovedPoints(Q)>15000 then Error("egad!");fi; q:=SmallerDegreePermutationRepresentation(Q); Info(InfoMorph,3,"reduced permrep Q ",NrMovedPoints(Q)," -> ", NrMovedPoints(Range(q))); hom:=hom*q; Q:=Image(hom,G); fi; + + # inherit radical factor map + q:=GroupHomomorphismByImagesNC(Q,Range(ff.factorhom), + List(GeneratorsOfGroup(G),x->ImagesRepresentative(hom,x)), + List(GeneratorsOfGroup(G),x->ImagesRepresentative(ff.factorhom,x))); + b:=Image(hom,ff.radical); + SetRadicalGroup(Q,b); + AddNaturalHomomorphismsPool(Q,b,q); + + # Use known maximals for Frattini + for j in ma do + D:=Image(hom,j); + if not IsSubset(D,b) then + b:=Core(Q,NormalIntersection(b,D)); + fi; + od; + SetIsNilpotentGroup(b,true); + SetFrattiniSubgroup(Q,b); + + # M-factor 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); diff --git a/lib/factgrp.gi b/lib/factgrp.gi index b2b635cf11..fca5f2c077 100644 --- a/lib/factgrp.gi +++ b/lib/factgrp.gi @@ -710,7 +710,7 @@ totalcnt, interupt, u, nu, cor, zzz,bigperm,perm,badcores,max,i; Info(InfoFactor,3," ext ",cnt,": ",Index(G,u)," best degree:",zzz); if Size(cor)>Size(N) and Index(G,u)*2IndexNC(G,x) Date: Tue, 15 Nov 2016 11:04:53 +0100 Subject: [PATCH 35/35] FIX: ShallowCopy immutable orbit. --- lib/autsr.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/autsr.gi b/lib/autsr.gi index 343fe95219..b238ab5838 100644 --- a/lib/autsr.gi +++ b/lib/autsr.gi @@ -729,7 +729,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, for j in u do if IsList(j) then # stabilizer set of subgroups - jorb:=Orbit(AQP,j[1],C[2],C[1],asAutom); + jorb:=ShallowCopy(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));