# Group homomorphisms for groups with a GAP backend¶

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: A = AbelianGroupGap([2, 4])
sage: F.<a,b> = FreeGroup()
sage: f = F.hom([g for g in A.gens()])
sage: K = f.kernel()
sage: K
Group(<free, no generators known>)


AUTHORS:

• Simon Brandhorst (2018-02-08): initial version
• Sebastian Oehms (2018-11-15): have this functionality work for permutation groups (trac ticket #26750) and implement section() and natural_map()
class sage.groups.libgap_morphism.GroupHomset_libgap(G, H, category=None, check=True)

Homsets of groups with a libgap backend.

Do not call this directly instead use Hom().

INPUT:

• G – a libgap group
• H – a libgap group
• category – a category

OUTPUT:

The homset of two libgap groups.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: A = AbelianGroupGap([2,4])
sage: H = A.Hom(A)
sage: H
Set of Morphisms from Abelian group with gap, generator orders (2, 4)
to Abelian group with gap, generator orders (2, 4)
in Category of finite enumerated commutative groups

Element

alias of GroupMorphism_libgap

natural_map()

This method from HomsetWithBase is overloaded here for cases in which both groups have corresponding lists of generators.

OUTPUT:

an instance of the element class of self if there exists a group homomorphism mapping the generators of the domain of self to the according generators of the codomain. Else the method falls back to the default.

EXAMPLES:

sage: G = GL(3,2)
sage: P = PGL(3,2)
sage: nat = Hom(G, P).natural_map()
sage: type(nat)
<class 'sage.groups.libgap_morphism.GroupHomset_libgap_with_category.element_class'>
sage: g1, g2 = G.gens()
sage: nat(g1*g2)
(1,2,4,5,7,3,6)

class sage.groups.libgap_morphism.GroupMorphism_libgap(homset, gap_hom, check=True)

This wraps GAP group homomorphisms.

Checking if the input defines a group homomorphism can be expensive if the group is large.

INPUT:

• homset – the parent
• gap_hom – a sage.libs.gap.element.GapElement consisting of a group homomorphism
• check – (default: True) check if the gap_hom is a group homomorphism; this can be expensive

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: A = AbelianGroupGap([2, 4])
sage: A.hom([g^2 for g in A.gens()])
Group endomorphism of Abelian group with gap, generator orders (2, 4)


Homomorphisms can be defined between different kinds of GAP groups:

sage: G = MatrixGroup([Matrix(ZZ, 2, [0,1,1,0])])
sage: f = A.hom([G.0, G(1)])
sage: f
Group morphism:
From: Abelian group with gap, generator orders (2, 4)
To:   Matrix group over Integer Ring with 1 generators (
[0 1]
[1 0]
)
sage: G.<a,b> = FreeGroup()
sage: H = G / (G([1]), G([2])^3)
sage: f = G.hom(H.gens())
sage: f
Group morphism:
From: Free Group on generators {a, b}
To:   Finitely presented group < a, b | a, b^3 >


Homomorphisms can be defined between GAP groups and permutation groups:

sage: S = Sp(4,3)
sage: P = PSp(4,3)
sage: pr = S.hom(P.gens())
sage: E = copy(S.one().matrix())
sage: E[3,0] = 2; e = S(E)
sage: pr(e)
(1,16,15)(3,22,18)(4,19,21)(6,34,24)(7,25,33)(9,40,27)(10,28,39)(12,37,30)(13,31,36)

gap()

Return the underlying LibGAP group homomorphism.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: A = AbelianGroupGap([2,4])
sage: f = A.hom([g^2 for g in A.gens()])
sage: f.gap()
[ f1, f2 ] -> [ <identity> of ..., f3 ]

image(J, *args, **kwds)

The image of an element or a subgroup.

INPUT:

• J – a subgroup or an element of the domain of self

OUTPUT:

The image of J under self.

Note

pushforward is the method that is used when a map is called on anything that is not an element of its domain. For historical reasons, we keep the alias image() for this method.

EXAMPLES:

sage: G.<a,b> = FreeGroup()
sage: H = G / (G([1]), G([2])^3)
sage: f = G.hom(H.gens())
sage: S = G.subgroup([a.gap()])
sage: f.pushforward(S)
Group([ a ])
sage: x = f.image(a)
sage: x
a
sage: x.parent()
Finitely presented group < a, b | a, b^3 >
sage: G = GU(3,2)
sage: P = PGU(3,2)
sage: pr = Hom(G, P).natural_map()
sage: GS = G.subgroup([G.gen(0)])
sage: pr.pushforward(GS)
Subgroup generated by [(3,4,5)(10,18,14)(11,19,15)(12,20,16)(13,21,17)] of (The projective general unitary group of degree 3 over Finite Field of size 2)

kernel()

Return the kernel of self.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: A1 = AbelianGroupGap([6, 6])
sage: A2 = AbelianGroupGap([3, 3])
sage: f = A1.hom(A2.gens())
sage: f.kernel()
Subgroup of Abelian group with gap, generator orders (6, 6)
generated by (f1*f2, f3*f4)
sage: f.kernel().order()
4
sage: S = Sp(6,3)
sage: P = PSp(6,3)
sage: pr = Hom(S, P).natural_map()
sage: pr.kernel()
Subgroup with 1 generators (
[2 0 0 0 0 0]
[0 2 0 0 0 0]
[0 0 2 0 0 0]
[0 0 0 2 0 0]
[0 0 0 0 2 0]
[0 0 0 0 0 2]
) of Symplectic Group of degree 6 over Finite Field of size 3

lift(h)

Return an element of the domain that maps to h.

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: A = AbelianGroupGap([2,4])
sage: f = A.hom([g^2 for g in A.gens()])
sage: a = A.gens()[1]
sage: f.lift(a^2)
f2


If the element is not in the image, we raise an error:

sage: f.lift(a)
Traceback (most recent call last):
...
ValueError: f2 is not an element of the image of Group endomorphism
of Abelian group with gap, generator orders (2, 4)

preimage(S)

Return the preimage of the subgroup S.

INPUT:

• S – a subgroup of this group

EXAMPLES:

sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
sage: A = AbelianGroupGap([2,4])
sage: B = AbelianGroupGap([4])
sage: f = A.hom([B.one(), B.gen(0)^2])
sage: S = B.subgroup([B.one()])
sage: f.preimage(S) == f.kernel()
True
sage: S = Sp(4,3)
sage: P = PSp(4,3)
sage: pr = Hom(S, P).natural_map()
sage: PS = P.subgroup([P.gen(0)])
sage: pr.preimage(PS)
Subgroup with 2 generators (
[2 0 0 0]  [1 0 0 0]
[0 2 0 0]  [0 2 0 0]
[0 0 2 0]  [0 0 2 0]
[0 0 0 2], [0 0 0 1]
) of Symplectic Group of degree 4 over Finite Field of size 3

pushforward(J, *args, **kwds)

The image of an element or a subgroup.

INPUT:

• J – a subgroup or an element of the domain of self

OUTPUT:

The image of J under self.

Note

pushforward is the method that is used when a map is called on anything that is not an element of its domain. For historical reasons, we keep the alias image() for this method.

EXAMPLES:

sage: G.<a,b> = FreeGroup()
sage: H = G / (G([1]), G([2])^3)
sage: f = G.hom(H.gens())
sage: S = G.subgroup([a.gap()])
sage: f.pushforward(S)
Group([ a ])
sage: x = f.image(a)
sage: x
a
sage: x.parent()
Finitely presented group < a, b | a, b^3 >
sage: G = GU(3,2)
sage: P = PGU(3,2)
sage: pr = Hom(G, P).natural_map()
sage: GS = G.subgroup([G.gen(0)])
sage: pr.pushforward(GS)
Subgroup generated by [(3,4,5)(10,18,14)(11,19,15)(12,20,16)(13,21,17)] of (The projective general unitary group of degree 3 over Finite Field of size 2)

section()

This method returns a section map of self by use of lift(). See section() of sage.categories.map.Map, as well.

OUTPUT:

an instance of sage.categories.morphism.SetMorphism mapping an element of the codomain of self to one of its preimages

EXAMPLES:

sage: G = GU(3,2)
sage: P = PGU(3,2)
sage: pr = Hom(G, P).natural_map()
sage: sect = pr.section()
sage: sect(P.an_element())
[a + 1     a     a]
[    1     1     0]
[    a     0     0]