Universal cyclotomic field - Algebraic Numbers and Number Fields

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

# Universal cyclotomic field

The universal cyclotomic field is the smallest subfield of the complex field containing all roots of unity. It is also the maximal abelian extension of the rational numbers.

EXAMPLES:

Sage

    sage: UCF = UniversalCyclotomicField(); UCF
    Universal Cyclotomic Field

Python

    >>> from sage.all import *
    >>> UCF = UniversalCyclotomicField(); UCF
    Universal Cyclotomic Field

To generate cyclotomic elements:

Sage

    sage: UCF.gen(5)
    E(5)
    sage: UCF.gen(5,2)
    E(5)^2

    sage: E = UCF.gen

[Python]

    >>> from sage.all import *
    >>> UCF.gen(Integer(5))
    E(5)
    >>> UCF.gen(Integer(5),Integer(2))
    E(5)^2

    >>> E = UCF.gen

Equality and inequality checks:

Sage

    sage: E(6,2) == E(6)^2 == E(3)
    True

    sage: E(6)^2 != E(3)
    False

Python

    >>> from sage.all import *
    >>> E(Integer(6),Integer(2)) == E(Integer(6))**Integer(2) == E(Integer(3))
    True

    >>> E(Integer(6))**Integer(2) != E(Integer(3))
    False

Addition and multiplication:

Sage

    sage: E(2) * E(3)
    -E(3)
    sage: f = E(2) + E(3); f
    2*E(3) + E(3)^2

[Python]

    >>> from sage.all import *
    >>> E(Integer(2)) * E(Integer(3))
    -E(3)
    >>> f = E(Integer(2)) + E(Integer(3)); f
    2*E(3) + E(3)^2

Inverses:

Sage

    sage: f^-1
    1/3*E(3) + 2/3*E(3)^2
    sage: f.inverse()
    1/3*E(3) + 2/3*E(3)^2
    sage: f * f.inverse()
    1

Python

    >>> from sage.all import *
    >>> f**-Integer(1)
    1/3*E(3) + 2/3*E(3)^2
    >>> f.inverse()
    1/3*E(3) + 2/3*E(3)^2
    >>> f * f.inverse()
    1

Conjugation and Galois conjugates:

Sage

    sage: f.conjugate()
    E(3) + 2*E(3)^2

    sage: f.galois_conjugates()
    [2*E(3) + E(3)^2, E(3) + 2*E(3)^2]
    sage: f.norm_of_galois_extension()
    3

[Python]

    >>> from sage.all import *
    >>> f.conjugate()
    E(3) + 2*E(3)^2

    >>> f.galois_conjugates()
    [2*E(3) + E(3)^2, E(3) + 2*E(3)^2]
    >>> f.norm_of_galois_extension()
    3

One can create matrices and polynomials:

Sage

    sage: m = matrix(2,[E(3),1,1,E(4)]); m
    [E(3)    1]
    [   1 E(4)]
    sage: m.parent()
    Full MatrixSpace of 2 by 2 dense matrices over Universal Cyclotomic Field
    sage: m**2
    [                       -E(3) E(12)^4 - E(12)^7 - E(12)^11]
    [E(12)^4 - E(12)^7 - E(12)^11                            0]

    sage: m.charpoly()
    x^2 + (-E(12)^4 + E(12)^7 + E(12)^11)*x + E(12)^4 + E(12)^7 + E(12)^8

    sage: m.echelon_form()
    [1 0]
    [0 1]

    sage: m.pivots()
    (0, 1)

    sage: m.rank()
    2

    sage: R.<x> = PolynomialRing(UniversalCyclotomicField(), 'x')
    sage: E(3) * x - 1
    E(3)*x - 1

Python

    >>> from sage.all import *
    >>> m = matrix(Integer(2),[E(Integer(3)),Integer(1),Integer(1),E(Integer(4))]); m
    [E(3)    1]
    [   1 E(4)]
    >>> m.parent()
    Full MatrixSpace of 2 by 2 dense matrices over Universal Cyclotomic Field
    >>> m**Integer(2)
    [                       -E(3) E(12)^4 - E(12)^7 - E(12)^11]
    [E(12)^4 - E(12)^7 - E(12)^11                            0]

    >>> m.charpoly()
    x^2 + (-E(12)^4 + E(12)^7 + E(12)^11)*x + E(12)^4 + E(12)^7 + E(12)^8

    >>> m.echelon_form()
    [1 0]
    [0 1]

    >>> m.pivots()
    (0, 1)

    >>> m.rank()
    2

    >>> R = PolynomialRing(UniversalCyclotomicField(), 'x', names=('x',)); (x,) = R._first_ngens(1)
    >>> E(Integer(3)) * x - Integer(1)
    E(3)*x - 1

The implementation simply wraps GAP Cyclotomic. As mentioned in their documentation: arithmetical operations are quite expensive, so the use of internally represented cyclotomics is not recommended for doing arithmetic over number fields, such as calculations with matrices of cyclotomics.

Note

There used to be a native Sage version of the universal cyclotomic field written by Christian Stump (see Issue #8327). It was slower on most operations and it was decided to use a version based on GAP instead (see Issue #18152). One main difference in the design choices is that GAP stores dense vectors whereas the native ones used Python dictionaries (storing only nonzero coefficients). Most operations are faster with GAP except some operation on very sparse elements. All details can be found in Issue #18152.

REFERENCES:

- [Bre1997]

AUTHORS:

- Christian Stump (2013): initial Sage version (see Issue #8327)

- Vincent Delecroix (2015): completed rewriting using libgap (see Issue #18152)

- Sebastian Oehms (2018): deleted the method is_finite since it returned the wrong result (see Issue #25686)

- Sebastian Oehms (2019): added `_factor_univariate_polynomial()` (see Issue #28631)

sage.rings.universal_cyclotomic_field.E(n, k=1)

  Return the `n`-th root of unity as an element of the universal cyclotomic field.

  EXAMPLES:

  Sage

      sage: E(3)
      E(3)
      sage: E(3) + E(5)
      -E(15)^2 - 2*E(15)^8 - E(15)^11 - E(15)^13 - E(15)^14

  Python

      >>> from sage.all import *
      >>> E(Integer(3))
      E(3)
      >>> E(Integer(3)) + E(Integer(5))
      -E(15)^2 - 2*E(15)^8 - E(15)^11 - E(15)^13 - E(15)^14

sage.rings.universal_cyclotomic_field.UCF_sqrt_int(N, UCF)

  Return the square root of the integer `N`.

  EXAMPLES:

  Sage

      sage: from sage.rings.universal_cyclotomic_field import UCF_sqrt_int
      sage: UCF = UniversalCyclotomicField()
      sage: UCF_sqrt_int(0, UCF)
      0
      sage: UCF_sqrt_int(1, UCF)
      1
      sage: UCF_sqrt_int(-1, UCF)
      E(4)
      sage: UCF_sqrt_int(2, UCF)
      E(8) - E(8)^3
      sage: UCF_sqrt_int(-2, UCF)
      E(8) + E(8)^3

  Python

      >>> from sage.all import *
      >>> from sage.rings.universal_cyclotomic_field import UCF_sqrt_int
      >>> UCF = UniversalCyclotomicField()
      >>> UCF_sqrt_int(Integer(0), UCF)
      0
      >>> UCF_sqrt_int(Integer(1), UCF)
      1
      >>> UCF_sqrt_int(-Integer(1), UCF)
      E(4)
      >>> UCF_sqrt_int(Integer(2), UCF)
      E(8) - E(8)^3
      >>> UCF_sqrt_int(-Integer(2), UCF)
      E(8) + E(8)^3

class sage.rings.universal_cyclotomic_field.UCFtoQQbar(UCF)

  Bases: `Morphism`

  Conversion to `QQbar`.

  EXAMPLES:

  Sage

      sage: UCF = UniversalCyclotomicField()
      sage: QQbar(UCF.gen(3))
      -0.500000000000000? + 0.866025403784439?*I

      sage: CC(UCF.gen(7,2) + UCF.gen(7,6))
      0.400968867902419 + 0.193096429713793*I

      sage: complex(E(7)+E(7,2))
      (0.40096886790241915+1.7567593946498534j)
      sage: complex(UCF.one()/2)
      (0.5+0j)

  Python

      >>> from sage.all import *
      >>> UCF = UniversalCyclotomicField()
      >>> QQbar(UCF.gen(Integer(3)))
      -0.500000000000000? + 0.866025403784439?*I

      >>> CC(UCF.gen(Integer(7),Integer(2)) + UCF.gen(Integer(7),Integer(6)))
      0.400968867902419 + 0.193096429713793*I

      >>> complex(E(Integer(7))+E(Integer(7),Integer(2)))
      (0.40096886790241915+1.7567593946498534j)
      >>> complex(UCF.one()/Integer(2))
      (0.5+0j)

class sage.rings.universal_cyclotomic_field.UniversalCyclotomicField(names=None)

  Bases: `UniqueRepresentation`, `UniversalCyclotomicField`

  The universal cyclotomic field.

  The universal cyclotomic field is the infinite algebraic extension of \(\QQ\) generated by the roots of unity. It is also the maximal Abelian extension of \(\QQ\) in the sense that any Abelian Galois extension of \(\QQ\) is also a subfield of the universal cyclotomic field.

  Element

    alias of `UniversalCyclotomicFieldElement`

  algebraic_closure()

    The algebraic closure.

    EXAMPLES:

    Sage

        sage: UniversalCyclotomicField().algebraic_closure()
        Algebraic Field

    Python

        >>> from sage.all import *
        >>> UniversalCyclotomicField().algebraic_closure()
        Algebraic Field

  an_element()

    Return an element.

    EXAMPLES:

    Sage

        sage: UniversalCyclotomicField().an_element()
        E(5) - 3*E(5)^2

    Python

        >>> from sage.all import *
        >>> UniversalCyclotomicField().an_element()
        E(5) - 3*E(5)^2

  characteristic()

    Return the characteristic.

    EXAMPLES:

    Sage

        sage: UniversalCyclotomicField().characteristic()
        0
        sage: parent(_)
        Integer Ring

    Python

        >>> from sage.all import *
        >>> UniversalCyclotomicField().characteristic()
        0
        >>> parent(_)
        Integer Ring

  degree()

    Return the degree of `self` as a field extension over the Rationals.

    EXAMPLES:

    Sage

        sage: UCF = UniversalCyclotomicField()
        sage: UCF.degree()
        +Infinity

    Python

        >>> from sage.all import *
        >>> UCF = UniversalCyclotomicField()
        >>> UCF.degree()
        +Infinity

  gen(n, k=1)

    Return the standard primitive `n`-th root of unity.

    If `k` is not `None`, return the `k`-th power of it.

    EXAMPLES:

    Sage

        sage: UCF = UniversalCyclotomicField()
        sage: UCF.gen(15)
        E(15)
        sage: UCF.gen(7,3)
        E(7)^3
        sage: UCF.gen(4,2)
        -1

    Python

        >>> from sage.all import *
        >>> UCF = UniversalCyclotomicField()
        >>> UCF.gen(Integer(15))
        E(15)
        >>> UCF.gen(Integer(7),Integer(3))
        E(7)^3
        >>> UCF.gen(Integer(4),Integer(2))
        -1

    There is an alias `zeta` also available:

    Sage

        sage: UCF.zeta(6)
        -E(3)^2

    [Python]

        >>> from sage.all import *
        >>> UCF.zeta(Integer(6))
        -E(3)^2

  is_exact()

    Return `True` as this is an exact ring (i.e. not numerical).

    EXAMPLES:

    Sage

        sage: UniversalCyclotomicField().is_exact()
        True

    Python

        >>> from sage.all import *
        >>> UniversalCyclotomicField().is_exact()
        True

  one()

    Return one.

    EXAMPLES:

    Sage

        sage: UCF = UniversalCyclotomicField()
        sage: UCF.one()
        1
        sage: parent(_)
        Universal Cyclotomic Field

    Python

        >>> from sage.all import *
        >>> UCF = UniversalCyclotomicField()
        >>> UCF.one()
        1
        >>> parent(_)
        Universal Cyclotomic Field

  some_elements()

    Return a tuple of some elements in the universal cyclotomic field.

    EXAMPLES:

    Sage

        sage: UniversalCyclotomicField().some_elements()
        (0, 1, -1, E(3), E(7) - 2/3*E(7)^2)
        sage: all(parent(x) is UniversalCyclotomicField() for x in _)
        True

    Python

        >>> from sage.all import *
        >>> UniversalCyclotomicField().some_elements()
        (0, 1, -1, E(3), E(7) - 2/3*E(7)^2)
        >>> all(parent(x) is UniversalCyclotomicField() for x in _)
        True

  zero()

    Return zero.

    EXAMPLES:

    Sage

        sage: UCF = UniversalCyclotomicField()
        sage: UCF.zero()
        0
        sage: parent(_)
        Universal Cyclotomic Field

    Python

        >>> from sage.all import *
        >>> UCF = UniversalCyclotomicField()
        >>> UCF.zero()
        0
        >>> parent(_)
        Universal Cyclotomic Field

  zeta(n, k=1)

    alias of `gen()`.

class sage.rings.universal_cyclotomic_field.UniversalCyclotomicFieldElement(parent, obj)

  Bases: `FieldElement`

  INPUT:

  - `parent` – a universal cyclotomic field

  - `obj` – a libgap element (either an integer, a rational or a cyclotomic)

  abs()

    Return the absolute value (or complex modulus) of `self`.

    The absolute value is returned as an algebraic real number.

    EXAMPLES:

    Sage

        sage: f = 5/2*E(3)+E(5)/7
        sage: f.abs()
        2.597760303873084?
        sage: abs(f)
        2.597760303873084?
        sage: a = E(8)
        sage: abs(a)
        1
        sage: v, w = vector([a]), vector([a, a])
        sage: v.norm(), w.norm()
        (1, 1.414213562373095?)
        sage: v.norm().parent()
        Algebraic Real Field

    Python

        >>> from sage.all import *
        >>> f = Integer(5)/Integer(2)*E(Integer(3))+E(Integer(5))/Integer(7)
        >>> f.abs()
        2.597760303873084?
        >>> abs(f)
        2.597760303873084?
        >>> a = E(Integer(8))
        >>> abs(a)
        1
        >>> v, w = vector([a]), vector([a, a])
        >>> v.norm(), w.norm()
        (1, 1.414213562373095?)
        >>> v.norm().parent()
        Algebraic Real Field

  additive_order()

    Return the additive order.

    EXAMPLES:

    Sage

        sage: UCF = UniversalCyclotomicField()
        sage: UCF.zero().additive_order()
        0
        sage: UCF.one().additive_order()
        +Infinity
        sage: UCF.gen(3).additive_order()
        +Infinity

    Python

        >>> from sage.all import *
        >>> UCF = UniversalCyclotomicField()
        >>> UCF.zero().additive_order()
        0
        >>> UCF.one().additive_order()
        +Infinity
        >>> UCF.gen(Integer(3)).additive_order()
        +Infinity

  conductor()

    Return the conductor of `self`.

    EXAMPLES:

    Sage

        sage: E(3).conductor()
        3
        sage: (E(5) + E(3)).conductor()
        15

    Python

        >>> from sage.all import *
        >>> E(Integer(3)).conductor()
        3
        >>> (E(Integer(5)) + E(Integer(3))).conductor()
        15

  conjugate()

    Return the complex conjugate.

    EXAMPLES:

    Sage

        sage: (E(7) + 3*E(7,2) - 5 * E(7,3)).conjugate()
        -5*E(7)^4 + 3*E(7)^5 + E(7)^6

    Python

        >>> from sage.all import *
        >>> (E(Integer(7)) + Integer(3)*E(Integer(7),Integer(2)) - Integer(5) * E(Integer(7),Integer(3))).conjugate()
        -5*E(7)^4 + 3*E(7)^5 + E(7)^6

  denominator()

    Return the denominator of this element.

    See also

    `is_integral()`

    EXAMPLES:

    Sage

        sage: a = E(5) + 1/2*E(5,2) + 1/3*E(5,3)
        sage: a
        E(5) + 1/2*E(5)^2 + 1/3*E(5)^3
        sage: a.denominator()
        6
        sage: parent(_)
        Integer Ring

    Python

        >>> from sage.all import *
        >>> a = E(Integer(5)) + Integer(1)/Integer(2)*E(Integer(5),Integer(2)) + Integer(1)/Integer(3)*E(Integer(5),Integer(3))
        >>> a
        E(5) + 1/2*E(5)^2 + 1/3*E(5)^3
        >>> a.denominator()
        6
        >>> parent(_)
        Integer Ring

  galois_conjugates(n=None)

    Return the Galois conjugates of `self`.

    INPUT:

    - `n` – an optional integer. If provided, return the orbit of the Galois group of the `n`-th cyclotomic field over \(\QQ\). Note that `n` must be such that this element belongs to the `n`-th cyclotomic field (in other words, it must be a multiple of the conductor).

    EXAMPLES:

    Sage

        sage: E(6).galois_conjugates()
        [-E(3)^2, -E(3)]

        sage: E(6).galois_conjugates()
        [-E(3)^2, -E(3)]

        sage: (E(9,2) - E(9,4)).galois_conjugates()
        [E(9)^2 - E(9)^4,
         E(9)^2 + E(9)^4 + E(9)^5,
         -E(9)^2 - E(9)^5 - E(9)^7,
         -E(9)^2 - E(9)^4 - E(9)^7,
         E(9)^4 + E(9)^5 + E(9)^7,
         -E(9)^5 + E(9)^7]

        sage: zeta = E(5)
        sage: zeta.galois_conjugates(5)
        [E(5), E(5)^2, E(5)^3, E(5)^4]
        sage: zeta.galois_conjugates(10)
        [E(5), E(5)^3, E(5)^2, E(5)^4]
        sage: zeta.galois_conjugates(15)
        [E(5), E(5)^2, E(5)^4, E(5)^2, E(5)^3, E(5), E(5)^3, E(5)^4]

        sage: zeta.galois_conjugates(17)
        Traceback (most recent call last):
        ...
        ValueError: n = 17 must be a multiple of the conductor (5)

    Python

        >>> from sage.all import *
        >>> E(Integer(6)).galois_conjugates()
        [-E(3)^2, -E(3)]

        >>> E(Integer(6)).galois_conjugates()
        [-E(3)^2, -E(3)]

        >>> (E(Integer(9),Integer(2)) - E(Integer(9),Integer(4))).galois_conjugates()
        [E(9)^2 - E(9)^4,
         E(9)^2 + E(9)^4 + E(9)^5,
         -E(9)^2 - E(9)^5 - E(9)^7,
         -E(9)^2 - E(9)^4 - E(9)^7,
         E(9)^4 + E(9)^5 + E(9)^7,
         -E(9)^5 + E(9)^7]

        >>> zeta = E(Integer(5))
        >>> zeta.galois_conjugates(Integer(5))
        [E(5), E(5)^2, E(5)^3, E(5)^4]
        >>> zeta.galois_conjugates(Integer(10))
        [E(5), E(5)^3, E(5)^2, E(5)^4]
        >>> zeta.galois_conjugates(Integer(15))
        [E(5), E(5)^2, E(5)^4, E(5)^2, E(5)^3, E(5), E(5)^3, E(5)^4]

        >>> zeta.galois_conjugates(Integer(17))
        Traceback (most recent call last):
        ...
        ValueError: n = 17 must be a multiple of the conductor (5)

  imag()

    Return the imaginary part of this element.

    EXAMPLES:

    Sage

        sage: E(3).imag()
        -1/2*E(12)^7 + 1/2*E(12)^11
        sage: E(5).imag()
        1/2*E(20) - 1/2*E(20)^9

        sage: a = E(5) - 2*E(3)
        sage: AA(a.imag()) == QQbar(a).imag()
        True

    Python

        >>> from sage.all import *
        >>> E(Integer(3)).imag()
        -1/2*E(12)^7 + 1/2*E(12)^11
        >>> E(Integer(5)).imag()
        1/2*E(20) - 1/2*E(20)^9

        >>> a = E(Integer(5)) - Integer(2)*E(Integer(3))
        >>> AA(a.imag()) == QQbar(a).imag()
        True

  imag_part()

    alias of `imag()`.

  inverse()
  is_integral()

    Return whether `self` is an algebraic integer.

    This just wraps `IsIntegralCyclotomic` from GAP.

    See also

    `denominator()`

    EXAMPLES:

    Sage

        sage: E(6).is_integral()
        True
        sage: (E(4)/2).is_integral()
        False

    Python

        >>> from sage.all import *
        >>> E(Integer(6)).is_integral()
        True
        >>> (E(Integer(4))/Integer(2)).is_integral()
        False

  is_rational()

    Test whether this element is a rational number.

    EXAMPLES:

    Sage

        sage: E(3).is_rational()
        False
        sage: (E(3) + E(3,2)).is_rational()
        True

    Python

        >>> from sage.all import *
        >>> E(Integer(3)).is_rational()
        False
        >>> (E(Integer(3)) + E(Integer(3),Integer(2))).is_rational()
        True

  is_real()

    Test whether this element is real.

    EXAMPLES:

    Sage

        sage: E(3).is_real()
        False
        sage: (E(3) + E(3,2)).is_real()
        True

        sage: a = E(3) - 2*E(7)
        sage: a.real_part().is_real()
        True
        sage: a.imag_part().is_real()
        True

    Python

        >>> from sage.all import *
        >>> E(Integer(3)).is_real()
        False
        >>> (E(Integer(3)) + E(Integer(3),Integer(2))).is_real()
        True

        >>> a = E(Integer(3)) - Integer(2)*E(Integer(7))
        >>> a.real_part().is_real()
        True
        >>> a.imag_part().is_real()
        True

  is_square()

    EXAMPLES:

    Sage

        sage: UCF = UniversalCyclotomicField()
        sage: UCF(5/2).is_square()
        True

        sage: UCF.zeta(7,3).is_square()
        True

        sage: (2 + UCF.zeta(3)).is_square()
        Traceback (most recent call last):
        ...
        NotImplementedError: is_square() not fully implemented for elements of Universal Cyclotomic Field

    Python

        >>> from sage.all import *
        >>> UCF = UniversalCyclotomicField()
        >>> UCF(Integer(5)/Integer(2)).is_square()
        True

        >>> UCF.zeta(Integer(7),Integer(3)).is_square()
        True

        >>> (Integer(2) + UCF.zeta(Integer(3))).is_square()
        Traceback (most recent call last):
        ...
        NotImplementedError: is_square() not fully implemented for elements of Universal Cyclotomic Field

  minpoly(var='x')

    The minimal polynomial of `self` element over \(\QQ\).

    INPUT:

    - `var` – (default: `'x'`) the name of the variable to use

    EXAMPLES:

    Sage

        sage: UCF.<E> = UniversalCyclotomicField()

        sage: UCF(4).minpoly()
        x - 4

        sage: UCF(4).minpoly(var='y')
        y - 4

        sage: E(3).minpoly()
        x^2 + x + 1

        sage: E(3).minpoly(var='y')
        y^2 + y + 1

    Python

        >>> from sage.all import *
        >>> UCF = UniversalCyclotomicField(names=('E',)); (E,) = UCF._first_ngens(1)

        >>> UCF(Integer(4)).minpoly()
        x - 4

        >>> UCF(Integer(4)).minpoly(var='y')
        y - 4

        >>> E(Integer(3)).minpoly()
        x^2 + x + 1

        >>> E(Integer(3)).minpoly(var='y')
        y^2 + y + 1

    Todo

    Polynomials with libgap currently does not implement a `.sage()` method (see Issue #18266). It would be faster/safer to not use string to construct the polynomial.

  multiplicative_order()

    Return the multiplicative order.

    EXAMPLES:

    Sage

        sage: E(5).multiplicative_order()
        5
        sage: (E(5) + E(12)).multiplicative_order()
        +Infinity
        sage: UniversalCyclotomicField().zero().multiplicative_order()
        Traceback (most recent call last):
        ...
        GAPError: Error, argument must be nonzero

    Python

        >>> from sage.all import *
        >>> E(Integer(5)).multiplicative_order()
        5
        >>> (E(Integer(5)) + E(Integer(12))).multiplicative_order()
        +Infinity
        >>> UniversalCyclotomicField().zero().multiplicative_order()
        Traceback (most recent call last):
        ...
        GAPError: Error, argument must be nonzero

  norm_of_galois_extension()

    Return the norm as a Galois extension of \(\QQ\), which is given by the product of all galois_conjugates.

    EXAMPLES:

    Sage

        sage: E(3).norm_of_galois_extension()
        1
        sage: E(6).norm_of_galois_extension()
        1
        sage: (E(2) + E(3)).norm_of_galois_extension()
        3
        sage: parent(_)
        Integer Ring

    Python

        >>> from sage.all import *
        >>> E(Integer(3)).norm_of_galois_extension()
        1
        >>> E(Integer(6)).norm_of_galois_extension()
        1
        >>> (E(Integer(2)) + E(Integer(3))).norm_of_galois_extension()
        3
        >>> parent(_)
        Integer Ring

  real()

    Return the real part of this element.

    EXAMPLES:

    Sage

        sage: E(3).real()
        -1/2
        sage: E(5).real()
        1/2*E(5) + 1/2*E(5)^4

        sage: a = E(5) - 2*E(3)
        sage: AA(a.real()) == QQbar(a).real()
        True

    Python

        >>> from sage.all import *
        >>> E(Integer(3)).real()
        -1/2
        >>> E(Integer(5)).real()
        1/2*E(5) + 1/2*E(5)^4

        >>> a = E(Integer(5)) - Integer(2)*E(Integer(3))
        >>> AA(a.real()) == QQbar(a).real()
        True

  real_part()

    alias of `real()`.

  sqrt(extend=True, all=False)

    Return a square root of `self`.

    With default options, the output is an element of the universal cyclotomic field when this element is expressed via a single root of unity (including rational numbers). Otherwise, return an algebraic number.

    INPUT:

    - `extend` – boolean (default: `True`); if `True`, might return a square root in the algebraic closure of the rationals. If `False`, return a square root in the universal cyclotomic field or raises an error.

    - `all` – boolean (default: `False`); if `True`, return a list of all square roots

    EXAMPLES:

    Sage

        sage: UCF = UniversalCyclotomicField()
        sage: UCF(3).sqrt()
        E(12)^7 - E(12)^11
        sage: (UCF(3).sqrt())**2
        3

        sage: r = UCF(-1400 / 143).sqrt()
        sage: r**2
        -1400/143

        sage: E(33).sqrt()
        -E(33)^17
        sage: E(33).sqrt() ** 2
        E(33)

        sage: (3 * E(5)).sqrt()
        -E(60)^11 + E(60)^31
        sage: (3 * E(5)).sqrt() ** 2
        3*E(5)

    Python

        >>> from sage.all import *
        >>> UCF = UniversalCyclotomicField()
        >>> UCF(Integer(3)).sqrt()
        E(12)^7 - E(12)^11
        >>> (UCF(Integer(3)).sqrt())**Integer(2)
        3

        >>> r = UCF(-Integer(1400) / Integer(143)).sqrt()
        >>> r**Integer(2)
        -1400/143

        >>> E(Integer(33)).sqrt()
        -E(33)^17
        >>> E(Integer(33)).sqrt() ** Integer(2)
        E(33)

        >>> (Integer(3) * E(Integer(5))).sqrt()
        -E(60)^11 + E(60)^31
        >>> (Integer(3) * E(Integer(5))).sqrt() ** Integer(2)
        3*E(5)

    Setting `all=True` you obtain the two square roots in a list:

    Sage

        sage: UCF(3).sqrt(all=True)
        [E(12)^7 - E(12)^11, -E(12)^7 + E(12)^11]
        sage: (1 + UCF.zeta(5)).sqrt(all=True)
        [1.209762576525833? + 0.3930756888787117?*I,
         -1.209762576525833? - 0.3930756888787117?*I]

    [Python]

        >>> from sage.all import *
        >>> UCF(Integer(3)).sqrt(all=True)
        [E(12)^7 - E(12)^11, -E(12)^7 + E(12)^11]
        >>> (Integer(1) + UCF.zeta(Integer(5))).sqrt(all=True)
        [1.209762576525833? + 0.3930756888787117?*I,
         -1.209762576525833? - 0.3930756888787117?*I]

    In the following situation, Sage is not (yet) able to compute a square root within the universal cyclotomic field:

    Sage

        sage: (E(5) + E(5, 2)).sqrt()
        0.7476743906106103? + 1.029085513635746?*I
        sage: (E(5) + E(5, 2)).sqrt(extend=False)
        Traceback (most recent call last):
        ...
        NotImplementedError: sqrt() not fully implemented for elements of Universal Cyclotomic Field

    Python

        >>> from sage.all import *
        >>> (E(Integer(5)) + E(Integer(5), Integer(2))).sqrt()
        0.7476743906106103? + 1.029085513635746?*I
        >>> (E(Integer(5)) + E(Integer(5), Integer(2))).sqrt(extend=False)
        Traceback (most recent call last):
        ...
        NotImplementedError: sqrt() not fully implemented for elements of Universal Cyclotomic Field

  to_cyclotomic_field(R=None)

    Return this element as an element of a cyclotomic field.

    EXAMPLES:

    Sage

        sage: UCF = UniversalCyclotomicField()

        sage: UCF.gen(3).to_cyclotomic_field()
        zeta3
        sage: UCF.gen(3,2).to_cyclotomic_field()
        -zeta3 - 1

        sage: CF = CyclotomicField(5)
        sage: CF(E(5)) # indirect doctest
        zeta5

        sage: CF = CyclotomicField(7)
        sage: CF(E(5)) # indirect doctest
        Traceback (most recent call last):
        ...
        TypeError: cannot coerce zeta5 into Cyclotomic Field of order 7 and
        degree 6

        sage: CF = CyclotomicField(10)
        sage: CF(E(5)) # indirect doctest
        zeta10^2

    Python

        >>> from sage.all import *
        >>> UCF = UniversalCyclotomicField()

        >>> UCF.gen(Integer(3)).to_cyclotomic_field()
        zeta3
        >>> UCF.gen(Integer(3),Integer(2)).to_cyclotomic_field()
        -zeta3 - 1

        >>> CF = CyclotomicField(Integer(5))
        >>> CF(E(Integer(5))) # indirect doctest
        zeta5

        >>> CF = CyclotomicField(Integer(7))
        >>> CF(E(Integer(5))) # indirect doctest
        Traceback (most recent call last):
        ...
        TypeError: cannot coerce zeta5 into Cyclotomic Field of order 7 and
        degree 6

        >>> CF = CyclotomicField(Integer(10))
        >>> CF(E(Integer(5))) # indirect doctest
        zeta10^2

    Matrices are correctly dealt with:

    Sage

        sage: M = Matrix(UCF,2,[E(3),E(4),E(5),E(6)]); M
        [   E(3)    E(4)]
        [   E(5) -E(3)^2]

        sage: Matrix(CyclotomicField(60),M)  # indirect doctest
        [zeta60^10 - 1     zeta60^15]
        [    zeta60^12     zeta60^10]

    [Python]

        >>> from sage.all import *
        >>> M = Matrix(UCF,Integer(2),[E(Integer(3)),E(Integer(4)),E(Integer(5)),E(Integer(6))]); M
        [   E(3)    E(4)]
        [   E(5) -E(3)^2]

        >>> Matrix(CyclotomicField(Integer(60)),M)  # indirect doctest
        [zeta60^10 - 1     zeta60^15]
        [    zeta60^12     zeta60^10]

    Using a non-standard embedding:

    Sage

        sage: # needs sage.symbolic
        sage: CF = CyclotomicField(5, embedding=CC(exp(4*pi*i/5)))
        sage: x = E(5)
        sage: CC(x)
        0.309016994374947 + 0.951056516295154*I
        sage: CC(CF(x))
        0.309016994374947 + 0.951056516295154*I

    Python

        >>> from sage.all import *
        >>> # needs sage.symbolic
        >>> CF = CyclotomicField(Integer(5), embedding=CC(exp(Integer(4)*pi*i/Integer(5))))
        >>> x = E(Integer(5))
        >>> CC(x)
        0.309016994374947 + 0.951056516295154*I
        >>> CC(CF(x))
        0.309016994374947 + 0.951056516295154*I

    Test that the bug reported in Issue #19912 has been fixed:

    Sage

        sage: a = 1+E(4); a
        1 + E(4)
        sage: a.to_cyclotomic_field()
        zeta4 + 1

    [Python]

        >>> from sage.all import *
        >>> a = Integer(1)+E(Integer(4)); a
        1 + E(4)
        >>> a.to_cyclotomic_field()
        zeta4 + 1

sage.rings.universal_cyclotomic_field.late_import()

  This function avoids importing libgap on startup. It is called once through the constructor of `UniversalCyclotomicField`.

  EXAMPLES:

  Sage

      sage: import sage.rings.universal_cyclotomic_field as ucf
      sage: _ = UniversalCyclotomicField()   # indirect doctest
      sage: ucf.libgap is None               # indirect doctest
      False

  Python

      >>> from sage.all import *
      >>> import sage.rings.universal_cyclotomic_field as ucf
      >>> _ = UniversalCyclotomicField()   # indirect doctest
      >>> ucf.libgap is None               # indirect doctest
      False