Group homomorphisms for groups with a GAP backend - Groups

Skip to content
Back to top
View this page
Edit this page

# Group homomorphisms for groups with a GAP backend

EXAMPLES:

Sage

    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>)

Python

    >>> from sage.all import *
    >>> from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
    >>> A = AbelianGroupGap([Integer(2), Integer(4)])
    >>> F = FreeGroup(names=('a', 'b',)); (a, b,) = F._first_ngens(2)
    >>> f = F.hom([g for g in A.gens()])
    >>> K = f.kernel()
    >>> 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 (Issue #26750) and implement `section()` and `natural_map()`

class sage.groups.libgap_morphism.GroupHomset_libgap(G, H, category=None, check=True)

  Bases: `HomsetWithBase`

  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

      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

  Python

      >>> from sage.all import *
      >>> from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
      >>> A = AbelianGroupGap([Integer(2),Integer(4)])
      >>> H = A.Hom(A)
      >>> 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. Otherwise, the method falls back to the default.

    EXAMPLES:

    Sage

        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)

    Python

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

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

  Bases: `Morphism`

  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` – boolean (default: `True`); check if the `gap_hom` is a group homomorphism (this can be expensive)

  EXAMPLES:

  Sage

      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)

  Python

      >>> from sage.all import *
      >>> from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
      >>> A = AbelianGroupGap([Integer(2), Integer(4)])
      >>> A.hom([g**Integer(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

      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 >

  [Python]

      >>> from sage.all import *
      >>> G = MatrixGroup([Matrix(ZZ, Integer(2), [Integer(0),Integer(1),Integer(1),Integer(0)])])
      >>> f = A.hom([G.gen(0), G(Integer(1))])
      >>> 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]
      )
      >>> G = FreeGroup(names=('a', 'b',)); (a, b,) = G._first_ngens(2)
      >>> H = G / (G([Integer(1)]), G([Integer(2)])**Integer(3))
      >>> f = G.hom(H.gens())
      >>> 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

      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)

  Python

      >>> from sage.all import *
      >>> S = Sp(Integer(4),Integer(3))
      >>> P = PSp(Integer(4),Integer(3))
      >>> pr = S.hom(P.gens())
      >>> E = copy(S.one().matrix())
      >>> E[Integer(3),Integer(0)] = Integer(2); e = S(E)
      >>> 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

        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 ]

    Python

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

  image(J, *args, **kwds)

    alias of `pushforward()`.

  kernel()

    Return the kernel of `self`.

    EXAMPLES:

    Sage

        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

    Python

        >>> from sage.all import *
        >>> from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
        >>> A1 = AbelianGroupGap([Integer(6), Integer(6)])
        >>> A2 = AbelianGroupGap([Integer(3), Integer(3)])
        >>> f = A1.hom(A2.gens())
        >>> f.kernel()
        Subgroup of Abelian group with gap, generator orders (6, 6)
         generated by (f1*f2, f3*f4)
        >>> f.kernel().order()
        4
        >>> S = Sp(Integer(6),Integer(3))
        >>> P = PSp(Integer(6),Integer(3))
        >>> pr = Hom(S, P).natural_map()
        >>> 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

        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

    Python

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

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

    Sage

        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)

    [Python]

        >>> from sage.all import *
        >>> 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

        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

    Python

        >>> from sage.all import *
        >>> from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
        >>> A = AbelianGroupGap([Integer(2),Integer(4)])
        >>> B = AbelianGroupGap([Integer(4)])
        >>> f = A.hom([B.one(), B.gen(Integer(0))**Integer(2)])
        >>> S = B.subgroup([B.one()])
        >>> f.preimage(S) == f.kernel()
        True
        >>> S = Sp(Integer(4),Integer(3))
        >>> P = PSp(Integer(4),Integer(3))
        >>> pr = Hom(S, P).natural_map()
        >>> PS = P.subgroup([P.gen(Integer(0))])
        >>> 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

        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: # needs sage.rings.finite_rings
        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)

    Python

        >>> from sage.all import *
        >>> G = FreeGroup(names=('a', 'b',)); (a, b,) = G._first_ngens(2)
        >>> H = G / (G([Integer(1)]), G([Integer(2)])**Integer(3))
        >>> f = G.hom(H.gens())
        >>> S = G.subgroup([a.gap()])
        >>> f.pushforward(S)
        Group([ a ])
        >>> x = f.image(a)
        >>> x
        a
        >>> x.parent()
        Finitely presented group < a, b | a, b^3 >

        >>> # needs sage.rings.finite_rings
        >>> G = GU(Integer(3),Integer(2))
        >>> P = PGU(Integer(3),Integer(2))
        >>> pr = Hom(G, P).natural_map()
        >>> GS = G.subgroup([G.gen(Integer(0))])
        >>> 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()

    Return 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

        sage: # needs sage.rings.finite_rings
        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]

    Python

        >>> from sage.all import *
        >>> # needs sage.rings.finite_rings
        >>> G = GU(Integer(3),Integer(2))
        >>> P = PGU(Integer(3),Integer(2))
        >>> pr = Hom(G, P).natural_map()
        >>> sect = pr.section()
        >>> sect(P.an_element())
        [a + 1     a     a]
        [    1     1     0]
        [    a     0     0]