An important special class of mappings are homomorphisms.

A mapping *map* is a **homomorphism** if the source and the range are
domains of the same category, and *map* respects their structure. For
example, if both source and range are groups and for each *x,y* in the
source *(xy)^{map} = x^{map} y^{map}*, then *map* is a group
homomorphism.

Field Homomorphisms, Group Homomorphisms).

Homomorphism are created by **homomorphism constructors**, which are
ordinary **GAP** functions that return homomorphisms, such as
`FrobeniusAutomorphism`

(see FrobeniusAutomorphism) or
`NaturalHomomorphism`

(see NaturalHomomorphism).

The first section in this chapter describes the function that tests whether a mapping is a homomorphism (see IsHomomorphism). The next sections describe the functions that test whether a homomorphism has certain properties (see IsMonomorphism, IsEpimorphism, IsIsomorphism, IsEndomorphism, and IsAutomorphism). The last section describes the function that computes the kernel of a homomorphism (see Kernel).

Because homomorphisms are just a special case of mappings all operations
and functions described in chapter Mappings are applicable to
homomorphisms. For example, the image of an element `elm` under a
Operations for Mappings).

`IsHomomorphism( `

`map` )

`IsHomomorphism`

returns `true`

if the mapping `map` is a homomorphism
and `false`

otherwise. Signals an error if `map` is a multi valued
mapping.

A mapping *map* is a **homomorphism** if the source and the range are
sources of the same category, and *map* respects the structure. For
example, if both source and range are groups and for each *x,y* in the
source *(xy)^{map} = x^{map} y^{map}*, then *map* is a homomorphism.

gap> g := Group( (1,2,3,4), (2,4), (5,6,7) );; g.name := "g";; gap> p4 := MappingByFunction( g, g, x -> x^4 ); MappingByFunction( g, g, function ( x ) return x ^ 4; end ) gap> IsHomomorphism( p4 ); true gap> p5 := MappingByFunction( g, g, x -> x^5 ); MappingByFunction( g, g, function ( x ) return x ^ 5; end ) gap> IsHomomorphism( p5 ); true gap> p6 := MappingByFunction( g, g, x -> x^6 ); MappingByFunction( g, g, function ( x ) return x ^ 6; end ) gap> IsHomomorphism( p6 ); false

`IsHomomorphism`

first tests if the flag

is bound.
If the flag is bound, it returns its value. Otherwise it calls
`map`.isHomomorphism

, remembers the returned
value in `map`.source.operations.IsHomomorphism( `map` )

, and returns it.
`map`.isHomomorphism

The functions usually called this way are `IsGroupHomomorphism`

if the
source of `map` is a group and `IsFieldHomomorphism`

if the source of
`map` is a field (see IsGroupHomomorphism, IsFieldHomomorphism).

`IsMonomorphism( `

`map` )

`IsMonomorphism`

returns `true`

if the mapping `map` is a monomorphism
and `false`

otherwise. Signals an error if `map` is a multi valued
mapping.

A mapping is a **monomorphism** if it is an injective homomorphism (see
IsInjective, IsHomomorphism).

gap> g := Group( (1,2,3,4), (2,4), (5,6,7) );; g.name := "g";; gap> p4 := MappingByFunction( g, g, x -> x^4 ); MappingByFunction( g, g, function ( x ) return x ^ 4; end ) gap> IsMonomorphism( p4 ); false gap> p5 := MappingByFunction( g, g, x -> x^5 ); MappingByFunction( g, g, function ( x ) return x ^ 5; end ) gap> IsMonomorphism( p5 ); true

`IsMonomorphism`

first test if the flag

is bound.
If the flag is bound, it returns this value. Otherwise it calls
`map`.isMonomorphism

, remembers the returned value
in `map`.operations.IsMonomorphism( `map` )

, and returns it.
`map`.isMonomorphism

The default function called this way is `MappingOps.IsMonomorphism`

,
which calls the functions `IsInjective`

and `IsHomomorphism`

, and returns
the logical **and** of the results. This function is seldom overlaid,
because all the interesting work is done in `IsInjective`

and
`IsHomomorphism`

.

`IsEpimorphism( `

`map` )

`IsEpimorphism`

returns `true`

if the mapping `map` is an epimorphism and
`false`

otherwise. Signals an error if `map` is a multi valued mapping.

A mapping is an **epimorphism** if it is an surjective homomorphism (see
IsSurjective, IsHomomorphism).

gap> g := Group( (1,2,3,4), (2,4), (5,6,7) );; g.name := "g";; gap> p4 := MappingByFunction( g, g, x -> x^4 ); MappingByFunction( g, g, function ( x ) return x ^ 4; end ) gap> IsEpimorphism( p4 ); false gap> p5 := MappingByFunction( g, g, x -> x^5 ); MappingByFunction( g, g, function ( x ) return x ^ 5; end ) gap> IsEpimorphism( p5 ); true

`IsEpimorphism`

first test if the flag

is bound.
If the flag is bound, it returns this value. Otherwise it calls
`map`.isEpimorphism

, remembers the returned value
in `map`.operations.IsEpimorphism( `map` )

, and returns it.
`map`.isEpimorphism

The default function called this way is `MappingOps.IsEpimorphism`

, which
calls the functions `IsSurjective`

and `IsHomomorphism`

, and returns the
logical **and** of the results. This function is seldom overlaid, because
all the interesting work is done in `IsSurjective`

and `IsHomomorphism`

.

`IsIsomorphism( `

`map` )

`IsIsomorphism`

returns `true`

if the mapping `map` is an isomorphism and
`false`

otherwise. Signals an error if `map` is a multi valued mapping.

A mapping is an **isomorphism** if it is a bijective homomorphism (see
IsBijection, IsHomomorphism).

gap> g := Group( (1,2,3,4), (2,4), (5,6,7) );; g.name := "g";; gap> p4 := MappingByFunction( g, g, x -> x^4 ); MappingByFunction( g, g, function ( x ) return x ^ 4; end ) gap> IsIsomorphism( p4 ); false gap> p5 := MappingByFunction( g, g, x -> x^5 ); MappingByFunction( g, g, function ( x ) return x ^ 5; end ) gap> IsIsomorphism( p5 ); true

`IsIsomorphism`

first test if the flag

is bound.
If the flag is bound, it returns this value. Otherwise it calls
`map`.isIsomorphism

, remembers the returned value
in `map`.operations.IsIsomorphism( `map` )

, and returns it.
`map`.isIsomorphism

The default function called this way is `MappingOps.IsIsomorphism`

, which
calls the functions `IsInjective`

, `IsSurjective`

, and `IsHomomorphism`

,
and returns the logical **and** of the results. This function is seldom
overlaid, because all the interesting work is done in `IsInjective`

,
`IsSurjective`

, and `IsHomomorphism`

.

`IsEndomorphism( `

`map` )

`IsEndomorphism`

returns `true`

if the mapping `map` is a endomorphism
and `false`

otherwise. Signals an error if `map` is a multi valued
mapping.

A mapping is an **endomorphism** if it is a homomorphism (see
IsHomomorphism) and the range is a subset of the source.

gap> g := Group( (1,2,3,4), (2,4), (5,6,7) );; g.name := "g";; gap> p4 := MappingByFunction( g, g, x -> x^4 ); MappingByFunction( g, g, function ( x ) return x ^ 4; end ) gap> IsEndomorphism( p4 ); true gap> p5 := MappingByFunction( g, g, x -> x^5 ); MappingByFunction( g, g, function ( x ) return x ^ 5; end ) gap> IsEndomorphism( p5 ); true

`IsEndomorphism`

first test if the flag

is bound.
If the flag is bound, it returns this value. Otherwise it calls
`map`.isEndomorphism

, remembers the returned value
in `map`.operations.IsEndomorphism( `map` )

, and returns it.
`map`.isEndomorphism

The default function called this way is `MappingOps.IsEndomorphism`

,
which tests if the range is a subset of the source, calls
`IsHomomorphism`

, and returns the logical **and** of the results. This
function is seldom overlaid, because all the interesting work is done in
`IsSubset`

and `IsHomomorphism`

.

`IsAutomorphism( `

`map` )

`IsAutomorphism`

returns `true`

if the mapping `map` is an automorphism
and `false`

otherwise. Signals an error if `map` is a multi valued
mapping.

A mapping is an **automorphism** if it is an isomorphism where the source
and the range are equal (see IsIsomorphism, IsEndomorphism).

gap> g := Group( (1,2,3,4), (2,4), (5,6,7) );; g.name := "g";; gap> p4 := MappingByFunction( g, g, x -> x^4 ); MappingByFunction( g, g, function ( x ) return x ^ 4; end ) gap> IsAutomorphism( p4 ); false gap> p5 := MappingByFunction( g, g, x -> x^5 ); MappingByFunction( g, g, function ( x ) return x ^ 5; end ) gap> IsAutomorphism( p5 ); true

`IsAutomorphism`

first test if the flag

is bound.
If the flag is bound, it returns this value. Otherwise it calls
`map`.isAutomorphism

, remembers the returned value
in `map`.operations.IsAutomorphism( `map` )

, and returns it.
`map`.isAutomorphism

The default function called this way is `MappingOps.IsAutomorphism`

,
which calls the functions `IsEndomorphism`

and `IsBijection`

, and returns
the logical **and** of the results. This function is seldom overlaid,
because all the interesting work is done in `IsEndomorphism`

and
`IsBijection`

.

`Kernel( `

`hom` )

`Kernel`

returns the kernel of the homomorphism `hom`. The kernel is
usually returned as a source, though in some cases it might be returned
as a proper set.

The kernel is the set of elements that are mapped `hom` to the identity
element of

, i.e., to `hom`.range

if `hom`.range.identity`hom` is a
group homomorphism, and to

if `hom`.range.zero`hom` is a ring or field
homomorphism. The kernel is a substructure of

.
`hom`.source

gap> g := Group( (1,2,3,4), (2,4), (5,6,7) );; g.name := "g";; gap> p4 := MappingByFunction( g, g, x -> x^4 ); MappingByFunction( g, g, function ( x ) return x ^ 4; end ) gap> Kernel( p4 ); Subgroup( g, [ (1,2,3,4), (1,4)(2,3) ] ) gap> p5 := MappingByFunction( g, g, x -> x^5 ); MappingByFunction( g, g, function ( x ) return x ^ 5; end ) gap> Kernel( p5 ); Subgroup( g, [ ] )

`Kernel`

first tests if the field

is bound. If the field
is bound it returns its value. Otherwise it calls
`hom`.kernel

, remembers the returned value
in `hom`.source.operations.Kernel( `hom` )

, and returns it.
`hom`.kernel

The functions usually called this way from the dispatcher are
`KernelGroupHomomorphism`

and `KernelFieldHomomorphism`

(see
KernelGroupHomomorphism, KernelFieldHomomorphism).

GAP 3.4.4

April 1997