We have already seen examples of group homomorphisms in the last
sections, namely natural homomorphisms and action homomorphisms. In
this section we will show how to construct a group homomorphism G® H
by specifying a generating set for G and the images of these generators
in H. We use the function GroupHomomorphismByImages( G, H, gens,
imgs ) where gens is a generating set for G and imgs is a list
whose ith entry is the image of gens[ i ] under the homomorphism.
gap> s4 := Group((1,2,3,4),(1,2));; s3 := Group((1,2,3),(1,2));; gap> hom := GroupHomomorphismByImages( s4, s3, > GeneratorsOfGroup(s4), [(1,2),(2,3)] ); [ (1,2,3,4), (1,2) ] -> [ (1,2), (2,3) ] gap> Kernel( hom ); Group( [ (1,2)(3,4), (1,4)(2,3) ] ) # the Klein four-group gap> Image( hom, (1,2,3) ); (1,2,3) gap> Image( hom, DerivedSubgroup(s4) ); Group( [ (1,3,2), (1,2,3) ] )
gap> PreImage( hom, (1,2,3) ); Error <map> must be an inj. and surj. mapping at Error( "<map> must be an inj. and surj. mapping" ); Entering break read-eval-print loop, you can `quit;' to quit to outer \ loop, or you can return to continue brk> quit;
gap> PreImagesRepresentative( hom, (1,2,3) ); (2,4,3) gap> PreImage( hom, TrivialSubgroup(s3) ); Group( [ (1,2)(3,4), (1,4)(2,3) ] ) # the kernelThis homomorphism from S4 onto S3 is well known from elementary group theory. Images of elements and subgroups under
hom can be
calculated with the function Image. But since the mapping hom is not
bijective, we cannot use the function PreImage for preimages of
elements (they can have several preimages). Instead, we have to use
PreImagesRepresentative, which returns one preimage if at least one
exists (and would return fail if none exists, which cannot occur for
our surjective hom.) On the other hand, we can use PreImage for the
preimage of a set (which always exists, even if it is empty).
Suppose we mistype the input when trying to construct a homomorphism, as in the following example.
gap> GroupHomomorphismByImages( s4, s3, > GeneratorsOfGroup(s4), [(1,2,3),(2,3)] ); failThere is no such homomorphism, hence
fail is returned.
But note that because of this, GroupHomomorphismByImages must do
some checks, and this was also done for the mapping hom above.
One can avoid these checks if one is sure that the desired
homomorphism really exists.
For that, the function GroupHomomorphismByImagesNC can be used;
the NC stands for ``no check''.
But note that horrible things can happen if GroupHomomorphismByImagesNC
is used when the input does not describe a homomorphism.
gap> hom2 := GroupHomomorphismByImagesNC( s4, s3, > GeneratorsOfGroup(s4), [(1,2,3),(2,3)] ); [ (1,2,3,4), (1,2) ] -> [ (1,2,3), (2,3) ] gap> Size( Kernel(hom2) ); 24In other words, GAP claims that the kernel is the full
s4,
yet hom2 obviously has some non-trivial images!
Clearly there is no such thing as a homomorphism
which maps an element of order 4 (namely, (1,2,3,4))
to an element of order 3 (namely, (1,2,3)).
But if you use the command GroupHomomorphismByImagesNC,
GAP trusts you.
gap> IsGroupHomomorphism( hom2 ); trueAnd then it produces serious nonsense if the thing is not a homomorphism, as seen above!
Besides the safe command GroupHomomorphismByImages,
which returns fail if the requested homomorphism does not exist,
there is the function GroupGeneralMappingByImages,
which returns a general mapping (that is, a possibly multi-valued
mapping) that can be tested with IsGroupHomomorphism.
gap> hom2 := GroupGeneralMappingByImages( s4, s3, > GeneratorsOfGroup(s4), [(1,2,3),(2,3)] );; gap> IsGroupHomomorphism( hom2 ); false
But the possibility of testing for being a homomorphism is not the only
reason why GAP offers group general mappings. Another (more
important?) reason is that their existence allows ``reversal of arrows''
in a homomorphism such as our original hom. By this we mean the
GroupHomomorphismByImages with left and right sides exchanged, in which
case it is of course merely a GroupGeneralMappingByImages.
gap> rev := GroupGeneralMappingByImages( s3, s4, > [(1,2),(2,3)], GeneratorsOfGroup(s4) );;Now we have a\longmapsto b Û b\longmapsto a for a Î s4 and b Î s3. Since every such b has 4 preimages under
hom, it now has 4 images under rev.
Just as the 4 preimages form a coset of the kernel V4 £ s4 of
hom, they also form a coset of the cokernel V4 £ s4 of
rev. The cokernel itself is the set of all images of One( s3 )
(it is a normal subgroup in the group of all images under rev). The
operation 'One' returns the identity element of a group, see One
in the reference manual. And this is why GAP wants to perform such
a reversal of arrows: it calculates the kernel of a homomorphism like
hom as the cokernel of the reversed group general mapping (here
rev).
gap> CoKernel( rev ); Group( [ (1,4)(2,3), (1,2)(3,4) ] )The reason why
rev is not a homomorphism is that it is not
single-valued (because hom was not injective). But there is another
critical condition: If we reverse the arrows of a non-surjective
homomorphism, we obtain a group general mapping which is not defined
everywhere, i.e., which is not total (although it will be single-valued
if the original homomorphism is injective). GAP requires that a group
homomorphism be both single-valued and total,
so you will get fail if you say
GroupHomomorphismByImages( G, H, gens, imgs ) where gens does
not generate G (even if this would give a decent homomorphism on the
subgroup generated by gens). For a full description,
see Chapter Group Homomorphisms in the reference manual.
The last example of this section shows that the notion of kernel and
cokernel naturally extends even to the case where neither hom2 nor its
inverse general mapping (with arrows reversed) is a homomorphism.
gap> CoKernel( hom2 ); Kernel( hom2 ); Group( [ (2,3), (1,3,2) ] ) Group( [ (3,4), (2,4,3), (1,2)(3,4) ] ) gap> IsGroupHomomorphism( InverseGeneralMapping( hom2 ) ); false
[Top] [Previous] [Up] [Next] [Index]
GAP 4 manual