GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#(C) Graham ellis, 2005-2006 ##################################################################### InstallGlobalFunction(EvaluateProperty, function(X,name) local x; if not "properties" in NamesOfComponents(X) then return fail; fi; x:=First(X!.properties,v->v[1]=name); if x=fail then return fail; else return x[2]; fi; end); ##################################################################### ##################################################################### InstallGlobalFunction(EvenSubgroup, function(G) local x,y,gens; gens:=[]; for x in GeneratorsOfGroup(G) do for y in GeneratorsOfGroup(G) do Append(gens,[x*y]); od; od; return Group(gens); end); ##################################################################### ##################################################################### InstallGlobalFunction(ReduceGenerators, function(gens,G) #I should probably use the #Frattini subgroup! local x,newgens; for x in gens do newgens:=DifferenceLists(gens, [x]); #if Order(Group(Concatenation(newgens,[Identity(G)])))=Order(G) then if Group(Concatenation(newgens,[Identity(G)]))=G then return ReduceGenerators(newgens,G); fi; od; return SSortedList(gens); end); ##################################################################### ##################################################################### InstallGlobalFunction(ReduceGenerators_alt, function(gens,G) local x,newgens; newgens:=[gens[1]]; for x in gens do if not x in Group(newgens) then Add(newgens,x); fi; if Order(Group(newgens))=Order(G) then break; fi; od; return newgens; end); ##################################################################### ##################################################################### InstallGlobalFunction(AbelianInvariantsToTorsionCoefficients, function(L) local primes, invariants,max,coeffs,i,x; primes:=SSortedList(Factors(Product(L))); invariants:=[]; for i in [1..Length(primes)] do invariants[i]:=Filtered(L,x->(primes[i] in Factors(x))); od; max:=Maximum(List(invariants,x->Length(x))); for x in invariants do while Length(x)<max do Append(x,[1]); od; od; coeffs:=[]; for i in [1..max] do coeffs[i]:= Product(List([1..Length(primes)],j->invariants[j][i])); od; return coeffs; end); ##################################################################### ##################################################################### InstallGlobalFunction(TorsionGeneratorsAbelianGroup, function(G) local L,L1,gens,x,y; L:=IndependentGeneratorsOfAbelianGroup(G); L1:=SSortedList(StructuralCopy(L)); gens:=[]; while Length(L1)>0 do x:=L1[1]; RemoveSet(L1,x); for y in L1 do if Gcd(Order(x),Order(y))=1 then x:=x*y; RemoveSet(L1,y); fi; od; Append(gens,[x]); od; return gens; end); ##################################################################### ##################################################################### InstallGlobalFunction(BigStepLCS, function(G,n) local LCS,BSLCS,i; LCS:=LowerCentralSeries(G);; BSLCS:=[LCS[1]]; for i in [2..Length(LCS)] do if Order(LCS[i])=1 or Order(BSLCS[Length(BSLCS)])/Order(LCS[i])>n then Append(BSLCS,[LCS[i]]); fi; od; return BSLCS; end); ##################################################################### ##################################################################### InstallGlobalFunction(CoClass, function(G) local facs; facs:=SSortedList(Factors(Order(G))); if Length(facs)>1 then Print("G should be a prime-power group. \n"); return fail; fi; return LogInt(Order(G),facs[1])-NilpotencyClassOfGroup(G); end); ##################################################################### ##################################################################### InstallGlobalFunction(BoundaryMatrix, function(C,n) local M,i,j; M:=[]; for i in [1..C!.dimension(n)] do M[i]:=C!.boundary(n,i); od; return TransposedMat(M); end); #################################################################### ##################################################################### InstallGlobalFunction(PrankAlt, function(G) local H,S,x, p; p:=SSortedList(Factors(Order(G))); if not Length(p)=1 then Print("G must be a finite p-group. \n"); return fail; fi; H:=[]; for x in G do if Order(x)=p then Add(H,x); fi; od; H:=Group(H); p:=p[1]; S:=LatticeSubgroups(H); S:=ConjugacyClassesSubgroups(S); S:=List(S,x->ClassElementLattice(x,1)); S:=Filtered(S,x->IsElementaryAbelian(x)); S:=List(S,x->Order(x)); return Log(Maximum(S),p); end); #################################################################### ##################################################################### InstallGlobalFunction(Prank, function(G) local pPowers, xP, x,y, p, AbSubGrps, AbSubGrps1, AbSubGrps2, S, Sx, A, N, N1, reps, toggle; ########################################################### p:=SSortedList(Factors(Order(G))); if not Length(p)=1 then Print("G must be a finite p-group. \n"); return fail; fi; ########################################################### p:=PrimePGroup(G); ########################################################### if IsAbelian(G) then return Length(AbelianInvariants(G)); fi; ########################################################### pPowers:=[]; xP:=[]; AbSubGrps:=[]; AbSubGrps1:=[GeneratorsOfGroup(Center(G))]; AbSubGrps2:=[]; reps:=[Center(G)]; xP:=Concatenation(List(reps,x->Elements(x))); xP:=SSortedList(xP); for x in G do if Order(x)=p and not (x in xP) then Add(pPowers,x); Append(xP,Elements(Group(x))); fi; od; toggle:=true; while toggle do toggle:=false; for S in AbSubGrps1 do for x in pPowers do if not x in Group(S) then Sx:=Concatenation(S,[x]); A:=Group(Sx); if IsAbelian(A) and not (A in reps) then Add(AbSubGrps2,Sx); AddSet(reps,A); toggle:=true; fi; fi; od; od; Append(AbSubGrps,AbSubGrps1); AbSubGrps1:=AbSubGrps2; AbSubGrps2:=[]; od; Apply(AbSubGrps, x->Prank(Group(x))); return Maximum(AbSubGrps); end); ##################################################################### #################################################################### ##################################################################### InstallMethod(Compose, "for group homomorphisms xoy=x(y)", [IsGroupHomomorphism,IsGroupHomomorphism], function(x,y) if not (Source(x)=Range(y)) then return fail; fi; return GroupHomomorphismByFunction(Source(y),Range(x), a->Image(x,Image(y,a))); end); ##################################################################### ##################################################################### InstallOtherMethod(Compose, "for FpG-module homomorphisms xoy=x(y)", [IsHapFPGModuleHomomorphism,IsHapFPGModuleHomomorphism], function(x,y) return CompositionOfFpGModuleHomomorphisms(x,y); end); ##################################################################### ##################################################################### InstallOtherMethod(Size, "for free ZG-resolutions", [IsHapResolution], function(R) local n,i,s,L; L:=[]; for n in [1..Length(R)] do s:=0; for i in [1..R!.dimension(n)] do s:=s+Length(R!.boundary(n,i)); od; Add(L,s); od; return L; end); ##################################################################### #################################################################### ##################################################################### InstallGlobalFunction(PCentre, function(arg) local G,prime, gens, gensp, C, hom; G:=arg[1]; if not IsPGroup(G) and Length(arg)=1 then Print("Error: input must be a p-group or a group and a prime.\n"); return fail; fi; if Length(arg)=2 then prime:=arg[2]; else prime:=PrimePGroup(G); fi; if Order(G)=1 then return G; fi; C:=Centre(G); gens:=GeneratorsOfGroup(C); gensp:=List(gens,x->x^prime); hom:=GroupHomomorphismByImages(C,C,gens,gensp); return Kernel(hom); end); #################################################################### ##################################################################### #################################################################### ##################################################################### InstallGlobalFunction(PUpperCentralSeries, function(arg) local G,Q,S,U,P,prime, hom, sz; G:=arg[1]; if not IsPGroup(G) and Length(arg)=1 then Print("Error: input must be a p-group or a group and a prime.\n"); return fail; fi; if Length(arg)=2 then prime:=arg[2]; else prime:=PrimePGroup(G); fi; U:=[Group(Identity(G))]; P:=U[Length(U)]; sz:=0; while Order(P)>sz do sz:=Order(P); hom:=NaturalHomomorphismByNormalSubgroup(G,P); Q:=Image(hom); P:=PreImagesSet(hom,PCentre(Q,prime)); if Order(P)>sz then Add(U,P); fi; od; return Reversed(U); end); #################################################################### ##################################################################### #################################################################### ##################################################################### InstallGlobalFunction(CanonicalRightCountableCosetElement, function(U,g) local x, h; if IsFinite(U) then return CanonicalRightCosetElement(U,g); fi; if g in U then return One(U); fi; if not IsBound(U!.ccelts) then U!.ccelts:=[]; fi; h:=g^-1; for x in U!.ccelts do if x*h in U then return x; fi; od; Add(U!.ccelts,g); return g; end); #################################################################### ##################################################################### #################################################################### ##################################################################### InstallGlobalFunction( SL2Z, function(g) local p,S, F, T, G,P,gens; S:=[[0,-1],[1,0]]; T:=[[1,0],[1,1]]; if IsInt(g) then ############################ if (not IsPrime(g)) and (not g=1) then Print("SL2Z(p) is not yet implemented for non primes p.\n"); return fail; fi; P:=[[1,0],[0,g]]; G:=Group([P*S*P^-1,P*T*P^-1]); SetName(G,Concatenation("SL(2,Z)^",String(P)) ); G!.mat:=P; SetIsHAPRationalMatrixGroup(G,true); SetIsHAPRationalSpecialLinearGroup(G,true); return G; ############################ fi; ############################ gens:=[S,T]; F:=DenominatorRat(g); F:=Factors(F); if Length(F)>Length(SSortedList(F)) then Print("SL(Z[1/m]) is implemented only for m a square free integer.\n"); return fail; fi; for p in F do P:=[[1,0],[0,p]]; Add(gens,P*S*P^-1); Add(gens,P*T*P^-1); od; G:=Group(gens); SetName(G,Concatenation("SL(2,Z[1/",String(DenominatorRat(g)),"])") ); #G!.primes:=F[1]; G!.primes:=DenominatorRat(g); SetIsHAPRationalMatrixGroup(G,true); SetIsHAPRationalSpecialLinearGroup(G,true); return G; ############################ end); #################################################################### ##################################################################### ###################### InstallMethod( \in, "for SL(2,Z)_p", [ IsMatrix, IsHAPRationalSpecialLinearGroup ], function ( g, G ) local P,n,d,facs, m,p,H,K; if IsBound(G!.mat) then ############### P:=G!.mat; return P^-1*g*P in SL(2,Integers); ############### fi; if IsBound(G!.primes) then ############### facs:=SSortedList(Factors(G!.primes)); AddSet(facs,1); for n in Flat(g) do d:=SSortedList(Factors(DenominatorRat(n))); if not IsSubset(facs,d) then # and n>1 then return false; fi; od; if Determinant(g)=1 then return true; fi; return false; ############### fi; ######## if IsBound(G!.coprimes) then m:=G!.coprimes[1]; p:=G!.coprimes[2]; P:=[[1,0],[0,p]]; return P^-1*g*P in SL2Z(1/m); fi; ############### if IsBound(G!.levels) then m:=G!.levels[1]; p:=G!.levels[2]; H:=SL2Z(1/m); K:=ConjugateSL2ZGroup(H,[[1,0],[0,p]]); return (g in H and g in K); fi; ############################## end ); ###################### if IsPackageMarkedForLoading("congruence","0.0") then ###################### InstallMethod( \in, "for CongruenceSubgroupGamma0(p)", [ IsMatrix, IsCongruenceSubgroupGamma0 ], function ( g, G ) local p; p:=G!.LevelOfCongruenceSubgroup; if g in SL(2,Integers) then if Determinant(g)=1 then if IsInt(g[2][1]/p) then return true;fi; fi; fi; ############################ return false; end ); fi; ############################################ InstallGlobalFunction(KernelWG, function(phi) local K; K:=Kernel(phi); if Length(GeneratorsOfGroup(K))=0 then K:=Group(One(K)); fi; return K; end); ############################################ ############################################ InstallGlobalFunction(ScatterPlot, function(LL) local L, tmpdir, file, colour, i, x, xmax, xmin, ymax, ymin, xscale, yscale, xminnew, yminnew, xmaxnew, ymaxnew; tmpdir := DirectoryTemporary();; file:=Filename( tmpdir , "tmp.asy" ); xmax:=Maximum(List(LL,x->x[1])); xmin:=Minimum(List(LL,x->x[1])); ymax:=Maximum(List(LL,x->x[2])); ymin:=Minimum(List(LL,x->x[2])); xscale:=200/(xmax-xmin); yscale:=200/(ymax-ymin); L:=List(LL,x->[x[1]-xmin,x[2]-ymin]); L:=List(L,x->[x[1]*xscale,x[2]*yscale]); for i in [1..Length(LL)] do if Length(LL[i])=3 then Add(L[i],LL[i][3]); fi; od; xminnew:=0; yminnew:=0; xmaxnew:=200; ymaxnew:=200; PrintTo(file,"import math; size(200,200);"); AppendTo(file,"draw((", xminnew, ",", yminnew,")--(",xmaxnew,",",yminnew,"),blue+linewidth(0.5));"); AppendTo(file,"draw((", xminnew, ",", yminnew,")--(",xminnew,",",ymaxnew,"),blue+linewidth(0.5));"); AppendTo(file,"label(\"$" , xmin , "$\" , (" , xminnew , ",", yminnew-20, "),blue);"); AppendTo(file,"label(\"$" , xmax , "$\" , (" , xmaxnew , ",", yminnew-20, "),blue);"); AppendTo(file,"label(\"$" , ymin , "$\" , (" , xminnew-20 , ",", yminnew, "),blue);"); AppendTo(file,"label(\"$" , ymax , "$\" , (" , xminnew-20 , ",", ymaxnew, "),blue);"); for x in L do if Length(x)=3 then colour:=x[3]; else colour:="blue"; fi; AppendTo(file, "dot((", x[1], ",", x[2], "),",colour, "+linewidth(4));"); od; Exec( Concatenation( ASY_PATH,"-V ", file) ); RemoveFile(file); file:=Filename(tmpdir,""); RemoveFile(file); end); ########################################################## ########################################################## ########################################################## InstallGlobalFunction(PushoutOfFpGroups, function(f,g) local P, rels, FhomP, FFhomP, GhomP, GGhomP, FGhomP, F, FF, G, GG, FG, gensF, gensFF, gensG, gensGG, gensP, x, gg; #if not Source(f)=Source(g) then return fail; fi; F:=Target(f); FF:=FreeGroupOfFpGroup(F); G:=Target(g); GG:=FreeGroupOfFpGroup(G); FG:=Source(f); gensFF:=GeneratorsOfGroup(FF); gensF:=GeneratorsOfGroup(F); gensGG:=GeneratorsOfGroup(GG); gensG:=GeneratorsOfGroup(G); P:=FreeGroup(Length(gensFF)+Length(gensGG)); gensP:=GeneratorsOfGroup(P); FFhomP:=GroupHomomorphismByImagesNC(FF,P,gensFF, gensP{[1..Length(gensFF)]}); FhomP:=GroupHomomorphismByImagesNC(F,P,gensF, gensP{[1..Length(gensFF)]}); GGhomP:=GroupHomomorphismByImagesNC(GG,P,gensGG, gensP{[1+Length(gensFF)..Length(gensP)]}); GhomP:=GroupHomomorphismByImagesNC(G,P,gensG, gensP{[1+Length(gensFF)..Length(gensP)]}); gg:=GroupHomomorphismByImagesNC(FG,G,GeneratorsOfGroup(FG), List(GeneratorsOfGroup(Source(g)),x->Image(g,x)) ); rels:=[]; Append(rels, List(RelatorsOfFpGroup(F),x->Image(FFhomP,x)) ); Append(rels, List(RelatorsOfFpGroup(G),x->Image(GGhomP,x)) ); for x in GeneratorsOfGroup(FG) do Add(rels, Image(FhomP, Image(f,x))^-1 * Image(GhomP, Image(gg,x)) ); od; return P/rels; end); ########################################################################## ########################################################################## ########################################################################## ########################################################################## InstallGlobalFunction(Fp2PcpAbelianGroupHomomorphism, function(F) local P, S, T, pS, pT, ShompS, pShomS, pThomT, ThompT, gensS, genspS; S:=Source(F); T:=Target(F); ShompS:=HAP_NqEpimorphismNilpotentQuotient(S,1); pS:=Range(ShompS); genspS:=GeneratorsOfGroup(pS); gensS:=List(genspS, x->PreImagesRepresentative(ShompS,x)); pShomS:=GroupHomomorphismByImagesNC(pS,S,genspS,gensS); ThompT:=HAP_NqEpimorphismNilpotentQuotient(T,1); pT:=Range(ThompT); P:=GroupHomomorphismByFunction(pS,pT, x->Image(ThompT,Image(F, Image(pShomS,x) ) ) ); return P; end); ########################################################################## ########################################################################## ########################################################################## ########################################################################## InstallGlobalFunction(IsIsomorphismOfAbelianFpGroups, function(F) local h; h:=Fp2PcpAbelianGroupHomomorphism(F); if not IsTrivial(Kernel(h)) then return false; fi; if not IsTrivial(Range(h)/Image(h)) then return false; fi; return true; end); ########################################################################## ########################################################################## ########################################################################## ########################################################################## InstallGlobalFunction(SignedPermutationGroup, function(n) local A, i, gens; gens:=[];; for i in [1..n-1] do Add(gens, PermutationMat((i,i+1),n)); od; for i in [1..n] do A:=1*IdentityMat(n); A[i]:=-A[i]; Add(gens,A); od; return Group(gens); end); ########################################################################## ##########################################################################