5 Groups and homomorphisms 5.1 Functions for groups 5.1-1 Comm Comm( L )  operation This method has been transferred from package ResClasses. It provides a method for Comm when the argument is a list (enclosed in square brackets), and calls the function LeftNormedComm.  Example   gap> Comm( [ (1,2), (2,3) ] ); (1,2,3) gap> Comm( [(1,2),(2,3),(3,4),(4,5),(5,6)] ); (1,5,6) gap> Comm(Comm(Comm(Comm((1,2),(2,3)),(3,4)),(4,5)),(5,6)); ## the same (1,5,6)   5.1-2 IsCommuting IsCommuting( a, b )  operation This function has been transferred from package ResClasses. It tests whether two elements in a group commute.  Example   gap> D12 := DihedralGroup( 12 );  gap> SetName( D12, "D12" );  gap> a := D12.1;; b := D12.2;;  gap> IsCommuting( a, b ); false   5.1-3 ListOfPowers ListOfPowers( g, exp )  operation This function has been transferred from package RCWA. The operation ListOfPowers(g,exp) returns the list [g,g^2,...,g^exp] of powers of the element g.  Example   gap> ListOfPowers( 2, 20 ); [ 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384,  32768, 65536, 131072, 262144, 524288, 1048576 ] gap> ListOfPowers( (1,2,3)(4,5), 12 ); [ (1,2,3)(4,5), (1,3,2), (4,5), (1,2,3), (1,3,2)(4,5), (),  (1,2,3)(4,5), (1,3,2), (4,5), (1,2,3), (1,3,2)(4,5), () ] gap> ListOfPowers( D12.2, 6 ); [ f2, f3, f2*f3, f3^2, f2*f3^2, of ... ]   5.1-4 GeneratorsAndInverses GeneratorsAndInverses( G )  operation This function has been transferred from package RCWA. This operation returns a list containing the generators of G followed by the inverses of these generators.  Example   gap> GeneratorsAndInverses( D12 ); [ f1, f2, f3, f1, f2*f3^2, f3^2 ] gap> GeneratorsAndInverses( SymmetricGroup(5) );  [ (1,2,3,4,5), (1,2), (1,5,4,3,2), (1,2) ]   5.1-5 UpperFittingSeries UpperFittingSeries( G )  attribute LowerFittingSeries( G )  attribute FittingLength( G )  attribute These three functions have been transferred from package ResClasses. The upper and lower Fitting series and the Fitting length of a solvable group are described here: https://en.wikipedia.org/wiki/Fitting_length.  Example   gap> UpperFittingSeries( D12 ); LowerFittingSeries( D12 ); [ Group([ ]), Group([ f3, f2*f3 ]), Group([ f1, f3, f2*f3 ]) ] [ D12, Group([ f3 ]), Group([ ]) ] gap> FittingLength( D12 ); 2 gap> S4 := SymmetricGroup( 4 );; gap> UpperFittingSeries( S4 ); [ Group(()), Group([ (1,2)(3,4), (1,4)(2,3) ]), Group([ (1,2)(3,4), (1,4)  (2,3), (2,4,3) ]), Group([ (3,4), (2,3,4), (1,2)(3,4) ]) ] gap> List( last, StructureDescription ); [ "1", "C2 x C2", "A4", "S4" ] gap> LowerFittingSeries( S4 ); [ Sym( [ 1 .. 4 ] ), Alt( [ 1 .. 4 ] ), Group([ (1,4)(2,3), (1,3)  (2,4) ]), Group(()) ] gap> List( last, StructureDescription ); [ "S4", "A4", "C2 x C2", "1" ] gap> FittingLength( S4); 3   5.2 Left Cosets for Groups 5.2-1 LeftCoset LeftCoset( g, U )  operation Since GAP uses right actions by default, the library contains the operation RightCoset(U,g) for constructing the right coset Ug of a subgroup U ≤ G and an element g ∈ G. It has been noted in the reference manual that, by inverting all the elements in Ug, the left coset g^-1U is obtained. Just for the sake of completeness, from August 2022 this package provides the operation LeftCoset(g,U) for constructing the left coset gU. Users are strongly recommended to continue to use RightCoset for all serious calculations, since left cosets have a much simpler implementation and do not behave exactly like right cosets. The methods for left cosets which are provided generally work by converting gU to Ug^-1; applying the equivalent method for right cosets; and, if necessary, converting back again to left cosets. G acts on gU by OnLeftInverse: (gU)^g_0 = g_0^-1*(gU) = (g_0^-1g)U.  Example   gap> lc1 := LeftCoset( (1,2,3), Group( [ (1,2), (3,4) ] ) );  LeftCoset((1,2,3),Group([ (1,2), (3,4) ])) gap> Representative( lc1 ); (1,2,3) gap> ActingDomain( lc1 ); Group([ (1,2), (3,4) ]) gap> AsSet( lc1 ); [ (2,3), (2,4,3), (1,2,3), (1,2,4,3) ] gap> (1,2,3) in lc1; true gap> lc2 := (2,4,3) * lc1;  LeftCoset((1,2,4),Group([ (1,2), (3,4) ])) gap> lc3 := lc1^(2,3,4);; gap> lc2 = lc3;  true   5.2-2 Inverse The inverse of the left coset gU is the right coset Ug^-1, and conversely. This is an abuse of the attribute Inverse, since the standard requirement, that x*x^-1 is an identity, does not hold.  Example   gap> rc1 := Inverse( lc1 );  RightCoset(Group([ (1,2), (3,4) ]),(1,3,2)) gap> rc4 := RightCoset( Group( (1,2), (2,3) ), (3,4) );  RightCoset(Group([ (1,2), (2,3) ]),(3,4)) gap> lc4 := Inverse( rc4 ); LeftCoset((3,4),Group([ (1,2), (2,3) ])) gap> Intersection( lc2, lc4 ); [ (2,3,4), (1,2,3,4) ]   5.3 Functions for group homomorphisms 5.3-1 EpimorphismByGenerators EpimorphismByGenerators( G, H )  operation This function has been transferred from package RCWA. It constructs a group homomorphism which maps the generators of G to those of H. Its intended use is when G is a free group, and a warning is printed when this is not the case. Note that anything may happen if the resulting map is not a homomorphism!  Example   gap> G := Group( (1,2,3), (3,4,5), (5,6,7), (7,8,9) );; gap> phi := EpimorphismByGenerators( FreeGroup("a","b","c","d"), G ); [ a, b, c, d ] -> [ (1,2,3), (3,4,5), (5,6,7), (7,8,9) ] gap> PreImagesRepresentativeNC( phi, (1,2,3,4,5,6,7,8,9) ); d*c*b*a gap> a := G.1;; b := G.2;; c := G.3;; d := G.4;; gap> d*c*b*a; (1,2,3,4,5,6,7,8,9) gap> ## note that it is easy to produce nonsense:  gap> epi := EpimorphismByGenerators( Group((1,2,3)), Group((8,9)) ); Warning: calling GroupHomomorphismByImagesNC without checks [ (1,2,3) ] -> [ (8,9) ] gap> IsGroupHomomorphism( epi ); true gap> Image( epi, (1,2,3) );  () gap> Image( epi, (1,3,2) ); (8,9)   5.3-2 Pullback Pullback( hom1, hom2 )  operation PullbackInfo( G )  attribute If ϕ_1 : G_1 -> H and ϕ_2 : G_2 -> H are two group homomorphisms with the same range, then their pullback is the subgroup of G_1 × G_2 consisting of those elements (g_1,g_2) such that ϕ_1 g_1 = ϕ_2 g_2. The attribute PullbackInfo of a pullback group P is similar to DirectProductInfo for a direct product of groups. Its value is a record with the following components: directProduct the direct product G_1 × G_2, and projections a list with the two projections onto G_1 and G_2. There are no embeddings in this record, but it is possible to use the embeddings into the direct product, see Embedding (Reference: Embedding).  Example   gap> s4 := Group( (1,2),(2,3),(3,4) );; gap> s3 := Group( (5,6),(6,7) );; gap> c3 := Subgroup( s3, [ (5,6,7) ] );; gap> f := GroupHomomorphismByImages( s4, s3,  >  [(1,2),(2,3),(3,4)], [(5,6),(6,7),(5,6)] );;  gap> i := GroupHomomorphismByImages( c3, s3, [(5,6,7)], [(5,6,7)] );;  gap> Pfi := Pullback( f, i ); Group([ (2,3,4)(5,7,6), (1,2)(3,4) ]) gap> StructureDescription( Pfi ); "A4" gap> info := PullbackInfo( Pfi ); rec( directProduct := Group([ (1,2), (2,3), (3,4), (5,6,7) ]),   projections := [ [ (2,3,4)(5,7,6), (1,2)(3,4) ] -> [ (2,3,4), (1,2)(3,4) ],   [ (2,3,4)(5,7,6), (1,2)(3,4) ] -> [ (5,7,6), () ] ] ) gap> g := (1,2,3)(5,6,7);;  gap> ImageElm( info!.projections[1], g ); (1,2,3) gap> ImageElm( info!.projections[2], g ); (5,6,7)  gap> dp := info!.directProduct;;  gap> a := ImageElm( Embedding( dp, 1 ), (1,4,3) );;  gap> b := ImageElm( Embedding( dp, 2 ), (5,7,6) );;  gap> a*b in Pfi; true   5.3-3 CentralProduct CentralProduct( G1, G2, Z1, Phi )  operation CentralProductInfo( G )  attribute This function was added by Thomas Breuer, following discussions with Hongyi Zhao (see https://github.com/gap-packages/hap/issues/73). Let G1 and G2 be two groups, Z1 be a central subgroup of G1, and Phi be an isomorphism from Z1 to a central subgroup of G2. The central product defined by these arguments is the factor group of the direct product of G1 and G2 by the central subgroup { (z, (Phi(z))^-1) : z ∈ Z1 }. The attribute CentralProductInfo of a group G that has been created by CentralProduct is similar to PullbackInfo (5.3-2) for pullback groups. Its value is a record with the following components. projection the epimorphism from the direct product of G1 and G2 to G, and phi the map Phi. Note that one can access the direct product as the Source (Reference: Source) value of the projection map, and one can access G1 and G2 as the two embeddings of this direct product, see Embedding (Reference: Embedding).  Example  gap> g1 := DihedralGroup( 8 );  gap> c1 := Centre( g1 ); Group([ f3 ]) gap> cp1 := CentralProduct( g1, g1, c1, IdentityMapping( c1 ) ); Group([ f1, f2, f5, f3, f4, f5 ]) gap> IdGroup( cp1 ) = IdGroup( ExtraspecialGroup( 2^5, "+" ) ); true gap> g2 := QuaternionGroup( 8 );  gap> c2 := Centre( g2 ); Group([ y2 ]) gap> cp2 := CentralProduct( g2, g2, c2, IdentityMapping( c2 ) ); Group([ f1, f2, f5, f3, f4, f5 ]) gap> IdGroup( cp2 ) = IdGroup( ExtraspecialGroup( 2^5, "+" ) ); true gap> info2 := CentralProductInfo( cp2 ); rec( phi := IdentityMapping( Group([ y2 ]) ),   projection := [ f1, f2, f3, f4, f5, f6 ] -> [ f1, f2, f5, f3, f4, f5 ] ) gap> Source( Embedding( Source( info2.projection ), 1 ) ) = g2; true  5.3-4 IdempotentEndomorphisms IdempotentEndomorphisms( G )  operation IdempotentEndomorphismsData( G )  attribute IdempotentEndomorphismsWithImage( genG, R )  operation An endomorphism f : G -> G is idempotent if f^2=f. It has an image R leqslant G; is the identity map when restricted to R; and has a kernel N which has trivial intersection with R and has size |G|/|R|. The operation IdempotentEndomorphismsWithImage(genG,R) returns a list of the images of the generating set genG of a group G under the idempotent endomorphisms with image R. The attribute IdempotentEndomorphismsData(G) returns a record data with fields data.gens, a fixed generating set for G, and data.images a list of the non-empty outputs of IdempotentEndomorphismsWithImage(genG,R) obtained by iterating over all subgroups of G. The operation IdempotentEndomorphisms(G) returns the list of these mappings obtained using IdempotentEndomorphismsData(G). The first of these is the zero map, the second is the identity.  Example   gap> gens := [ (1,2,3,4), (1,2)(3,4) ];;  gap> d8 := Group( gens );; gap> SetName( d8, "d8" ); gap> c2 := Subgroup( d8, [ (2,4) ] );; gap> IdempotentEndomorphismsWithImage( gens, c2 ); [ [ (), (2,4) ], [ (2,4), () ] ] gap> IdempotentEndomorphismsData( d8 ); rec( gens := [ (1,2,3,4), (1,2)(3,4) ],   images := [ [ [ (), () ] ], [ [ (), (2,4) ], [ (2,4), () ] ],   [ [ (), (1,3) ], [ (1,3), () ] ],   [ [ (), (1,2)(3,4) ], [ (1,2)(3,4), (1,2)(3,4) ] ],   [ [ (), (1,4)(2,3) ], [ (1,4)(2,3), (1,4)(2,3) ] ],   [ [ (1,2,3,4), (1,2)(3,4) ] ] ] ) gap> List( last.images, L -> Length(L) ); [ 1, 2, 2, 2, 2, 1 ] gap> IdempotentEndomorphisms( d8 );  [ [ (1,2,3,4), (1,2)(3,4) ] -> [ (), () ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (2,4) ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (2,4), () ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (1,3) ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,3), () ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (1,2)(3,4) ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,2)(3,4), (1,2)(3,4) ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (), (1,4)(2,3) ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,4)(2,3), (1,4)(2,3) ],   [ (1,2,3,4), (1,2)(3,4) ] -> [ (1,2,3,4), (1,2)(3,4) ] ]   The quaternion group q8 is an example of a group with a tail: there is only one subgroup in the lattice which covers the identity subgroup. The only idempotent isomorphisms of such groups are the identity mapping and the zero mapping because the only pairs N,R are the whole group and the identity subgroup.  Example   gap> q8 := QuaternionGroup( 8 );; gap> IdempotentEndomorphisms( q8 ); [ [ x, y ] -> [ of ..., of ... ], [ x, y ] -> [ x, y ] ]   5.3-5 DirectProductOfFunctions DirectProductOfFunctions( G, H, f1, f2 )  operation Given group homomorphisms f_1 : G_1 -> G_2 and f_2 : H_1 -> H_2, this operation return the product homomorphism f_1 × f_2 : G_1 × G_2 -> H_1 × H_2.  Example   gap> c4 := Group( (1,2,3,4) );;  gap> c2 := Group( (5,6) );;  gap> f1 := GroupHomomorphismByImages( c4, c2, [(1,2,3,4)], [(5,6)] );; gap> c3 := Group( (1,2,3) );;  gap> c6 := Group( (1,2,3,4,5,6) );;  gap> f2 := GroupHomomorphismByImages( c3, c6, [(1,2,3)], [(1,3,5)(2,4,6)] );;  gap> c4c3 := DirectProduct( c4, c3 );  Group([ (1,2,3,4), (5,6,7) ]) gap> c2c6 := DirectProduct( c2, c6 );  Group([ (1,2), (3,4,5,6,7,8) ]) gap> f := DirectProductOfFunctions( c4c3, c2c6, f1, f2 );  [ (1,2,3,4), (5,6,7) ] -> [ (1,2), (3,5,7)(4,6,8) ] gap> ImageElm( f, (1,4,3,2)(5,7,6) );  (1,2)(3,7,5)(4,8,6)   5.3-6 DirectProductOfAutomorphismGroups DirectProductOfAutomorphismGroups( A1, A2 )  operation Let A_1,A_2 be groups of automorphism of groups G_1,G_2 respectively. The output of this function is a group A_1 × A_2 of automorphisms of G_1 × G_2.  Example   gap> c9 := Group( (1,2,3,4,5,6,7,8,9) );;  gap> ac9 := AutomorphismGroup( c9 );;  gap> q8 := QuaternionGroup( IsPermGroup, 8 );; gap> aq8 := AutomorphismGroup( q8 );; gap> A := DirectProductOfAutomorphismGroups( ac9, aq8 );  gap> genA := GeneratorsOfGroup( A );; gap> G := Source( genA[1] ); Group([ (1,2,3,4,5,6,7,8,9), (10,14,12,16)(11,17,13,15), (10,11,12,13) (14,15,16,17) ]) gap> a := genA[1]*genA[5];  [ (1,2,3,4,5,6,7,8,9), (10,14,12,16)(11,17,13,15), (10,11,12,13)(14,15,16,17)   ] -> [ (1,3,5,7,9,2,4,6,8), (10,16,12,14)(11,15,13,17),   (10,11,12,13)(14,15,16,17) ] gap> ImageElm( a, (1,9,8,7,6,5,4,3,2)(10,14,12,16)(11,17,13,15) ); (1,8,6,4,2,9,7,5,3)(10,16,12,14)(11,15,13,17)