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: UCF = UniversalCyclotomicField(); UCF
Universal Cyclotomic Field
>>> from sage.all import *
>>> UCF = UniversalCyclotomicField(); UCF
Universal Cyclotomic Field
UCF = UniversalCyclotomicField(); UCF

To generate cyclotomic elements:

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

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

>>> E = UCF.gen
UCF.gen(5)
UCF.gen(5,2)
E = UCF.gen

Equality and inequality checks:

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

sage: E(6)^2 != E(3)
False
>>> 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
E(6,2) == E(6)^2 == E(3)
E(6)^2 != E(3)

Addition and multiplication:

sage: E(2) * E(3)
-E(3)
sage: f = E(2) + E(3); f
2*E(3) + E(3)^2
>>> 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
E(2) * E(3)
f = E(2) + E(3); f

Inverses:

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
>>> 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
f^-1
f.inverse()
f * f.inverse()

Conjugation and Galois conjugates:

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
>>> 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
f.conjugate()
f.galois_conjugates()
f.norm_of_galois_extension()

One can create matrices and polynomials:

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
>>> 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
m = matrix(2,[E(3),1,1,E(4)]); m
m.parent()
m**2
m.charpoly()
m.echelon_form()
m.pivots()
m.rank()
R.<x> = PolynomialRing(UniversalCyclotomicField(), 'x')
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:

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)[source]

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

EXAMPLES:

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
>>> 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
E(3)
E(3) + E(5)
sage.rings.universal_cyclotomic_field.UCF_sqrt_int(N, UCF)[source]

Return the square root of the integer N.

EXAMPLES:

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
>>> 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
from sage.rings.universal_cyclotomic_field import UCF_sqrt_int
UCF = UniversalCyclotomicField()
UCF_sqrt_int(0, UCF)
UCF_sqrt_int(1, UCF)
UCF_sqrt_int(-1, UCF)
UCF_sqrt_int(2, UCF)
UCF_sqrt_int(-2, UCF)
class sage.rings.universal_cyclotomic_field.UCFtoQQbar(UCF)[source]

Bases: Morphism

Conversion to QQbar.

EXAMPLES:

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)
>>> 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)
UCF = UniversalCyclotomicField()
QQbar(UCF.gen(3))
CC(UCF.gen(7,2) + UCF.gen(7,6))
complex(E(7)+E(7,2))
complex(UCF.one()/2)
class sage.rings.universal_cyclotomic_field.UniversalCyclotomicField(names=None)[source]

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[source]

alias of UniversalCyclotomicFieldElement

algebraic_closure()[source]

The algebraic closure.

EXAMPLES:

sage: UniversalCyclotomicField().algebraic_closure()
Algebraic Field
>>> from sage.all import *
>>> UniversalCyclotomicField().algebraic_closure()
Algebraic Field
UniversalCyclotomicField().algebraic_closure()
an_element()[source]

Return an element.

EXAMPLES:

sage: UniversalCyclotomicField().an_element()
E(5) - 3*E(5)^2
>>> from sage.all import *
>>> UniversalCyclotomicField().an_element()
E(5) - 3*E(5)^2
UniversalCyclotomicField().an_element()
characteristic()[source]

Return the characteristic.

EXAMPLES:

sage: UniversalCyclotomicField().characteristic()
0
sage: parent(_)
Integer Ring
>>> from sage.all import *
>>> UniversalCyclotomicField().characteristic()
0
>>> parent(_)
Integer Ring
UniversalCyclotomicField().characteristic()
parent(_)
degree()[source]

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

EXAMPLES:

sage: UCF = UniversalCyclotomicField()
sage: UCF.degree()
+Infinity
>>> from sage.all import *
>>> UCF = UniversalCyclotomicField()
>>> UCF.degree()
+Infinity
UCF = UniversalCyclotomicField()
UCF.degree()
gen(n, k=1)[source]

Return the standard primitive n-th root of unity.

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

EXAMPLES:

sage: UCF = UniversalCyclotomicField()
sage: UCF.gen(15)
E(15)
sage: UCF.gen(7,3)
E(7)^3
sage: UCF.gen(4,2)
-1
>>> 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
UCF = UniversalCyclotomicField()
UCF.gen(15)
UCF.gen(7,3)
UCF.gen(4,2)

There is an alias zeta also available:

sage: UCF.zeta(6)
-E(3)^2
>>> from sage.all import *
>>> UCF.zeta(Integer(6))
-E(3)^2
UCF.zeta(6)
is_exact()[source]

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

EXAMPLES:

sage: UniversalCyclotomicField().is_exact()
True
>>> from sage.all import *
>>> UniversalCyclotomicField().is_exact()
True
UniversalCyclotomicField().is_exact()
one()[source]

Return one.

EXAMPLES:

sage: UCF = UniversalCyclotomicField()
sage: UCF.one()
1
sage: parent(_)
Universal Cyclotomic Field
>>> from sage.all import *
>>> UCF = UniversalCyclotomicField()
>>> UCF.one()
1
>>> parent(_)
Universal Cyclotomic Field
UCF = UniversalCyclotomicField()
UCF.one()
parent(_)
some_elements()[source]

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

EXAMPLES:

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
>>> 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
UniversalCyclotomicField().some_elements()
all(parent(x) is UniversalCyclotomicField() for x in _)
zero()[source]

Return zero.

EXAMPLES:

sage: UCF = UniversalCyclotomicField()
sage: UCF.zero()
0
sage: parent(_)
Universal Cyclotomic Field
>>> from sage.all import *
>>> UCF = UniversalCyclotomicField()
>>> UCF.zero()
0
>>> parent(_)
Universal Cyclotomic Field
UCF = UniversalCyclotomicField()
UCF.zero()
parent(_)
zeta(n, k=1)[source]

Return the standard primitive n-th root of unity.

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

EXAMPLES:

sage: UCF = UniversalCyclotomicField()
sage: UCF.gen(15)
E(15)
sage: UCF.gen(7,3)
E(7)^3
sage: UCF.gen(4,2)
-1
>>> 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
UCF = UniversalCyclotomicField()
UCF.gen(15)
UCF.gen(7,3)
UCF.gen(4,2)

There is an alias zeta also available:

sage: UCF.zeta(6)
-E(3)^2
>>> from sage.all import *
>>> UCF.zeta(Integer(6))
-E(3)^2
UCF.zeta(6)
class sage.rings.universal_cyclotomic_field.UniversalCyclotomicFieldElement(parent, obj)[source]

Bases: FieldElement

INPUT:

  • parent – a universal cyclotomic field

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

abs()[source]

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

The absolute value is returned as an algebraic real number.

EXAMPLES:

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
>>> 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
f = 5/2*E(3)+E(5)/7
f.abs()
abs(f)
a = E(8)
abs(a)
v, w = vector([a]), vector([a, a])
v.norm(), w.norm()
v.norm().parent()
additive_order()[source]

Return the additive order.

EXAMPLES:

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

Return the conductor of self.

EXAMPLES:

sage: E(3).conductor()
3
sage: (E(5) + E(3)).conductor()
15
>>> from sage.all import *
>>> E(Integer(3)).conductor()
3
>>> (E(Integer(5)) + E(Integer(3))).conductor()
15
E(3).conductor()
(E(5) + E(3)).conductor()
conjugate()[source]

Return the complex conjugate.

EXAMPLES:

sage: (E(7) + 3*E(7,2) - 5 * E(7,3)).conjugate()
-5*E(7)^4 + 3*E(7)^5 + E(7)^6
>>> 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
(E(7) + 3*E(7,2) - 5 * E(7,3)).conjugate()
denominator()[source]

Return the denominator of this element.

See also

is_integral()

EXAMPLES:

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
>>> 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
a = E(5) + 1/2*E(5,2) + 1/3*E(5,3)
a
a.denominator()
parent(_)
galois_conjugates(n=None)[source]

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: 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)
>>> 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)
E(6).galois_conjugates()
E(6).galois_conjugates()
(E(9,2) - E(9,4)).galois_conjugates()
zeta = E(5)
zeta.galois_conjugates(5)
zeta.galois_conjugates(10)
zeta.galois_conjugates(15)
zeta.galois_conjugates(17)
imag()[source]

Return the imaginary part of this element.

EXAMPLES:

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
>>> 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
E(3).imag()
E(5).imag()
a = E(5) - 2*E(3)
AA(a.imag()) == QQbar(a).imag()
imag_part()[source]

Return the imaginary part of this element.

EXAMPLES:

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
>>> 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
E(3).imag()
E(5).imag()
a = E(5) - 2*E(3)
AA(a.imag()) == QQbar(a).imag()
inverse()[source]
is_integral()[source]

Return whether self is an algebraic integer.

This just wraps IsIntegralCyclotomic from GAP.

See also

denominator()

EXAMPLES:

sage: E(6).is_integral()
True
sage: (E(4)/2).is_integral()
False
>>> from sage.all import *
>>> E(Integer(6)).is_integral()
True
>>> (E(Integer(4))/Integer(2)).is_integral()
False
E(6).is_integral()
(E(4)/2).is_integral()
is_rational()[source]

Test whether this element is a rational number.

EXAMPLES:

sage: E(3).is_rational()
False
sage: (E(3) + E(3,2)).is_rational()
True
>>> from sage.all import *
>>> E(Integer(3)).is_rational()
False
>>> (E(Integer(3)) + E(Integer(3),Integer(2))).is_rational()
True
E(3).is_rational()
(E(3) + E(3,2)).is_rational()
is_real()[source]

Test whether this element is real.

EXAMPLES:

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
>>> 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
E(3).is_real()
(E(3) + E(3,2)).is_real()
a = E(3) - 2*E(7)
a.real_part().is_real()
a.imag_part().is_real()
is_square()[source]

EXAMPLES:

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
>>> 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
UCF = UniversalCyclotomicField()
UCF(5/2).is_square()
UCF.zeta(7,3).is_square()
(2 + UCF.zeta(3)).is_square()
minpoly(var='x')[source]

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

INPUT:

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

EXAMPLES:

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
>>> 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
UCF.<E> = UniversalCyclotomicField()
UCF(4).minpoly()
UCF(4).minpoly(var='y')
E(3).minpoly()
E(3).minpoly(var='y')

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()[source]

Return the multiplicative order.

EXAMPLES:

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
>>> 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
E(5).multiplicative_order()
(E(5) + E(12)).multiplicative_order()
UniversalCyclotomicField().zero().multiplicative_order()
norm_of_galois_extension()[source]

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

EXAMPLES:

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
>>> 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
E(3).norm_of_galois_extension()
E(6).norm_of_galois_extension()
(E(2) + E(3)).norm_of_galois_extension()
parent(_)
real()[source]

Return the real part of this element.

EXAMPLES:

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
>>> 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
E(3).real()
E(5).real()
a = E(5) - 2*E(3)
AA(a.real()) == QQbar(a).real()
real_part()[source]

Return the real part of this element.

EXAMPLES:

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
>>> 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
E(3).real()
E(5).real()
a = E(5) - 2*E(3)
AA(a.real()) == QQbar(a).real()
sqrt(extend=True, all=False)[source]

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: 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)
>>> 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)
UCF = UniversalCyclotomicField()
UCF(3).sqrt()
(UCF(3).sqrt())**2
r = UCF(-1400 / 143).sqrt()
r**2
E(33).sqrt()
E(33).sqrt() ** 2
(3 * E(5)).sqrt()
(3 * E(5)).sqrt() ** 2

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

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]
>>> 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]
UCF(3).sqrt(all=True)
(1 + UCF.zeta(5)).sqrt(all=True)

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

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
>>> 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
(E(5) + E(5, 2)).sqrt()
(E(5) + E(5, 2)).sqrt(extend=False)
to_cyclotomic_field(R=None)[source]

Return this element as an element of a cyclotomic field.

EXAMPLES:

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
>>> 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
UCF = UniversalCyclotomicField()
UCF.gen(3).to_cyclotomic_field()
UCF.gen(3,2).to_cyclotomic_field()
CF = CyclotomicField(5)
CF(E(5)) # indirect doctest
CF = CyclotomicField(7)
CF(E(5)) # indirect doctest
CF = CyclotomicField(10)
CF(E(5)) # indirect doctest

Matrices are correctly dealt with:

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]
>>> 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]
M = Matrix(UCF,2,[E(3),E(4),E(5),E(6)]); M
Matrix(CyclotomicField(60),M)  # indirect doctest

Using a non-standard embedding:

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
>>> 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
# needs sage.symbolic
CF = CyclotomicField(5, embedding=CC(exp(4*pi*i/5)))
x = E(5)
CC(x)
CC(CF(x))

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

sage: a = 1+E(4); a
1 + E(4)
sage: a.to_cyclotomic_field()
zeta4 + 1
>>> from sage.all import *
>>> a = Integer(1)+E(Integer(4)); a
1 + E(4)
>>> a.to_cyclotomic_field()
zeta4 + 1
a = 1+E(4); a
a.to_cyclotomic_field()
sage.rings.universal_cyclotomic_field.late_import()[source]

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

EXAMPLES:

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