Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->1<!-- %% -->2<!-- %W group.tex GAP documentation Thomas Breuer -->3<!-- %W & Frank Celler -->4<!-- %W & Martin Schönert -->5<!-- %W & Heiko Theißen -->6<!-- %% -->7<!-- %H @(#)<M>Id: group.tex,v 4.42 2006/11/08 11:50:35 gap Exp </M> -->8<!-- %% -->9<!-- %Y Copyright 1997, Lehrstuhl D für Mathematik, RWTH Aachen, Germany -->10<!-- %% -->11<!-- %% This file contains a tutorial introduction to groups. -->12<!-- %% -->13<P/>1415<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->16<Chapter Label="Groups and Homomorphisms">17<Heading>Groups and Homomorphisms</Heading>1819In this chapter we will show some computations with groups. The examples20deal mostly with permutation groups, because they are the easiest21to input.22The functions mentioned here, like <Ref Func="Group" BookName="ref"/>,23<Ref Func="Size" BookName="ref"/> or24<Ref Func="SylowSubgroup" BookName="ref"/>, however,25are the same for all kinds of groups, although26the algorithms which compute the information of course will be different27in most cases.282930<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->31<Section Label="Permutation groups">32<Heading>Permutation groups</Heading>3334Permutation groups are so easy to input because their elements, i.e.,35permutations, are so easy to type: they are entered and displayed in36disjoint cycle notation. So let's construct a permutation group:37<P/>38<Example><![CDATA[39gap> s8 := Group( (1,2), (1,2,3,4,5,6,7,8) );40Group([ (1,2), (1,2,3,4,5,6,7,8) ])41]]></Example>42<P/>43We formed the group generated by the permutations <C>(1,2)</C> and44<C>(1,2,3,4,5,6,7,8)</C>, which is well known to be the symmetric group45<M>S_8</M> on eight points, and assigned it to the identifier <C>s8</C>.46Now <M>S_8</M> contains the alternating group on eight points which can be47described in several ways, e.g., as the group of all even permutations48in <C>s8</C>, or as its derived subgroup. Once we ask &GAP; to verify that49the group is an alternating group acting in its natural permutation50representation, the system will display the group accordingly.51<P/>52<Example><![CDATA[53gap> a8 := DerivedSubgroup( s8 );54Group([ (1,2,3), (2,3,4), (2,4)(3,5), (2,6,4), (2,4)(5,7),55(2,8,6,4)(3,5) ])56gap> Size( a8 ); IsAbelian( a8 ); IsPerfect( a8 );572016058false59true60gap> IsNaturalAlternatingGroup(a8);61true62gap> a8;63Alt( [ 1 .. 8 ] )64]]></Example>65<P/>66Once information about a group like <C>s8</C> or <C>a8</C> has been computed,67it is stored in the group so that it can simply be looked up when it is68required again. This holds for all pieces of information in the69previous example. Namely, <C>a8</C> stores its order and that it is70nonabelian and perfect, and <C>s8</C> stores its derived subgroup <C>a8</C>.71Had we computed <C>a8</C> as <C>CommutatorSubgroup( s8, s8 )</C>, however, it72would not have been stored, because it would then have been computed73as a function of <E>two</E> arguments, and hence one could not attribute it74to just one of them.75(Of course the function <Ref Func="CommutatorSubgroup" BookName="ref"/> can76compute the commutator subgroup of <E>two</E> arbitrary subgroups.) The77situation is a bit different for Sylow <M>p</M>-subgroups: The function78<Ref Func="SylowSubgroup" BookName="ref"/> also requires two arguments,79namely a group and a80prime <M>p</M>, but the result is stored in the group –namely together81with the prime <M>p</M> in a list that can be accessed with82<C>ComputedSylowSubgroups</C>, but we83won't dwell on the details here.84<P/>85<Example><![CDATA[86gap> syl2 := SylowSubgroup( a8, 2 );; Size( syl2 );876488gap> Normalizer( a8, syl2 ) = syl2;89true90gap> cent := Centralizer( a8, Centre( syl2 ) );; Size( cent );9119292gap> DerivedSeries( cent );; List( last, Size );93[ 192, 96, 32, 2, 1 ]94]]></Example>95<P/>96We have typed double semicolons after some commands to avoid the output97of the groups (which would be printed by their generator lists).98Nevertheless, the beginner is encouraged to type a single semicolon99instead and study the full output. This remark also applies for the rest100of this tutorial.101<P/>102With the next examples, we want to calculate a subgroup of <C>a8</C>, then103its normalizer and finally determine the structure of the extension. We104begin by forming a subgroup generated by three commuting involutions,105i.e., a subgroup isomorphic to the additive group of the vector space106<M>2^3</M>.107<P/>108<Example><![CDATA[109gap> elab := Group( (1,2)(3,4)(5,6)(7,8), (1,3)(2,4)(5,7)(6,8),110> (1,5)(2,6)(3,7)(4,8) );;111gap> Size( elab );1128113gap> IsElementaryAbelian( elab );114true115]]></Example>116<P/>117As usual, &GAP; prints the group by giving all its generators. This can118be annoying, especially if there are many of them or if they are of huge119degree. It also makes it difficult to recognize a particular group when120there are already several around. Note that although it is no problem for121<E>us</E> to specify a particular group to &GAP;, by using well-chosen122identifiers such as <C>a8</C> and <C>elab</C>, it is impossible for &GAP; to use123these identifiers when printing a group for us, because the group does124not know which identifier(s) point to it, in fact there can be several.125In order to give a name to the group itself (rather than to the126identifier),127you can use the function <Ref Func="SetName" BookName="ref"/>.128We do this with the129name <C>2^3</C> here which reflects the mathematical properties of the group.130From now on, &GAP; will use this name when printing the group for us,131but we still cannot use this name to specify the group to &GAP;, because132the name does not know to which group it was assigned (after all, you133could assign the same name to several groups). When talking to the134computer, you must always use identifiers.135<P/>136<Example><![CDATA[137gap> SetName( elab, "<group of type 2^3>" ); elab;138<group of type 2^3>139gap> norm := Normalizer( a8, elab );; Size( norm );1401344141]]></Example>142<P/>143<Index Subkey="natural">homomorphism</Index>144Now that we have the subgroup <C>norm</C> of order 1344 and its subgroup145<C>elab</C>, we want to look at its factor group. But since we also want to146find preimages of factor group elements in <C>norm</C>, we really want to look147at the <E>natural homomorphism</E> defined on <C>norm</C> with kernel <C>elab</C> and148whose image is the factor group.149<P/>150<Example><![CDATA[151gap> hom := NaturalHomomorphismByNormalSubgroup( norm, elab );152<action epimorphism>153gap> f := Image( hom );154Group([ (), (), (), (4,5)(6,7), (4,6)(5,7), (2,3)(6,7), (2,4)(3,5),155(1,2)(5,6) ])156gap> Size( f );157168158]]></Example>159<P/>160The factor group is again represented as a permutation group161(its first three generators are trivial, meaning that the first three162generators of the preimage are in the kernel of <C>hom</C>). However,163the action domain of this factor group has nothing to do with the164action domain of <C>norm</C>. (It only happens that both are subsets of the165natural numbers.) We can now form images and preimages under the natural166homomorphism. The set of preimages of an element under <C>hom</C> is a coset167modulo <C>elab</C>.168We use the function <Ref Func="PreImages" BookName="ref"/> here because169<C>hom</C> is not170a bijection, so an element of the range can have several preimages or171none at all.172<P/>173<Example><![CDATA[174gap> ker:= Kernel( hom );175<group of type 2^3>176gap> x := (1,8,3,5,7,6,2);; Image( hom, x );177(1,7,5,6,2,3,4)178gap> coset := PreImages( hom, last );179RightCoset(<group of type 2^3>,(2,8,6,7,3,4,5))180]]></Example>181<P/>182Note that &GAP; is free to choose any representative for the coset183of preimages.184Of course the quotient of two representatives lies in the kernel of185the homomorphism.186<P/>187<Example><![CDATA[188gap> rep:= Representative( coset );189(2,8,6,7,3,4,5)190gap> x * rep^-1 in ker;191true192]]></Example>193<P/>194The factor group <C>f</C> is a simple group, i.e., it has no non-trivial195normal subgroups. &GAP; can detect this fact, and it can then also find196the name by which this simple group is known among group theorists. (Such197names are of course not available for non-simple groups.)198<P/>199<Example><![CDATA[200gap> IsSimple( f ); IsomorphismTypeInfoFiniteSimpleGroup( f );201true202rec(203name := "A(1,7) = L(2,7) ~ B(1,7) = O(3,7) ~ C(1,7) = S(2,7) ~ 2A(1,\2047) = U(2,7) ~ A(2,2) = L(3,2)", parameter := [ 2, 7 ], series := "L" )205gap> SetName( f, "L_3(2)" );206]]></Example>207<P/>208We give <C>f</C> the name <C>L_3(2)</C> because the last part of the name string209reveals that it is isomorphic to the simple linear group <M>L_3(2)</M>. This210group, however, also has a lot of other names. Names that are connected211with a <C>=</C> sign are different names for the same matrix group, e.g.,212<C>A(2,2)</C> is the Lie type notation for the classical notation <C>L(3,2)</C>.213Other pairs of names are connected via <C>~</C>, these then specify other214classical groups that are isomorphic to that linear group (e.g., the215symplectic group <C>S(2,7)</C>, whose Lie type notation would be <C>C(1,7)</C>).216<P/>217The group <C>norm</C> acts on the eight elements of its normal subgroup <C>elab</C>218by conjugation, yielding a representation of <M>L_3(2)</M> in <C>s8</C> which219leaves one point fixed (namely point <C>1</C>).220The image of this representation can be computed with the function221<Ref Func="Action" BookName="ref"/>; it is even222contained in the group <C>norm</C> and we can show that <C>norm</C> is indeed a223split extension of the elementary abelian group <M>2^3</M> with this image of224<M>L_3(2)</M>.225<P/>226<Example><![CDATA[227gap> op := Action( norm, elab );228Group([ (), (), (), (5,6)(7,8), (5,7)(6,8), (3,4)(7,8), (3,5)(4,6),229(2,3)(6,7) ])230gap> IsSubgroup( a8, op ); IsSubgroup( norm, op );231true232true233gap> IsTrivial( Intersection( elab, op ) );234true235gap> SetName( norm, "2^3:L_3(2)" );236]]></Example>237<P/>238By the way, you should not try the operator <C><</C> instead of the function239<Ref Func="IsSubgroup" BookName="ref"/>. Something like240<P/>241<Example><![CDATA[242gap> elab < a8;243false244]]></Example>245<P/>246will not cause an error, but the result does not signify anything about the247inclusion of one group in another; <C><</C> tests which of the two groups is248less in some total order. On the other hand, the equality operator <C>=</C> in249fact does test the equality of its arguments.250<P/>251<E>Summary.</E> In this section we have used the elementary group252functions to determine the structure of a normalizer. We have assigned253names to the involved groups which reflect their mathematical structure254and &GAP; uses these names when printing the groups.255256</Section>257258259<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->260<Section Label="Actions of Groups">261<Heading>Actions of Groups</Heading>262263In order to get another representation of <C>a8</C>, we consider another264action, namely that on the elements of a certain conjugacy class by265conjugation.266<P/>267In the following example we temporarily increase the line length limit268from its default value 80 to 82 in order to make the long expression fit269into one line.270<P/>271<Example><![CDATA[272gap> ccl := ConjugacyClasses( a8 );; Length( ccl );27314274gap> List( ccl, c -> Order( Representative( c ) ) );275[ 1, 2, 2, 3, 6, 3, 4, 4, 5, 15, 15, 6, 7, 7 ]276gap> List( ccl, Size );277[ 1, 210, 105, 112, 1680, 1120, 2520, 1260, 1344, 1344, 1344, 3360,2782880, 2880 ]279]]></Example>280<P/>281Note the difference between <Ref Func="Order" BookName="ref"/>282(which means the element order),283<Ref Func="Size" BookName="ref"/>284(which means the size of the conjugacy class) and285<Ref Func="Length" BookName="ref"/> (which means the length of a list).286We choose to let <C>a8</C> operate on the class of length 112.287<P/>288<Example><![CDATA[289gap> class := First( ccl, c -> Size(c) = 112 );;290gap> op := Action( a8, AsList( class ),OnPoints );;291]]></Example>292<P/>293We use <Ref Func="AsList" BookName="ref"/> here to convert the conjugacy294class into a list of its elements whereas we wrote295<C>Action( norm, elab )</C> directly in the previous section.296The reason is that the elementary abelian group <C>elab</C>297can be quickly enumerated by &GAP; whereas the standard enumeration298method for conjugacy classes is slower than just explicit calculation of299the elements. However, &GAP; is reluctant to construct explicit element300lists, because for really large groups this direct method is infeasible.301<P/>302Note also the function <Ref Func="First" BookName="ref"/>,303used to find the first element in a list which passes some test.304<P/>305In this example,306we have specified the action function <Ref Func="OnPoints" BookName="ref"/>307in this example,308which is defined as309<C>OnPoints( </C><M>d</M><C>, </C><M>g</M><C> ) = </C><M>d</M><C> ^ </C><M>g</M>.310This <Q>caret</Q> operator denotes conjugation in a group if both311arguments <M>d</M> and <M>g</M> are group elements (contained in a common312group), but it also denotes the natural action of permutations on313positive integers (and exponentiation of integers as well, of course).314It is in fact the default action and will be supplied by the system if not315given. Another common action is for example316always assumes <Ref Func="OnRight" BookName="ref"/>, which means right317multiplication, defined as <M>d</M><C> * </C><M>g</M>.318(Group actions in &GAP; are always from the right.)319<P/>320We now have a permutation representation <C>op</C> on 112 points, which we321test for primitivity. If it is not primitive, we can obtain a minimal322block system (i.e., one where the blocks have minimal length) by the323function <Ref Func="Blocks" BookName="ref"/>.324<P/>325<Example><![CDATA[326gap> IsPrimitive( op, [ 1 .. 112 ] );327false328gap> blocks := Blocks( op, [ 1 .. 112 ] );;329]]></Example>330<P/>331Note that we must specify the domain of the action. You might think332that the functions <Ref Func="IsPrimitive" BookName="ref"/> and333<Ref Func="Blocks" BookName="ref"/> could use <C>[ 1 .. 112 ]</C> as334default domain if no domain was given. But this is not so easy,335for example would the default domain of <C>Group( (2,3,4) )</C> be336<C>[ 1 .. 4 ]</C> or <C>[ 2 .. 4 ]</C>?337To avoid confusion, all action functions require that you338specify the domain of action.339If we had specified <C>[ 1 .. 113 ]</C> in the340primitivity test above, point 113 would have been a fixpoint (and the341action would not even have been transitive).342<P/>343Now <C>blocks</C> is a list of blocks (i.e., a list of lists), which we do not344print here for the sake of saving paper (try it for yourself). In fact345all we want to know is the size of the blocks, or rather how many there346are (the product of these two numbers must of course be 112). Then we can347obtain a new permutation group of the corresponding degree by letting348<C>op</C> act on these blocks setwise.349<P/>350<Example><![CDATA[351gap> Length( blocks[1] ); Length( blocks );352235356354gap> op2 := Action( op, blocks, OnSets );;355gap> IsPrimitive( op2, [ 1 .. 56 ] );356true357]]></Example>358<P/>359Note that we give a third argument (the action function360<Ref Func="OnSets" BookName="ref"/>) to361indicate that the action is not the default action on points but an362action on sets of elements given as sorted lists.363(Section <Ref Sect="Basic Actions" BookName="ref"/> lists all364actions that are pre-defined by &GAP;.)365<P/>366The action of <C>op</C> on the given block system gave us a new representation367on 56 points which is primitive, i.e., the point stabilizer is a maximal368subgroup. We compute its preimage in the representation on eight points369using the associated action homomorphisms (which of course in this370case are371monomorphisms). We construct the composition of two homomorphisms with372the <C>*</C> operator, reading left-to-right.373<P/>374<Example><![CDATA[375gap> ophom := ActionHomomorphism( a8, op );;376gap> ophom2 := ActionHomomorphism( op, op2 );;377gap> composition := ophom * ophom2;;378gap> stab := Stabilizer( op2, 2 );;379gap> preim := PreImages( composition, stab );380Group([ (1,4,2), (3,6,7), (3,8,5,7,6), (1,4)(7,8) ])381]]></Example>382<P/>383Alternatively, it is possible to create action homomorphisms immediately384(without creating the action first) by giving the same set of arguments to385<Ref Func="ActionHomomorphism" BookName="ref"/>.386<Example><![CDATA[387gap> nophom := ActionHomomorphism( a8, AsList(class) );388<action homomorphism>389gap> IsSurjective(nophom);390false391gap> Image(nophom,(1,2,3));392(2,43,14)(3,44,20)(4,45,26)(5,46,32)(6,47,38)(8,13,48)(9,19,53)(10,25,39358)(11,31,63)(12,37,68)(15,49,73)(16,50,74)(17,51,75)(18,52,76)(21,54,39477)(22,55,78)(23,56,79)(24,57,80)(27,59,81)(28,60,82)(29,61,83)(30,62,39584)(33,64,85)(34,65,86)(35,66,87)(36,67,88)(39,69,89)(40,70,90)(41,71,39691)(42,72,92)397]]></Example>398<P/>399In this situation, however (for performance reasons, avoiding computation400an image that might never be needed) the homomorphism is defined to be not401into the <E>Image</E> of the action, but into the <E>full symmetric402group</E>, i.e. it is not automatically surjective. Surjectivity can be403enforced by giving the string <C>"surjective"</C> as an extra last argument.404The <C>Image</C> of the action homomorphism of course is the same group in405either case.406<Example><![CDATA[407gap> Size(Range(nophom));4081974506857221074023536820372759924883412778680349753377966562950949028\4095896977181144089422435502777936659795733823785363827233491968638562181\4101850780464277094400000000000000000000000000411gap> Size(Range(ophom));41220160413gap> nophom := ActionHomomorphism( a8, AsList(class),"surjective" );414<action epimorphism>415gap> Size(Range(nophom));41620160417]]></Example>418<P/>419Continuing the example,420the normalizer of an element in the conjugacy class <C>class</C> is a group of421order 360, too. In fact, it is a conjugate of the maximal subgroup we had422found before, and a conjugating element in <C>a8</C> is found by the function423<Ref Func="RepresentativeAction" BookName="ref"/>.424<P/>425<Example><![CDATA[426gap> sgp := Normalizer( a8, Subgroup(a8,[Representative(class)]) );;427gap> Size( sgp );428360429gap> RepresentativeAction( a8, sgp, preim );430(2,4,3)431]]></Example>432<!-- % The scalar product of permutation characters of two subgroups <A>U</A>, <A>V</A>, -->433<!-- % say, equals the number of <M>(<A>U</A>,<A>V</A>)</M>-double cosets. For example, the -->434<!-- % norm of the natural permutation character of degree eight is two since -->435<!-- % the action of <C>a8</C> on the cosets of a point stabilizer is at least doubly -->436<!-- % transitive. We also compute the numbers of <M>(<C>sgp</C>,<C>sgp</C>)</M> and -->437<!-- % <M>(<C>sgp</C>,<C>stab</C>)</M> double cosets. -->438<!-- % \b eginexample -->439<!-- % gap> stab := Stabilizer( a8, 1 );; -->440<!-- % gap> Length( DoubleCosets( a8, stab, stab ) ); -->441<!-- % 2 -->442<!-- % gap> Length( DoubleCosets( a8, sgp, sgp ) ); -->443<!-- % 4 -->444<!-- % gap> Length( DoubleCosets( a8, sgp, stab ) ); -->445<!-- % 2 -->446<!-- % \e ndexample -->447<P/>448<Index Subkey="operation">homomorphism</Index>449<Index Subkey="action">homomorphism</Index>450<Index>enumerator</Index>451<Index>transversal</Index>452<Index>canonical position</Index>453454One of the most prominent actions of a group is on the cosets of a subgroup.455Naïvely this can be done by constructing the cosets and acting on them456by right multiplication.457<Example><![CDATA[458gap> cosets:=RightCosets(a8,norm);;459gap> op:=Action(a8,cosets,OnRight);460Group([ (1,2,3)(4,6,5)(7,8,9)(10,12,11)(13,14,15),461(1,3,2)(4,9,13)(5,11,7)(6,15,10)(8,12,14),462(1,13)(2,7)(3,10)(4,11)(5,15)(6,9),463(1,8,13)(2,7,12)(3,9,5)(4,14,11)(6,10,15),464(2,3)(4,14)(5,7)(8,13)(9,12)(10,15),465(1,8)(2,3,11,6)(4,12,10,15)(5,7,14,9) ])466gap> NrMovedPoints(op);46715468]]></Example>469<P/>470A problem with this approach is that creating (and storing) all cosets can471be very memory intensive if the subgroup index gets large.472Because of this, &GAP; provides special473objects which act like a list of elements, but do not actually store474elements but compute them on the go. Such a simulated list is called an475<E>enumerator</E>. The easiest example of this concept is the476<Ref Func="Enumerator" BookName="ref"/> of a group.477While it behaves like a list of elements, it requires far less storage, and478is applicable to potentially huge groups for which it would be completely479infeasible to write down all elements:480<Example><![CDATA[481gap> enum:=Enumerator(SymmetricGroup(20));482<enumerator of perm group>483gap> Length(enum);4842432902008176640000485gap> enum[123456789012345];486(1,4,15,3,14,11,8,17,6,18,5,7,20,13,10,9,2,12)487gap> Position(enum,(1,2,3,4,5,6,7,8,9,10));48871948729603489]]></Example>490<P/>491For the action on cosets the object of interest is the492<Ref Func="RightTransversal" BookName="ref"/> of a subgroup. Again, it does493not write out actual elements and thus can be created even for subgroups of494large index.495<Example><![CDATA[496gap> t:=RightTransversal(a8,norm);497RightTransversal(Alt( [ 1 .. 8 ] ),2^3:L_3(2))498gap> t[7];499(4,6,5)500gap> Position(t,(4,6,7,8,5));5018502gap> Position(t,(1,2,3));503fail504]]></Example>505<P/>506For the action on cosets there is the added complication that not507every group element is in the transversal (as the last example shows) but508the action on cosets of a subgroup509usually will not preserve a chosen set of coset representatives.510Because of this issue, all action functionality actually uses511<Ref Func="PositionCanonical" BookName="ref"/> instead of512<Ref Func="Position" BookName="ref"/>. In general, for elements contained in513a list,514<Ref Func="PositionCanonical" BookName="ref"/> returns the same as515<C>Position</C>. If the element is not contained in the list (and for516special lists, such as transversals), <C>PositionCanonical</C> returns the517list element representing the same objects, e.g. the transversal element518representing the same coset.519<Example><![CDATA[520gap> PositionCanonical(t,(1,2,3));5212522gap> t[2];523(6,7,8)524gap> t[2]/(1,2,3);525(1,3,2)(6,7,8)526gap> last in norm;527true528]]></Example>529Thus, acting on a <C>RightTransversal</C> with the <C>OnRight</C> action530will in fact (in a slight abuse of definitions)531produce the action of a group on cosets of a subgroup and is in general the532most efficient way of creating this action.533<Example><![CDATA[534gap> Action(a8,RightTransversal(a8,norm),OnRight);535Group([ (1,2,3)(4,6,5)(7,8,9)(10,12,11)(13,14,15),536(1,3,2)(4,9,13)(5,11,7)(6,15,10)(8,12,14),537(1,13)(2,7)(3,10)(4,11)(5,15)(6,9),538(1,8,13)(2,7,12)(3,9,5)(4,14,11)(6,10,15),539(2,3)(4,14)(5,7)(8,13)(9,12)(10,15),540(1,8)(2,3,11,6)(4,12,10,15)(5,7,14,9) ])541]]></Example>542<P/>543544<E>Summary.</E> In this section we have learned how groups can operate on545&GAP; objects such as integers and group elements. We have used546<Ref Func="ActionHomomorphism" BookName="ref"/>,547among others, to construct the corresponding actions and homomorphisms548and have seen how transversals can be used to create the action on cosets of549a subgroup.550</Section>551552553<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->554<Section Label="Subgroups!as Stabilizers">555<Heading>Subgroups as Stabilizers</Heading>556557Action functions can also be used without constructing external sets.558We will try to find several subgroups in <C>a8</C> as stabilizers of such559actions. One subgroup is immediately available, namely the stabilizer560of one point. The index of the stabilizer must of course be equal to the561length of the orbit, i.e., 8.562<P/>563<Example><![CDATA[564gap> u8 := Stabilizer( a8, 1 );565Group([ (2,3,4,5,6,7,8), (2,4,5,6,7,8,3) ])566gap> Index( a8, u8 );5678568gap> Orbit( a8, 1 ); Length( last );569[ 1, 3, 2, 4, 5, 6, 7, 8 ]5708571]]></Example>572<P/>573This gives us a hint how to find further subgroups. Each subgroup is the574stabilizer of a point of an appropriate transitive action (namely the575action on the cosets of that subgroup or another action that is576equivalent to this action). So the question is how to find other577actions. The obvious thing is to operate on pairs of points.578So using the function <Ref Func="Tuples" BookName="ref"/> we first generate579a list of all pairs.580<P/>581<Example><![CDATA[582gap> pairs := Tuples( [1..8], 2 );;583]]></Example>584<P/>585Now we would like to have <C>a8</C> operate on this domain.586But we cannot use the default action <Ref Func="OnPoints" BookName="ref"/>587because powering a list by a permutation via the caret operator <C>^</C>588is not defined. So we must tell the functions from the actions package how589the group elements operate on the elements of the domain590(here and below, the word <Q>package</Q> refers to the &GAP; functionality591for group actions, not to a &GAP; package). In our example592we can do this by simply passing <Ref Func="OnPairs" BookName="ref"/>593as an optional last argument.594All functions from the actions package accept such an optional argument595that describes the action.596One example is <Ref Func="IsTransitive" BookName="ref"/>.597<P/>598<Example><![CDATA[599gap> IsTransitive( a8, pairs, OnPairs );600false601]]></Example>602<P/>603The action is of course not transitive, since the pairs <C>[ 1, 1 ]</C> and604<C>[ 1, 2 ]</C> cannot lie in the same orbit.605So we want to find out what the orbits are.606The function <Ref Func="Orbits" BookName="ref"/> does that for us.607It returns a list of all the orbits.608We look at the orbit lengths and representatives for the orbits.609<P/>610<Example><![CDATA[611gap> orbs := Orbits( a8, pairs, OnPairs );; Length( orbs );6122613gap> List( orbs, Length );614[ 8, 56 ]615gap> List( orbs, o -> o[1] );616[ [ 1, 1 ], [ 1, 2 ] ]617]]></Example>618<P/>619The action of <C>a8</C> on the first orbit (this is the one containing620<C>[1,1]</C>, try <C>[1,1] in orbs[1]</C>) is of course equivalent to the original621action, so we ignore it and work with the second orbit.622<P/>623<Example><![CDATA[624gap> u56 := Stabilizer( a8, orbs[2][1], OnPairs );; Index( a8, u56 );62556626]]></Example>627<P/>628So now we have found a second subgroup. To make the following629computations a little bit easier and more efficient we would now like to630work on the points <C>[ 1 .. 56 ]</C> instead of the list of pairs.631The function <Ref Func="ActionHomomorphism" BookName="ref"/> does what we632need.633It creates a homomorphism defined on <C>a8</C> whose image is a new group634that acts on <C>[ 1 .. 56 ]</C> in635the same way that <C>a8</C> acts on the second orbit.636<P/>637<Example><![CDATA[638gap> h56 := ActionHomomorphism( a8, orbs[2], OnPairs );;639gap> a8_56 := Image( h56 );;640]]></Example>641<P/>642We would now like to know if the subgroup <C>u56</C> of index 56 that we found643is maximal or not.644As we have used already in Section <Ref Sect="Actions of Groups"/>,645a subgroup is maximal if and only if the action on the cosets of this646subgroup is primitive.647<P/>648<Example><![CDATA[649gap> IsPrimitive( a8_56, [1..56] );650false651]]></Example>652<P/>653Remember that we can leave out the function if we mean654<Ref Func="OnPoints" BookName="ref"/>655but that we have to specify the action domain for all action functions.656<P/>657We see that <C>a8_56</C> is not primitive. This means of course that the658action of <C>a8</C> on <C>orb[2]</C> is not primitive, because those two659actions are equivalent. So the stabilizer <C>u56</C> is not maximal. Let us660try to find its supergroups.661We use the function <Ref Func="Blocks" BookName="ref"/> to find a block662system. The (optional) third argument in the following example tells663<Ref Func="Blocks" BookName="ref"/> that we want a block system664where 1 and 3 lie in one block.665<P/>666<Example><![CDATA[667gap> blocks := Blocks( a8_56, [1..56], [1,3] );;668]]></Example>669<P/>670The result is a list of sets, such that <C>a8_56</C> acts on those sets.671Now we would like the stabilizer of this action on the sets.672Because we want to operate on the sets we have to pass673<Ref Func="OnSets" BookName="ref"/> as third argument.674<P/>675<Example><![CDATA[676gap> u8_56 := Stabilizer( a8_56, blocks[1], OnSets );;677gap> Index( a8_56, u8_56 );6788679gap> u8b := PreImages( h56, u8_56 );; Index( a8, u8b );6808681gap> IsConjugate( a8, u8, u8b );682true683]]></Example>684<P/>685So we have found a supergroup of <C>u56</C> that is conjugate in <C>a8</C> to <C>u8</C>.686This is not surprising, since <C>u8</C> is a point stabilizer, and <C>u56</C> is a687two point stabilizer in the natural action of <C>a8</C> on eight points.688<P/>689Here is a <E>warning</E>:690If you specify <Ref Func="OnSets" BookName="ref"/> as third argument to a691function like <Ref Func="Stabilizer" BookName="ref"/>,692you have to make sure that the point (i.e.693the second argument) is indeed a set. Otherwise you will get a puzzling694error message or even wrong results!695In the above example, the second argument <C>blocks[1]</C> came from the696function <Ref Func="Blocks" BookName="ref"/>, which returns a697list of sets, so everything was OK.698<P/>699Actually there is a third block system of <C>a8_56</C> that gives rise to a700third subgroup.701<P/>702<Example><![CDATA[703gap> blocks := Blocks( a8_56, [1..56], [1,13] );;704gap> u28_56 := Stabilizer( a8_56, [1,13], OnSets );;705gap> u28 := PreImages( h56, u28_56 );;706gap> Index( a8, u28 );70728708]]></Example>709<P/>710We know that the subgroup <C>u28</C> of index 28 is maximal, because we know711that <C>a8</C> has no subgroups of index 2, 4, or 7. However we can also712quickly verify this by checking that <C>a8_56</C> acts primitively on the71328 blocks.714<P/>715<Example><![CDATA[716gap> IsPrimitive( a8_56, blocks, OnSets );717true718]]></Example>719<P/>720<Ref Func="Stabilizer" BookName="ref"/> is not only applicable to groups721like <C>a8</C> but also to their722subgroups like <C>u56</C>. So another method to find a new subgroup is to723compute the stabilizer of another point in <C>u56</C>. Note that <C>u56</C> already724leaves 1 and 2 fixed.725<P/>726<Example><![CDATA[727gap> u336 := Stabilizer( u56, 3 );;728gap> Index( a8, u336 );729336730]]></Example>731<P/>732Other functions are also applicable to subgroups. In the following we733show that <C>u336</C> acts regularly on the 60 triples of734<C>[ 4 .. 8 ]</C> which735contain no element twice.736We construct the list of these 60 triples with737the function <Ref Func="Orbit" BookName="ref"/>738(using <Ref Func="OnTuples" BookName="ref"/> as the natural generalization739of <Ref Func="OnPairs" BookName="ref"/>)740and then pass it as action domain to the function741<Ref Func="IsRegular" BookName="ref"/>.742The positive result of the regularity test means that this743action is equivalent to the actions of <C>u336</C> on its 60 elements744from the right.745<P/>746<Example><![CDATA[747gap> IsRegular( u336, Orbit( u336, [4,5,6], OnTuples ), OnTuples );748true749]]></Example>750<P/>751Just as we did in the case of the action on the pairs above, we now752construct a new permutation group that acts on <C>[ 1 .. 336 ]</C>753in the same way that <C>a8</C> acts on the cosets of <C>u336</C>.754But this time we let <C>a8</C> operate on a right transversal,755just like <C>norm</C> did in the natural homomorphism above.756<P/>757<Example><![CDATA[758gap> t := RightTransversal( a8, u336 );;759gap> a8_336 := Action( a8, t, OnRight );;760]]></Example>761<P/>762To find subgroups above <C>u336</C> we again look for nontrivial block systems.763<P/>764<Example><![CDATA[765gap> blocks := Blocks( a8_336, [1..336] );; blocks[1];766[ 1, 43, 85 ]767]]></Example>768<P/>769We see that the union of <C>u336</C> with its 43rd and its 85th coset770is a subgroup in <C>a8_336</C>, its index is 112.771We can obtain it as the closure of <C>u336</C> with a representative772of the 43rd coset, which can be found as the 43rd element773of the transversal <C>t</C>.774Note that in the representation <C>a8_336</C> on 336 points,775this subgroup corresponds to the stabilizer of the block <C>[ 1, 43, 85 ]</C>.776<P/>777<Example><![CDATA[778gap> u112 := ClosureGroup( u336, t[43] );;779gap> Index( a8, u112 );780112781]]></Example>782<P/>783Above this subgroup of index 112 lies a subgroup of index 56, which is784not conjugate to <C>u56</C>. In fact, unlike <C>u56</C> it is maximal. We obtain785this subgroup in the same way that we obtained <C>u112</C>, this time forcing786two points, namely 7 and 43 into the first block.787<P/>788<Example><![CDATA[789gap> blocks := Blocks( a8_336, [1..336], [1,7,43] );;790gap> Length( blocks );79156792gap> u56b := ClosureGroup( u112, t[7] );; Index( a8, u56b );79356794gap> IsPrimitive( a8_336, blocks, OnSets );795true796]]></Example>797<P/>798We already mentioned in Section <Ref Sect="Actions of Groups"/>799that there is another standard800action of permutations, namely the conjugation.801E.g., since no other action is specified in the following example,802<Ref Func="OrbitLength" BookName="ref"/> simply acts via803<Ref Func="OnPoints" BookName="ref"/>,804and because <A>perm_1</A><C> ^ </C><A>perm_2</A> is defined as the conjugation805of <A>perm_2</A> on <A>perm_1</A>, in fact we compute the length of806the conjugacy class of <C>(1,2)(3,4)(5,6)(7,8)</C>.807<P/>808<Example><![CDATA[809gap> OrbitLength( a8, (1,2)(3,4)(5,6)(7,8) );810105811gap> orb := Orbit( a8, (1,2)(3,4)(5,6)(7,8) );;812gap> u105 := Stabilizer( a8, (1,2)(3,4)(5,6)(7,8) );; Index( a8, u105 );813105814]]></Example>815<P/>816Note that although the length of a conjugacy class of any element <M>g</M>817in any finite group <M>G</M> can be computed as818<C>OrbitLength( </C><M>G</M><C>, </C><M>g</M><C> )</C>,819the command <C>Size( ConjugacyClass( </C><M>G</M><C>, </C><M>g</M><C> ) )</C>820is probably more efficient.821<P/>822<Example><![CDATA[823gap> Size( ConjugacyClass( a8, (1,2)(3,4)(5,6)(7,8) ) );824105825]]></Example>826<P/>827Of course the stabilizer <C>u105</C> is in fact the centralizer of the element828<C>(1,2)(3,4)(5,6)(7,8)</C>.829<Ref Func="Stabilizer" BookName="ref"/> notices that and computes the830stabilizer using the centralizer algorithm for permutation groups. In the831usual way we now look for the subgroups above <C>u105</C>.832<P/>833<Example><![CDATA[834gap> blocks := Blocks( a8, orb );; Length( blocks );83515836gap> blocks[1];837[ (1,2)(3,4)(5,6)(7,8), (1,3)(2,4)(5,7)(6,8), (1,4)(2,3)(5,8)(6,7),838(1,5)(2,6)(3,7)(4,8), (1,6)(2,5)(3,8)(4,7), (1,7)(2,8)(3,5)(4,6),839(1,8)(2,7)(3,6)(4,5) ]840]]></Example>841<P/>842To find the subgroup of index 15 we again use closure. Now we must be a843little bit careful to avoid confusion. <C>u105</C> is the stabilizer of844<C>(1,2)(3,4)(5,6)(7,8)</C>. We know that there is a correspondence between845the points of the orbit and the cosets of <C>u105</C>. The point846<C>(1,2)(3,4)(5,6)(7,8)</C> corresponds to <C>u105</C>.847To get the subgroup above <C>u105</C> that has index 15 in <C>a8</C>,848we must form the closure of <C>u105</C> with an element of the coset that849corresponds to any other point in the first block.850If we choose the point <C>(1,3)(2,4)(5,8)(6,7)</C>,851we must use an element of <C>a8</C> that maps <C>(1,2)(3,4)(5,6)(7,8)</C> to852<C>(1,3)(2,4)(5,8)(6,7)</C>.853The function <Ref Func="RepresentativeAction" BookName="ref"/> does854what we need.855It takes a group and two points and returns an element of the group856that maps the first point to the second.857In fact it also allows you to specify the action as an optional fourth858argument as usual, but we do not need this here.859If no such element exists in the group, i.e., if the two points do not860lie in one orbit under the group,861<Ref Func="RepresentativeAction" BookName="ref"/> returns <K>fail</K>.862<P/>863<Example><![CDATA[864gap> rep := RepresentativeAction( a8, (1,2)(3,4)(5,6)(7,8),865> (1,3)(2,4)(5,8)(6,7) );866(2,3)(6,8)867gap> u15 := ClosureGroup( u105, rep );; Index( a8, u15 );86815869]]></Example>870<P/>871<C>u15</C> is of course a maximal subgroup, because <C>a8</C> has no subgroups of872index 3 or 5. There is in fact another class of subgroups of index 15873above <C>u105</C> that we get by adding <C>(2,3)(6,7)</C> to <C>u105</C>.874<P/>875<Example><![CDATA[876gap> u15b := ClosureGroup( u105, (2,3)(6,7) );; Index( a8, u15b );87715878gap> RepresentativeAction( a8, u15, u15b );879fail880]]></Example>881<P/>882<Ref Func="RepresentativeAction" BookName="ref"/> tells us that there is no883element <M>g</M> in <C>a8</C>884such that <C>u15 ^ </C><M>g</M><C> = u15b</C>.885Because <C>^</C> also denotes the conjugation of subgroups886this tells us that <C>u15</C> and <C>u15b</C> are not conjugate.887<P/>888<E>Summary.</E> In this section we have demonstrated some functions from889the actions package. There is a whole class of functions that we did890not mention, namely those that take a single element instead of a whole891group as first argument, e.g., <Ref Func="Cycle" BookName="ref"/> and892<Ref Func="Permutation" BookName="ref"/>. These are fully893described in Chapter <Ref Chap="Group Actions" BookName="ref"/>.894895</Section>896897898<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->899<Section Label="Group Homomorphisms!by Images">900<Heading>Group Homomorphisms by Images</Heading>901902We have already seen examples of group homomorphisms in the last903sections, namely natural homomorphisms and action homomorphisms.904In this section we will show how to construct a group homomorphism905<M>G \rightarrow H</M>906by specifying a generating set for <M>G</M> and the images of these generators907in <M>H</M>.908We use the function909<C>GroupHomomorphismByImages( <A>G</A>, <A>H</A>, <A>gens</A>,910<A>imgs</A> )</C> where <A>gens</A> is a generating set for <A>G</A> and <A>imgs</A> is a list911whose <M>i</M>th entry is the image of <M><A>gens</A>[i]</M> under the homomorphism.912<P/>913<Example><![CDATA[914gap> s4 := Group((1,2,3,4),(1,2));; s3 := Group((1,2,3),(1,2));;915gap> hom := GroupHomomorphismByImages( s4, s3,916> GeneratorsOfGroup(s4), [(1,2),(2,3)] );917[ (1,2,3,4), (1,2) ] -> [ (1,2), (2,3) ]918gap> Kernel( hom );919Group([ (1,4)(2,3), (1,3)(2,4) ])920gap> Image( hom, (1,2,3) );921(1,2,3)922gap> Size( Image( hom, DerivedSubgroup(s4) ) );9233924]]></Example>925<P/>926<Log><![CDATA[927gap> PreImage( hom, (1,2,3) );928Error, <map> must be an inj. and surj. mapping called from929<function "PreImage">( <arguments> )930called from read-eval loop at line 4 of *stdin*931you can 'quit;' to quit to outer loop, or932you can 'return;' to continue933brk> quit;934]]></Log>935<P/>936<Example><![CDATA[937gap> PreImagesRepresentative( hom, (1,2,3) );938(1,4,2)939gap> PreImage( hom, TrivialSubgroup(s3) ); # the kernel940Group([ (1,4)(2,3), (1,3)(2,4) ])941]]></Example>942<P/>943This homomorphism from <M>S_4</M> onto <M>S_3</M> is well known from elementary944group theory. Images of elements and subgroups under <C>hom</C> can be945calculated with the function <Ref Func="Image" BookName="ref"/>.946But since the mapping <C>hom</C> is not bijective, we cannot use the947function <Ref Func="PreImage" BookName="ref"/> for preimages of948elements (they can have several preimages). Instead, we have to use949<Ref Func="PreImagesRepresentative" BookName="ref"/>,950which returns one preimage if at least one951exists (and would return <K>fail</K> if none exists, which cannot occur for952our surjective <C>hom</C>).953On the other hand, we can use <Ref Func="PreImage" BookName="ref"/> for the954preimage of a set (which always exists, even if it is empty).955<P/>956Suppose we mistype the input when trying to construct a homomorphism as below.957<P/>958<Example><![CDATA[959gap> GroupHomomorphismByImages( s4, s3,960> GeneratorsOfGroup(s4), [(1,2,3),(2,3)] );961fail962]]></Example>963<P/>964There is no such homomorphism, hence <K>fail</K> is returned.965But note that because of this,966<Ref Func="GroupHomomorphismByImages" BookName="ref"/> must do967some checks, and this was also done for the mapping <C>hom</C> above.968One can avoid these checks if one is sure that the desired969homomorphism really exists.970For that,971the function <Ref Func="GroupHomomorphismByImagesNC" BookName="ref"/>972can be used; the <C>NC</C> stands for <Q>no check</Q>.973<P/>974But note that horrible things can happen if975<Ref Func="GroupHomomorphismByImagesNC" BookName="ref"/>976is used when the input does not describe a homomorphism.977<P/>978<Log><![CDATA[979gap> hom2 := GroupHomomorphismByImagesNC( s4, s3,980> GeneratorsOfGroup(s4), [(1,2,3),(2,3)] );981[ (1,2,3,4), (1,2) ] -> [ (1,2,3), (2,3) ]982gap> Size( Kernel(hom2) );98324984]]></Log>985<P/>986In other words, &GAP; claims that the kernel is the full <C>s4</C>,987yet <C>hom2</C> obviously has some non-trivial images!988Clearly there is no such thing as a homomorphism989which maps an element of order 4 (namely, (1,2,3,4))990to an element of order 3 (namely, (1,2,3)).991<E>But if you use the command992<Ref Func="GroupHomomorphismByImagesNC" BookName="ref"/>,993&GAP; trusts you.</E>994<P/>995<Log><![CDATA[996gap> IsGroupHomomorphism( hom2 );997true998]]></Log>999<P/>1000And then it produces serious nonsense if the thing is not a homomorphism,1001as seen above!1002<P/>1003Besides the safe command1004<Ref Func="GroupHomomorphismByImages" BookName="ref"/>,1005which returns <K>fail</K> if the requested homomorphism does not exist,1006there is the function1007<Ref Func="GroupGeneralMappingByImages" BookName="ref"/>,1008which returns a general mapping (that is, a possibly multi-valued1009mapping) that can be tested with1010<Ref Func="IsGroupHomomorphism" BookName="ref"/>.1011<P/>1012<Example><![CDATA[1013gap> hom2 := GroupGeneralMappingByImages( s4, s3,1014> GeneratorsOfGroup(s4), [(1,2,3),(2,3)] );;1015gap> IsGroupHomomorphism( hom2 );1016false1017]]></Example>1018<P/>1019<Index>group general mapping</Index><Index>cokernel</Index><Index>kernel</Index>1020<Index Key="GroupHomomorphismByImages vs. GroupGeneralMappingByImages"><C>GroupHomomorphismByImages</C> vs. <C>GroupGeneralMappingByImages</C></Index>1021But the possibility of testing for being a homomorphism is not the only1022reason why &GAP; offers <E>group general mappings</E>. Another (more1023important?) reason is that their existence allows <Q>reversal of arrows</Q>1024in a homomorphism such as our original <C>hom</C>.1025By this we mean the <Ref Func="GroupHomomorphismByImages" BookName="ref"/>1026with left and right sides exchanged, in which1027case it is of course merely a1028<Ref Func="GroupGeneralMappingByImages" BookName="ref"/>.1029<P/>1030<Example><![CDATA[1031gap> rev := GroupGeneralMappingByImages( s3, s4,1032> [(1,2),(2,3)], GeneratorsOfGroup(s4) );;1033]]></Example>1034<P/>1035Now <M>hom</M> maps <M>a</M> to <M>b</M> if and only if1036<M>rev</M> maps <M>b</M> to <M>a</M>,1037for <M>a \in</M> <C>s4</C> and <M>b \in</M> <C>s3</C>.1038Since every such <M>b</M> has four preimages under <C>hom</C>,1039it now has four images under <C>rev</C>.1040Just as the four preimages form a coset of the kernel1041<M>V_4 \leq </M><C>s4</C> of <C>hom</C>,1042they also form a coset of the <E>cokernel</E> <M>V_4 \leq </M><C>s4</C> of1043<C>rev</C>.1044The cokernel itself is the set of all images of <C>One( s3 )</C>.1045(It is a normal subgroup in the group of all images under <C>rev</C>.)1046The operation <Ref Func="One" BookName="ref"/> returns the identity element1047of a group.1048And this is why &GAP; wants to perform such a reversal of arrows:1049it calculates the kernel of a homomorphism like <C>hom</C>1050as the cokernel of the reversed group general mapping (here <C>rev</C>).1051<P/>1052<Example><![CDATA[1053gap> CoKernel( rev );1054Group([ (1,4)(2,3), (1,3)(2,4) ])1055]]></Example>1056<P/>1057<Index Subkey="single-valued">group general mapping</Index>1058<Index Subkey="total">group general mapping</Index>1059The reason why <C>rev</C> is not a homomorphism is that it is not1060single-valued (because <C>hom</C> was not injective). But there is another1061critical condition: If we reverse the arrows of a non-surjective1062homomorphism, we obtain a group general mapping which is not defined1063everywhere, i.e., which is not total (although it will be single-valued1064if the original homomorphism is injective). &GAP; requires that a group1065homomorphism be both single-valued and total,1066so you will get <K>fail</K> if you say1067<C>GroupHomomorphismByImages( <A>G</A>, <A>H</A>, <A>gens</A>, <A>imgs</A> )</C> where <A>gens</A> does1068not generate <A>G</A> (even if this would give a decent homomorphism on the1069subgroup generated by <A>gens</A>). For a full description,1070see Chapter <Ref Chap="Group Homomorphisms" BookName="ref"/>.1071<P/>1072The last example of this section shows that the notion of kernel and1073cokernel naturally extends even to the case where neither <C>hom2</C> nor its1074inverse general mapping (with arrows reversed) is a homomorphism.1075<P/>1076<Example><![CDATA[1077gap> CoKernel( hom2 ); Kernel( hom2 );1078Group([ (2,3), (1,3) ])1079Group([ (3,4), (2,3,4), (1,2,4) ])1080gap> IsGroupHomomorphism( InverseGeneralMapping( hom2 ) );1081false1082]]></Example>1083<P/>1084<E>Summary.</E> In this section we have constructed homomorphisms by1085specifying images for a set of generators. We have seen that by reversing1086the direction of the mapping, we get group general mappings, which need1087not be single-valued (unless the mapping was injective) nor total (unless1088the mapping was surjective).10891090</Section>109110921093<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->1094<Section Label="Nice Monomorphisms">1095<Heading>Nice Monomorphisms</Heading>10961097For some types of groups, the best method to calculate in an isomorphic1098group in a <Q>better</Q> representation (say, a permutation group).1099We call an injective homomorphism,1100that will give such an isomorphic image a <Q>nice monomorphism</Q>.1101<P/>1102For example in the case of a matrix group we can take the action on the1103underlying vector space (or a suitable subset) to obtain such a1104monomorphism:1105<P/>1106<Example><![CDATA[1107gap> grp:=GL(2,3);;1108gap> dom:=GF(3)^2;;1109gap> hom := ActionHomomorphism( grp, dom );; IsInjective( hom );1110true1111gap> p := Image( hom,grp );1112Group([ (4,7)(5,8)(6,9), (2,7,6)(3,4,8) ])1113]]></Example>1114<P/>1115To demonstrate the technique of nice monomorphisms, we compute the1116conjugacy classes of the permutation group and lift them back into the1117matrix group with the monomorphism <C>hom</C>. Lifting back a conjugacy class1118means finding the preimage of the representative and of the centralizer;1119the latter is called <Ref Func="StabilizerOfExternalSet" BookName="ref"/>1120in &GAP; (because conjugacy classes are represented as external sets, see1121Section <Ref Sect="Conjugacy Classes" BookName="ref"/>).1122<P/>1123<Example><![CDATA[1124gap> pcls := ConjugacyClasses( p );; gcls := [ ];;1125gap> for pc in pcls do1126> gc:=ConjugacyClass(grp,1127> PreImagesRepresentative(hom,Representative(pc)));1128> SetStabilizerOfExternalSet(gc,PreImage(hom,1129> StabilizerOfExternalSet(pc)));1130> Add( gcls, gc );1131> od;1132gap> List( gcls, Size );1133[ 1, 8, 12, 1, 8, 6, 6, 6 ]1134]]></Example>1135<P/>1136All the steps we have made above are automatically performed by &GAP;1137if you simply ask for <C>ConjugacyClasses( grp )</C>,1138provided that &GAP; already knows that <C>grp</C> is finite1139(e.g., because you asked <C>IsFinite( grp )</C> before).1140The reason for this is that a finite matrix group like <C>grp</C> is1141<Q>handled by a nice monomorphism</Q>.1142For such groups, &GAP; uses the command1143<Ref Func="NiceMonomorphism" BookName="ref"/>1144to construct a monomorphism (such as the <C>hom</C> in the previous example)1145and then proceeds as we have done above.1146<P/>1147<Example><![CDATA[1148gap> grp:=GL(2,3);;1149gap> IsHandledByNiceMonomorphism( grp );1150true1151gap> hom := NiceMonomorphism( grp );1152<action isomorphism>1153gap> p :=Image(hom,grp);1154Group([ (4,7)(5,8)(6,9), (2,7,6)(3,4,8) ])1155gap> cc := ConjugacyClasses( grp );; ForAll(cc, x-> x in gcls);1156true1157gap> ForAll(gcls, x->x in cc); # cc and gcls might be ordered differently1158true1159]]></Example>1160<P/>1161Note that a nice monomorphism might be defined on a larger group than1162<C>grp</C>1163–so we have to use <C>Image( hom, grp )</C> and not only1164<C>Image( hom )</C>.1165<P/>1166Nice monomorphisms are not only used for matrix groups, but also for1167other kinds of groups in which one cannot calculate easily enough. As1168another example, let us show that the automorphism group of the1169quaternion group of order 8 is isomorphic to the symmetric group of1170degree 4 by examining the <Q>nice object</Q> associated with that1171automorphism group.1172<P/>1173<Example><![CDATA[1174gap> p:=Group((1,7,6,8)(2,5,3,4), (1,2,6,3)(4,8,5,7));;1175gap> aut := AutomorphismGroup( p );; NiceMonomorphism(aut);;1176gap> niceaut := NiceObject( aut );1177Group([ (1,4,2,3), (1,5,4)(2,6,3), (1,2)(3,4), (3,4)(5,6) ])1178gap> IsomorphismGroups( niceaut, SymmetricGroup( 4 ) );1179[ (1,4,2,3), (1,5,4)(2,6,3), (1,2)(3,4), (3,4)(5,6) ] ->1180[ (1,4,3,2), (1,3,2), (1,3)(2,4), (1,2)(3,4) ]1181]]></Example>1182<P/>1183The range of a nice monomorphism is in most cases a permutation group,1184because nice monomorphisms are mostly action homomorphisms. In some1185cases, like in our last example, the group is solvable and you might1186prefer a pc group as nice object. You cannot change the nice monomorphism1187of the automorphism group (because it is the value of the attribute1188<Ref Func="NiceMonomorphism" BookName="ref"/>),1189but you can compose it with an isomorphism from the permutation group1190to a pc group to obtain your personal nicer monomorphism.1191If you reconstruct the automorphism group, you can even prescribe it1192this nicer monomorphism as its <Ref Func="NiceMonomorphism" BookName="ref"/>,1193because a newly-constructed group will not yet have a1194<Ref Func="NiceMonomorphism" BookName="ref"/> set.1195<P/>1196<Example><![CDATA[1197gap> nicer := NiceMonomorphism(aut) * IsomorphismPcGroup(niceaut);;1198gap> aut2 := GroupByGenerators( GeneratorsOfGroup( aut ) );;1199gap> SetIsHandledByNiceMonomorphism( aut2, true );1200gap> SetNiceMonomorphism( aut2, nicer );1201gap> NiceObject( aut2 ); # a pc group1202Group([ f1*f2, f2^2*f3, f4, f3 ])1203]]></Example>1204<P/>1205The star <C>*</C> denotes composition of mappings from the left to the right,1206as we have seen in Section <Ref Sect="Actions of Groups"/> above.1207Reconstructing the1208automorphism group may of course result in the loss of other information1209&GAP; had already gathered, besides the (not-so-)nice monomorphism.1210<P/>1211<E>Summary.</E> In this section we have seen how calculations in groups1212can be carried out in isomorphic images in nicer groups. We have seen1213that &GAP; pursues this technique automatically for certain classes of1214groups, e.g., for matrix groups that are known to be finite.12151216</Section>121712181219<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->1220<Section Label="Further Information about Groups and Homomorphisms">1221<Heading>Further Information about Groups and Homomorphisms</Heading>12221223Groups and the functions for groups are treated in1224Chapter <Ref Chap="Groups" BookName="ref"/>.1225There are several chapters dealing with groups in specific representations,1226for example Chapter <Ref Chap="Permutation Groups" BookName="ref"/>1227on permutation groups,1228<Ref Chap="Polycyclic Groups" BookName="ref"/>1229on polycyclic (including finite solvable) groups,1230<Ref Chap="Matrix Groups" BookName="ref"/> on matrix groups and1231<Ref Chap="Finitely Presented Groups" BookName="ref"/> on1232finitely presented groups.1233Chapter <Ref Chap="Group Actions" BookName="ref"/> deals1234with group actions.1235Group homomorphisms are the subject of1236Chapter <Ref Chap="Group Homomorphisms" BookName="ref"/>.12371238</Section>1239</Chapter>124012411242<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->1243<!-- %% -->1244<!-- %E -->1245124612471248