Multiplicative Abelian Groups With Values - Groups

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

# Multiplicative Abelian Groups With Values

Often, one ends up with a set that forms an Abelian group. It would be nice if one could return an Abelian group class to encapsulate the data. However, `AbelianGroup()` is an abstract Abelian group defined by generators and relations. This module implements `AbelianGroupWithValues` that allows the group elements to be decorated with values.

An example where this module is used is the unit group of a number field, see `sage.rings.number_field.unit_group`. The units form a finitely generated Abelian group. We can think of the elements either as abstract Abelian group elements or as particular numbers in the number field. The `AbelianGroupWithValues()` keeps track of these associated values.

Warning

Really, this requires a group homomorphism from the abstract Abelian group to the set of values. This is only checked if you pass the `check=True` option to `AbelianGroupWithValues()`.

EXAMPLES:

Here is \(\ZZ_6\) with value \(-1\) assigned to the generator:

Sage

    sage: Z6 = AbelianGroupWithValues([-1], [6], names='g')
    sage: g = Z6.gen(0)
    sage: g.value()
    -1
    sage: g*g
    g^2
    sage: (g*g).value()
    1
    sage: for i in range(7):
    ....:     print((i, g^i, (g^i).value()))
    (0, 1, 1)
    (1, g, -1)
    (2, g^2, 1)
    (3, g^3, -1)
    (4, g^4, 1)
    (5, g^5, -1)
    (6, 1, 1)

Python

    >>> from sage.all import *
    >>> Z6 = AbelianGroupWithValues([-Integer(1)], [Integer(6)], names='g')
    >>> g = Z6.gen(Integer(0))
    >>> g.value()
    -1
    >>> g*g
    g^2
    >>> (g*g).value()
    1
    >>> for i in range(Integer(7)):
    ...     print((i, g**i, (g**i).value()))
    (0, 1, 1)
    (1, g, -1)
    (2, g^2, 1)
    (3, g^3, -1)
    (4, g^4, 1)
    (5, g^5, -1)
    (6, 1, 1)

The elements come with a coercion embedding into the `values_group()`, so you can use the group elements instead of the values:

Sage

    sage: # needs sage.rings.number_field
    sage: CF3.<zeta> = CyclotomicField(3)
    sage: Z3.<g> = AbelianGroupWithValues([zeta], [3])
    sage: Z3.values_group()
    Cyclotomic Field of order 3 and degree 2
    sage: g.value()
    zeta
    sage: CF3(g)
    zeta
    sage: g + zeta
    2*zeta
    sage: zeta + g
    2*zeta

[Python]

    >>> from sage.all import *
    >>> # needs sage.rings.number_field
    >>> CF3 = CyclotomicField(Integer(3), names=('zeta',)); (zeta,) = CF3._first_ngens(1)
    >>> Z3 = AbelianGroupWithValues([zeta], [Integer(3)], names=('g',)); (g,) = Z3._first_ngens(1)
    >>> Z3.values_group()
    Cyclotomic Field of order 3 and degree 2
    >>> g.value()
    zeta
    >>> CF3(g)
    zeta
    >>> g + zeta
    2*zeta
    >>> zeta + g
    2*zeta

sage.groups.abelian_gps.values.AbelianGroupWithValues(values, n, gens_orders=None, names='f', check=False, values_group=None)

  Construct an Abelian group with values associated to the generators.

  INPUT:

  - `values` – list/tuple/iterable of values that you want to associate to the generators

  - `n` – integer (optional); if not specified, will be derived from `gens_orders`

  - `gens_orders` – list of nonnegative integers in the form

      \([a_0, a_1, \dots, a_{n-1}]\), typically written in increasing order. This list is padded with zeros if it has length less than n. The orders of the commuting generators, with \(0\) denoting an infinite cyclic factor.

  - `names` – (optional) names of generators

  - `values_group` – a parent or `None` (default). The common parent of the values. This might be a group, but can also just contain the values. For example, if the values are units in a ring then the `values_group` would be the whole ring. If `None` it will be derived from the values.

  EXAMPLES:

  Sage

      sage: G = AbelianGroupWithValues([-1], [6])
      sage: g = G.gen(0)
      sage: for i in range(7):
      ....:     print((i, g^i, (g^i).value()))
      (0, 1, 1)
      (1, f, -1)
      (2, f^2, 1)
      (3, f^3, -1)
      (4, f^4, 1)
      (5, f^5, -1)
      (6, 1, 1)
      sage: G.values_group()
      Integer Ring

  Python

      >>> from sage.all import *
      >>> G = AbelianGroupWithValues([-Integer(1)], [Integer(6)])
      >>> g = G.gen(Integer(0))
      >>> for i in range(Integer(7)):
      ...     print((i, g**i, (g**i).value()))
      (0, 1, 1)
      (1, f, -1)
      (2, f^2, 1)
      (3, f^3, -1)
      (4, f^4, 1)
      (5, f^5, -1)
      (6, 1, 1)
      >>> G.values_group()
      Integer Ring

  The group elements come with a coercion embedding into the `values_group()`, so you can use them like their `value()`

  Sage

      sage: G.values_embedding()
      Generic morphism:
        From: Multiplicative Abelian group isomorphic to C6
        To:   Integer Ring
      sage: g.value()
      -1
      sage: 0 + g
      -1
      sage: 1 + 2*g
      -1

  [Python]

      >>> from sage.all import *
      >>> G.values_embedding()
      Generic morphism:
        From: Multiplicative Abelian group isomorphic to C6
        To:   Integer Ring
      >>> g.value()
      -1
      >>> Integer(0) + g
      -1
      >>> Integer(1) + Integer(2)*g
      -1

class sage.groups.abelian_gps.values.AbelianGroupWithValuesElement(parent, exponents, value=None)

  Bases: `AbelianGroupElement`

  An element of an Abelian group with values assigned to generators.

  INPUT:

  - `exponents` – tuple of integers; the exponent vector defining the group element

  - `parent` – the parent

  - `value` – the value assigned to the group element or `None` (default); in the latter case, the value is computed as needed

  EXAMPLES:

  Sage

      sage: F = AbelianGroupWithValues([1,-1], [2,4])
      sage: a,b = F.gens()
      sage: TestSuite(a*b).run()

  Python

      >>> from sage.all import *
      >>> F = AbelianGroupWithValues([Integer(1),-Integer(1)], [Integer(2),Integer(4)])
      >>> a,b = F.gens()
      >>> TestSuite(a*b).run()

  value()

    Return the value of the group element.

    OUTPUT: the value according to the values for generators; see `gens_values()`

    EXAMPLES:

    Sage

        sage: G = AbelianGroupWithValues([5], 1)
        sage: G.0.value()
        5

    Python

        >>> from sage.all import *
        >>> G = AbelianGroupWithValues([Integer(5)], Integer(1))
        >>> G.gen(0).value()
        5

class sage.groups.abelian_gps.values.AbelianGroupWithValuesEmbedding(domain, codomain)

  Bases: `Morphism`

  The morphism embedding the Abelian group with values in its values group.

  INPUT:

  - `domain` – a `AbelianGroupWithValues_class`

  - `codomain` – the values group (need not be in the category of groups, e.g. symbolic ring)

  EXAMPLES:

  Sage

      sage: # needs sage.symbolic
      sage: Z4.<g> = AbelianGroupWithValues([I], [4])
      sage: embedding = Z4.values_embedding();  embedding
      Generic morphism:
        From: Multiplicative Abelian group isomorphic to C4
        To:   Number Field in I with defining polynomial x^2 + 1 with I = 1*I
      sage: embedding(1)
      1
      sage: embedding(g)
      I
      sage: embedding(g^2)
      -1

  Python

      >>> from sage.all import *
      >>> # needs sage.symbolic
      >>> Z4 = AbelianGroupWithValues([I], [Integer(4)], names=('g',)); (g,) = Z4._first_ngens(1)
      >>> embedding = Z4.values_embedding();  embedding
      Generic morphism:
        From: Multiplicative Abelian group isomorphic to C4
        To:   Number Field in I with defining polynomial x^2 + 1 with I = 1*I
      >>> embedding(Integer(1))
      1
      >>> embedding(g)
      I
      >>> embedding(g**Integer(2))
      -1

class sage.groups.abelian_gps.values.AbelianGroupWithValues_class(generator_orders, names, values, values_group)

  Bases: `AbelianGroup_class`

  The class of an Abelian group with values associated to the generator.

  INPUT:

  - `generator_orders` – tuple of integers; the orders of the generators

  - `names` – string or list of strings; the names for the generators

  - `values` – tuple the same length as the number of generators; the values assigned to the generators

  - `values_group` – the common parent of the values

  EXAMPLES:

  Sage

      sage: G.<a,b> = AbelianGroupWithValues([2,-1], [0,4])
      sage: TestSuite(G).run()

  Python

      >>> from sage.all import *
      >>> G = AbelianGroupWithValues([Integer(2),-Integer(1)], [Integer(0),Integer(4)], names=('a', 'b',)); (a, b,) = G._first_ngens(2)
      >>> TestSuite(G).run()

  Element

    alias of `AbelianGroupWithValuesElement`

  gen(i=0)

    The \(i\)-th generator of the abelian group.

    INPUT:

    - `i` – integer (default: 0); the index of the generator

    OUTPUT: a group element

    EXAMPLES:

    Sage

        sage: F = AbelianGroupWithValues([1,2,3,4,5], 5, [], names='a')
        sage: F.0
        a0
        sage: F.0.value()
        1
        sage: F.2
        a2
        sage: F.2.value()
        3

        sage: G = AbelianGroupWithValues([-1,0,1], [2,1,3])
        sage: G.gens()
        (f0, 1, f2)

    Python

        >>> from sage.all import *
        >>> F = AbelianGroupWithValues([Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)], Integer(5), [], names='a')
        >>> F.gen(0)
        a0
        >>> F.gen(0).value()
        1
        >>> F.gen(2)
        a2
        >>> F.gen(2).value()
        3

        >>> G = AbelianGroupWithValues([-Integer(1),Integer(0),Integer(1)], [Integer(2),Integer(1),Integer(3)])
        >>> G.gens()
        (f0, 1, f2)

  gens_values()

    Return the values associated to the generators.

    OUTPUT: tuple

    EXAMPLES:

    Sage

        sage: G = AbelianGroupWithValues([-1,0,1], [2,1,3])
        sage: G.gens()
        (f0, 1, f2)
        sage: G.gens_values()
        (-1, 0, 1)

    Python

        >>> from sage.all import *
        >>> G = AbelianGroupWithValues([-Integer(1),Integer(0),Integer(1)], [Integer(2),Integer(1),Integer(3)])
        >>> G.gens()
        (f0, 1, f2)
        >>> G.gens_values()
        (-1, 0, 1)

  values_embedding()

    Return the embedding of `self` in `values_group()`.

    OUTPUT: a morphism

    EXAMPLES:

    Sage

        sage: Z4 = AbelianGroupWithValues([I], [4])                                 # needs sage.symbolic
        sage: Z4.values_embedding()                                                 # needs sage.symbolic
        Generic morphism:
          From: Multiplicative Abelian group isomorphic to C4
          To:   Number Field in I with defining polynomial x^2 + 1 with I = 1*I

    Python

        >>> from sage.all import *
        >>> Z4 = AbelianGroupWithValues([I], [Integer(4)])                                 # needs sage.symbolic
        >>> Z4.values_embedding()                                                 # needs sage.symbolic
        Generic morphism:
          From: Multiplicative Abelian group isomorphic to C4
          To:   Number Field in I with defining polynomial x^2 + 1 with I = 1*I

  values_group()

    The common parent of the values.

    The values need to form a multiplicative group, but can be embedded in a larger structure. For example, if the values are units in a ring then the `values_group()` would be the whole ring.

    OUTPUT: the common parent of the values, containing the group generated by all values

    EXAMPLES:

    Sage

        sage: G = AbelianGroupWithValues([-1,0,1], [2,1,3])
        sage: G.values_group()
        Integer Ring

        sage: Z4 = AbelianGroupWithValues([I], [4])                                 # needs sage.symbolic
        sage: Z4.values_group()                                                     # needs sage.symbolic
        Number Field in I with defining polynomial x^2 + 1 with I = 1*I

    Python

        >>> from sage.all import *
        >>> G = AbelianGroupWithValues([-Integer(1),Integer(0),Integer(1)], [Integer(2),Integer(1),Integer(3)])
        >>> G.values_group()
        Integer Ring

        >>> Z4 = AbelianGroupWithValues([I], [Integer(4)])                                 # needs sage.symbolic
        >>> Z4.values_group()                                                     # needs sage.symbolic
        Number Field in I with defining polynomial x^2 + 1 with I = 1*I