/* SECTION I ========= --------------------------------CUT------------------------------------------ ************************************* * SUMMARY OF HOMOTOPICAL FUNTIONS * ************************************* The following is a list of Magma functions for calculating a variety of homotopical functors and related constructions, which are defined on finitely presented finite groups. Throughout we use the term 'enumerated group' in three senses: in the presence of a prime p it means a finite power-commutator group obtained as the output from the p-quotient algorithm; in a situation where p=1 it means a finite permutation group (often obtained as the output from the Todd-Coxeter procedure); in the absence of p it can have either of the previous meanings, or it can mean a finite matrix group. (In short, a group is 'enumerated' if we can iterate over its elements.) Many of the functions require an input variable p. If all of the groups called by the function are prime-power groups then p should be set equal to this prime; otherwise set p=1. When p is prime the p-quotient algorithm is used to enumerate finitely presented groups (fp-groups); when p=1 the Todd-Coxeter procedure is used. EnumeratedGroup(G, p) = (eG, GhomeG, eGhomG) FpGrp, RngIntElt -> EnumGrp, Map, Map ============================================ Given a finite fp-group G this function yields an enumeratded version eG of the group, together with the 'isomorphisms' GhomeG:G-->eG and eGhomG:eG-->G. EnumeratedKernel(delta) = K Map -> EnumGrp =========================== Given a homomorphism delta:G-->H from an enumerated group G to any group H, this function returns the kernel of delta as an enumerated group K. This function should be used only in situations where Magma's internel Kernel function is undefined. PresentedGroup(eG) = (G, GhomeG, eGhomG) EnumGrp -> FpGrp, Map, Map ======================================== Given an enumerated group eG this function yields an fp-group G together with isomorphisms GhomeG:G-->eG and eGhomG:eG-->G. SelfAction(G, p) = (GactG, NiceGeneratorsG) FpGrp, RngIntElt -> Map, Set =========================================== Given a finite fp-group G this function yields the mapping GactG : GxG-->G, :-->(x^-1)yx from the cartesian product GxG into G. It also yields a 'nice' generating set for G. Action(GhomQ, HhomQ, p) = (HactG, NiceGeneratorsG) Map, Map, RngIntElt -> Map, Set ================================================== Given finite fp-groups G, H and an enumerated group Q, and a normal inclusion G>-->Q, and any homomorphism H-->Q, this function produces the mapping HactG : HxG-->G, :-->(x^-1)yx from the cartesian product GxH to G given by conjugation in Q. It also produces a 'nice' generating set for G. (In order to obtain the conjugation action GactG of a group G on itself, the more efficient function SelfAction should be used.) TensorSquare(G, p) = (GtensorG, delta) FpGrp, RngIntElt -> EnumGrp, Map ====================================== This function is defined for any finite fp-group G. It yields an enumerated version of the tensor square GtensorG of G. It also yields the homomorphism delta : GtensorG --> G which sends a tensor to the corresponding commutator in G. [An account of this "nonabelian" tensor square can be found in: R.Brown, D.L.Johnson, E.F.Robertson, 'Some computations of nonabelian tensor products of groups', Journal of Algebra 111 (1987), 177-202.] TensorCube(G, p) = (TCube, delta) FpGrp, RngIntElt -> EnumGrp, Map ================================= This function is defined for any finite fp-group G. It yields an enumerated version of the triple tensor product (GtensorG)tensorG. The function also returns the homomorphism delta : (GtensorG)tensorG --> G which send a triple tensor to the corresponding triple commutator in G. (The tensor square is understood to act on G by conjugation via the homomorphism delta:GtensorG --> G. The group G is understood to act on the tensor square by the "diagonal" action.) Jgroup(G, p) = JG FpGrp, RngIntElt -> EnumGrp =========================== This function is defined for any finite fp-group G. It yields the kernel JG of the homomorphism GtensorG-->G which sends each tensor to the corresponding commutator. The group JG is returned as an enumerated group. [The group JG is isomorphic to the third homotopy group of the space X=SK(G,1) constructed by taking the suspension of the classifying space of G. This isomorphism is proved in: R.Brown and J.-L.Loday, 'Van Kampen theorems for diagrams of spaces', Topology 26 (1987), 311-335.] Jtilde(G, p) = JtildeG FpGrp, RngIntElt -> EnumGrp =========================== This function is defined for any finite fp-group G. It yields the quotient of JG by those elements (x tensor y)(x tensor x) for x, y in G. [The group JtildeG is isomorphic to the fourth homotopy group of the space X= S^2K(G,1) constructed by taking the double suspension of the classifying space of G. This isomorphism is proved in: R.Brown and J.-L.Loday, 'Van Kampen theorems for diagrams of spaces', Topology 26 (1987), 311-335.] TensorCentre(G, p) = (TC, phi) FpGrp, RngIntElt -> EnumGrp, Map ================================ This function is defined for any finite fp-group G. It yields an enumerated version TC of the tensor centre of G. It also yields the inclusion phi:TC-->G. [The group TC is the largest central subgroup of G for which the canonical homomorphism JG ---> J(G/TC) is an inclusion.] Tensor(G, H, GactH, HactG, NiceGeneratorsG, NiceGeneratorsH, p) = (GtensorH, delta, TC, TChomG, phi, act) FpGrp, FpGrp, Map, Map, Set, Set, RngIntElt -> EnumGrp, Map, EnumGrp, Map, Map, Map ========================================================================== Given two finite fp-groups G, H with compactible actions (i.e. mappings GactH:car(G,H)-->H and HactG:car(H,G)-->G) and 'nice' generating sets (for instance, those which are closed under conjugation and under the given actions), this function yields: i) the tensor product GtensorH (as an enumerated group); ii) the homomorphism delta:GtensorH-->G which sends a tensor to the corresponding 'commutator' in G; iii) a subgroup TC of (an enumerated version of) G consisting of those elements g for which gtensorh is trivial in GtensorH for all h in H; iv) the inclusion homomorphism TChomG:TC-->G; v) the mapping phi:GxH-->GtensorH from the cartesian product into the tensor product which sends a pair to the corresponding tensor; vi) the G-action act:(G x GtensorH)-->GtensorH from the cartesian product to the tensor product. [Further details on this tensor product can be found in: R.Brown and J.-L.Loday, 'Van Kampen theorems for diagrams of spaces', Topology 26 (1987), 311-335.] ExteriorSquare(G, p) = (GexteriorG, delta) FpGrp, RngIntElt -> EnumGrp, Map ========================================== This function is defined for any finite fp-group G. It yields an enumerated version of the exterior square GexteriorG of G. It also yields the homomorphism delta : GexteriorG --> G which sends an exterior form to the corresponding commutator in G. Htwo(G, p) = HG FpGrp, RngIntElt -> EnumGrp =========================== This function is defined for any finite fp-group G. It yields the kernel HG of the homomorphism GexteriorG-->G which sends each exterior form to the corresponding commutator. The group HG is returned as an enumerated group. [The group HG is isomorphic to the Schur multiplier of G.] RelativeSchurMultiplier(G,N,p) = M(G,N) FpGrp, SubFpGrp, RngIntElt -> EnumGrp ======================================= This function is defined for any finite fp-group G with normal subgroup N. It yields the relative Schur multiplier M(G,N) as an enumerated group. [When N=G this relative multiplier is the usual Schur multiplier of G, that is M(G) = M(G,G). More generally, the relative Schur multiplier M(G,N) fits into a natural exact integral homology sequence ... --> H_3(G) --> H_3(G/H) --> M(G,H) --> H_2(G) --> H_2(G/H) --> ... . For further details see: J.-L. Loday, 'Cohomologie et group de Steinberg relatif', J. Algebra 54 (1978), 178-202. G. Ellis, 'The Schur multiplier of a pair of groups', Applied Categorical Structures', (to appear).] RelativeEpiCentre(G,N,p) = C FpGrp, SubFpGrp, RngIntElt -> EnumGrp ===================================== This function is defined for any finite fp-group G with normal subgroup N. It yields the relative epicentre C as a subgroup of an enumerated version of N. [This group C has the property that it is trivial if and only if there is a relative central extension E-->N of the pair N M(G/C,N/C) is an inclusion. When N=G the group C is more commonly known as the 'precise centre' of G, and is trivial if and only if G is isomorphic to the inner automorphism group of some group. For further details see: J.-L. Loday, 'Cohomologie et group de Steinberg relatif', J. Algebra 54 (1978), 178-202. G. Ellis, 'Capability, homology, and a central series of a pair of groups', J. Algebra 179 (1995), 31-46.] ThirdHomologyModP(G,p) = d FpGrp, RngIntElt -> RngIntElt ============================= Given a finitely presented finite p-group G, this function returns the dimension d of the third homology group H_3(G,Z/pZ) of G with coefficients in the integers modulo p. This homology group is a vector space. In practice, the function works only for groups G of extremely low order. Exterior(GhomQ, HhomQ, p) = (GexteriorH, delta,~C, ChomG, phi, act) Map, Map, RngIntElt -> EnumGrp, Map, EnumGrp, Map, Map, Map =================================================================== Given three finite fp-groups G, H, Q and normal inclusions GhomQ:G>-->Q, HhomQ:H>-->Q, this function yields: i) the exterior product GexteriorH (as an enumerated group); ii) the homomorphism delta:GexteriorH-->G which sends an exterior form to the corresponding 'commutator' in G; iii) a subgroup C of (an enumerated version of) G consisting of those elements g for which gexteriorh is trivial in GexteriorH for all h in H; iv) the inclusion homomorphism ChomG:C-->G; v) the mapping phi:GxH-->GexteriorH from the cartesian product into the exterior product which sends a pair to the corresponding exterior form; vi) the G-action act:(G x GexteriorH)-->GexteriorH from the cartesian product to the exterior product. BaerInvariant(G, c, q, p) = (BG, C) FpGrp, RngIntElt, RngIntElt, RngIntElt -> EnumGrp, EnumGrp ========================================================== Given a finite fp-group G, a positive integer c, and q a positive multiple of the exponent of the c-th Baer invariant BG of G (see below), this function returns BG as an enumerated group. The function also returns the cth term of the upper epicentral series of G as an enumerated group C. [The cth Baer Invariant of a group G is the abelian group R \cap [F,F,...,F] BG := ------------------ [R,F,...,F] defined from a free presentation G=F/R, in which \cap means "intersection", and [F,...,F] denotes the (c+1)-st term of the lower central series of F, and [R,F,...,F] is the subgroup of this term generated by commutators whose first entry lies in R. For c=1 this is just the Schur multiplier of G. If G is a group of prime-power exponent p^e and nilpotency class k>1, then the exponent of BG divides q:=p^{e*(k-1)}. Other results on the exponent of BG can be found in the second reference below. We say that the group G is '1-capable' if and only if it is the inner automorphism group of some group Q. More generally we say that G is 'c-capable' if and only if it is the inner automorphism group of some (c-1)-capable group Q. The cth term C of the upper epicentral series of G has the property that it is trivial if and only if G is c-capable. Further details can be found in: C.R. Leedham-Green and S. MacKay, "Baer invariants, isologism, varietal laws, and homology", Acta Math. 137 (1976), 99-150. J. Burns and G. Ellis, "On the nilpotent multipliers of a group:, Math. Z. (to appear).] CoveringGroup(G, p) = (DG, delta, Htwo) FpGrp, RngIntElt -> FpGrp, Map, EnumGrp ======================================= Given a finite fp-group G this function returns a finite fp-group DG which is a central extension DG-->>G of G with the property that the Schur multiplier of G is isomorphic to [DG,DG] meet kernel(DG-->>G). It also returns the homomorphism delta:eDG-->>eG given on enumerated groups, as well as the Schur multiplier Htwo as an enumerated group. (The fp-groups G and DG have the same generating set, but the order of DG is not minimal.) IsCapable(G,p) = B FpGrp, RngIntElt -> Boolean =========================== Given a finite fp-group G this function returns the boolean value TRUE if G is the inner automorphism group of some group, and returns the boolean value FALSE otherwise. IsTerminal(G,p) = B FpGrp, RngIntElt -> Boolean =========================== Given a finitely presented finite nilpotent group G this function returns the boolean value TRUE if G is a terminal group, and returns the boolean value FALSE otherwise. [Recall that a nilpotent group G of class c is said to be "terminal" if there is no group D of class c+1 such that G is isomorphic to D/[D,...,D] where [D,...,D] denotes the (c+1)-st term of the lower central series of D.] EXAMPLE ======= To find the order and nilpotency class of the tensor square of the Burnside group G=B(3,3) of exponent 3 on three generators, enter the following: F:=FreeGroup(3); a:=F.1; b:=F.2; c:=F.3; x1:=(c,a); x1:=(a,b); x2:=(a,c); x3:=(b,c); x4:=(x1,c); rels:=[ a^3, b^3, c^3, x1^3, x2^3, x3^3, x4^3, (b,a)*x1^-2, (c,a)*x2^-2, (x1,a), (x2,a), (x3,a)*x4^-1, (x4,a), (c,b)*x3^-2, (x1,b), (x2,b)*x4^-2, (x3,b), (x4,b), (x1,c)*x4^-1, (x2,c), (x3,c), (x4,c), (x2,x1), (x3,x1), (x4,x1), (x3,x2), (x4,x2), (x4,x3) ]; G:=quo; T:=TensorSquare(G,3); print Order(T); print NilpotencyClass(T); This tensor square turns out to have order 3^20 and nilpotency class 2. Now let N denote the centre of the Burnside group G. In order to determine the relative Schur multiplier M(G,N), enter the following. eG, GhomeG, eGhomG:=EnumeratedGroup(G,3); N:=Center(eG); N:=eGhomG(N); M:=RelativeSchurMultiplier(G,N,3); print M; It turns out that the relative multiplier M(G,N) is elementary abelian of order 27. -----------------------------CUT------------(end of Section I)--------------*/ /* SECTION II ========== --------------------------------CUT-----------------------------------------*/ /* This program contains Magma functions for calculating various homotopical functors and related constructions. For the program to run properly Version 2.3 of Magma needs to have been installed, and the file homotopyhelp.m (which contains detailed explanations of the functions) needs to be present in the same directory as this program. In writing the program the following conventions have been followed: an enumerated group is represented by a string (such as eG) whose first letter is a lower case "e", whereas a finitely presented group is represented by a string whose first letter is upper case; a homomorphism from a group G to a group H is denoted by GhomH. I would like to thank John Cannon for his very generous help in simplifying, drastically shortening, and speeding up an earier version of this program. */ /* ******************************************************************** */ print "Type 'help();' for information on the Homotopy Package. "; forward ProductRelations, Remainder; procedure help(); System("more homotopyhelp.m"); end procedure; /* ********************************************************************* */ /* ********************************************************************* */ EnumeratedGroup := function(G, p); if IsPrime(p) then eG, GhomeG := pQuotient(G, p, 63); eGhomG := hom< eG -> G | [ (eG.i)@@GhomeG : i in [1..NumberOfPCGenerators(eG)] ] >; else CSpc := CosetSpace(G, sub: CosetLimit := 2000000); GhomeG, eG := CosetAction(CSpc); eGhomG := hom< eG -> G | [ (eG.i)@@GhomeG : i in [1..#Generators(G)] ] >; end if; return eG, GhomeG, eGhomG; end function; /* ******************************************************************** */ /* ******************************************************************** */ EnumeratedKernel := function( delta ); K := {}; G := Domain(delta); trivialelt := delta(Id(G)); for x in G do if x in K then continue; end if; if delta(x) eq trivialelt then K := NormalClosure( G, sub); end if; end for; return K; end function; /* ******************************************************************** */ /* ******************************************************************** */ PresentedGroup := function( eG ); G, GhomeG := FPGroup( eG); NGens := Type(eG) eq GrpPC select NumberOfPCGenerators(eG) else Ngens(eG); eGhomG := hom< eG -> G | [ (eG.i)@@GhomeG : i in [1..NGens] ] >; return G, GhomeG, eGhomG; end function; /* ******************************************************************** */ /* ******************************************************************** */ SelfAction := function(G, p); eG, GhomeG, eGhomG := EnumeratedGroup(G, p); GactG := map< car->G | x:->eGhomG(GhomeG(x[2])^GhomeG(x[1])) >; NiceGeneratorsG := &join {Generators(UpperCentralSeries(eG)[i]) : i in [2..#UpperCentralSeries(eG)] }; T := Transversal(eG, sub< eG | NiceGeneratorsG > ); return GactG, eGhomG(T) join eGhomG(NiceGeneratorsG); end function; /* ******************************************************************** */ /* ******************************************************************** */ Action := function(GhomeQ, HhomeQ, p); G := Domain(GhomeQ); H := Domain(HhomeQ); eQ := Codomain(GhomeQ); eG, GhomeG, eGhomG := EnumeratedGroup(G, p); // If H=G then set eH=eG etc., else enumerate H. if G cmpeq H then eH:=eG; HhomeH:=GhomeG; eHhomH:=eGhomG; else eH, HhomeH, eHhomH := EnumeratedGroup(H, p); end if; imG := GhomeQ(G); m := IsPrime(p) select #PCGenerators(imG) else #Generators(imG); S := [ eGhomG(x) : x in eG, i in [1..m] | GhomeQ(eGhomG(x)) eq imG.i ]; imGhomG := hom< imG->G | S>; HactG := map< car->G | x :-> imGhomG(GhomeQ(x[2])^HhomeQ(x[1])) >; NiceGeneratorsG := &join {imGhomG(Generators(UpperCentralSeries(eQ)[i] meet imG)): i in [2..#UpperCentralSeries(eQ)] }; T:=Transversal(eG, sub< eG | GhomeG(NiceGeneratorsG) >); return HactG, eGhomG(T) join NiceGeneratorsG; end function; /* ******************************************************************** */ /* ******************************************************************** */ Tensor := function(G, H, GactH, HactG, NiceGeneratorsG, NiceGeneratorsH, p) nG := #Generators(G); nH := #Generators(H); n := nG + nH; eG, GhomeG, eGhomG := EnumeratedGroup(G, p); // If H=G then set eH=eG etc., else enumerate H if H cmpeq G then eH:=eG; HhomeH:=GhomeG; eHhomH:=eGhomG; else eH, HhomeH, eHhomH := EnumeratedGroup(H, p); end if; /* GH:=G*H/J will be a quotient of the free product G*H in which the commutator subgroup [G,H] is isomorphic to the tensor product of G with H. */ F := FreeGroup(n); GhomF := homF | [F.i : i in [1..nG]] >; HhomF := homF | [F.i : i in [nG+1..n]] >; // The function ProductRelations, defined below, yields generators for J rels := ProductRelations( GhomF, HhomF, GhomeG, eGhomG, NiceGeneratorsG, HhomeH, eHhomH, NiceGeneratorsH, GactH, HactG ); // The function Remainder completes the function Tensor. return Remainder( GhomF, HhomF, GhomeG, eGhomG, NiceGeneratorsG, HhomeH, eHhomH, NiceGeneratorsH, GactH, HactG, rels, p ); end function; /* ********************************************************************* */ /* ********************************************************************* */ Remainder := function( GhomF, HhomF, GhomeG, eGhomG, NiceGeneratorsG, HhomeH, eHhomH, NiceGeneratorsH, GactH, HactG, rels, p ); // This function completes the function Tensor. F := Codomain( GhomF ); G := Domain( GhomeG ); H := Domain( HhomeH ); eG := Codomain( GhomeG ); eH := Codomain( HhomeH ); nG := #Generators(G); nH := #Generators(H); n := nG + nH; GH, FhomGH := quo; GHhomG := hom< GH -> G | [G.i : i in [1..nG]] cat [Id(G) : i in [1..nH]]>; eGH, GHhomeGH, eGHhomGH := EnumeratedGroup(GH, p); eGtensorH := ncl< eGH | [ GHhomeGH(FhomGH(GhomF(G.i))) : i in [1..nG] ]> meet ncl< eGH | [ GHhomeGH(FhomGH(HhomF(H.i))) : i in [1..nH] ]>; GxHmapeGtensorH := map< car->eGtensorH | x:-> ( GHhomeGH(FhomGH(GhomF(x[1]))), GHhomeGH(FhomGH(HhomF(x[2]))) )>; eTCentre:= Centre(eGH) meet sub; eTCentrehomG := homG | x:-> GHhomG(eGHhomGH(x))>; GacteGtensorH := map->eGtensorH | x:-> x[2]^GHhomeGH(FhomGH(GhomF(x[1])))^-1>; /* The remainder of this procedure constructs the homomorphism delta. This is done by means of the semidirect product of G with H, which we denote by GsdH. */ S := { GhomF(x)^HhomF(y) = GhomF(HactG()) : y in Generators(H), x in NiceGeneratorsG } join { GhomF(r) : r in Relations(G) } join { HhomF(r) : r in Relations(H) }; GsdH, FhomGsdH := quo< F | S >; // The following is in fact not quite a homomorphism! GHmapGsdH := hom< GH->GsdH | [GsdH.i : i in [1..n]] >; eGsdH, GsdHhomeGsdH, eGsdHhomGsdH := EnumeratedGroup(GsdH, p); eGhomeGsdH := homeGsdH| x:->GsdHhomeGsdH(FhomGsdH(GhomF(eGhomG(x))))>; imG := eGhomeGsdH(eG); m := IsPrime(p) select #PCGenerators(imG) else #Generators(imG); S := [ eGhomG(x) : x in eG, i in [1..m] | eGhomeGsdH(x) eq imG.i ]; imageGhomG := hom< imG -> G | S >; delta := hom< eGtensorH->G | x :-> imageGhomG(GsdHhomeGsdH(GHmapGsdH(eGHhomGH(x)))) >; return eGtensorH, delta, eTCentre, eTCentrehomG, GxHmapeGtensorH, GacteGtensorH; end function; /* ******************************************************************** */ /* ******************************************************************** */ ProductRelations := function( GhomF, HhomF, GhomeG, eGhomG, NiceGeneratorsG, HhomeH, eHhomH, NiceGeneratorsH, GactH, HactG ); // This function produces the relations for G*H/J in the function Tensor. F := Codomain( GhomF ); G := Domain( GhomF ); H := Domain( HhomF ); rels := { GhomF(LHS(x)*RHS(x)^-1) : x in Relations(G) } join { HhomF(LHS(x)*RHS(x)^-1) : x in Relations(H) }; rels := SetToSequence(rels); for z in Generators(G) do for x in NiceGeneratorsG do for y in NiceGeneratorsH do x1:=eGhomG(GhomeG(x)); y1:=eHhomH(HhomeH(y)); c:=(GhomF(x1), HhomF(y1)) ^ GhomF(z); v:=GhomeG(z^-1*x1*z); v:=eGhomG(v); w:=HhomeH(GactH()); w:=eHhomH(w); d:=(HhomF(w),GhomF(v)); rels:= Append(rels,c*d); end for; end for; end for; for z in Generators(H) do for x in NiceGeneratorsG do for y in NiceGeneratorsH do x1:=eGhomG(GhomeG(x)); y1:=eHhomH(HhomeH(y)); c:=HhomF(z^-1) * (GhomF(x1),HhomF(y1)) * HhomF(z); v:=HhomeH(z^-1*y1*z); v:=eHhomH(v); w:=GhomeG(HactG()); w:=eGhomG(w); d:=(HhomF(v),GhomF(w)); rels:= Append(rels,c*d); end for; end for; end for; rels:=SequenceToSet(rels); return rels; end function; /* ******************************************************************** */ /* ******************************************************************** */ TensorSquare := function(G, p); GactG, NiceGensG := SelfAction(G, p); eGtensorG, delta := Tensor(G, G, GactG, GactG, NiceGensG, NiceGensG, p); return eGtensorG, delta; end function; /* ******************************************************************** */ /* ******************************************************************** */ Jgroup := function(G, p); _, delta := TensorSquare(G,p); return EnumeratedKernel(delta); end function; /* ******************************************************************** */ /* ******************************************************************** */ TensorCentre := function(G, p); GactG, NiceGensG := SelfAction(G, p); _, _, TC, phi := Tensor(G, G, GactG, GactG, NiceGensG, NiceGensG, p); return TC, phi; end function; /* ******************************************************************** */ /* ******************************************************************** */ TensorCube := function(G, p); // TS=TensorSquare and TC=TensorCube eG, GhomeG, eGhomG := EnumeratedGroup(G, p); GactG, NiceGensG := SelfAction(G, p); eTS, delta, _, _, _, GacteTS := Tensor(G, G, GactG, GactG, NiceGensG, NiceGensG, p ); TS, TShomeTS, eTShomTS := PresentedGroup( eTS ); TShomeG := hom< TS->eG | x:->GhomeG(delta(TShomeTS(x))) >; TSactG, NiceGensG := Action(GhomeG, TShomeG, p); GactTS:=map->TS|x:->eTShomTS(GacteTS())>; // We now construct a generating set for TS closed under the action of G. A := SetToIndexedSet(Generators(eTS)); i := 1; while i le #A do y := A[i]; for x in Generators(eG) do Include(~A, GacteTS()); end for; i := i + 1; end while; NiceGensTS := eTShomTS(A); Tcube, delta := Tensor(TS, G,TSactG, GactTS, NiceGensTS, NiceGensG, p); return Tcube, delta; end function; /* ******************************************************************** */ /* ******************************************************************** */ Jtilde := function(G, p); GactG, NiceGensG := SelfAction(G, p); eGtensorG, delta, _, _, phi := Tensor(G, G, GactG, GactG, NiceGensG, NiceGensG, p ); JG := sub< eGtensorG | { x : x in Centre(eGtensorG) | delta(x) eq delta(Id(eGtensorG)) }>; D := sub< eGtensorG | { phi(x,x) : x in Generators(G) }, { phi(x,y)*phi(y,x) : x, y in Generators(G) } >; eGsymmetricG, phi := quo< eGtensorG | D >; return phi(JG); end function; /* ******************************************************************** */ /* ******************************************************************** */ Exterior := function(GhomQ, HhomQ, p); G := Domain(GhomQ); H := Domain(HhomQ); Q := Codomain(GhomQ); nG := #Generators(G); nH := #Generators(H); n := nG+nH; eQ, QhomeQ, eQhomQ := EnumeratedGroup(Q, p); // If G=Q then set eG=eQ etc., else enumerate G. if G cmpeq Q then eG:=eQ; GhomeG:=QhomeQ; eGhomG:=eQhomQ; else eG, GhomeG, eGhomG := EnumeratedGroup(G, p); end if; // If H=Q then set eH=eQ etc., else enumerate H. if H cmpeq Q then eH:=eQ; HhomeH:=QhomeQ; eHhomH:=eQhomQ; else eH, HhomeH, eHhomH := EnumeratedGroup(H, p); end if; GhomeQ:=homeQ|x:->QhomeQ(GhomQ(x))>; HhomeQ:=homeQ|x:->QhomeQ(HhomQ(x))>; GIH := sub; if (G cmpeq Q) and (H cmpeq Q) then HactG, NiceGeneratorsG := SelfAction(G, p); GactH := HactG; NiceGeneratorsH := NiceGeneratorsG; else HactG, NiceGeneratorsG := Action(GhomeQ, HhomeQ, p); GactH, NiceGeneratorsH := Action(HhomeQ, GhomeQ, p); end if; /* GH:=G*H/J will be a quotient of the free product G*H in which the commutator subgroup [G,H] is isomorphic to the exterior product of G with H. */ F:=FreeGroup(n); GhomF:=homF | [F.i : i in [1..nG]] >; HhomF:=homF | [F.i : i in [nG+1..n]] >; rels := ProductRelations( GhomF, HhomF, GhomeG, eGhomG, NiceGeneratorsG, HhomeH, eHhomH, NiceGeneratorsH, GactH, HactG); /* We next add relations (x exterior x') to rels where the images of x and x' are equal in GIH. */ SG := []; SH := []; for x in Generators(GIH) do for y in eG do if GhomeQ(eGhomG(y)) eq x then x1:=y; break; end if; end for; Append(~SG,x1); for z in eH do if HhomeQ(eHhomH(z)) eq x then x2:=z; break; end if; end for; Append(~SH,x2); end for; for i in [1..#Generators(GIH)] do x1:=SG[i]; x2:=SH[i]; rels := rels join {( GhomF(eGhomG(x1)), HhomF(eHhomH(x2)) )}; for j in [1..#Generators(GIH)] do y1:=SG[j]; y2:=SH[j]; rels := rels join {( GhomF(eGhomG(x1)),HhomF(eHhomH(y2)) )* ( GhomF(eGhomG(y1)),HhomF(eHhomH(x2)) )}; end for; end for; return Remainder( GhomF, HhomF, GhomeG, eGhomG, NiceGeneratorsG, HhomeH, eHhomH, NiceGeneratorsH, GactH, HactG, rels, p); end function; /* ******************************************************************* */ /* ******************************************************************** */ ExteriorSquare := function(G, p); GactG, NiceGensG := SelfAction(G, p); GhomG := homG | x:->x >; eGexteriorG, delta:= Exterior(GhomG, GhomG, p); return eGexteriorG, delta; end function; /* ******************************************************************** */ /* ******************************************************************** */ Htwo := function(G, p); _, delta := ExteriorSquare(G,p); return EnumeratedKernel(delta); end function; /* ******************************************************************** */ /* ******************************************************************** */ RelativeSchurMultiplier := function(G, N, p); // Here N is a normal subgroup of G. N1 := Rewrite(G, N); GhomG := hom< G->G | x:->x >; N1homG := hom< N1->G | x:->x >; eGexteriorN, delta, _, _, _, _ := Exterior(GhomG, N1homG, p); alpha := hom< Centre(eGexteriorN)->G | x:->delta(x) >; return EnumeratedKernel(alpha); end function; /* ******************************************************************** */ /* ******************************************************************** */ RelativeEpiCentre := function(G, N, p); // Here N is a normal subgroup of G. N1:=Rewrite(G,N); GhomG:=homG|x:->x>; N1homG:=homG|x:->x>; _, _, REC, phi, _, _ := Exterior(GhomG, N1homG, p); return REC, phi; end function; /* ******************************************************************** */ /* ******************************************************************** */ BaerInvariant := function(G, c, q, p); n := #Generators(G); F := FreeGroup(n); GhomF := hom< G->F | [F.i : i in [1..n]] >; Grels := { GhomF(LHS(r)*RHS(r)^-1) : r in Relations(G) }; G1rels := Grels; for i in [1..c] do Drels := { r^q : r in G1rels } join { (r,x) : r in G1rels, x in Generators(F)}; G1rels := Drels; end for; Drels := (Drels join { r^q : r in Grels }) diff {Id(F)}; D, FhomD := quo< F | Drels >; eD, DhomeD, eDhomD := EnumeratedGroup(D, p); FhomeD := hom< F->eD | x:->DhomeD(FhomD(x)) >; N := NormalClosure(eD, sub ); eG, eDhomeG := quo< eD | N >; LCS := LowerCentralSeries(eD); d := #LCS; eBaer := Kernel(eDhomeG) meet LCS[Minimum(c+1,d)]; C := UpperCentralSeries(eD)[Minimum(c+1,d)]; return AbelianGroup(eBaer), eDhomeG(C); end function; /* ******************************************************************** */ /* ******************************************************************** */ CoveringGroup := function(G, p); n:=#Generators(G); F:=FreeGroup(n); GhomF:=homF | [F.i : i in [1..n]] >; FhomG:=homG | [G.i : i in [1..n]] >; eG, GhomeG, eGhomG := EnumeratedGroup(G,p); FhomeG:=homeG | x:->GhomeG(FhomG(x)) >; Grels:={ GhomF(LHS(x)*RHS(x)^-1) : x in Relations(G) }; DGrels:={}; for x in Generators(F) do m:=Order(FhomeG(x)); DGrels:=DGrels join {x^m}; for r in Grels do DGrels:=DGrels join {(r,x)}; end for; end for; DGrels:=DGrels diff {Id(F)}; DG, FhomDG := quo; DGhomF:=homF | [F.i : i in [1..n]]>; eDG, DGhomeDG, eDGhomDG := EnumeratedGroup(DG,p); delta:=homeG| x:-> GhomeG(FhomG(DGhomF(eDGhomDG(x))))>; eR:=NormalClosure(eDG,sub); Htwo := CommutatorSubgroup(eDG,eDG) meet eR; DG:=Simplify(DG); return DG, delta, Htwo; end function; /* ******************************************************************** */ /* ******************************************************************** */ IsCapable := function(G, p); DG, delta := CoveringGroup(G, p); N:=delta(Centre(Domain(delta))); return (#N eq 1); end function; /* ******************************************************************** */ /* ******************************************************************** */ IsTerminal := function(G, p); DG, delta, SM := CoveringGroup(G, p); Dom:=Domain(delta); Cod:=Codomain(delta); if not(IsNilpotent(Cod)) then print " "; print " "; print "The group is not nilpotent!"; else c:=NilpotencyClass(Cod); S:=PrimeDivisors(Order(Cod)); A:=LowerCentralSeries(Dom)[c+1]; B:=CommutatorSubgroup(Dom,Dom); alpha:=homCod | x:->delta(x)>; e:=1; for i in [1..#S] do e:=e*S[i]; end for; SMhomSM:=homSM | x:->x^e>; C:=SMhomSM(SM); return (#(C meet A) eq #A); end if; end function; /* ******************************************************************** */ /* ******************************************************************** */ ThirdHomologyModP := function(G, p); if not(IsPrime(p)) then print "The integer p must be a prime."; d:=0; else n:=#Generators(G); F:=FreeGroup(n); GhomF:=homF | [F.i : i in [1..n]] >; FhomG:=homG | [G.i : i in [1..n]] >; Grels := {GhomF(LHS(x)*RHS(x)^-1) : x in Relations(G)}; Grels := SetToIndexedSet(Grels); eG, GhomeG, eGhomG := EnumeratedGroup(G, p); GeneratorsOfR:=car; Phi:=mapF|x:->x[2]^GhomF(eGhomG(x[1]^-1))>; CommutatorRels := {(Phi(),Grels[j]) : x in eG, i, j in [1..#Grels] | i ge j} join {r^p : r in Grels}; // We set D:=F/[R,R]R^p, and S=R/[R,R]R^p. D, FhomD := quo; eD, DhomeD, eDhomD := EnumeratedGroup(D, p); eS:=NormalClosure(eD,sub); S, ShomeS, eShomS := PresentedGroup(eS); ShomeD:=homeD|x:->ShomeS(x)>; GhomeD:=homeD|x:->DhomeD(FhomD(GhomF(x)))>; GactS:=map->S|x:-> eShomS( GhomeD(x[1])*ShomeD(x[2])*GhomeD(x[1]^-1) )>; NiceGeneratorsS:=Generators(S); SactG := map->G|x:->x[2]>; X, NiceGeneratorsG := SelfAction(G, p); mS := #Generators(S); mG := #Generators(G); m := mS+mG; GensG := PCGenerators(eG); Bas := {}; V := sub; for x in PCGenerators(eS) do x1 := eShomS(x); for y in PCGenerators(eG) do y1:=eGhomG(y); NewV:=sub; if #NewV gt #V then V:=NewV; Bas:=Bas join {}; end if; end for; end for; /* SG:=S*G/J will be a quotient of the free product S*G in which the commutator subgroup [S,G] is isomorphic to the tensor product of S with G. */ E:=FreeGroup(m); ShomE:=homE | [E.i : i in [1..mS]] >; GhomE:=homE | [E.i : i in [mS+1..m]] >; rels := ProductRelations(ShomE, GhomE, ShomeS, eShomS, NiceGeneratorsS, GhomeG, eGhomG, NiceGeneratorsG, SactG, GactS); rels := rels join {(ShomE(w[1]),GhomE(w[2])) : w in Bas}; SG, EhomSG := quo; eSG, _, _ := EnumeratedGroup(SG, p); // X will be the subgroup [R,G]/[R,R]R^p of S=R/[R,R]R^p. X := {ShomeS(GactS(eGhomG(g),s^-1)*s) : g in eG, s in Generators(S)}; X:=NormalClosure(eS,sub); a:= #eSG * (p^#Bas) /((#eS)*(#eG)*(#X)); for i in [0..100] do if p^i eq a then d:=i; break; end if; end for; end if; return d; end function; /* ******************************************************************** */ /*-----------------------------CUT------------(end of Section II)-----------*/ /* SECTION III =========== ------------------------------CUT-------------------------------------------*/ /* This file should be loaded into Magma to test the various functions in the homotopy package. The file may take about 10 minutes to run. It will conclude by stating whether any errors were detected. */ print "We shall enter a presentation of the Burnside group G=B(3,3) ..."; F:=FreeGroup(3); a:=F.1; b:=F.2; c:=F.3; x1:=(c,a); x1:=(a,b); x2:=(a,c); x3:=(b,c); x4:=(x1,c); rels:=[ a^3, b^3, c^3, x1^3, x2^3, x3^3, x4^3, (b,a)*x1^-2, (c,a)*x2^-2, (x1,a), (x2,a), (x3,a)*x4^-1, (x4,a), (c,b)*x3^-2, (x1,b), (x2,b)*x4^-2, (x3,b), (x4,b), (x1,c)*x4^-1, (x2,c), (x3,c), (x4,c), (x2,x1), (x3,x1), (x4,x1), (x3,x2), (x4,x2), (x4,x3) ]; G:=quo; print "The generators of G are", Generators(G) ; print "WE SHALL SET p=3."; p:=3; print "We shall enumerate the group G ..."; eG,GhomeG,eGhomG := EnumeratedGroup(G,p); print "The order of the group G=B(3,3) was computed to be", #eG, ".", "This is", (#eG eq 2187), "."; B:=(#eG eq 2187); print "We shall construct two normal subgroups M, N in G ..."; eM:=NormalClosure(eG,sub); eN:=NormalClosure(eG,sub); M,MhomeM,eMhomM:=PresentedGroup(eM); N,NhomeN,eNhomN:=PresentedGroup(eN); MhomeG:=homeG|x:->MhomeM(x)>; NhomeG:=homeG|x:->NhomeN(x)>; print "The orders of M and N were computed to be",#eM, ",", #eN,". This is", (#eM eq 729) and (#eN eq 729), "."; B:=(#eM eq 729) and (#eN eq 729) and B; print "We shall construct a conjugation action of M on N, and a nice generating set for N ..."; MactN, NiceGeneratorsN:=Action(NhomeG,MhomeG,p); print "NiceGeneratorsN was found to have", #NiceGeneratorsN, "elements.", "This is", (#NiceGeneratorsN eq 7), "."; B:=(#NiceGeneratorsN eq 7) and B; print "We shall construct a conjugation action of N on M, and a nice generating set for M ..."; NactM, NiceGeneratorsM:=Action(MhomeG,NhomeG,p); print "NiceGeneratorsM was found to have", #NiceGeneratorsM, "elements.", "This is", (#NiceGeneratorsM eq 7), "."; B:=(#NiceGeneratorsM eq 7) and B; print "We shall use these actions to construct the tensor product of N and M ..."; T,delta:=Tensor(M,N,MactN,NactM,NiceGeneratorsM,NiceGeneratorsN,p); print "The order of the tensor product was computed to be", #T, ". This is", (#T eq 14348907), "."; B:=(#T eq 14348907) and B; delete T; print "We shall construct the tensor square of G=B(3,3) ..."; T:=TensorSquare(G,p); print "The order of the tensor square was computed to be", #T, ". This is", (#T eq 3^20), "."; B:=(#T eq 3^20) and B; delete T; print "We shall construct the relative Schur multiplier M(G,Z) where Z is the centre of G ..."; Z:=eGhomG(Center(eG)) ; RM:=RelativeSchurMultiplier(G,Z,p); print "The order of the relative Schur multiplier was computed to be", #RM, ". This is", (#RM eq 27), "."; B:=(#RM eq 27) and B; delete RM; print "We shall determine whether or not the group G=B(3,3) is capable ..."; Boole:=IsCapable(G,p); print Boole; B:=Boole and B; print "We shall determine whether or not the group G=B(3,3) is terminal ..."; Boole:= IsTerminal(G,p); print Boole; B:=not(Boole) and B; delete eG, G, eGhomG, GhomeG; print "We shall now enter a presentation for the dihedral group Q of order 16 ..."; F:=FreeGroup(2); Q:=quo; p:=2; print "WE SHALL SET p=2."; p:=2; print "We shall construct the tensor cube of Q ..."; T:=TensorCube(Q,p); print "The order of the tensor cube was computed to be", #T, ". This is", (#T eq 2048), "."; B:= (#T eq 2048) and B; delete T; print "We shall construct the second Baer invariant of Q ..."; M:=BaerInvariant(Q,2,4,p); print "The order of the Baer invariant was computed to be", #M, ". This is", (#M eq 8), "."; B:=(#M eq 8) and B; delete M; print "We shall determine the dimension of the third integral homology (mod 2) of Q ..."; d:=ThirdHomologyModP(Q,2); print "The dimesnion was computed to be", d, ". This is", (d eq 2), "."; B:=(d eq 2) and B; print "WE SHALL SET p=1."; p:=1; print "We shall compute the group Jtilde(Q) ..."; JT:=Jtilde(Q,p); print "The order of Jtilde was computed to be", #JT, ". This is", (#JT eq 2), "."; B:=(#JT eq 2) and B; delete JT; print "We shall determine whether or not the group Q is terminal ..."; Boole:= IsTerminal(Q,p); print Boole; B:=not(Boole) and B; if B then print "NO ERRORS WERE DETECTED"; else print "ERRORS OCCURRED WHEN THIS TESTFILE WAS RUN"; end if; /*-----------------------------CUT-----------------(end of Section III)----*/