Number fields

We define a quartic number field and its quadratic extension:

sage: x = polygen(ZZ, 'x')
sage: K.<y> = NumberField(x^4 - 420*x^2 + 40000)
sage: z = y^5/11; z
420/11*y^3 - 40000/11*y
sage: R.<y> = PolynomialRing(K)
sage: f = y^2 + y + 1
sage: L.<a> = K.extension(f); L
Number Field in a with defining polynomial y^2 + y + 1 over its base field
sage: KL.<b> = NumberField([x^4 - 420*x^2 + 40000, x^2 + x + 1]); KL
Number Field in b0 with defining polynomial x^4 - 420*x^2 + 40000 over its base field
>>> from sage.all import *
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(4) - Integer(420)*x**Integer(2) + Integer(40000), names=('y',)); (y,) = K._first_ngens(1)
>>> z = y**Integer(5)/Integer(11); z
420/11*y^3 - 40000/11*y
>>> R = PolynomialRing(K, names=('y',)); (y,) = R._first_ngens(1)
>>> f = y**Integer(2) + y + Integer(1)
>>> L = K.extension(f, names=('a',)); (a,) = L._first_ngens(1); L
Number Field in a with defining polynomial y^2 + y + 1 over its base field
>>> KL = NumberField([x**Integer(4) - Integer(420)*x**Integer(2) + Integer(40000), x**Integer(2) + x + Integer(1)], names=('b',)); (b,) = KL._first_ngens(1); KL
Number Field in b0 with defining polynomial x^4 - 420*x^2 + 40000 over its base field

We do some arithmetic in a tower of relative number fields:

sage: K.<cuberoot2> = NumberField(x^3 - 2)
sage: L.<cuberoot3> = K.extension(x^3 - 3)
sage: S.<sqrt2> = L.extension(x^2 - 2)
sage: S
Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field
sage: sqrt2 * cuberoot3
cuberoot3*sqrt2
sage: (sqrt2 + cuberoot3)^5
(20*cuberoot3^2 + 15*cuberoot3 + 4)*sqrt2 + 3*cuberoot3^2 + 20*cuberoot3 + 60
sage: cuberoot2 + cuberoot3
cuberoot3 + cuberoot2
sage: cuberoot2 + cuberoot3 + sqrt2
sqrt2 + cuberoot3 + cuberoot2
sage: (cuberoot2 + cuberoot3 + sqrt2)^2
(2*cuberoot3 + 2*cuberoot2)*sqrt2 + cuberoot3^2 + 2*cuberoot2*cuberoot3 + cuberoot2^2 + 2
sage: cuberoot2 + sqrt2
sqrt2 + cuberoot2
sage: a = S(cuberoot2); a
cuberoot2
sage: a.parent()
Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field
>>> from sage.all import *
>>> K = NumberField(x**Integer(3) - Integer(2), names=('cuberoot2',)); (cuberoot2,) = K._first_ngens(1)
>>> L = K.extension(x**Integer(3) - Integer(3), names=('cuberoot3',)); (cuberoot3,) = L._first_ngens(1)
>>> S = L.extension(x**Integer(2) - Integer(2), names=('sqrt2',)); (sqrt2,) = S._first_ngens(1)
>>> S
Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field
>>> sqrt2 * cuberoot3
cuberoot3*sqrt2
>>> (sqrt2 + cuberoot3)**Integer(5)
(20*cuberoot3^2 + 15*cuberoot3 + 4)*sqrt2 + 3*cuberoot3^2 + 20*cuberoot3 + 60
>>> cuberoot2 + cuberoot3
cuberoot3 + cuberoot2
>>> cuberoot2 + cuberoot3 + sqrt2
sqrt2 + cuberoot3 + cuberoot2
>>> (cuberoot2 + cuberoot3 + sqrt2)**Integer(2)
(2*cuberoot3 + 2*cuberoot2)*sqrt2 + cuberoot3^2 + 2*cuberoot2*cuberoot3 + cuberoot2^2 + 2
>>> cuberoot2 + sqrt2
sqrt2 + cuberoot2
>>> a = S(cuberoot2); a
cuberoot2
>>> a.parent()
Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field

Warning

Doing arithmetic in towers of relative fields that depends on canonical coercions is currently VERY SLOW. It is much better to explicitly coerce all elements into a common field, then do arithmetic with them there (which is quite fast).

AUTHORS:

  • William Stein (2004, 2005): initial version

  • Steven Sivek (2006-05-12): added support for relative extensions

  • William Stein (2007-09-04): major rewrite and documentation

  • Robert Bradshaw (2008-10): specified embeddings into ambient fields

  • Simon King (2010-05): improved coercion from GAP

  • Jeroen Demeyer (2010-07, 2011-04): upgraded PARI (Issue #9343, Issue #10430, Issue #11130)

  • Robert Harron (2012-08): added is_CM(), complex_conjugation(), and maximal_totally_real_subfield()

  • Christian Stump (2012-11): added conversion to universal cyclotomic field

  • Julian Rueth (2014-04-03): absolute number fields are unique parents

  • Vincent Delecroix (2015-02): comparisons/floor/ceil using embeddings

  • Kiran Kedlaya (2016-05): relative number fields hash based on relative polynomials

  • Peter Bruin (2016-06): made number fields fully satisfy unique representation

  • John Jones (2017-07): improved check for is_galois(), add is_abelian(), building on work in patch by Chris Wuthrich

  • Anna Haensch (2018-03): added quadratic_defect()

  • Michael Daub, Chris Wuthrich (2020-09-01): added Dirichlet characters for abelian fields

class sage.rings.number_field.number_field.CyclotomicFieldFactory[source]

Bases: UniqueFactory

Return the \(n\)-th cyclotomic field, where \(n\) is a positive integer, or the universal cyclotomic field if \(n=0\).

For the documentation of the universal cyclotomic field, see UniversalCyclotomicField.

INPUT:

  • n – nonnegative integer (default: \(0\))

  • names – name of generator (default: zetan)

  • bracket – defines the brackets in the case of \(n=0\), and is ignored otherwise. Can be any even length string, with '()' being the default.

  • embedding – boolean or \(n\)-th root of unity in an ambient field (default: True)

EXAMPLES:

If called without a parameter, we get the universal cyclotomic field:

sage: CyclotomicField()                                                         # needs sage.libs.gap
Universal Cyclotomic Field
>>> from sage.all import *
>>> CyclotomicField()                                                         # needs sage.libs.gap
Universal Cyclotomic Field

We create the \(7\)th cyclotomic field \(\QQ(\zeta_7)\) with the default generator name.

sage: k = CyclotomicField(7); k
Cyclotomic Field of order 7 and degree 6
sage: k.gen()
zeta7
>>> from sage.all import *
>>> k = CyclotomicField(Integer(7)); k
Cyclotomic Field of order 7 and degree 6
>>> k.gen()
zeta7

The default embedding sends the generator to the complex primitive \(n\)-th root of unity of least argument.

sage: CC(k.gen())
0.623489801858734 + 0.781831482468030*I
>>> from sage.all import *
>>> CC(k.gen())
0.623489801858734 + 0.781831482468030*I

Cyclotomic fields are of a special type.

sage: type(k)
<class 'sage.rings.number_field.number_field.NumberField_cyclotomic_with_category'>
>>> from sage.all import *
>>> type(k)
<class 'sage.rings.number_field.number_field.NumberField_cyclotomic_with_category'>

We can specify a different generator name as follows.

sage: k.<z7> = CyclotomicField(7); k
Cyclotomic Field of order 7 and degree 6
sage: k.gen()
z7
>>> from sage.all import *
>>> k = CyclotomicField(Integer(7), names=('z7',)); (z7,) = k._first_ngens(1); k
Cyclotomic Field of order 7 and degree 6
>>> k.gen()
z7

The \(n\) must be an integer.

sage: CyclotomicField(3/2)
Traceback (most recent call last):
...
TypeError: no conversion of this rational to integer
>>> from sage.all import *
>>> CyclotomicField(Integer(3)/Integer(2))
Traceback (most recent call last):
...
TypeError: no conversion of this rational to integer

The degree must be nonnegative.

sage: CyclotomicField(-1)
Traceback (most recent call last):
...
ValueError: n (=-1) must be a positive integer
>>> from sage.all import *
>>> CyclotomicField(-Integer(1))
Traceback (most recent call last):
...
ValueError: n (=-1) must be a positive integer

The special case \(n=1\) does not return the rational numbers:

sage: CyclotomicField(1)
Cyclotomic Field of order 1 and degree 1
>>> from sage.all import *
>>> CyclotomicField(Integer(1))
Cyclotomic Field of order 1 and degree 1

Due to their default embedding into \(\CC\), cyclotomic number fields are all compatible.

sage: cf30 = CyclotomicField(30)
sage: cf5 = CyclotomicField(5)
sage: cf3 = CyclotomicField(3)
sage: cf30.gen() + cf5.gen() + cf3.gen()
zeta30^6 + zeta30^5 + zeta30 - 1
sage: cf6 = CyclotomicField(6) ; z6 = cf6.0
sage: cf3 = CyclotomicField(3) ; z3 = cf3.0
sage: cf3(z6)
zeta3 + 1
sage: cf6(z3)
zeta6 - 1
sage: cf9 = CyclotomicField(9) ; z9 = cf9.0
sage: cf18 = CyclotomicField(18) ; z18 = cf18.0
sage: cf18(z9)
zeta18^2
sage: cf9(z18)
-zeta9^5
sage: cf18(z3)
zeta18^3 - 1
sage: cf18(z6)
zeta18^3
sage: cf18(z6)**2
zeta18^3 - 1
sage: cf9(z3)
zeta9^3
>>> from sage.all import *
>>> cf30 = CyclotomicField(Integer(30))
>>> cf5 = CyclotomicField(Integer(5))
>>> cf3 = CyclotomicField(Integer(3))
>>> cf30.gen() + cf5.gen() + cf3.gen()
zeta30^6 + zeta30^5 + zeta30 - 1
>>> cf6 = CyclotomicField(Integer(6)) ; z6 = cf6.gen(0)
>>> cf3 = CyclotomicField(Integer(3)) ; z3 = cf3.gen(0)
>>> cf3(z6)
zeta3 + 1
>>> cf6(z3)
zeta6 - 1
>>> cf9 = CyclotomicField(Integer(9)) ; z9 = cf9.gen(0)
>>> cf18 = CyclotomicField(Integer(18)) ; z18 = cf18.gen(0)
>>> cf18(z9)
zeta18^2
>>> cf9(z18)
-zeta9^5
>>> cf18(z3)
zeta18^3 - 1
>>> cf18(z6)
zeta18^3
>>> cf18(z6)**Integer(2)
zeta18^3 - 1
>>> cf9(z3)
zeta9^3
create_key(n=0, names=None, embedding=True)[source]

Create the unique key for the cyclotomic field specified by the parameters.

create_object(version, key, **extra_args)[source]

Create the unique cyclotomic field defined by key.

sage.rings.number_field.number_field.GaussianField()[source]

The field \(\QQ[i]\).

sage.rings.number_field.number_field.NumberField(polynomial, name, check=None, names=True, embedding=None, latex_name=None, assume_disc_small=None, maximize_at_primes=False, structure=None, latex_names=None, **kwds)[source]

Return the number field (or tower of number fields) defined by the irreducible polynomial.

INPUT:

  • polynomial – a polynomial over \(\QQ\) or a number field, or a list of such polynomials

  • names (or name) – string or list of strings, the names of the generators

  • check – boolean (default: True); do type checking and irreducibility checking

  • embeddingNone, an element, or a list of elements, the images of the generators in an ambient field (default: None)

  • latex_names (or latex_name) – None, a string, or a list of strings (default: None); how the generators are printed for latex output

  • assume_disc_small – boolean (default: False); if True, assume that no square of a prime greater than PARI’s primelimit (which should be 500000). Only applies for absolute fields at present.

  • maximize_at_primesNone or a list of primes (default: None); if not None, then the maximal order is computed by maximizing only at the primes in this list, which completely avoids having to factor the discriminant, but of course can lead to wrong results; only applies for absolute fields at present.

  • structureNone, a list or an instance of structure.NumberFieldStructure (default: None), internally used to pass in additional structural information, e.g., about the field from which this field is created as a subfield.

We accept implementation and prec attributes for compatibility with AlgebraicExtensionFunctor but we ignore them as they are not used.

EXAMPLES:

sage: z = QQ['z'].0
sage: K = NumberField(z^2 - 2, 's'); K
Number Field in s with defining polynomial z^2 - 2
sage: s = K.0; s
s
sage: s*s
2
sage: s^2
2
>>> from sage.all import *
>>> z = QQ['z'].gen(0)
>>> K = NumberField(z**Integer(2) - Integer(2), 's'); K
Number Field in s with defining polynomial z^2 - 2
>>> s = K.gen(0); s
s
>>> s*s
2
>>> s**Integer(2)
2

Constructing a relative number field:

sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^2 - 2)
sage: R.<t> = K[]
sage: L.<b> = K.extension(t^3 + t + a); L
Number Field in b with defining polynomial t^3 + t + a over its base field
sage: L.absolute_field('c')
Number Field in c with defining polynomial x^6 + 2*x^4 + x^2 - 2
sage: a*b
a*b
sage: L(a)
a
sage: L.lift_to_base(b^3 + b)
-a
>>> from sage.all import *
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(2) - Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> R = K['t']; (t,) = R._first_ngens(1)
>>> L = K.extension(t**Integer(3) + t + a, names=('b',)); (b,) = L._first_ngens(1); L
Number Field in b with defining polynomial t^3 + t + a over its base field
>>> L.absolute_field('c')
Number Field in c with defining polynomial x^6 + 2*x^4 + x^2 - 2
>>> a*b
a*b
>>> L(a)
a
>>> L.lift_to_base(b**Integer(3) + b)
-a

Constructing another number field:

sage: k.<i> = NumberField(x^2 + 1)
sage: R.<z> = k[]
sage: m.<j> = NumberField(z^3 + i*z + 3)
sage: m
Number Field in j with defining polynomial z^3 + i*z + 3 over its base field
>>> from sage.all import *
>>> k = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = k._first_ngens(1)
>>> R = k['z']; (z,) = R._first_ngens(1)
>>> m = NumberField(z**Integer(3) + i*z + Integer(3), names=('j',)); (j,) = m._first_ngens(1)
>>> m
Number Field in j with defining polynomial z^3 + i*z + 3 over its base field

Number fields are globally unique:

sage: K.<a> = NumberField(x^3 - 5)
sage: a^3
5
sage: L.<a> = NumberField(x^3 - 5)
sage: K is L
True
>>> from sage.all import *
>>> K = NumberField(x**Integer(3) - Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> a**Integer(3)
5
>>> L = NumberField(x**Integer(3) - Integer(5), names=('a',)); (a,) = L._first_ngens(1)
>>> K is L
True

Equality of number fields depends on the variable name of the defining polynomial:

sage: x = polygen(QQ, 'x'); y = polygen(QQ, 'y')
sage: k.<a> = NumberField(x^2 + 3)
sage: m.<a> = NumberField(y^2 + 3)
sage: k
Number Field in a with defining polynomial x^2 + 3
sage: m
Number Field in a with defining polynomial y^2 + 3
sage: k == m
False
>>> from sage.all import *
>>> x = polygen(QQ, 'x'); y = polygen(QQ, 'y')
>>> k = NumberField(x**Integer(2) + Integer(3), names=('a',)); (a,) = k._first_ngens(1)
>>> m = NumberField(y**Integer(2) + Integer(3), names=('a',)); (a,) = m._first_ngens(1)
>>> k
Number Field in a with defining polynomial x^2 + 3
>>> m
Number Field in a with defining polynomial y^2 + 3
>>> k == m
False

In case of conflict of the generator name with the name given by the preparser, the name given by the preparser takes precedence:

sage: K.<b> = NumberField(x^2 + 5, 'a'); K
Number Field in b with defining polynomial x^2 + 5
>>> from sage.all import *
>>> K = NumberField(x**Integer(2) + Integer(5), 'a', names=('b',)); (b,) = K._first_ngens(1); K
Number Field in b with defining polynomial x^2 + 5

One can also define number fields with specified embeddings, may be used for arithmetic and deduce relations with other number fields which would not be valid for an abstract number field.

sage: K.<a> = NumberField(x^3 - 2, embedding=1.2)
sage: RR.coerce_map_from(K)
Composite map:
  From: Number Field in a with defining polynomial x^3 - 2 with a = 1.259921049894873?
  To:   Real Field with 53 bits of precision
  Defn:   Generic morphism:
          From: Number Field in a with defining polynomial x^3 - 2
                with a = 1.259921049894873?
          To:   Real Lazy Field
          Defn: a -> 1.259921049894873?
        then
          Conversion via _mpfr_ method map:
          From: Real Lazy Field
          To:   Real Field with 53 bits of precision
sage: RR(a)
1.25992104989487
sage: 1.1 + a
2.35992104989487
sage: b = 1/(a+1); b
1/3*a^2 - 1/3*a + 1/3
sage: RR(b)
0.442493334024442
sage: L.<b> = NumberField(x^6 - 2, embedding=1.1)
sage: L(a)
b^2
sage: a + b
b^2 + b
>>> from sage.all import *
>>> K = NumberField(x**Integer(3) - Integer(2), embedding=RealNumber('1.2'), names=('a',)); (a,) = K._first_ngens(1)
>>> RR.coerce_map_from(K)
Composite map:
  From: Number Field in a with defining polynomial x^3 - 2 with a = 1.259921049894873?
  To:   Real Field with 53 bits of precision
  Defn:   Generic morphism:
          From: Number Field in a with defining polynomial x^3 - 2
                with a = 1.259921049894873?
          To:   Real Lazy Field
          Defn: a -> 1.259921049894873?
        then
          Conversion via _mpfr_ method map:
          From: Real Lazy Field
          To:   Real Field with 53 bits of precision
>>> RR(a)
1.25992104989487
>>> RealNumber('1.1') + a
2.35992104989487
>>> b = Integer(1)/(a+Integer(1)); b
1/3*a^2 - 1/3*a + 1/3
>>> RR(b)
0.442493334024442
>>> L = NumberField(x**Integer(6) - Integer(2), embedding=RealNumber('1.1'), names=('b',)); (b,) = L._first_ngens(1)
>>> L(a)
b^2
>>> a + b
b^2 + b

Note that the image only needs to be specified to enough precision to distinguish roots, and is exactly computed to any needed precision:

sage: RealField(200)(a)
1.2599210498948731647672106072782283505702514647015079800820
>>> from sage.all import *
>>> RealField(Integer(200))(a)
1.2599210498948731647672106072782283505702514647015079800820

One can embed into any other field:

sage: K.<a> = NumberField(x^3 - 2, embedding=CC.gen() - 0.6)
sage: CC(a)
-0.629960524947436 + 1.09112363597172*I

sage: # needs sage.rings.padics
sage: L = Qp(5)
sage: f = polygen(L)^3 - 2
sage: K.<a> = NumberField(x^3 - 2, embedding=f.roots()[0][0])
sage: a + L(1)
4 + 2*5^2 + 2*5^3 + 3*5^4 + 5^5 + 4*5^6 + 2*5^8 + 3*5^9 + 4*5^12
 + 4*5^14 + 4*5^15 + 3*5^16 + 5^17 + 5^18 + 2*5^19 + O(5^20)
sage: L.<b> = NumberField(x^6 - x^2 + 1/10, embedding=1)
sage: K.<a> = NumberField(x^3 - x + 1/10, embedding=b^2)
sage: a + b
b^2 + b
sage: CC(a) == CC(b)^2
True
sage: K.coerce_embedding()
Generic morphism:
  From: Number Field in a with defining polynomial x^3 - x + 1/10 with a = b^2
  To:   Number Field in b with defining polynomial x^6 - x^2 + 1/10
        with b = 0.9724449978911874?
  Defn: a -> b^2
>>> from sage.all import *
>>> K = NumberField(x**Integer(3) - Integer(2), embedding=CC.gen() - RealNumber('0.6'), names=('a',)); (a,) = K._first_ngens(1)
>>> CC(a)
-0.629960524947436 + 1.09112363597172*I

>>> # needs sage.rings.padics
>>> L = Qp(Integer(5))
>>> f = polygen(L)**Integer(3) - Integer(2)
>>> K = NumberField(x**Integer(3) - Integer(2), embedding=f.roots()[Integer(0)][Integer(0)], names=('a',)); (a,) = K._first_ngens(1)
>>> a + L(Integer(1))
4 + 2*5^2 + 2*5^3 + 3*5^4 + 5^5 + 4*5^6 + 2*5^8 + 3*5^9 + 4*5^12
 + 4*5^14 + 4*5^15 + 3*5^16 + 5^17 + 5^18 + 2*5^19 + O(5^20)
>>> L = NumberField(x**Integer(6) - x**Integer(2) + Integer(1)/Integer(10), embedding=Integer(1), names=('b',)); (b,) = L._first_ngens(1)
>>> K = NumberField(x**Integer(3) - x + Integer(1)/Integer(10), embedding=b**Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> a + b
b^2 + b
>>> CC(a) == CC(b)**Integer(2)
True
>>> K.coerce_embedding()
Generic morphism:
  From: Number Field in a with defining polynomial x^3 - x + 1/10 with a = b^2
  To:   Number Field in b with defining polynomial x^6 - x^2 + 1/10
        with b = 0.9724449978911874?
  Defn: a -> b^2

The QuadraticField and CyclotomicField constructors create an embedding by default unless otherwise specified:

sage: K.<zeta> = CyclotomicField(15)
sage: CC(zeta)
0.913545457642601 + 0.406736643075800*I
sage: L.<sqrtn3> = QuadraticField(-3)
sage: K(sqrtn3)
2*zeta^5 + 1
sage: sqrtn3 + zeta
2*zeta^5 + zeta + 1
>>> from sage.all import *
>>> K = CyclotomicField(Integer(15), names=('zeta',)); (zeta,) = K._first_ngens(1)
>>> CC(zeta)
0.913545457642601 + 0.406736643075800*I
>>> L = QuadraticField(-Integer(3), names=('sqrtn3',)); (sqrtn3,) = L._first_ngens(1)
>>> K(sqrtn3)
2*zeta^5 + 1
>>> sqrtn3 + zeta
2*zeta^5 + zeta + 1

Comparison depends on the (real) embedding specified (or the one selected by default). Note that the codomain of the embedding must be QQbar or AA for this to work (see Issue #20184):

sage: N.<g> = NumberField(x^3 + 2, embedding=1)
sage: 1 < g
False
sage: g > 1
False
sage: RR(g)
-1.25992104989487
>>> from sage.all import *
>>> N = NumberField(x**Integer(3) + Integer(2), embedding=Integer(1), names=('g',)); (g,) = N._first_ngens(1)
>>> Integer(1) < g
False
>>> g > Integer(1)
False
>>> RR(g)
-1.25992104989487

If no embedding is specified or is complex, the comparison is not returning something meaningful.:

sage: N.<g> = NumberField(x^3 + 2)
sage: 1 < g
False
sage: g > 1
True
>>> from sage.all import *
>>> N = NumberField(x**Integer(3) + Integer(2), names=('g',)); (g,) = N._first_ngens(1)
>>> Integer(1) < g
False
>>> g > Integer(1)
True

Since SageMath 6.9, number fields may be defined by polynomials that are not necessarily integral or monic. The only notable practical point is that in the PARI interface, a monic integral polynomial defining the same number field is computed and used:

sage: K.<a> = NumberField(2*x^3 + x + 1)
sage: K.pari_polynomial()
x^3 - x^2 - 2
>>> from sage.all import *
>>> K = NumberField(Integer(2)*x**Integer(3) + x + Integer(1), names=('a',)); (a,) = K._first_ngens(1)
>>> K.pari_polynomial()
x^3 - x^2 - 2

Elements and ideals may be converted to and from PARI as follows:

sage: pari(a)
Mod(-1/2*y^2 + 1/2*y, y^3 - y^2 - 2)
sage: K(pari(a))
a
sage: I = K.ideal(a); I
Fractional ideal (a)
sage: I.pari_hnf()
[1, 0, 0; 0, 1, 0; 0, 0, 1/2]
sage: K.ideal(I.pari_hnf())
Fractional ideal (a)
>>> from sage.all import *
>>> pari(a)
Mod(-1/2*y^2 + 1/2*y, y^3 - y^2 - 2)
>>> K(pari(a))
a
>>> I = K.ideal(a); I
Fractional ideal (a)
>>> I.pari_hnf()
[1, 0, 0; 0, 1, 0; 0, 0, 1/2]
>>> K.ideal(I.pari_hnf())
Fractional ideal (a)

Here is an example where the field has non-trivial class group:

sage: L.<b> = NumberField(3*x^2 - 1/5)
sage: L.pari_polynomial()
x^2 - 15
sage: J = L.primes_above(2)[0]; J
Fractional ideal (2, 15*b + 1)
sage: J.pari_hnf()
[2, 1; 0, 1]
sage: L.ideal(J.pari_hnf())
Fractional ideal (2, 15*b + 1)
>>> from sage.all import *
>>> L = NumberField(Integer(3)*x**Integer(2) - Integer(1)/Integer(5), names=('b',)); (b,) = L._first_ngens(1)
>>> L.pari_polynomial()
x^2 - 15
>>> J = L.primes_above(Integer(2))[Integer(0)]; J
Fractional ideal (2, 15*b + 1)
>>> J.pari_hnf()
[2, 1; 0, 1]
>>> L.ideal(J.pari_hnf())
Fractional ideal (2, 15*b + 1)

An example involving a variable name that defines a function in PARI:

sage: theta = polygen(QQ, 'theta')
sage: M.<z> = NumberField([theta^3 + 4, theta^2 + 3]); M
Number Field in z0 with defining polynomial theta^3 + 4 over its base field
>>> from sage.all import *
>>> theta = polygen(QQ, 'theta')
>>> M = NumberField([theta**Integer(3) + Integer(4), theta**Integer(2) + Integer(3)], names=('z',)); (z,) = M._first_ngens(1); M
Number Field in z0 with defining polynomial theta^3 + 4 over its base field
class sage.rings.number_field.number_field.NumberFieldFactory[source]

Bases: UniqueFactory

Factory for number fields.

This should usually not be called directly, use NumberField() instead.

INPUT:

  • polynomial – a polynomial over \(\QQ\) or a number field

  • name – string (default: 'a'); the name of the generator

  • check – boolean (default: True); do type checking and irreducibility checking

  • embeddingNone or an element, the images of the generator in an ambient field (default: None)

  • latex_nameNone or string (default: None); how the generator is printed for latex output

  • assume_disc_small – boolean (default: False); if True, assume that no square of a prime greater than PARI’s primelimit (which should be 500000). Only applies for absolute fields at present.

  • maximize_at_primesNone or a list of primes (default: None); if not None, then the maximal order is computed by maximizing only at the primes in this list, which completely avoids having to factor the discriminant, but of course can lead to wrong results; only applies for absolute fields at present.

  • structureNone or an instance of structure.NumberFieldStructure (default: None), internally used to pass in additional structural information, e.g., about the field from which this field is created as a subfield.

create_key_and_extra_args(polynomial, name, check, embedding, latex_name, assume_disc_small, maximize_at_primes, structure)[source]

Create a unique key for the number field specified by the parameters.

create_object(version, key, check)[source]

Create the unique number field defined by key.

sage.rings.number_field.number_field.NumberFieldTower(polynomials, names, check=True, embeddings=None, latex_names=None, assume_disc_small=False, maximize_at_primes=None, structures=None)[source]

Create the tower of number fields defined by the polynomials in the list polynomials.

INPUT:

  • polynomials – list of polynomials. Each entry must be polynomial which is irreducible over the number field generated by the roots of the following entries.

  • names – list of strings or a string, the names of the generators of the relative number fields. If a single string, then names are generated from that string.

  • check – boolean (default: True); whether to check that the polynomials are irreducible

  • embeddings – list of elements or None (default: None); embeddings of the relative number fields in an ambient field

  • latex_names – list of strings or None (default: None); names used to print the generators for latex output

  • assume_disc_small – boolean (default: False); if True, assume that no square of a prime greater than PARI’s primelimit (which should be 500000). Only applies for absolute fields at present.

  • maximize_at_primesNone or a list of primes (default: None); if not None, then the maximal order is computed by maximizing only at the primes in this list, which completely avoids having to factor the discriminant, but of course can lead to wrong results; only applies for absolute fields at present.

  • structuresNone or a list (default: None), internally used to provide additional information about the number field such as the field from which it was created.

OUTPUT:

The relative number field generated by a root of the first entry of polynomials over the relative number field generated by root of the second entry of polynomials … over the number field over which the last entry of polynomials is defined.

EXAMPLES:

sage: x = polygen(ZZ, 'x')
sage: k.<a,b,c> = NumberField([x^2 + 1, x^2 + 3, x^2 + 5]); k  # indirect doctest
Number Field in a with defining polynomial x^2 + 1 over its base field
sage: a^2
-1
sage: b^2
-3
sage: c^2
-5
sage: (a+b+c)^2
(2*b + 2*c)*a + 2*c*b - 9
>>> from sage.all import *
>>> x = polygen(ZZ, 'x')
>>> k = NumberField([x**Integer(2) + Integer(1), x**Integer(2) + Integer(3), x**Integer(2) + Integer(5)], names=('a', 'b', 'c',)); (a, b, c,) = k._first_ngens(3); k  # indirect doctest
Number Field in a with defining polynomial x^2 + 1 over its base field
>>> a**Integer(2)
-1
>>> b**Integer(2)
-3
>>> c**Integer(2)
-5
>>> (a+b+c)**Integer(2)
(2*b + 2*c)*a + 2*c*b - 9

The Galois group is a product of 3 groups of order 2:

sage: k.absolute_field(names='c').galois_group()                                # needs sage.groups
Galois group 8T3 (2[x]2[x]2) with order 8 of x^8 + 36*x^6 + 302*x^4 + 564*x^2 + 121
>>> from sage.all import *
>>> k.absolute_field(names='c').galois_group()                                # needs sage.groups
Galois group 8T3 (2[x]2[x]2) with order 8 of x^8 + 36*x^6 + 302*x^4 + 564*x^2 + 121

Repeatedly calling base_field allows us to descend the internally constructed tower of fields:

sage: k.base_field()
Number Field in b with defining polynomial x^2 + 3 over its base field
sage: k.base_field().base_field()
Number Field in c with defining polynomial x^2 + 5
sage: k.base_field().base_field().base_field()
Rational Field
>>> from sage.all import *
>>> k.base_field()
Number Field in b with defining polynomial x^2 + 3 over its base field
>>> k.base_field().base_field()
Number Field in c with defining polynomial x^2 + 5
>>> k.base_field().base_field().base_field()
Rational Field

In the following example the second polynomial is reducible over the first, so we get an error:

sage: v = NumberField([x^3 - 2, x^3 - 2], names='a')
Traceback (most recent call last):
...
ValueError: defining polynomial (x^3 - 2) must be irreducible
>>> from sage.all import *
>>> v = NumberField([x**Integer(3) - Integer(2), x**Integer(3) - Integer(2)], names='a')
Traceback (most recent call last):
...
ValueError: defining polynomial (x^3 - 2) must be irreducible

We mix polynomial parent rings:

sage: k.<y> = QQ[]
sage: m = NumberField([y^3 - 3, x^2 + x + 1, y^3 + 2], 'beta'); m
Number Field in beta0 with defining polynomial y^3 - 3 over its base field
sage: m.base_field ()
Number Field in beta1 with defining polynomial x^2 + x + 1 over its base field
>>> from sage.all import *
>>> k = QQ['y']; (y,) = k._first_ngens(1)
>>> m = NumberField([y**Integer(3) - Integer(3), x**Integer(2) + x + Integer(1), y**Integer(3) + Integer(2)], 'beta'); m
Number Field in beta0 with defining polynomial y^3 - 3 over its base field
>>> m.base_field ()
Number Field in beta1 with defining polynomial x^2 + x + 1 over its base field

A tower of quadratic fields:

sage: K.<a> = NumberField([x^2 + 3, x^2 + 2, x^2 + 1]); K
Number Field in a0 with defining polynomial x^2 + 3 over its base field
sage: K.base_field()
Number Field in a1 with defining polynomial x^2 + 2 over its base field
sage: K.base_field().base_field()
Number Field in a2 with defining polynomial x^2 + 1
>>> from sage.all import *
>>> K = NumberField([x**Integer(2) + Integer(3), x**Integer(2) + Integer(2), x**Integer(2) + Integer(1)], names=('a',)); (a,) = K._first_ngens(1); K
Number Field in a0 with defining polynomial x^2 + 3 over its base field
>>> K.base_field()
Number Field in a1 with defining polynomial x^2 + 2 over its base field
>>> K.base_field().base_field()
Number Field in a2 with defining polynomial x^2 + 1

LaTeX versions of generator names can be specified either as:

sage: K = NumberField([x^3 - 2, x^3 - 3, x^3 - 5], names=['a', 'b', 'c'],
....:                 latex_names=[r'\alpha', r'\beta', r'\gamma'])
sage: K.inject_variables(verbose=False)
sage: latex(a + b + c)
\alpha + \beta + \gamma
>>> from sage.all import *
>>> K = NumberField([x**Integer(3) - Integer(2), x**Integer(3) - Integer(3), x**Integer(3) - Integer(5)], names=['a', 'b', 'c'],
...                 latex_names=[r'\alpha', r'\beta', r'\gamma'])
>>> K.inject_variables(verbose=False)
>>> latex(a + b + c)
\alpha + \beta + \gamma

or as:

sage: K = NumberField([x^3 - 2, x^3 - 3, x^3 - 5], names='a', latex_names=r'\alpha')
sage: K.inject_variables()
Defining a0, a1, a2
sage: latex(a0 + a1 + a2)
\alpha_{0} + \alpha_{1} + \alpha_{2}
>>> from sage.all import *
>>> K = NumberField([x**Integer(3) - Integer(2), x**Integer(3) - Integer(3), x**Integer(3) - Integer(5)], names='a', latex_names=r'\alpha')
>>> K.inject_variables()
Defining a0, a1, a2
>>> latex(a0 + a1 + a2)
\alpha_{0} + \alpha_{1} + \alpha_{2}

A bigger tower of quadratic fields:

sage: K.<a2,a3,a5,a7> = NumberField([x^2 + p for p in [2,3,5,7]]); K
Number Field in a2 with defining polynomial x^2 + 2 over its base field
sage: a2^2
-2
sage: a3^2
-3
sage: (a2+a3+a5+a7)^3
((6*a5 + 6*a7)*a3 + 6*a7*a5 - 47)*a2 + (6*a7*a5 - 45)*a3 - 41*a5 - 37*a7
>>> from sage.all import *
>>> K = NumberField([x**Integer(2) + p for p in [Integer(2),Integer(3),Integer(5),Integer(7)]], names=('a2', 'a3', 'a5', 'a7',)); (a2, a3, a5, a7,) = K._first_ngens(4); K
Number Field in a2 with defining polynomial x^2 + 2 over its base field
>>> a2**Integer(2)
-2
>>> a3**Integer(2)
-3
>>> (a2+a3+a5+a7)**Integer(3)
((6*a5 + 6*a7)*a3 + 6*a7*a5 - 47)*a2 + (6*a7*a5 - 45)*a3 - 41*a5 - 37*a7

The function can also be called by name:

sage: NumberFieldTower([x^2 + 1, x^2 + 2], ['a','b'])
Number Field in a with defining polynomial x^2 + 1 over its base field
>>> from sage.all import *
>>> NumberFieldTower([x**Integer(2) + Integer(1), x**Integer(2) + Integer(2)], ['a','b'])
Number Field in a with defining polynomial x^2 + 1 over its base field
class sage.rings.number_field.number_field.NumberField_absolute(polynomial, name, latex_name=None, check=True, embedding=None, assume_disc_small=False, maximize_at_primes=None, structure=None)[source]

Bases: NumberField_generic

Function to initialize an absolute number field.

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K = NumberField(x^17 + 3, 'a'); K
Number Field in a with defining polynomial x^17 + 3
sage: type(K)
<class 'sage.rings.number_field.number_field.NumberField_absolute_with_category'>
sage: TestSuite(K).run()
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(17) + Integer(3), 'a'); K
Number Field in a with defining polynomial x^17 + 3
>>> type(K)
<class 'sage.rings.number_field.number_field.NumberField_absolute_with_category'>
>>> TestSuite(K).run()
abs_val(v, iota, prec=None)[source]

Return the value \(|\iota|_{v}\).

INPUT:

  • v – a place of K, finite (a fractional ideal) or infinite (element of K.places(prec))

  • iota – an element of K

  • prec – (default: None) the precision of the real field

OUTPUT: the absolute value as a real number

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<xi> = NumberField(x^3 - 3)
sage: phi_real = K.places()[0]
sage: phi_complex = K.places()[1]
sage: v_fin = tuple(K.primes_above(3))[0]

sage: K.abs_val(phi_real, xi^2)
2.08008382305190

sage: K.abs_val(phi_complex, xi^2)
4.32674871092223

sage: K.abs_val(v_fin, xi^2)
0.111111111111111
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(3) - Integer(3), names=('xi',)); (xi,) = K._first_ngens(1)
>>> phi_real = K.places()[Integer(0)]
>>> phi_complex = K.places()[Integer(1)]
>>> v_fin = tuple(K.primes_above(Integer(3)))[Integer(0)]

>>> K.abs_val(phi_real, xi**Integer(2))
2.08008382305190

>>> K.abs_val(phi_complex, xi**Integer(2))
4.32674871092223

>>> K.abs_val(v_fin, xi**Integer(2))
0.111111111111111

Check that Issue #28345 is fixed:

sage: K.abs_val(v_fin, K.zero())
0.000000000000000
>>> from sage.all import *
>>> K.abs_val(v_fin, K.zero())
0.000000000000000
absolute_degree()[source]

A synonym for degree().

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<i> = NumberField(x^2 + 1)
sage: K.absolute_degree()
2
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> K.absolute_degree()
2
absolute_different()[source]

A synonym for different().

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<i> = NumberField(x^2 + 1)
sage: K.absolute_different()
Fractional ideal (2)
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> K.absolute_different()
Fractional ideal (2)
absolute_discriminant()[source]

A synonym for discriminant().

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<i> = NumberField(x^2 + 1)
sage: K.absolute_discriminant()
-4
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> K.absolute_discriminant()
-4
absolute_generator()[source]

An alias for sage.rings.number_field.number_field.NumberField_generic.gen(). This is provided for consistency with relative fields, where the element returned by sage.rings.number_field.number_field_rel.NumberField_relative.gen() only generates the field over its base field (not necessarily over \(\QQ\)).

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<a> = NumberField(x^2 - 17)
sage: K.absolute_generator()
a
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(2) - Integer(17), names=('a',)); (a,) = K._first_ngens(1)
>>> K.absolute_generator()
a
absolute_polynomial()[source]

Return absolute polynomial that defines this absolute field. This is the same as polynomial().

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<a> = NumberField(x^2 + 1)
sage: K.absolute_polynomial ()
x^2 + 1
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(2) + Integer(1), names=('a',)); (a,) = K._first_ngens(1)
>>> K.absolute_polynomial ()
x^2 + 1
absolute_vector_space(*args, **kwds)[source]

Return vector space over \(\QQ\) corresponding to this number field, along with maps from that space to this number field and in the other direction.

For an absolute extension this is identical to vector_space().

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<a> = NumberField(x^3 - 5)
sage: K.absolute_vector_space()
(Vector space of dimension 3 over Rational Field,
 Isomorphism map:
  From: Vector space of dimension 3 over Rational Field
  To:   Number Field in a with defining polynomial x^3 - 5,
 Isomorphism map:
  From: Number Field in a with defining polynomial x^3 - 5
  To:   Vector space of dimension 3 over Rational Field)
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(3) - Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> K.absolute_vector_space()
(Vector space of dimension 3 over Rational Field,
 Isomorphism map:
  From: Vector space of dimension 3 over Rational Field
  To:   Number Field in a with defining polynomial x^3 - 5,
 Isomorphism map:
  From: Number Field in a with defining polynomial x^3 - 5
  To:   Vector space of dimension 3 over Rational Field)
automorphisms()[source]

Compute all Galois automorphisms of self.

This uses PARI’s pari:nfgaloisconj and is much faster than root finding for many fields.

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<a> = NumberField(x^2 + 10000)
sage: K.automorphisms()
[
Ring endomorphism of Number Field in a with defining polynomial x^2 + 10000
  Defn: a |--> a,
Ring endomorphism of Number Field in a with defining polynomial x^2 + 10000
  Defn: a |--> -a
]
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(2) + Integer(10000), names=('a',)); (a,) = K._first_ngens(1)
>>> K.automorphisms()
[
Ring endomorphism of Number Field in a with defining polynomial x^2 + 10000
  Defn: a |--> a,
Ring endomorphism of Number Field in a with defining polynomial x^2 + 10000
  Defn: a |--> -a
]

Here’s a larger example, that would take some time if we found roots instead of using PARI’s specialized machinery:

sage: K = NumberField(x^6 - x^4 - 2*x^2 + 1, 'a')
sage: len(K.automorphisms())
2
>>> from sage.all import *
>>> K = NumberField(x**Integer(6) - x**Integer(4) - Integer(2)*x**Integer(2) + Integer(1), 'a')
>>> len(K.automorphisms())
2

\(L\) is the Galois closure of \(K\):

sage: L = NumberField(x^24 - 84*x^22 + 2814*x^20 - 15880*x^18 - 409563*x^16
....:                  - 8543892*x^14 + 25518202*x^12 + 32831026956*x^10
....:                  - 672691027218*x^8 - 4985379093428*x^6 + 320854419319140*x^4
....:                  + 817662865724712*x^2 + 513191437605441, 'a')
sage: len(L.automorphisms())
24
>>> from sage.all import *
>>> L = NumberField(x**Integer(24) - Integer(84)*x**Integer(22) + Integer(2814)*x**Integer(20) - Integer(15880)*x**Integer(18) - Integer(409563)*x**Integer(16)
...                  - Integer(8543892)*x**Integer(14) + Integer(25518202)*x**Integer(12) + Integer(32831026956)*x**Integer(10)
...                  - Integer(672691027218)*x**Integer(8) - Integer(4985379093428)*x**Integer(6) + Integer(320854419319140)*x**Integer(4)
...                  + Integer(817662865724712)*x**Integer(2) + Integer(513191437605441), 'a')
>>> len(L.automorphisms())
24

Number fields defined by non-monic and non-integral polynomials are supported (Issue #252):

sage: R.<x> = QQ[]
sage: f = 7/9*x^3 + 7/3*x^2 - 56*x + 123
sage: K.<a> = NumberField(f)
sage: A = K.automorphisms(); A
[
Ring endomorphism of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123
  Defn: a |--> a,
Ring endomorphism of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123
  Defn: a |--> -7/15*a^2 - 18/5*a + 96/5,
Ring endomorphism of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123
  Defn: a |--> 7/15*a^2 + 13/5*a - 111/5
]
sage: prod(x - sigma(a) for sigma in A) == f.monic()
True
>>> from sage.all import *
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> f = Integer(7)/Integer(9)*x**Integer(3) + Integer(7)/Integer(3)*x**Integer(2) - Integer(56)*x + Integer(123)
>>> K = NumberField(f, names=('a',)); (a,) = K._first_ngens(1)
>>> A = K.automorphisms(); A
[
Ring endomorphism of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123
  Defn: a |--> a,
Ring endomorphism of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123
  Defn: a |--> -7/15*a^2 - 18/5*a + 96/5,
Ring endomorphism of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123
  Defn: a |--> 7/15*a^2 + 13/5*a - 111/5
]
>>> prod(x - sigma(a) for sigma in A) == f.monic()
True
base_field()[source]

Return the base field of self, which is always QQ.

EXAMPLES:

sage: K = CyclotomicField(5)
sage: K.base_field()
Rational Field
>>> from sage.all import *
>>> K = CyclotomicField(Integer(5))
>>> K.base_field()
Rational Field
change_names(names)[source]

Return number field isomorphic to self but with the given generator name.

INPUT:

  • names – should be exactly one variable name

Also, K.structure() returns from_K and to_K, where from_K is an isomorphism from \(K\) to self and to_K is an isomorphism from self to \(K\).

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<z> = NumberField(x^2 + 3); K
Number Field in z with defining polynomial x^2 + 3
sage: L.<ww> = K.change_names()
sage: L
Number Field in ww with defining polynomial x^2 + 3
sage: L.structure()[0]
Isomorphism given by variable name change map:
  From: Number Field in ww with defining polynomial x^2 + 3
  To:   Number Field in z with defining polynomial x^2 + 3
sage: L.structure()[0](ww + 5/3)
z + 5/3
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(2) + Integer(3), names=('z',)); (z,) = K._first_ngens(1); K
Number Field in z with defining polynomial x^2 + 3
>>> L = K.change_names(names=('ww',)); (ww,) = L._first_ngens(1)
>>> L
Number Field in ww with defining polynomial x^2 + 3
>>> L.structure()[Integer(0)]
Isomorphism given by variable name change map:
  From: Number Field in ww with defining polynomial x^2 + 3
  To:   Number Field in z with defining polynomial x^2 + 3
>>> L.structure()[Integer(0)](ww + Integer(5)/Integer(3))
z + 5/3
elements_of_bounded_height(**kwds)[source]

Return an iterator over the elements of self with relative multiplicative height at most bound.

This algorithm computes 2 lists: \(L\) containing elements \(x\) in \(K\) such that \(H_k(x) \leq B\), and a list \(L'\) containing elements \(x\) in \(K\) that, due to floating point issues, may be slightly larger than the bound. This can be controlled by lowering the tolerance.

In the current implementation, both lists \((L,L')\) are merged and returned in form of iterator.

ALGORITHM:

This is an implementation of the revised algorithm (Algorithm 4) in [DK2013]. Algorithm 5 is used for imaginary quadratic fields.

INPUT: keyword arguments:

  • bound – a real number

  • tolerance – (default: 0.01) a rational number in \((0,1]\)

  • precision – (default: 53) a positive integer

OUTPUT: an iterator of number field elements

EXAMPLES:

There are no elements in a number field with multiplicative height less than 1:

sage: x = polygen(QQ, 'x')
sage: K.<g> = NumberField(x^5 - x + 19)
sage: list(K.elements_of_bounded_height(bound=0.9))
[]
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(5) - x + Integer(19), names=('g',)); (g,) = K._first_ngens(1)
>>> list(K.elements_of_bounded_height(bound=RealNumber('0.9')))
[]

The only elements in a number field of height 1 are 0 and the roots of unity:

sage: K.<a> = NumberField(x^2 + x + 1)
sage: list(K.elements_of_bounded_height(bound=1))
[0, a + 1, a, -1, -a - 1, -a, 1]
>>> from sage.all import *
>>> K = NumberField(x**Integer(2) + x + Integer(1), names=('a',)); (a,) = K._first_ngens(1)
>>> list(K.elements_of_bounded_height(bound=Integer(1)))
[0, a + 1, a, -1, -a - 1, -a, 1]

sage: K.<a> = CyclotomicField(20)
sage: len(list(K.elements_of_bounded_height(bound=1)))
21
>>> from sage.all import *
>>> K = CyclotomicField(Integer(20), names=('a',)); (a,) = K._first_ngens(1)
>>> len(list(K.elements_of_bounded_height(bound=Integer(1))))
21

The elements in the output iterator all have relative multiplicative height at most the input bound:

sage: K.<a> = NumberField(x^6 + 2)
sage: L = K.elements_of_bounded_height(bound=5)
sage: for t in L:
....:     exp(6*t.global_height())
1.00000000000000
1.00000000000000
1.00000000000000
2.00000000000000
2.00000000000000
2.00000000000000
2.00000000000000
4.00000000000000
4.00000000000000
4.00000000000000
4.00000000000000
>>> from sage.all import *
>>> K = NumberField(x**Integer(6) + Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> L = K.elements_of_bounded_height(bound=Integer(5))
>>> for t in L:
...     exp(Integer(6)*t.global_height())
1.00000000000000
1.00000000000000
1.00000000000000
2.00000000000000
2.00000000000000
2.00000000000000
2.00000000000000
4.00000000000000
4.00000000000000
4.00000000000000
4.00000000000000

sage: K.<a> = NumberField(x^2 - 71)
sage: L = K.elements_of_bounded_height(bound=20)
sage: all(exp(2*t.global_height()) <= 20 for t in L) # long time (5 s)
True
>>> from sage.all import *
>>> K = NumberField(x**Integer(2) - Integer(71), names=('a',)); (a,) = K._first_ngens(1)
>>> L = K.elements_of_bounded_height(bound=Integer(20))
>>> all(exp(Integer(2)*t.global_height()) <= Integer(20) for t in L) # long time (5 s)
True

sage: K.<a> = NumberField(x^2 + 17)
sage: L = K.elements_of_bounded_height(bound=120)
sage: len(list(L))
9047
>>> from sage.all import *
>>> K = NumberField(x**Integer(2) + Integer(17), names=('a',)); (a,) = K._first_ngens(1)
>>> L = K.elements_of_bounded_height(bound=Integer(120))
>>> len(list(L))
9047

sage: K.<a> = NumberField(x^4 - 5)
sage: L = K.elements_of_bounded_height(bound=50)
sage: len(list(L)) # long time (2 s)
2163
>>> from sage.all import *
>>> K = NumberField(x**Integer(4) - Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> L = K.elements_of_bounded_height(bound=Integer(50))
>>> len(list(L)) # long time (2 s)
2163

sage: K.<a> = CyclotomicField(13)
sage: L = K.elements_of_bounded_height(bound=2)
sage: len(list(L)) # long time (3 s)
27
>>> from sage.all import *
>>> K = CyclotomicField(Integer(13), names=('a',)); (a,) = K._first_ngens(1)
>>> L = K.elements_of_bounded_height(bound=Integer(2))
>>> len(list(L)) # long time (3 s)
27

sage: K.<a> = NumberField(x^6 + 2)
sage: L = K.elements_of_bounded_height(bound=60, precision=100)
sage: len(list(L)) # long time (5 s)
1899
>>> from sage.all import *
>>> K = NumberField(x**Integer(6) + Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> L = K.elements_of_bounded_height(bound=Integer(60), precision=Integer(100))
>>> len(list(L)) # long time (5 s)
1899

sage: K.<a> = NumberField(x^4 - x^3 - 3*x^2 + x + 1)
sage: L = K.elements_of_bounded_height(bound=10, tolerance=0.1)
sage: len(list(L))
99
>>> from sage.all import *
>>> K = NumberField(x**Integer(4) - x**Integer(3) - Integer(3)*x**Integer(2) + x + Integer(1), names=('a',)); (a,) = K._first_ngens(1)
>>> L = K.elements_of_bounded_height(bound=Integer(10), tolerance=RealNumber('0.1'))
>>> len(list(L))
99

AUTHORS:

  • John Doyle (2013)

  • David Krumm (2013)

  • Raman Raghukul (2018)

embeddings(K)[source]

Compute all field embeddings of this field into the field \(K\) (which need not even be a number field, e.g., it could be the complex numbers). This will return an identical result when given \(K\) as input again.

If possible, the most natural embedding of this field into \(K\) is put first in the list.

INPUT:

  • K – a field

EXAMPLES:

sage: # needs sage.groups
sage: x = polygen(QQ, 'x')
sage: K.<a> = NumberField(x^3 - 2)
sage: L.<a1> = K.galois_closure(); L
Number Field in a1 with defining polynomial x^6 + 108
sage: K.embeddings(L)[0]
Ring morphism:
  From: Number Field in a with defining polynomial x^3 - 2
  To:   Number Field in a1 with defining polynomial x^6 + 108
  Defn: a |--> 1/18*a1^4
sage: K.embeddings(L) is K.embeddings(L)
True
>>> from sage.all import *
>>> # needs sage.groups
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(3) - Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> L = K.galois_closure(names=('a1',)); (a1,) = L._first_ngens(1); L
Number Field in a1 with defining polynomial x^6 + 108
>>> K.embeddings(L)[Integer(0)]
Ring morphism:
  From: Number Field in a with defining polynomial x^3 - 2
  To:   Number Field in a1 with defining polynomial x^6 + 108
  Defn: a |--> 1/18*a1^4
>>> K.embeddings(L) is K.embeddings(L)
True

We embed a quadratic field into a cyclotomic field:

sage: L.<a> = QuadraticField(-7)
sage: K = CyclotomicField(7)
sage: L.embeddings(K)
[
Ring morphism:
  From: Number Field in a with defining polynomial x^2 + 7
        with a = 2.645751311064591?*I
  To:   Cyclotomic Field of order 7 and degree 6
  Defn: a |--> 2*zeta7^4 + 2*zeta7^2 + 2*zeta7 + 1,
Ring morphism:
  From: Number Field in a with defining polynomial x^2 + 7
        with a = 2.645751311064591?*I
  To:   Cyclotomic Field of order 7 and degree 6
  Defn: a |--> -2*zeta7^4 - 2*zeta7^2 - 2*zeta7 - 1
]
>>> from sage.all import *
>>> L = QuadraticField(-Integer(7), names=('a',)); (a,) = L._first_ngens(1)
>>> K = CyclotomicField(Integer(7))
>>> L.embeddings(K)
[
Ring morphism:
  From: Number Field in a with defining polynomial x^2 + 7
        with a = 2.645751311064591?*I
  To:   Cyclotomic Field of order 7 and degree 6
  Defn: a |--> 2*zeta7^4 + 2*zeta7^2 + 2*zeta7 + 1,
Ring morphism:
  From: Number Field in a with defining polynomial x^2 + 7
        with a = 2.645751311064591?*I
  To:   Cyclotomic Field of order 7 and degree 6
  Defn: a |--> -2*zeta7^4 - 2*zeta7^2 - 2*zeta7 - 1
]

We embed a cubic field in the complex numbers:

sage: x = polygen(QQ, 'x')
sage: K.<a> = NumberField(x^3 - 2)
sage: K.embeddings(CC)
[
Ring morphism:
  From: Number Field in a with defining polynomial x^3 - 2
  To:   Complex Field with 53 bits of precision
  Defn: a |--> -0.62996052494743... - 1.09112363597172*I,
Ring morphism:
  From: Number Field in a with defining polynomial x^3 - 2
  To:   Complex Field with 53 bits of precision
  Defn: a |--> -0.62996052494743... + 1.09112363597172*I,
Ring morphism:
  From: Number Field in a with defining polynomial x^3 - 2
  To:   Complex Field with 53 bits of precision
  Defn: a |--> 1.25992104989487
]
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(3) - Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> K.embeddings(CC)
[
Ring morphism:
  From: Number Field in a with defining polynomial x^3 - 2
  To:   Complex Field with 53 bits of precision
  Defn: a |--> -0.62996052494743... - 1.09112363597172*I,
Ring morphism:
  From: Number Field in a with defining polynomial x^3 - 2
  To:   Complex Field with 53 bits of precision
  Defn: a |--> -0.62996052494743... + 1.09112363597172*I,
Ring morphism:
  From: Number Field in a with defining polynomial x^3 - 2
  To:   Complex Field with 53 bits of precision
  Defn: a |--> 1.25992104989487
]

Some more (possible and impossible) embeddings of cyclotomic fields:

sage: CyclotomicField(5).embeddings(QQbar)
[
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Algebraic Field
  Defn: zeta5 |--> 0.3090169943749474? + 0.9510565162951536?*I,
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Algebraic Field
  Defn: zeta5 |--> -0.8090169943749474? + 0.5877852522924731?*I,
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Algebraic Field
  Defn: zeta5 |--> -0.8090169943749474? - 0.5877852522924731?*I,
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Algebraic Field
  Defn: zeta5 |--> 0.3090169943749474? - 0.9510565162951536?*I
]
sage: CyclotomicField(3).embeddings(CyclotomicField(7))
[ ]
sage: CyclotomicField(3).embeddings(CyclotomicField(6))
[
Ring morphism:
  From: Cyclotomic Field of order 3 and degree 2
  To:   Cyclotomic Field of order 6 and degree 2
  Defn: zeta3 |--> zeta6 - 1,
Ring morphism:
  From: Cyclotomic Field of order 3 and degree 2
  To:   Cyclotomic Field of order 6 and degree 2
  Defn: zeta3 |--> -zeta6
]
>>> from sage.all import *
>>> CyclotomicField(Integer(5)).embeddings(QQbar)
[
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Algebraic Field
  Defn: zeta5 |--> 0.3090169943749474? + 0.9510565162951536?*I,
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Algebraic Field
  Defn: zeta5 |--> -0.8090169943749474? + 0.5877852522924731?*I,
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Algebraic Field
  Defn: zeta5 |--> -0.8090169943749474? - 0.5877852522924731?*I,
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Algebraic Field
  Defn: zeta5 |--> 0.3090169943749474? - 0.9510565162951536?*I
]
>>> CyclotomicField(Integer(3)).embeddings(CyclotomicField(Integer(7)))
[ ]
>>> CyclotomicField(Integer(3)).embeddings(CyclotomicField(Integer(6)))
[
Ring morphism:
  From: Cyclotomic Field of order 3 and degree 2
  To:   Cyclotomic Field of order 6 and degree 2
  Defn: zeta3 |--> zeta6 - 1,
Ring morphism:
  From: Cyclotomic Field of order 3 and degree 2
  To:   Cyclotomic Field of order 6 and degree 2
  Defn: zeta3 |--> -zeta6
]

Test that Issue #15053 is fixed:

sage: K = NumberField(x^3 - 2, 'a')
sage: K.embeddings(GF(3))
[]
>>> from sage.all import *
>>> K = NumberField(x**Integer(3) - Integer(2), 'a')
>>> K.embeddings(GF(Integer(3)))
[]
free_module(base=None, basis=None, map=True)[source]

Return a vector space \(V\) and isomorphisms self \(\to\) \(V\) and \(V\) \(\to\) self.

INPUT:

  • base – a subfield (default: None); the returned vector space is over this subfield \(R\), which defaults to the base field of this function field

  • basis – a basis for this field over the base

  • maps – boolean (default: True); whether to return \(R\)-linear maps to and from \(V\)

OUTPUT:

  • V – a vector space over the rational numbers

  • from_V – an isomorphism from \(V\) to self (if requested)

  • to_V – an isomorphism from self to \(V\) (if requested)

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: k.<a> = NumberField(x^3 + 2)
sage: V, from_V, to_V  = k.free_module()
sage: from_V(V([1,2,3]))
3*a^2 + 2*a + 1
sage: to_V(1 + 2*a + 3*a^2)
(1, 2, 3)
sage: V
Vector space of dimension 3 over Rational Field
sage: to_V
Isomorphism map:
  From: Number Field in a with defining polynomial x^3 + 2
  To:   Vector space of dimension 3 over Rational Field
sage: from_V(to_V(2/3*a - 5/8))
2/3*a - 5/8
sage: to_V(from_V(V([0,-1/7,0])))
(0, -1/7, 0)
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> k = NumberField(x**Integer(3) + Integer(2), names=('a',)); (a,) = k._first_ngens(1)
>>> V, from_V, to_V  = k.free_module()
>>> from_V(V([Integer(1),Integer(2),Integer(3)]))
3*a^2 + 2*a + 1
>>> to_V(Integer(1) + Integer(2)*a + Integer(3)*a**Integer(2))
(1, 2, 3)
>>> V
Vector space of dimension 3 over Rational Field
>>> to_V
Isomorphism map:
  From: Number Field in a with defining polynomial x^3 + 2
  To:   Vector space of dimension 3 over Rational Field
>>> from_V(to_V(Integer(2)/Integer(3)*a - Integer(5)/Integer(8)))
2/3*a - 5/8
>>> to_V(from_V(V([Integer(0),-Integer(1)/Integer(7),Integer(0)])))
(0, -1/7, 0)
galois_closure(names=None, map=False)[source]

Return number field \(K\) that is the Galois closure of self, i.e., is generated by all roots of the defining polynomial of self, and possibly an embedding of self into \(K\).

INPUT:

  • names – variable name for Galois closure

  • map – boolean (default: False); also return an embedding of self into \(K\)

EXAMPLES:

sage: # needs sage.groups
sage: x = polygen(QQ, 'x')
sage: K.<a> = NumberField(x^4 - 2)
sage: M = K.galois_closure('b'); M
Number Field in b with defining polynomial x^8 + 28*x^4 + 2500
sage: L.<a2> = K.galois_closure(); L
Number Field in a2 with defining polynomial x^8 + 28*x^4 + 2500
sage: K.galois_group(names=("a3")).order()
8
>>> from sage.all import *
>>> # needs sage.groups
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(4) - Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> M = K.galois_closure('b'); M
Number Field in b with defining polynomial x^8 + 28*x^4 + 2500
>>> L = K.galois_closure(names=('a2',)); (a2,) = L._first_ngens(1); L
Number Field in a2 with defining polynomial x^8 + 28*x^4 + 2500
>>> K.galois_group(names=("a3")).order()
8

sage: # needs sage.groups
sage: phi = K.embeddings(L)[0]
sage: phi(K.0)
1/120*a2^5 + 19/60*a2
sage: phi(K.0).minpoly()
x^4 - 2

sage: # needs sage.groups
sage: L, phi = K.galois_closure('b', map=True)
sage: L
Number Field in b with defining polynomial x^8 + 28*x^4 + 2500
sage: phi
Ring morphism:
  From: Number Field in a with defining polynomial x^4 - 2
  To:   Number Field in b with defining polynomial x^8 + 28*x^4 + 2500
  Defn: a |--> 1/240*b^5 - 41/120*b
>>> from sage.all import *
>>> # needs sage.groups
>>> phi = K.embeddings(L)[Integer(0)]
>>> phi(K.gen(0))
1/120*a2^5 + 19/60*a2
>>> phi(K.gen(0)).minpoly()
x^4 - 2

>>> # needs sage.groups
>>> L, phi = K.galois_closure('b', map=True)
>>> L
Number Field in b with defining polynomial x^8 + 28*x^4 + 2500
>>> phi
Ring morphism:
  From: Number Field in a with defining polynomial x^4 - 2
  To:   Number Field in b with defining polynomial x^8 + 28*x^4 + 2500
  Defn: a |--> 1/240*b^5 - 41/120*b

A cyclotomic field is already Galois:

sage: # needs sage.groups
sage: K.<a> = NumberField(cyclotomic_polynomial(23))
sage: L.<z> = K.galois_closure()
sage: L
Number Field in z with defining polynomial
 x^22 + x^21 + x^20 + x^19 + x^18 + x^17 + x^16 + x^15 + x^14 + x^13 + x^12
  + x^11 + x^10 + x^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1
>>> from sage.all import *
>>> # needs sage.groups
>>> K = NumberField(cyclotomic_polynomial(Integer(23)), names=('a',)); (a,) = K._first_ngens(1)
>>> L = K.galois_closure(names=('z',)); (z,) = L._first_ngens(1)
>>> L
Number Field in z with defining polynomial
 x^22 + x^21 + x^20 + x^19 + x^18 + x^17 + x^16 + x^15 + x^14 + x^13 + x^12
  + x^11 + x^10 + x^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1
hilbert_conductor(a, b)[source]

This is the product of all (finite) primes where the Hilbert symbol is \(-1\). What is the same, this is the (reduced) discriminant of the quaternion algebra \((a,b)\) over a number field.

INPUT:

  • a, b – elements of the number field self

OUTPUT: squarefree ideal of the ring of integers of self

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: F.<a> = NumberField(x^2 - x - 1)
sage: F.hilbert_conductor(2*a, F(-1))
Fractional ideal (2)
sage: K.<b> = NumberField(x^3 - 4*x + 2)
sage: K.hilbert_conductor(K(2), K(-2))
Fractional ideal (1)
sage: K.hilbert_conductor(K(2*b), K(-2))
Fractional ideal (b^2 + b - 2)
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> F = NumberField(x**Integer(2) - x - Integer(1), names=('a',)); (a,) = F._first_ngens(1)
>>> F.hilbert_conductor(Integer(2)*a, F(-Integer(1)))
Fractional ideal (2)
>>> K = NumberField(x**Integer(3) - Integer(4)*x + Integer(2), names=('b',)); (b,) = K._first_ngens(1)
>>> K.hilbert_conductor(K(Integer(2)), K(-Integer(2)))
Fractional ideal (1)
>>> K.hilbert_conductor(K(Integer(2)*b), K(-Integer(2)))
Fractional ideal (b^2 + b - 2)

AUTHOR:

  • Aly Deines

hilbert_symbol(a, b, P=None)[source]

Return the Hilbert symbol \((a,b)_P\) for a prime \(P\) of self and nonzero elements \(a\) and \(b\) of self.

If \(P\) is omitted, return the global Hilbert symbol \((a,b)\) instead.

INPUT:

  • a, b – elements of self

  • P – (default: None) if None, compute the global symbol. Otherwise, \(P\) should be either a prime ideal of self (which may also be given as a generator or set of generators) or a real or complex embedding.

OUTPUT: if \(a\) or \(b\) is zero, returns 0

If \(a\) and \(b\) are nonzero and \(P\) is specified, returns the Hilbert symbol \((a,b)_P\), which is \(1\) if the equation \(a x^2 + b y^2 = 1\) has a solution in the completion of self at \(P\), and is \(-1\) otherwise.

If \(a\) and \(b\) are nonzero and \(P\) is unspecified, returns \(1\) if the equation has a solution in self and \(-1\) otherwise.

EXAMPLES:

Some global examples:

sage: x = polygen(QQ, 'x')
sage: K.<a> = NumberField(x^2 - 23)
sage: K.hilbert_symbol(0, a + 5)
0
sage: K.hilbert_symbol(a, 0)
0
sage: K.hilbert_symbol(-a, a + 1)
1
sage: K.hilbert_symbol(-a, a + 2)
-1
sage: K.hilbert_symbol(a, a + 5)
-1
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(2) - Integer(23), names=('a',)); (a,) = K._first_ngens(1)
>>> K.hilbert_symbol(Integer(0), a + Integer(5))
0
>>> K.hilbert_symbol(a, Integer(0))
0
>>> K.hilbert_symbol(-a, a + Integer(1))
1
>>> K.hilbert_symbol(-a, a + Integer(2))
-1
>>> K.hilbert_symbol(a, a + Integer(5))
-1

That the latter two are unsolvable should be visible in local obstructions. For the first, this is a prime ideal above 19. For the second, the ramified prime above 23:

sage: K.hilbert_symbol(-a, a + 2, a + 2)
-1
sage: K.hilbert_symbol(a, a + 5, K.ideal(23).factor()[0][0])
-1
>>> from sage.all import *
>>> K.hilbert_symbol(-a, a + Integer(2), a + Integer(2))
-1
>>> K.hilbert_symbol(a, a + Integer(5), K.ideal(Integer(23)).factor()[Integer(0)][Integer(0)])
-1

More local examples:

sage: K.hilbert_symbol(a, 0, K.fractional_ideal(5))
0
sage: K.hilbert_symbol(a, a + 5, K.fractional_ideal(5))
1
sage: K.hilbert_symbol(a + 1, 13, (a+6)*K)
-1
sage: [emb1, emb2] = K.embeddings(AA)
sage: K.hilbert_symbol(a, -1, emb1)
-1
sage: K.hilbert_symbol(a, -1, emb2)
1
>>> from sage.all import *
>>> K.hilbert_symbol(a, Integer(0), K.fractional_ideal(Integer(5)))
0
>>> K.hilbert_symbol(a, a + Integer(5), K.fractional_ideal(Integer(5)))
1
>>> K.hilbert_symbol(a + Integer(1), Integer(13), (a+Integer(6))*K)
-1
>>> [emb1, emb2] = K.embeddings(AA)
>>> K.hilbert_symbol(a, -Integer(1), emb1)
-1
>>> K.hilbert_symbol(a, -Integer(1), emb2)
1

Ideals P can be given by generators:

sage: K.<a> = NumberField(x^5 - 23)
sage: pi = 2*a^4 + 3*a^3 + 4*a^2 + 15*a + 11
sage: K.hilbert_symbol(a, a + 5, pi)
1
sage: rho = 2*a^4 + 3*a^3 + 4*a^2 + 15*a + 11
sage: K.hilbert_symbol(a, a + 5, rho)
1
>>> from sage.all import *
>>> K = NumberField(x**Integer(5) - Integer(23), names=('a',)); (a,) = K._first_ngens(1)
>>> pi = Integer(2)*a**Integer(4) + Integer(3)*a**Integer(3) + Integer(4)*a**Integer(2) + Integer(15)*a + Integer(11)
>>> K.hilbert_symbol(a, a + Integer(5), pi)
1
>>> rho = Integer(2)*a**Integer(4) + Integer(3)*a**Integer(3) + Integer(4)*a**Integer(2) + Integer(15)*a + Integer(11)
>>> K.hilbert_symbol(a, a + Integer(5), rho)
1

This also works for non-principal ideals:

sage: K.<a> = QuadraticField(-5)
sage: P = K.ideal(3).factor()[0][0]
sage: P.gens_reduced()  # random, could be the other factor
(3, a + 1)
sage: K.hilbert_symbol(a, a + 3, P)
1
sage: K.hilbert_symbol(a, a + 3, [3, a+1])
1
>>> from sage.all import *
>>> K = QuadraticField(-Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> P = K.ideal(Integer(3)).factor()[Integer(0)][Integer(0)]
>>> P.gens_reduced()  # random, could be the other factor
(3, a + 1)
>>> K.hilbert_symbol(a, a + Integer(3), P)
1
>>> K.hilbert_symbol(a, a + Integer(3), [Integer(3), a+Integer(1)])
1

Primes above 2:

sage: K.<a> = NumberField(x^5 - 23)
sage: p = [p[0] for p in (2*K).factor() if p[0].norm() == 16][0]
sage: K.hilbert_symbol(a, a + 5, p)
1
sage: K.hilbert_symbol(a, 2, p)
1
sage: K.hilbert_symbol(-1, a - 2, p)
-1
>>> from sage.all import *
>>> K = NumberField(x**Integer(5) - Integer(23), names=('a',)); (a,) = K._first_ngens(1)
>>> p = [p[Integer(0)] for p in (Integer(2)*K).factor() if p[Integer(0)].norm() == Integer(16)][Integer(0)]
>>> K.hilbert_symbol(a, a + Integer(5), p)
1
>>> K.hilbert_symbol(a, Integer(2), p)
1
>>> K.hilbert_symbol(-Integer(1), a - Integer(2), p)
-1

Various real fields are allowed:

sage: K.<a> = NumberField(x^3+x+1)
sage: K.hilbert_symbol(a/3, 1/2, K.embeddings(RDF)[0])
1
sage: K.hilbert_symbol(a/5, -1, K.embeddings(RR)[0])
-1
sage: [K.hilbert_symbol(a, -1, e) for e in K.embeddings(AA)]
[-1]
>>> from sage.all import *
>>> K = NumberField(x**Integer(3)+x+Integer(1), names=('a',)); (a,) = K._first_ngens(1)
>>> K.hilbert_symbol(a/Integer(3), Integer(1)/Integer(2), K.embeddings(RDF)[Integer(0)])
1
>>> K.hilbert_symbol(a/Integer(5), -Integer(1), K.embeddings(RR)[Integer(0)])
-1
>>> [K.hilbert_symbol(a, -Integer(1), e) for e in K.embeddings(AA)]
[-1]

Real embeddings are not allowed to be disguised as complex embeddings:

sage: K.<a> = QuadraticField(5)
sage: K.hilbert_symbol(-1, -1, K.embeddings(CC)[0])
Traceback (most recent call last):
...
ValueError: Possibly real place (=Ring morphism:
  From: Number Field in a with defining polynomial x^2 - 5
        with a = 2.236067977499790?
  To:   Complex Field with 53 bits of precision
  Defn: a |--> -2.23606797749979)
given as complex embedding in hilbert_symbol. Is it real or complex?
sage: K.hilbert_symbol(-1, -1, K.embeddings(QQbar)[0])
Traceback (most recent call last):
...
ValueError: Possibly real place (=Ring morphism:
  From: Number Field in a with defining polynomial x^2 - 5
        with a = 2.236067977499790?
  To:   Algebraic Field
  Defn: a |--> -2.236067977499790?)
given as complex embedding in hilbert_symbol. Is it real or complex?
sage: K.<b> = QuadraticField(-5)
sage: K.hilbert_symbol(-1, -1, K.embeddings(CDF)[0])
1
sage: K.hilbert_symbol(-1, -1, K.embeddings(QQbar)[0])
1
>>> from sage.all import *
>>> K = QuadraticField(Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> K.hilbert_symbol(-Integer(1), -Integer(1), K.embeddings(CC)[Integer(0)])
Traceback (most recent call last):
...
ValueError: Possibly real place (=Ring morphism:
  From: Number Field in a with defining polynomial x^2 - 5
        with a = 2.236067977499790?
  To:   Complex Field with 53 bits of precision
  Defn: a |--> -2.23606797749979)
given as complex embedding in hilbert_symbol. Is it real or complex?
>>> K.hilbert_symbol(-Integer(1), -Integer(1), K.embeddings(QQbar)[Integer(0)])
Traceback (most recent call last):
...
ValueError: Possibly real place (=Ring morphism:
  From: Number Field in a with defining polynomial x^2 - 5
        with a = 2.236067977499790?
  To:   Algebraic Field
  Defn: a |--> -2.236067977499790?)
given as complex embedding in hilbert_symbol. Is it real or complex?
>>> K = QuadraticField(-Integer(5), names=('b',)); (b,) = K._first_ngens(1)
>>> K.hilbert_symbol(-Integer(1), -Integer(1), K.embeddings(CDF)[Integer(0)])
1
>>> K.hilbert_symbol(-Integer(1), -Integer(1), K.embeddings(QQbar)[Integer(0)])
1

\(a\) and \(b\) do not have to be integral or coprime:

sage: K.<i> = QuadraticField(-1)
sage: K.hilbert_symbol(1/2, 1/6, 3*K)
1
sage: p = 1 + i
sage: K.hilbert_symbol(p, p, p)
1
sage: K.hilbert_symbol(p, 3*p, p)
-1
sage: K.hilbert_symbol(3, p, p)
-1
sage: K.hilbert_symbol(1/3, 1/5, 1 + i)
1
sage: L = QuadraticField(5, 'a')
sage: L.hilbert_symbol(-3, -1/2, 2)
1
>>> from sage.all import *
>>> K = QuadraticField(-Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> K.hilbert_symbol(Integer(1)/Integer(2), Integer(1)/Integer(6), Integer(3)*K)
1
>>> p = Integer(1) + i
>>> K.hilbert_symbol(p, p, p)
1
>>> K.hilbert_symbol(p, Integer(3)*p, p)
-1
>>> K.hilbert_symbol(Integer(3), p, p)
-1
>>> K.hilbert_symbol(Integer(1)/Integer(3), Integer(1)/Integer(5), Integer(1) + i)
1
>>> L = QuadraticField(Integer(5), 'a')
>>> L.hilbert_symbol(-Integer(3), -Integer(1)/Integer(2), Integer(2))
1

Various other examples:

sage: K.<a> = NumberField(x^3 + x + 1)
sage: K.hilbert_symbol(-6912, 24, -a^2 - a - 2)
1
sage: K.<a> = NumberField(x^5 - 23)
sage: P = K.ideal(-1105*a^4 + 1541*a^3 - 795*a^2 - 2993*a + 11853)
sage: Q = K.ideal(-7*a^4 + 13*a^3 - 13*a^2 - 2*a + 50)
sage: b = -a+5
sage: K.hilbert_symbol(a, b, P)
1
sage: K.hilbert_symbol(a, b, Q)
1
sage: K.<a> = NumberField(x^5 - 23)
sage: P = K.ideal(-1105*a^4 + 1541*a^3 - 795*a^2 - 2993*a + 11853)
sage: K.hilbert_symbol(a, a + 5, P)
1
sage: K.hilbert_symbol(a, 2, P)
1
sage: K.hilbert_symbol(a + 5, 2, P)
-1
sage: K.<a> = NumberField(x^3 - 4*x + 2)
sage: K.hilbert_symbol(2, -2, K.primes_above(2)[0])
1
>>> from sage.all import *
>>> K = NumberField(x**Integer(3) + x + Integer(1), names=('a',)); (a,) = K._first_ngens(1)
>>> K.hilbert_symbol(-Integer(6912), Integer(24), -a**Integer(2) - a - Integer(2))
1
>>> K = NumberField(x**Integer(5) - Integer(23), names=('a',)); (a,) = K._first_ngens(1)
>>> P = K.ideal(-Integer(1105)*a**Integer(4) + Integer(1541)*a**Integer(3) - Integer(795)*a**Integer(2) - Integer(2993)*a + Integer(11853))
>>> Q = K.ideal(-Integer(7)*a**Integer(4) + Integer(13)*a**Integer(3) - Integer(13)*a**Integer(2) - Integer(2)*a + Integer(50))
>>> b = -a+Integer(5)
>>> K.hilbert_symbol(a, b, P)
1
>>> K.hilbert_symbol(a, b, Q)
1
>>> K = NumberField(x**Integer(5) - Integer(23), names=('a',)); (a,) = K._first_ngens(1)
>>> P = K.ideal(-Integer(1105)*a**Integer(4) + Integer(1541)*a**Integer(3) - Integer(795)*a**Integer(2) - Integer(2993)*a + Integer(11853))
>>> K.hilbert_symbol(a, a + Integer(5), P)
1
>>> K.hilbert_symbol(a, Integer(2), P)
1
>>> K.hilbert_symbol(a + Integer(5), Integer(2), P)
-1
>>> K = NumberField(x**Integer(3) - Integer(4)*x + Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> K.hilbert_symbol(Integer(2), -Integer(2), K.primes_above(Integer(2))[Integer(0)])
1

Check that the bug reported at Issue #16043 has been fixed:

sage: K.<a> = NumberField(x^2 + 5)
sage: p = K.primes_above(2)[0]; p
Fractional ideal (2, a + 1)
sage: K.hilbert_symbol(2*a, -1, p)
1
sage: K.hilbert_symbol(2*a, 2, p)
-1
sage: K.hilbert_symbol(2*a, -2, p)
-1
>>> from sage.all import *
>>> K = NumberField(x**Integer(2) + Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> p = K.primes_above(Integer(2))[Integer(0)]; p
Fractional ideal (2, a + 1)
>>> K.hilbert_symbol(Integer(2)*a, -Integer(1), p)
1
>>> K.hilbert_symbol(Integer(2)*a, Integer(2), p)
-1
>>> K.hilbert_symbol(Integer(2)*a, -Integer(2), p)
-1

AUTHOR:

  • Aly Deines (2010-08-19): part of the doctests

  • Marco Streng (2010-12-06)

hilbert_symbol_negative_at_S(S, b, check=True)[source]

Return \(a\) such that the Hilbert conductor of \(a\) and \(b\) is \(S\).

INPUT:

  • S – list of places (or prime ideals) of even cardinality

  • b – a nonzero rational number which is a non-square locally at every place in \(S\)

  • check – boolean (default: True); perform additional checks on the input and confirm the output

OUTPUT:

  • an element \(a\) that has negative Hilbert symbol \((a,b)_p\) for every (finite and infinite) place \(p\) in \(S\).

ALGORITHM:

The implementation is following algorithm 3.4.1 in [Kir2016]. We note that class and unit groups are computed using the generalized Riemann hypothesis. If it is false, this may result in an infinite loop. Nevertheless, if the algorithm terminates the output is correct.

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<a> = NumberField(x^2 + 20072)
sage: S = [K.primes_above(3)[0], K.primes_above(23)[0]]
sage: b = K.hilbert_symbol_negative_at_S(S, a + 1)
sage: [K.hilbert_symbol(b, a + 1, p) for p in S]
[-1, -1]
sage: K.<d> = CyclotomicField(11)
sage: S = [K.primes_above(2)[0], K.primes_above(11)[0]]
sage: b = d + 5
sage: a = K.hilbert_symbol_negative_at_S(S, b)
sage: [K.hilbert_symbol(a,b,p) for p in S]
[-1, -1]
sage: k.<c> = K.maximal_totally_real_subfield()[0]
sage: S = [k.primes_above(3)[0], k.primes_above(5)[0]]
sage: S += k.real_places()[:2]
sage: b = 5 + c + c^9
sage: a = k.hilbert_symbol_negative_at_S(S, b)
sage: [k.hilbert_symbol(a, b, p) for p in S]
[-1, -1, -1, -1]
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(2) + Integer(20072), names=('a',)); (a,) = K._first_ngens(1)
>>> S = [K.primes_above(Integer(3))[Integer(0)], K.primes_above(Integer(23))[Integer(0)]]
>>> b = K.hilbert_symbol_negative_at_S(S, a + Integer(1))
>>> [K.hilbert_symbol(b, a + Integer(1), p) for p in S]
[-1, -1]
>>> K = CyclotomicField(Integer(11), names=('d',)); (d,) = K._first_ngens(1)
>>> S = [K.primes_above(Integer(2))[Integer(0)], K.primes_above(Integer(11))[Integer(0)]]
>>> b = d + Integer(5)
>>> a = K.hilbert_symbol_negative_at_S(S, b)
>>> [K.hilbert_symbol(a,b,p) for p in S]
[-1, -1]
>>> k = K.maximal_totally_real_subfield()[Integer(0)]; (c,) = k._first_ngens(1)
>>> S = [k.primes_above(Integer(3))[Integer(0)], k.primes_above(Integer(5))[Integer(0)]]
>>> S += k.real_places()[:Integer(2)]
>>> b = Integer(5) + c + c**Integer(9)
>>> a = k.hilbert_symbol_negative_at_S(S, b)
>>> [k.hilbert_symbol(a, b, p) for p in S]
[-1, -1, -1, -1]

Note that the closely related Hilbert conductor takes only the finite places into account:

sage: k.hilbert_conductor(a, b)
Fractional ideal (15)
>>> from sage.all import *
>>> k.hilbert_conductor(a, b)
Fractional ideal (15)

AUTHORS:

  • Simon Brandhorst, Anna Haensch (01-05-2018)

is_absolute()[source]

Return True since self is an absolute field.

EXAMPLES:

sage: K = CyclotomicField(5)
sage: K.is_absolute()
True
>>> from sage.all import *
>>> K = CyclotomicField(Integer(5))
>>> K.is_absolute()
True
logarithmic_embedding(prec=53)[source]

Return the morphism of self under the logarithmic embedding in the category Set.

The logarithmic embedding is defined as a map from the number field self to \(\RR^n\).

It is defined under Definition 4.9.6 in [Coh1993].

INPUT:

  • prec – desired floating point precision

OUTPUT: the morphism of self under the logarithmic embedding in the category Set

EXAMPLES:

sage: CF.<a> = CyclotomicField(5)
sage: f = CF.logarithmic_embedding()
sage: f(0)
(-1, -1)
sage: f(7)
(3.89182029811063, 3.89182029811063)
>>> from sage.all import *
>>> CF = CyclotomicField(Integer(5), names=('a',)); (a,) = CF._first_ngens(1)
>>> f = CF.logarithmic_embedding()
>>> f(Integer(0))
(-1, -1)
>>> f(Integer(7))
(3.89182029811063, 3.89182029811063)

sage: x = polygen(QQ, 'x')
sage: K.<a> = NumberField(x^3 + 5)
sage: f = K.logarithmic_embedding()
sage: f(0)
(-1, -1)
sage: f(7)
(1.94591014905531, 3.89182029811063)
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(3) + Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> f = K.logarithmic_embedding()
>>> f(Integer(0))
(-1, -1)
>>> f(Integer(7))
(1.94591014905531, 3.89182029811063)

sage: F.<a> = NumberField(x^4 - 8*x^2 + 3)
sage: f = F.logarithmic_embedding()
sage: f(0)
(-1, -1, -1, -1)
sage: f(7)
(1.94591014905531, 1.94591014905531, 1.94591014905531, 1.94591014905531)
>>> from sage.all import *
>>> F = NumberField(x**Integer(4) - Integer(8)*x**Integer(2) + Integer(3), names=('a',)); (a,) = F._first_ngens(1)
>>> f = F.logarithmic_embedding()
>>> f(Integer(0))
(-1, -1, -1, -1)
>>> f(Integer(7))
(1.94591014905531, 1.94591014905531, 1.94591014905531, 1.94591014905531)
minkowski_embedding(B=None, prec=None)[source]

Return an \(n \times n\) matrix over RDF whose columns are the images of the basis \(\{1, \alpha, \dots, \alpha^{n-1}\}\) of self over \(\QQ\) (as vector spaces), where here \(\alpha\) is the generator of self over \(\QQ\), i.e. self.gen(0). If \(B\) is not None, return the images of the vectors in \(B\) as the columns instead. If prec is not None, use RealField(prec) instead of RDF.

This embedding is the so-called “Minkowski embedding” of a number field in \(\RR^n\): given the \(n\) embeddings \(\sigma_1, \dots, \sigma_n\) of self in \(\CC\), write \(\sigma_1, \dots, \sigma_r\) for the real embeddings, and \(\sigma_{r+1}, \dots, \sigma_{r+s}\) for choices of one of each pair of complex conjugate embeddings (in our case, we simply choose the one where the image of \(\alpha\) has positive real part). Here \((r,s)\) is the signature of self. Then the Minkowski embedding is given by

\[x \mapsto ( \sigma_1(x), \dots, \sigma_r(x), \sqrt{2}\Re(\sigma_{r+1}(x)), \sqrt{2}\Im(\sigma_{r+1}(x)), \dots, \sqrt{2}\Re(\sigma_{r+s}(x)), \sqrt{2}\Im(\sigma_{r+s}(x)))\]

Equivalently, this is an embedding of self in \(\RR^n\) so that the usual norm on \(\RR^n\) coincides with \(|x| = \sum_i |\sigma_i(x)|^2\) on self.

Todo

This could be much improved by implementing homomorphisms over VectorSpaces.

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: F.<alpha> = NumberField(x^3 + 2)
sage: F.minkowski_embedding()
[ 1.00000000000000 -1.25992104989487  1.58740105196820]
[ 1.41421356237... 0.8908987181... -1.12246204830...]
[0.000000000000000  1.54308184421...  1.94416129723...]
sage: F.minkowski_embedding([1, alpha+2, alpha^2-alpha])
[ 1.00000000000000 0.740078950105127  2.84732210186307]
[ 1.41421356237...  3.7193258428... -2.01336076644...]
[0.000000000000000  1.54308184421... 0.40107945302...]
sage: F.minkowski_embedding() * (alpha + 2).vector().column()
[0.740078950105127]
[ 3.7193258428...]
[ 1.54308184421...]
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> F = NumberField(x**Integer(3) + Integer(2), names=('alpha',)); (alpha,) = F._first_ngens(1)
>>> F.minkowski_embedding()
[ 1.00000000000000 -1.25992104989487  1.58740105196820]
[ 1.41421356237... 0.8908987181... -1.12246204830...]
[0.000000000000000  1.54308184421...  1.94416129723...]
>>> F.minkowski_embedding([Integer(1), alpha+Integer(2), alpha**Integer(2)-alpha])
[ 1.00000000000000 0.740078950105127  2.84732210186307]
[ 1.41421356237...  3.7193258428... -2.01336076644...]
[0.000000000000000  1.54308184421... 0.40107945302...]
>>> F.minkowski_embedding() * (alpha + Integer(2)).vector().column()
[0.740078950105127]
[ 3.7193258428...]
[ 1.54308184421...]
optimized_representation(name=None, both_maps=True)[source]

Return a field isomorphic to self with a better defining polynomial if possible, along with field isomorphisms from the new field to self and from self to the new field.

EXAMPLES: We construct a compositum of 3 quadratic fields, then find an optimized representation and transform elements back and forth.

sage: x = polygen(QQ, 'x')
sage: K = NumberField([x^2 + p for p in [5, 3, 2]],'a').absolute_field('b'); K
Number Field in b with defining polynomial x^8 + 40*x^6 + 352*x^4 + 960*x^2 + 576
sage: L, from_L, to_L = K.optimized_representation()
sage: L    # your answer may different, since algorithm is random
Number Field in b1 with defining polynomial x^8 + 4*x^6 + 7*x^4 + 36*x^2 + 81
sage: to_L(K.0)   # random
4/189*b1^7 + 1/63*b1^6 + 1/27*b1^5 - 2/9*b1^4 - 5/27*b1^3 - 8/9*b1^2 + 3/7*b1 - 3/7
sage: from_L(L.0)   # random
1/1152*b^7 - 1/192*b^6 + 23/576*b^5 - 17/96*b^4 + 37/72*b^3 - 5/6*b^2 + 55/24*b - 3/4
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField([x**Integer(2) + p for p in [Integer(5), Integer(3), Integer(2)]],'a').absolute_field('b'); K
Number Field in b with defining polynomial x^8 + 40*x^6 + 352*x^4 + 960*x^2 + 576
>>> L, from_L, to_L = K.optimized_representation()
>>> L    # your answer may different, since algorithm is random
Number Field in b1 with defining polynomial x^8 + 4*x^6 + 7*x^4 + 36*x^2 + 81
>>> to_L(K.gen(0))   # random
4/189*b1^7 + 1/63*b1^6 + 1/27*b1^5 - 2/9*b1^4 - 5/27*b1^3 - 8/9*b1^2 + 3/7*b1 - 3/7
>>> from_L(L.gen(0))   # random
1/1152*b^7 - 1/192*b^6 + 23/576*b^5 - 17/96*b^4 + 37/72*b^3 - 5/6*b^2 + 55/24*b - 3/4

The transformation maps are mutually inverse isomorphisms.

sage: from_L(to_L(K.0)) == K.0
True
sage: to_L(from_L(L.0)) == L.0
True
>>> from sage.all import *
>>> from_L(to_L(K.gen(0))) == K.gen(0)
True
>>> to_L(from_L(L.gen(0))) == L.gen(0)
True

Number fields defined by non-monic and non-integral polynomials are supported (Issue #252):

sage: K.<a> = NumberField(7/9*x^3 + 7/3*x^2 - 56*x + 123)
sage: K.optimized_representation()  # representation varies, not tested
(Number Field in a1 with defining polynomial x^3 - 7*x - 7,
 Ring morphism:
   From: Number Field in a1 with defining polynomial x^3 - 7*x - 7
   To:   Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123
   Defn: a1 |--> 7/225*a^2 - 7/75*a - 42/25,
 Ring morphism:
   From: Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123
   To:   Number Field in a1 with defining polynomial x^3 - 7*x - 7
   Defn: a |--> -15/7*a1^2 + 9)
>>> from sage.all import *
>>> K = NumberField(Integer(7)/Integer(9)*x**Integer(3) + Integer(7)/Integer(3)*x**Integer(2) - Integer(56)*x + Integer(123), names=('a',)); (a,) = K._first_ngens(1)
>>> K.optimized_representation()  # representation varies, not tested
(Number Field in a1 with defining polynomial x^3 - 7*x - 7,
 Ring morphism:
   From: Number Field in a1 with defining polynomial x^3 - 7*x - 7
   To:   Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123
   Defn: a1 |--> 7/225*a^2 - 7/75*a - 42/25,
 Ring morphism:
   From: Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123
   To:   Number Field in a1 with defining polynomial x^3 - 7*x - 7
   Defn: a |--> -15/7*a1^2 + 9)
optimized_subfields(degree=0, name=None, both_maps=True)[source]

Return optimized representations of many (but not necessarily all!) subfields of self of the given degree, or of all possible degrees if degree is 0.

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K = NumberField([x^2 + p for p in [5, 3, 2]],'a').absolute_field('b'); K
Number Field in b with defining polynomial x^8 + 40*x^6 + 352*x^4 + 960*x^2 + 576
sage: L = K.optimized_subfields(name='b')
sage: L[0][0]
Number Field in b0 with defining polynomial x
sage: L[1][0]
Number Field in b1 with defining polynomial x^2 - 3*x + 3
sage: [z[0] for z in L]          # random -- since algorithm is random
[Number Field in b0 with defining polynomial x - 1,
 Number Field in b1 with defining polynomial x^2 - x + 1,
 Number Field in b2 with defining polynomial x^4 - 5*x^2 + 25,
 Number Field in b3 with defining polynomial x^4 - 2*x^2 + 4,
 Number Field in b4 with defining polynomial x^8 + 4*x^6 + 7*x^4 + 36*x^2 + 81]
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField([x**Integer(2) + p for p in [Integer(5), Integer(3), Integer(2)]],'a').absolute_field('b'); K
Number Field in b with defining polynomial x^8 + 40*x^6 + 352*x^4 + 960*x^2 + 576
>>> L = K.optimized_subfields(name='b')
>>> L[Integer(0)][Integer(0)]
Number Field in b0 with defining polynomial x
>>> L[Integer(1)][Integer(0)]
Number Field in b1 with defining polynomial x^2 - 3*x + 3
>>> [z[Integer(0)] for z in L]          # random -- since algorithm is random
[Number Field in b0 with defining polynomial x - 1,
 Number Field in b1 with defining polynomial x^2 - x + 1,
 Number Field in b2 with defining polynomial x^4 - 5*x^2 + 25,
 Number Field in b3 with defining polynomial x^4 - 2*x^2 + 4,
 Number Field in b4 with defining polynomial x^8 + 4*x^6 + 7*x^4 + 36*x^2 + 81]

We examine one of the optimized subfields in more detail:

sage: M, from_M, to_M = L[2]
sage: M                             # random
Number Field in b2 with defining polynomial x^4 - 5*x^2 + 25
sage: from_M     # may be slightly random
Ring morphism:
  From: Number Field in b2 with defining polynomial x^4 - 5*x^2 + 25
  To:   Number Field in a1 with defining polynomial
        x^8 + 40*x^6 + 352*x^4 + 960*x^2 + 576
  Defn: b2 |--> -5/1152*a1^7 + 1/96*a1^6 - 97/576*a1^5 + 17/48*a1^4
                - 95/72*a1^3 + 17/12*a1^2 - 53/24*a1 - 1
>>> from sage.all import *
>>> M, from_M, to_M = L[Integer(2)]
>>> M                             # random
Number Field in b2 with defining polynomial x^4 - 5*x^2 + 25
>>> from_M     # may be slightly random
Ring morphism:
  From: Number Field in b2 with defining polynomial x^4 - 5*x^2 + 25
  To:   Number Field in a1 with defining polynomial
        x^8 + 40*x^6 + 352*x^4 + 960*x^2 + 576
  Defn: b2 |--> -5/1152*a1^7 + 1/96*a1^6 - 97/576*a1^5 + 17/48*a1^4
                - 95/72*a1^3 + 17/12*a1^2 - 53/24*a1 - 1

The to_M map is None, since there is no map from \(K\) to \(M\):

sage: to_M
>>> from sage.all import *
>>> to_M

We apply the from_M map to the generator of M, which gives a rather large element of \(K\):

sage: from_M(M.0)          # random
-5/1152*a1^7 + 1/96*a1^6 - 97/576*a1^5 + 17/48*a1^4
 - 95/72*a1^3 + 17/12*a1^2 - 53/24*a1 - 1
>>> from sage.all import *
>>> from_M(M.gen(0))          # random
-5/1152*a1^7 + 1/96*a1^6 - 97/576*a1^5 + 17/48*a1^4
 - 95/72*a1^3 + 17/12*a1^2 - 53/24*a1 - 1

Nevertheless, that large-ish element lies in a degree 4 subfield:

sage: from_M(M.0).minpoly()   # random
x^4 - 5*x^2 + 25
>>> from sage.all import *
>>> from_M(M.gen(0)).minpoly()   # random
x^4 - 5*x^2 + 25
order(*args, **kwds)[source]

Return the order with given ring generators in the maximal order of this number field.

INPUT:

  • gens – list of elements in this number field; if no generators are given, just returns the cardinality of this number field (\(\infty\)) for consistency.

  • check_is_integral – boolean (default: True); whether to check that each generator is integral

  • check_rank – boolean (default: True); whether to check that the ring generated by gens is of full rank

  • allow_subfield – boolean (default: False); if True and the generators do not generate an order, i.e., they generate a subring of smaller rank, instead of raising an error, return an order in a smaller number field

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: k.<i> = NumberField(x^2 + 1)
sage: k.order(2*i)
Order of conductor 2 generated by 2*i in Number Field in i with defining polynomial x^2 + 1
sage: k.order(10*i)
Order of conductor 10 generated by 10*i in Number Field in i with defining polynomial x^2 + 1
sage: k.order(3)
Traceback (most recent call last):
...
ValueError: the rank of the span of gens is wrong
sage: k.order(i/2)
Traceback (most recent call last):
...
ValueError: each generator must be integral
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> k = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = k._first_ngens(1)
>>> k.order(Integer(2)*i)
Order of conductor 2 generated by 2*i in Number Field in i with defining polynomial x^2 + 1
>>> k.order(Integer(10)*i)
Order of conductor 10 generated by 10*i in Number Field in i with defining polynomial x^2 + 1
>>> k.order(Integer(3))
Traceback (most recent call last):
...
ValueError: the rank of the span of gens is wrong
>>> k.order(i/Integer(2))
Traceback (most recent call last):
...
ValueError: each generator must be integral

Alternatively, an order can be constructed by adjoining elements to \(\ZZ\):

sage: K.<a> = NumberField(x^3 - 2)
sage: ZZ[a]
Order generated by a0 in Number Field in a0 with defining polynomial x^3 - 2 with a0 = a
>>> from sage.all import *
>>> K = NumberField(x**Integer(3) - Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> ZZ[a]
Order generated by a0 in Number Field in a0 with defining polynomial x^3 - 2 with a0 = a
places(all_complex=False, prec=None)[source]

Return the collection of all infinite places of self.

By default, this returns the set of real places as homomorphisms into RIF first, followed by a choice of one of each pair of complex conjugate homomorphisms into CIF.

On the other hand, if prec is not None, we simply return places into RealField(prec) and ComplexField(prec) (or RDF, CDF if prec=53). One can also use prec=infinity, which returns embeddings into the field \(\overline{\QQ}\) of algebraic numbers (or its subfield \(\mathbb{A}\) of algebraic reals); this permits exact computation, but can be extremely slow.

There is an optional flag all_complex, which defaults to False. If all_complex is True, then the real embeddings are returned as embeddings into CIF instead of RIF.

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: F.<alpha> = NumberField(x^3 - 100*x + 1); F.places()
[Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 - 100*x + 1
   To:   Real Field with 106 bits of precision
   Defn: alpha |--> -10.00499625499181184573367219280,
 Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 - 100*x + 1
   To:   Real Field with 106 bits of precision
   Defn: alpha |--> 0.01000001000003000012000055000273,
 Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 - 100*x + 1
   To:   Real Field with 106 bits of precision
   Defn: alpha |--> 9.994996244991781845613530439509]
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> F = NumberField(x**Integer(3) - Integer(100)*x + Integer(1), names=('alpha',)); (alpha,) = F._first_ngens(1); F.places()
[Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 - 100*x + 1
   To:   Real Field with 106 bits of precision
   Defn: alpha |--> -10.00499625499181184573367219280,
 Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 - 100*x + 1
   To:   Real Field with 106 bits of precision
   Defn: alpha |--> 0.01000001000003000012000055000273,
 Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 - 100*x + 1
   To:   Real Field with 106 bits of precision
   Defn: alpha |--> 9.994996244991781845613530439509]

sage: F.<alpha> = NumberField(x^3 + 7); F.places()
[Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 + 7
   To:   Real Field with 106 bits of precision
   Defn: alpha |--> -1.912931182772389101199116839549,
 Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 + 7
   To:   Complex Field with 53 bits of precision
   Defn: alpha |--> 0.956465591386195 + 1.65664699997230*I]
>>> from sage.all import *
>>> F = NumberField(x**Integer(3) + Integer(7), names=('alpha',)); (alpha,) = F._first_ngens(1); F.places()
[Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 + 7
   To:   Real Field with 106 bits of precision
   Defn: alpha |--> -1.912931182772389101199116839549,
 Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 + 7
   To:   Complex Field with 53 bits of precision
   Defn: alpha |--> 0.956465591386195 + 1.65664699997230*I]

sage: F.<alpha> = NumberField(x^3 + 7) ; F.places(all_complex=True)
[Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 + 7
   To:   Complex Field with 53 bits of precision
   Defn: alpha |--> -1.91293118277239,
 Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 + 7
   To:   Complex Field with 53 bits of precision
   Defn: alpha |--> 0.956465591386195 + 1.65664699997230*I]
sage: F.places(prec=10)
[Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 + 7
   To:   Real Field with 10 bits of precision
   Defn: alpha |--> -1.9,
 Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 + 7
   To:   Complex Field with 10 bits of precision
   Defn: alpha |--> 0.96 + 1.7*I]
>>> from sage.all import *
>>> F = NumberField(x**Integer(3) + Integer(7), names=('alpha',)); (alpha,) = F._first_ngens(1); F.places(all_complex=True)
[Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 + 7
   To:   Complex Field with 53 bits of precision
   Defn: alpha |--> -1.91293118277239,
 Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 + 7
   To:   Complex Field with 53 bits of precision
   Defn: alpha |--> 0.956465591386195 + 1.65664699997230*I]
>>> F.places(prec=Integer(10))
[Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 + 7
   To:   Real Field with 10 bits of precision
   Defn: alpha |--> -1.9,
 Ring morphism:
   From: Number Field in alpha with defining polynomial x^3 + 7
   To:   Complex Field with 10 bits of precision
   Defn: alpha |--> 0.96 + 1.7*I]
real_places(prec=None)[source]

Return all real places of self as homomorphisms into RIF.

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: F.<alpha> = NumberField(x^4 - 7) ; F.real_places()
[Ring morphism:
   From: Number Field in alpha with defining polynomial x^4 - 7
   To:   Real Field with 106 bits of precision
   Defn: alpha |--> -1.626576561697785743211232345494,
 Ring morphism:
   From: Number Field in alpha with defining polynomial x^4 - 7
   To:   Real Field with 106 bits of precision
   Defn: alpha |--> 1.626576561697785743211232345494]
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> F = NumberField(x**Integer(4) - Integer(7), names=('alpha',)); (alpha,) = F._first_ngens(1); F.real_places()
[Ring morphism:
   From: Number Field in alpha with defining polynomial x^4 - 7
   To:   Real Field with 106 bits of precision
   Defn: alpha |--> -1.626576561697785743211232345494,
 Ring morphism:
   From: Number Field in alpha with defining polynomial x^4 - 7
   To:   Real Field with 106 bits of precision
   Defn: alpha |--> 1.626576561697785743211232345494]
relative_degree()[source]

A synonym for degree().

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<i> = NumberField(x^2 + 1)
sage: K.relative_degree()
2
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> K.relative_degree()
2
relative_different()[source]

A synonym for different().

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<i> = NumberField(x^2 + 1)
sage: K.relative_different()
Fractional ideal (2)
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> K.relative_different()
Fractional ideal (2)
relative_discriminant()[source]

A synonym for discriminant().

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<i> = NumberField(x^2 + 1)
sage: K.relative_discriminant()
-4
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> K.relative_discriminant()
-4
relative_polynomial()[source]

A synonym for polynomial().

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<i> = NumberField(x^2 + 1)
sage: K.relative_polynomial()
x^2 + 1
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> K.relative_polynomial()
x^2 + 1
relative_vector_space(*args, **kwds)[source]

A synonym for vector_space().

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<i> = NumberField(x^2 + 1)
sage: K.relative_vector_space()
(Vector space of dimension 2 over Rational Field,
 Isomorphism map:
  From: Vector space of dimension 2 over Rational Field
  To:   Number Field in i with defining polynomial x^2 + 1,
 Isomorphism map:
  From: Number Field in i with defining polynomial x^2 + 1
  To:   Vector space of dimension 2 over Rational Field)
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> K.relative_vector_space()
(Vector space of dimension 2 over Rational Field,
 Isomorphism map:
  From: Vector space of dimension 2 over Rational Field
  To:   Number Field in i with defining polynomial x^2 + 1,
 Isomorphism map:
  From: Number Field in i with defining polynomial x^2 + 1
  To:   Vector space of dimension 2 over Rational Field)
relativize(alpha, names, structure=None)[source]

Given an element in self or an embedding of a subfield into self, return a relative number field \(K\) isomorphic to self that is relative over the absolute field \(\QQ(\alpha)\) or the domain of \(\alpha\), along with isomorphisms from \(K\) to self and from self to \(K\).

INPUT:

  • alpha – an element of self or an embedding of a subfield into self

  • names – 2-tuple of names of generator for output field \(K\) and the subfield \(\QQ(\alpha)\)

  • structure – an instance of structure.NumberFieldStructure or None (default: None), if None, then the resulting field’s structure() will return isomorphisms from and to this field. Otherwise, the field will be equipped with structure.

OUTPUT: \(K\) – relative number field

Also, K.structure() returns from_K and to_K, where from_K is an isomorphism from \(K\) to self and to_K is an isomorphism from self to \(K\).

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<a> = NumberField(x^10 - 2)
sage: L.<c,d> = K.relativize(a^4 + a^2 + 2); L
Number Field in c with defining polynomial
 x^2 - 1/5*d^4 + 8/5*d^3 - 23/5*d^2 + 7*d - 18/5 over its base field
sage: c.absolute_minpoly()
x^10 - 2
sage: d.absolute_minpoly()
x^5 - 10*x^4 + 40*x^3 - 90*x^2 + 110*x - 58
sage: (a^4 + a^2 + 2).minpoly()
x^5 - 10*x^4 + 40*x^3 - 90*x^2 + 110*x - 58
sage: from_L, to_L = L.structure()
sage: to_L(a)
c
sage: to_L(a^4 + a^2 + 2)
d
sage: from_L(to_L(a^4 + a^2 + 2))
a^4 + a^2 + 2
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(10) - Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> L = K.relativize(a**Integer(4) + a**Integer(2) + Integer(2), names=('c', 'd',)); (c, d,) = L._first_ngens(2); L
Number Field in c with defining polynomial
 x^2 - 1/5*d^4 + 8/5*d^3 - 23/5*d^2 + 7*d - 18/5 over its base field
>>> c.absolute_minpoly()
x^10 - 2
>>> d.absolute_minpoly()
x^5 - 10*x^4 + 40*x^3 - 90*x^2 + 110*x - 58
>>> (a**Integer(4) + a**Integer(2) + Integer(2)).minpoly()
x^5 - 10*x^4 + 40*x^3 - 90*x^2 + 110*x - 58
>>> from_L, to_L = L.structure()
>>> to_L(a)
c
>>> to_L(a**Integer(4) + a**Integer(2) + Integer(2))
d
>>> from_L(to_L(a**Integer(4) + a**Integer(2) + Integer(2)))
a^4 + a^2 + 2

The following demonstrates distinct embeddings of a subfield into a larger field:

sage: K.<a> = NumberField(x^4 + 2*x^2 + 2)
sage: K0 = K.subfields(2)[0][0]; K0
Number Field in a0 with defining polynomial x^2 - 2*x + 2
sage: rho, tau = K0.embeddings(K)
sage: L0 = K.relativize(rho(K0.gen()), 'b'); L0
Number Field in b0 with defining polynomial x^2 - b1 + 2 over its base field
sage: L1 = K.relativize(rho, 'b'); L1
Number Field in b with defining polynomial x^2 - a0 + 2 over its base field
sage: L2 = K.relativize(tau, 'b'); L2
Number Field in b with defining polynomial x^2 + a0 over its base field
sage: L0.base_field() is K0
False
sage: L1.base_field() is K0
True
sage: L2.base_field() is K0
True
>>> from sage.all import *
>>> K = NumberField(x**Integer(4) + Integer(2)*x**Integer(2) + Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> K0 = K.subfields(Integer(2))[Integer(0)][Integer(0)]; K0
Number Field in a0 with defining polynomial x^2 - 2*x + 2
>>> rho, tau = K0.embeddings(K)
>>> L0 = K.relativize(rho(K0.gen()), 'b'); L0
Number Field in b0 with defining polynomial x^2 - b1 + 2 over its base field
>>> L1 = K.relativize(rho, 'b'); L1
Number Field in b with defining polynomial x^2 - a0 + 2 over its base field
>>> L2 = K.relativize(tau, 'b'); L2
Number Field in b with defining polynomial x^2 + a0 over its base field
>>> L0.base_field() is K0
False
>>> L1.base_field() is K0
True
>>> L2.base_field() is K0
True

Here we see that with the different embeddings, the relative norms are different:

sage: a0 = K0.gen()
sage: L1_into_K, K_into_L1 = L1.structure()
sage: L2_into_K, K_into_L2 = L2.structure()
sage: len(K.factor(41))
4
sage: w1 = -a^2 + a + 1; P = K.ideal([w1])
sage: Pp = L1.ideal(K_into_L1(w1)).ideal_below(); Pp == K0.ideal([4*a0 + 1])
True
sage: Pp == w1.norm(rho)
True

sage: w2 = a^2 + a - 1; Q = K.ideal([w2])
sage: Qq = L2.ideal(K_into_L2(w2)).ideal_below(); Qq == K0.ideal([-4*a0 + 9])
True
sage: Qq == w2.norm(tau)
True

sage: Pp == Qq
False
>>> from sage.all import *
>>> a0 = K0.gen()
>>> L1_into_K, K_into_L1 = L1.structure()
>>> L2_into_K, K_into_L2 = L2.structure()
>>> len(K.factor(Integer(41)))
4
>>> w1 = -a**Integer(2) + a + Integer(1); P = K.ideal([w1])
>>> Pp = L1.ideal(K_into_L1(w1)).ideal_below(); Pp == K0.ideal([Integer(4)*a0 + Integer(1)])
True
>>> Pp == w1.norm(rho)
True

>>> w2 = a**Integer(2) + a - Integer(1); Q = K.ideal([w2])
>>> Qq = L2.ideal(K_into_L2(w2)).ideal_below(); Qq == K0.ideal([-Integer(4)*a0 + Integer(9)])
True
>>> Qq == w2.norm(tau)
True

>>> Pp == Qq
False
subfields(degree=0, name=None)[source]

Return all subfields of self of the given degree, or of all possible degrees if degree is 0. The subfields are returned as absolute fields together with an embedding into self. For the case of the field itself, the reverse isomorphism is also provided.

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<a> = NumberField([x^3 - 2, x^2 + x + 1])
sage: K = K.absolute_field('b')
sage: S = K.subfields()
sage: len(S)
6
sage: [k[0].polynomial() for k in S]
[x - 3,
 x^2 - 3*x + 9,
 x^3 - 3*x^2 + 3*x + 1,
 x^3 - 3*x^2 + 3*x + 1,
 x^3 - 3*x^2 + 3*x - 17,
 x^6 - 3*x^5 + 6*x^4 - 11*x^3 + 12*x^2 + 3*x + 1]
sage: R.<t> = QQ[]
sage: L = NumberField(t^3 - 3*t + 1, 'c')
sage: [k[1] for k in L.subfields()]
[Ring morphism:
  From: Number Field in c0 with defining polynomial t
  To:   Number Field in c with defining polynomial t^3 - 3*t + 1
  Defn: 0 |--> 0,
 Ring morphism:
  From: Number Field in c1 with defining polynomial t^3 - 3*t + 1
  To:   Number Field in c with defining polynomial t^3 - 3*t + 1
  Defn: c1 |--> c]
sage: len(L.subfields(2))
0
sage: len(L.subfields(1))
1
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField([x**Integer(3) - Integer(2), x**Integer(2) + x + Integer(1)], names=('a',)); (a,) = K._first_ngens(1)
>>> K = K.absolute_field('b')
>>> S = K.subfields()
>>> len(S)
6
>>> [k[Integer(0)].polynomial() for k in S]
[x - 3,
 x^2 - 3*x + 9,
 x^3 - 3*x^2 + 3*x + 1,
 x^3 - 3*x^2 + 3*x + 1,
 x^3 - 3*x^2 + 3*x - 17,
 x^6 - 3*x^5 + 6*x^4 - 11*x^3 + 12*x^2 + 3*x + 1]
>>> R = QQ['t']; (t,) = R._first_ngens(1)
>>> L = NumberField(t**Integer(3) - Integer(3)*t + Integer(1), 'c')
>>> [k[Integer(1)] for k in L.subfields()]
[Ring morphism:
  From: Number Field in c0 with defining polynomial t
  To:   Number Field in c with defining polynomial t^3 - 3*t + 1
  Defn: 0 |--> 0,
 Ring morphism:
  From: Number Field in c1 with defining polynomial t^3 - 3*t + 1
  To:   Number Field in c with defining polynomial t^3 - 3*t + 1
  Defn: c1 |--> c]
>>> len(L.subfields(Integer(2)))
0
>>> len(L.subfields(Integer(1)))
1
sage.rings.number_field.number_field.NumberField_absolute_v1(poly, name, latex_name, canonical_embedding=None)[source]

Used for unpickling old pickles.

EXAMPLES:

sage: from sage.rings.number_field.number_field import NumberField_absolute_v1
sage: R.<x> = QQ[]
sage: NumberField_absolute_v1(x^2 + 1, 'i', 'i')
Number Field in i with defining polynomial x^2 + 1
>>> from sage.all import *
>>> from sage.rings.number_field.number_field import NumberField_absolute_v1
>>> R = QQ['x']; (x,) = R._first_ngens(1)
>>> NumberField_absolute_v1(x**Integer(2) + Integer(1), 'i', 'i')
Number Field in i with defining polynomial x^2 + 1
class sage.rings.number_field.number_field.NumberField_cyclotomic(n, names, embedding=None, assume_disc_small=False, maximize_at_primes=None)[source]

Bases: NumberField_absolute, NumberField_cyclotomic

Create a cyclotomic extension of the rational field.

The command CyclotomicField(n) creates the \(n\)-th cyclotomic field, obtained by adjoining an \(n\)-th root of unity to the rational field.

EXAMPLES:

sage: CyclotomicField(3)
Cyclotomic Field of order 3 and degree 2
sage: CyclotomicField(18)
Cyclotomic Field of order 18 and degree 6
sage: z = CyclotomicField(6).gen(); z
zeta6
sage: z^3
-1
sage: (1+z)^3
6*zeta6 - 3
>>> from sage.all import *
>>> CyclotomicField(Integer(3))
Cyclotomic Field of order 3 and degree 2
>>> CyclotomicField(Integer(18))
Cyclotomic Field of order 18 and degree 6
>>> z = CyclotomicField(Integer(6)).gen(); z
zeta6
>>> z**Integer(3)
-1
>>> (Integer(1)+z)**Integer(3)
6*zeta6 - 3

sage: K = CyclotomicField(197)
sage: loads(K.dumps()) == K
True
sage: loads((z^2).dumps()) == z^2
True
>>> from sage.all import *
>>> K = CyclotomicField(Integer(197))
>>> loads(K.dumps()) == K
True
>>> loads((z**Integer(2)).dumps()) == z**Integer(2)
True

sage: cf12 = CyclotomicField(12)
sage: z12 = cf12.0
sage: cf6 = CyclotomicField(6)
sage: z6 = cf6.0
sage: FF = Frac(cf12['x'])
sage: x = FF.0
sage: z6*x^3/(z6 + x)
zeta12^2*x^3/(x + zeta12^2)
>>> from sage.all import *
>>> cf12 = CyclotomicField(Integer(12))
>>> z12 = cf12.gen(0)
>>> cf6 = CyclotomicField(Integer(6))
>>> z6 = cf6.gen(0)
>>> FF = Frac(cf12['x'])
>>> x = FF.gen(0)
>>> z6*x**Integer(3)/(z6 + x)
zeta12^2*x^3/(x + zeta12^2)

sage: cf6 = CyclotomicField(6); z6 = cf6.gen(0)
sage: cf3 = CyclotomicField(3); z3 = cf3.gen(0)
sage: cf3(z6)
zeta3 + 1
sage: cf6(z3)
zeta6 - 1
sage: type(cf6(z3))
<class 'sage.rings.number_field.number_field_element_quadratic.NumberFieldElement_quadratic'>
sage: cf1 = CyclotomicField(1); z1 = cf1.0
sage: cf3(z1)
1
sage: type(cf3(z1))
<class 'sage.rings.number_field.number_field_element_quadratic.NumberFieldElement_quadratic'>
>>> from sage.all import *
>>> cf6 = CyclotomicField(Integer(6)); z6 = cf6.gen(Integer(0))
>>> cf3 = CyclotomicField(Integer(3)); z3 = cf3.gen(Integer(0))
>>> cf3(z6)
zeta3 + 1
>>> cf6(z3)
zeta6 - 1
>>> type(cf6(z3))
<class 'sage.rings.number_field.number_field_element_quadratic.NumberFieldElement_quadratic'>
>>> cf1 = CyclotomicField(Integer(1)); z1 = cf1.gen(0)
>>> cf3(z1)
1
>>> type(cf3(z1))
<class 'sage.rings.number_field.number_field_element_quadratic.NumberFieldElement_quadratic'>
complex_embedding(prec=53)[source]

Return the embedding of this cyclotomic field into the approximate complex field with precision prec obtained by sending the generator \(\zeta\) of self to exp(2*pi*i/n), where \(n\) is the multiplicative order of \(\zeta\).

EXAMPLES:

sage: C = CyclotomicField(4)
sage: C.complex_embedding()
Ring morphism:
  From: Cyclotomic Field of order 4 and degree 2
  To:   Complex Field with 53 bits of precision
  Defn: zeta4 |--> 6.12323399573677e-17 + 1.00000000000000*I
>>> from sage.all import *
>>> C = CyclotomicField(Integer(4))
>>> C.complex_embedding()
Ring morphism:
  From: Cyclotomic Field of order 4 and degree 2
  To:   Complex Field with 53 bits of precision
  Defn: zeta4 |--> 6.12323399573677e-17 + 1.00000000000000*I

Note in the example above that the way zeta is computed (using sine and cosine in MPFR) means that only the prec bits of the number after the decimal point are valid.

sage: K = CyclotomicField(3)
sage: phi = K.complex_embedding(10)
sage: phi(K.0)
-0.50 + 0.87*I
sage: phi(K.0^3)
1.0
sage: phi(K.0^3 - 1)
0.00
sage: phi(K.0^3 + 7)
8.0
>>> from sage.all import *
>>> K = CyclotomicField(Integer(3))
>>> phi = K.complex_embedding(Integer(10))
>>> phi(K.gen(0))
-0.50 + 0.87*I
>>> phi(K.gen(0)**Integer(3))
1.0
>>> phi(K.gen(0)**Integer(3) - Integer(1))
0.00
>>> phi(K.gen(0)**Integer(3) + Integer(7))
8.0
complex_embeddings(prec=53)[source]

Return all embeddings of this cyclotomic field into the approximate complex field with precision prec.

If you want 53-bit double precision, which is faster but less reliable, then do self.embeddings(CDF).

EXAMPLES:

sage: CyclotomicField(5).complex_embeddings()
[
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Complex Field with 53 bits of precision
  Defn: zeta5 |--> 0.309016994374947 + 0.951056516295154*I,
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Complex Field with 53 bits of precision
  Defn: zeta5 |--> -0.809016994374947 + 0.587785252292473*I,
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Complex Field with 53 bits of precision
  Defn: zeta5 |--> -0.809016994374947 - 0.587785252292473*I,
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Complex Field with 53 bits of precision
  Defn: zeta5 |--> 0.309016994374947 - 0.951056516295154*I
]
>>> from sage.all import *
>>> CyclotomicField(Integer(5)).complex_embeddings()
[
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Complex Field with 53 bits of precision
  Defn: zeta5 |--> 0.309016994374947 + 0.951056516295154*I,
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Complex Field with 53 bits of precision
  Defn: zeta5 |--> -0.809016994374947 + 0.587785252292473*I,
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Complex Field with 53 bits of precision
  Defn: zeta5 |--> -0.809016994374947 - 0.587785252292473*I,
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Complex Field with 53 bits of precision
  Defn: zeta5 |--> 0.309016994374947 - 0.951056516295154*I
]
construction()[source]

Return data defining a functorial construction of self.

EXAMPLES:

sage: F, R = CyclotomicField(5).construction()
sage: R
Rational Field
sage: F.polys
[x^4 + x^3 + x^2 + x + 1]
sage: F.names
['zeta5']
sage: F.embeddings
[0.309016994374948? + 0.951056516295154?*I]
sage: F.structures
[None]
>>> from sage.all import *
>>> F, R = CyclotomicField(Integer(5)).construction()
>>> R
Rational Field
>>> F.polys
[x^4 + x^3 + x^2 + x + 1]
>>> F.names
['zeta5']
>>> F.embeddings
[0.309016994374948? + 0.951056516295154?*I]
>>> F.structures
[None]
different()[source]

Return the different ideal of the cyclotomic field self.

EXAMPLES:

sage: C20 = CyclotomicField(20)
sage: C20.different()
Fractional ideal (10, 2*zeta20^6 - 4*zeta20^4 - 4*zeta20^2 + 2)
sage: C18 = CyclotomicField(18)
sage: D = C18.different().norm()
sage: D == C18.discriminant().abs()
True
>>> from sage.all import *
>>> C20 = CyclotomicField(Integer(20))
>>> C20.different()
Fractional ideal (10, 2*zeta20^6 - 4*zeta20^4 - 4*zeta20^2 + 2)
>>> C18 = CyclotomicField(Integer(18))
>>> D = C18.different().norm()
>>> D == C18.discriminant().abs()
True
discriminant(v=None)[source]

Return the discriminant of the ring of integers of the cyclotomic field self, or if v is specified, the determinant of the trace pairing on the elements of the list v.

Uses the formula for the discriminant of a prime power cyclotomic field and Hilbert Theorem 88 on the discriminant of composita.

INPUT:

  • v – (optional) list of elements of this number field

OUTPUT: integer if v is omitted, and Rational otherwise

EXAMPLES:

sage: CyclotomicField(20).discriminant()
4000000
sage: CyclotomicField(18).discriminant()
-19683
>>> from sage.all import *
>>> CyclotomicField(Integer(20)).discriminant()
4000000
>>> CyclotomicField(Integer(18)).discriminant()
-19683
embeddings(K)[source]

Compute all field embeddings of this field into the field \(K\).

INPUT:

  • K – a field

EXAMPLES:

sage: CyclotomicField(5).embeddings(ComplexField(53))[1]
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Complex Field with 53 bits of precision
  Defn: zeta5 |--> -0.809016994374947 + 0.587785252292473*I
sage: CyclotomicField(5).embeddings(Qp(11, 4, print_mode='digits'))[1]      # needs sage.rings.padics
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   11-adic Field with capped relative precision 4
  Defn: zeta5 |--> ...1525
>>> from sage.all import *
>>> CyclotomicField(Integer(5)).embeddings(ComplexField(Integer(53)))[Integer(1)]
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   Complex Field with 53 bits of precision
  Defn: zeta5 |--> -0.809016994374947 + 0.587785252292473*I
>>> CyclotomicField(Integer(5)).embeddings(Qp(Integer(11), Integer(4), print_mode='digits'))[Integer(1)]      # needs sage.rings.padics
Ring morphism:
  From: Cyclotomic Field of order 5 and degree 4
  To:   11-adic Field with capped relative precision 4
  Defn: zeta5 |--> ...1525
is_abelian()[source]

Return True since all cyclotomic fields are automatically abelian.

EXAMPLES:

sage: CyclotomicField(29).is_abelian()
True
>>> from sage.all import *
>>> CyclotomicField(Integer(29)).is_abelian()
True
is_galois()[source]

Return True since all cyclotomic fields are automatically Galois.

EXAMPLES:

sage: CyclotomicField(29).is_galois()
True
>>> from sage.all import *
>>> CyclotomicField(Integer(29)).is_galois()
True
is_isomorphic(other)[source]

Return True if the cyclotomic field self is isomorphic as a number field to other.

EXAMPLES:

sage: CyclotomicField(11).is_isomorphic(CyclotomicField(22))
True
sage: CyclotomicField(11).is_isomorphic(CyclotomicField(23))
False
sage: x = polygen(QQ, 'x')
sage: CyclotomicField(3).is_isomorphic(NumberField(x^2 + x + 1, 'a'))
True
sage: CyclotomicField(18).is_isomorphic(CyclotomicField(9))
True
sage: CyclotomicField(10).is_isomorphic(NumberField(x^4 - x^3 + x^2 - x + 1, 'b'))
True
>>> from sage.all import *
>>> CyclotomicField(Integer(11)).is_isomorphic(CyclotomicField(Integer(22)))
True
>>> CyclotomicField(Integer(11)).is_isomorphic(CyclotomicField(Integer(23)))
False
>>> x = polygen(QQ, 'x')
>>> CyclotomicField(Integer(3)).is_isomorphic(NumberField(x**Integer(2) + x + Integer(1), 'a'))
True
>>> CyclotomicField(Integer(18)).is_isomorphic(CyclotomicField(Integer(9)))
True
>>> CyclotomicField(Integer(10)).is_isomorphic(NumberField(x**Integer(4) - x**Integer(3) + x**Integer(2) - x + Integer(1), 'b'))
True

Check Issue #14300:

sage: K = CyclotomicField(4)
sage: N = K.extension(x^2 - 5, 'z')
sage: K.is_isomorphic(N)
False
sage: K.is_isomorphic(CyclotomicField(8))
False
>>> from sage.all import *
>>> K = CyclotomicField(Integer(4))
>>> N = K.extension(x**Integer(2) - Integer(5), 'z')
>>> K.is_isomorphic(N)
False
>>> K.is_isomorphic(CyclotomicField(Integer(8)))
False
next_split_prime(p=2)[source]

Return the next prime integer \(p\) that splits completely in this cyclotomic field (and does not ramify).

EXAMPLES:

sage: K.<z> = CyclotomicField(3)
sage: K.next_split_prime(7)
13
>>> from sage.all import *
>>> K = CyclotomicField(Integer(3), names=('z',)); (z,) = K._first_ngens(1)
>>> K.next_split_prime(Integer(7))
13
number_of_roots_of_unity()[source]

Return number of roots of unity in this cyclotomic field.

EXAMPLES:

sage: K.<a> = CyclotomicField(21)
sage: K.number_of_roots_of_unity()
42
>>> from sage.all import *
>>> K = CyclotomicField(Integer(21), names=('a',)); (a,) = K._first_ngens(1)
>>> K.number_of_roots_of_unity()
42
real_embeddings(prec=53)[source]

Return all embeddings of this cyclotomic field into the approximate real field with precision prec.

Mostly, of course, there are no such embeddings.

EXAMPLES:

sage: len(CyclotomicField(4).real_embeddings())
0
sage: CyclotomicField(2).real_embeddings()
[
Ring morphism:
  From: Cyclotomic Field of order 2 and degree 1
  To:   Real Field with 53 bits of precision
  Defn: -1 |--> -1.00000000000000
]
>>> from sage.all import *
>>> len(CyclotomicField(Integer(4)).real_embeddings())
0
>>> CyclotomicField(Integer(2)).real_embeddings()
[
Ring morphism:
  From: Cyclotomic Field of order 2 and degree 1
  To:   Real Field with 53 bits of precision
  Defn: -1 |--> -1.00000000000000
]
roots_of_unity()[source]

Return all the roots of unity in this cyclotomic field, primitive or not.

EXAMPLES:

sage: K.<a> = CyclotomicField(3)
sage: zs = K.roots_of_unity(); zs
[1, a, -a - 1, -1, -a, a + 1]
sage: [z**K.number_of_roots_of_unity() for z in zs]
[1, 1, 1, 1, 1, 1]
>>> from sage.all import *
>>> K = CyclotomicField(Integer(3), names=('a',)); (a,) = K._first_ngens(1)
>>> zs = K.roots_of_unity(); zs
[1, a, -a - 1, -1, -a, a + 1]
>>> [z**K.number_of_roots_of_unity() for z in zs]
[1, 1, 1, 1, 1, 1]
signature()[source]

Return \((r_1, r_2)\), where \(r_1\) and \(r_2\) are the number of real embeddings and pairs of complex embeddings of this cyclotomic field, respectively.

Trivial since, apart from \(\QQ\), cyclotomic fields are totally complex.

EXAMPLES:

sage: CyclotomicField(5).signature()
(0, 2)
sage: CyclotomicField(2).signature()
(1, 0)
>>> from sage.all import *
>>> CyclotomicField(Integer(5)).signature()
(0, 2)
>>> CyclotomicField(Integer(2)).signature()
(1, 0)
zeta(n=None, all=False)[source]

Return an element of multiplicative order \(n\) in this cyclotomic field.

If there is no such element, raise a ValueError.

INPUT:

  • n – integer (default: None, returns element of maximal order)

  • all – boolean (default: False); whether to return a list of all primitive \(n\)-th roots of unity

OUTPUT: root of unity or list

EXAMPLES:

sage: k = CyclotomicField(4)
sage: k.zeta()
zeta4
sage: k.zeta(2)
-1
sage: k.zeta().multiplicative_order()
4
>>> from sage.all import *
>>> k = CyclotomicField(Integer(4))
>>> k.zeta()
zeta4
>>> k.zeta(Integer(2))
-1
>>> k.zeta().multiplicative_order()
4

sage: k = CyclotomicField(21)
sage: k.zeta().multiplicative_order()
42
sage: k.zeta(21).multiplicative_order()
21
sage: k.zeta(7).multiplicative_order()
7
sage: k.zeta(6).multiplicative_order()
6
sage: k.zeta(84)
Traceback (most recent call last):
...
ValueError: 84 does not divide order of generator (42)
>>> from sage.all import *
>>> k = CyclotomicField(Integer(21))
>>> k.zeta().multiplicative_order()
42
>>> k.zeta(Integer(21)).multiplicative_order()
21
>>> k.zeta(Integer(7)).multiplicative_order()
7
>>> k.zeta(Integer(6)).multiplicative_order()
6
>>> k.zeta(Integer(84))
Traceback (most recent call last):
...
ValueError: 84 does not divide order of generator (42)

sage: K.<a> = CyclotomicField(7)
sage: K.zeta(all=True)
[-a^4, -a^5, a^5 + a^4 + a^3 + a^2 + a + 1, -a, -a^2, -a^3]
sage: K.zeta(14, all=True)
[-a^4, -a^5, a^5 + a^4 + a^3 + a^2 + a + 1, -a, -a^2, -a^3]
sage: K.zeta(2, all=True)
[-1]
sage: K.<a> = CyclotomicField(10)
sage: K.zeta(20, all=True)
Traceback (most recent call last):
...
ValueError: 20 does not divide order of generator (10)
>>> from sage.all import *
>>> K = CyclotomicField(Integer(7), names=('a',)); (a,) = K._first_ngens(1)
>>> K.zeta(all=True)
[-a^4, -a^5, a^5 + a^4 + a^3 + a^2 + a + 1, -a, -a^2, -a^3]
>>> K.zeta(Integer(14), all=True)
[-a^4, -a^5, a^5 + a^4 + a^3 + a^2 + a + 1, -a, -a^2, -a^3]
>>> K.zeta(Integer(2), all=True)
[-1]
>>> K = CyclotomicField(Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> K.zeta(Integer(20), all=True)
Traceback (most recent call last):
...
ValueError: 20 does not divide order of generator (10)

sage: K.<a> = CyclotomicField(5)
sage: K.zeta(4)
Traceback (most recent call last):
...
ValueError: 4 does not divide order of generator (10)
sage: v = K.zeta(5, all=True); v
[a, a^2, a^3, -a^3 - a^2 - a - 1]
sage: [b^5 for b in v]
[1, 1, 1, 1]
>>> from sage.all import *
>>> K = CyclotomicField(Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> K.zeta(Integer(4))
Traceback (most recent call last):
...
ValueError: 4 does not divide order of generator (10)
>>> v = K.zeta(Integer(5), all=True); v
[a, a^2, a^3, -a^3 - a^2 - a - 1]
>>> [b**Integer(5) for b in v]
[1, 1, 1, 1]
zeta_order()[source]

Return the order of the maximal root of unity contained in this cyclotomic field.

EXAMPLES:

sage: CyclotomicField(1).zeta_order()
2
sage: CyclotomicField(4).zeta_order()
4
sage: CyclotomicField(5).zeta_order()
10
sage: CyclotomicField(5)._n()
5
sage: CyclotomicField(389).zeta_order()
778
>>> from sage.all import *
>>> CyclotomicField(Integer(1)).zeta_order()
2
>>> CyclotomicField(Integer(4)).zeta_order()
4
>>> CyclotomicField(Integer(5)).zeta_order()
10
>>> CyclotomicField(Integer(5))._n()
5
>>> CyclotomicField(Integer(389)).zeta_order()
778
sage.rings.number_field.number_field.NumberField_cyclotomic_v1(zeta_order, name, canonical_embedding=None)[source]

Used for unpickling old pickles.

EXAMPLES:

sage: from sage.rings.number_field.number_field import NumberField_cyclotomic_v1
sage: NumberField_cyclotomic_v1(5,'a')
Cyclotomic Field of order 5 and degree 4
sage: NumberField_cyclotomic_v1(5,'a').variable_name()
'a'
>>> from sage.all import *
>>> from sage.rings.number_field.number_field import NumberField_cyclotomic_v1
>>> NumberField_cyclotomic_v1(Integer(5),'a')
Cyclotomic Field of order 5 and degree 4
>>> NumberField_cyclotomic_v1(Integer(5),'a').variable_name()
'a'
class sage.rings.number_field.number_field.NumberField_generic(polynomial, name, latex_name, check=True, embedding=None, category=None, assume_disc_small=False, maximize_at_primes=None, structure=None)[source]

Bases: WithEqualityById, NumberField

Generic class for number fields defined by an irreducible polynomial over \(\QQ\).

EXAMPLES:

sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^3 - 2); K
Number Field in a with defining polynomial x^3 - 2
sage: TestSuite(K).run()
>>> from sage.all import *
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(3) - Integer(2), names=('a',)); (a,) = K._first_ngens(1); K
Number Field in a with defining polynomial x^3 - 2
>>> TestSuite(K).run()
S_class_group(S, proof=None, names='c')[source]

Return the S-class group of this number field over its base field.

INPUT:

  • S – set of primes of the base field

  • proof – if False, assume the GRH in computing the class group. Default is True. Call number_field_proof to change this default globally.

  • names – names of the generators of this class group

OUTPUT: the S-class group of this number field

EXAMPLES:

A well known example:

sage: K.<a> = QuadraticField(-5)
sage: K.S_class_group([])
S-class group of order 2 with structure C2 of Number Field in a
 with defining polynomial x^2 + 5 with a = 2.236067977499790?*I
>>> from sage.all import *
>>> K = QuadraticField(-Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> K.S_class_group([])
S-class group of order 2 with structure C2 of Number Field in a
 with defining polynomial x^2 + 5 with a = 2.236067977499790?*I

When we include the prime \((2, a+1)\), the S-class group becomes trivial:

sage: K.S_class_group([K.ideal(2, a + 1)])
S-class group of order 1 of Number Field in a
 with defining polynomial x^2 + 5 with a = 2.236067977499790?*I
>>> from sage.all import *
>>> K.S_class_group([K.ideal(Integer(2), a + Integer(1))])
S-class group of order 1 of Number Field in a
 with defining polynomial x^2 + 5 with a = 2.236067977499790?*I
S_unit_group(proof=None, S=None)[source]

Return the \(S\)-unit group (including torsion) of this number field.

ALGORITHM: Uses PARI’s pari:bnfsunit command.

INPUT:

  • proof – boolean (default: True); flag passed to PARI

  • S – list or tuple of prime ideals, or an ideal, or a single ideal or element from which an ideal can be constructed, in which case the support is used. If None, the global unit group is constructed; otherwise, the \(S\)-unit group is constructed.

Note

The group is cached.

EXAMPLES:

sage: x = polygen(QQ)
sage: K.<a> = NumberField(x^4 - 10*x^3 + 20*5*x^2 - 15*5^2*x + 11*5^3)
sage: U = K.S_unit_group(S=a); U
S-unit group with structure C10 x Z x Z x Z of
 Number Field in a with defining polynomial x^4 - 10*x^3 + 100*x^2 - 375*x + 1375
 with S = (Fractional ideal (5, 1/275*a^3 + 4/55*a^2 - 5/11*a + 5),
           Fractional ideal (11, 1/275*a^3 + 4/55*a^2 - 5/11*a + 9))
sage: U.gens()
(u0, u1, u2, u3)
sage: U.gens_values()  # random
[-1/275*a^3 + 7/55*a^2 - 6/11*a + 4, 1/275*a^3 + 4/55*a^2 - 5/11*a + 3,
 1/275*a^3 + 4/55*a^2 - 5/11*a + 5, -14/275*a^3 + 21/55*a^2 - 29/11*a + 6]
sage: U.invariants()
(10, 0, 0, 0)
sage: [u.multiplicative_order() for u in U.gens()]
[10, +Infinity, +Infinity, +Infinity]
sage: U.primes()
(Fractional ideal (5, 1/275*a^3 + 4/55*a^2 - 5/11*a + 5),
 Fractional ideal (11, 1/275*a^3 + 4/55*a^2 - 5/11*a + 9))
>>> from sage.all import *
>>> x = polygen(QQ)
>>> K = NumberField(x**Integer(4) - Integer(10)*x**Integer(3) + Integer(20)*Integer(5)*x**Integer(2) - Integer(15)*Integer(5)**Integer(2)*x + Integer(11)*Integer(5)**Integer(3), names=('a',)); (a,) = K._first_ngens(1)
>>> U = K.S_unit_group(S=a); U
S-unit group with structure C10 x Z x Z x Z of
 Number Field in a with defining polynomial x^4 - 10*x^3 + 100*x^2 - 375*x + 1375
 with S = (Fractional ideal (5, 1/275*a^3 + 4/55*a^2 - 5/11*a + 5),
           Fractional ideal (11, 1/275*a^3 + 4/55*a^2 - 5/11*a + 9))
>>> U.gens()
(u0, u1, u2, u3)
>>> U.gens_values()  # random
[-1/275*a^3 + 7/55*a^2 - 6/11*a + 4, 1/275*a^3 + 4/55*a^2 - 5/11*a + 3,
 1/275*a^3 + 4/55*a^2 - 5/11*a + 5, -14/275*a^3 + 21/55*a^2 - 29/11*a + 6]
>>> U.invariants()
(10, 0, 0, 0)
>>> [u.multiplicative_order() for u in U.gens()]
[10, +Infinity, +Infinity, +Infinity]
>>> U.primes()
(Fractional ideal (5, 1/275*a^3 + 4/55*a^2 - 5/11*a + 5),
 Fractional ideal (11, 1/275*a^3 + 4/55*a^2 - 5/11*a + 9))

With the default value of \(S\), the S-unit group is the same as the global unit group:

sage: x = polygen(QQ)
sage: K.<a> = NumberField(x^3 + 3)
sage: U = K.unit_group(proof=False)
sage: U.is_isomorphic(K.S_unit_group(proof=False))
True
>>> from sage.all import *
>>> x = polygen(QQ)
>>> K = NumberField(x**Integer(3) + Integer(3), names=('a',)); (a,) = K._first_ngens(1)
>>> U = K.unit_group(proof=False)
>>> U.is_isomorphic(K.S_unit_group(proof=False))
True

The value of \(S\) may be specified as a list of prime ideals, or an ideal, or an element of the field:

sage: K.<a> = NumberField(x^3 + 3)
sage: U = K.S_unit_group(proof=False, S=K.ideal(6).prime_factors()); U
S-unit group with structure C2 x Z x Z x Z x Z
 of Number Field in a with defining polynomial x^3 + 3
 with S = (Fractional ideal (-a^2 + a - 1),
           Fractional ideal (a + 1),
           Fractional ideal (a))
sage: K.<a> = NumberField(x^3 + 3)
sage: U = K.S_unit_group(proof=False, S=K.ideal(6)); U
S-unit group with structure C2 x Z x Z x Z x Z
 of Number Field in a with defining polynomial x^3 + 3
 with S = (Fractional ideal (-a^2 + a - 1),
           Fractional ideal (a + 1),
           Fractional ideal (a))
sage: K.<a> = NumberField(x^3 + 3)
sage: U = K.S_unit_group(proof=False, S=6); U
S-unit group with structure C2 x Z x Z x Z x Z
 of Number Field in a with defining polynomial x^3 + 3
 with S = (Fractional ideal (-a^2 + a - 1),
           Fractional ideal (a + 1),
           Fractional ideal (a))
sage: U.primes()
(Fractional ideal (-a^2 + a - 1),
 Fractional ideal (a + 1),
 Fractional ideal (a))
sage: U.gens()
(u0, u1, u2, u3, u4)
sage: U.gens_values()
[-1, a^2 - 2, -a^2 + a - 1, a + 1, a]
>>> from sage.all import *
>>> K = NumberField(x**Integer(3) + Integer(3), names=('a',)); (a,) = K._first_ngens(1)
>>> U = K.S_unit_group(proof=False, S=K.ideal(Integer(6)).prime_factors()); U
S-unit group with structure C2 x Z x Z x Z x Z
 of Number Field in a with defining polynomial x^3 + 3
 with S = (Fractional ideal (-a^2 + a - 1),
           Fractional ideal (a + 1),
           Fractional ideal (a))
>>> K = NumberField(x**Integer(3) + Integer(3), names=('a',)); (a,) = K._first_ngens(1)
>>> U = K.S_unit_group(proof=False, S=K.ideal(Integer(6))); U
S-unit group with structure C2 x Z x Z x Z x Z
 of Number Field in a with defining polynomial x^3 + 3
 with S = (Fractional ideal (-a^2 + a - 1),
           Fractional ideal (a + 1),
           Fractional ideal (a))
>>> K = NumberField(x**Integer(3) + Integer(3), names=('a',)); (a,) = K._first_ngens(1)
>>> U = K.S_unit_group(proof=False, S=Integer(6)); U
S-unit group with structure C2 x Z x Z x Z x Z
 of Number Field in a with defining polynomial x^3 + 3
 with S = (Fractional ideal (-a^2 + a - 1),
           Fractional ideal (a + 1),
           Fractional ideal (a))
>>> U.primes()
(Fractional ideal (-a^2 + a - 1),
 Fractional ideal (a + 1),
 Fractional ideal (a))
>>> U.gens()
(u0, u1, u2, u3, u4)
>>> U.gens_values()
[-1, a^2 - 2, -a^2 + a - 1, a + 1, a]

The exp and log methods can be used to create \(S\)-units from sequences of exponents, and recover the exponents:

sage: U.gens_orders()
(2, 0, 0, 0, 0)
sage: u = U.exp((3,1,4,1,5)); u
-6*a^2 + 18*a - 54
sage: u.norm().factor()
-1 * 2^9 * 3^5
sage: U.log(u)
(1, 1, 4, 1, 5)
>>> from sage.all import *
>>> U.gens_orders()
(2, 0, 0, 0, 0)
>>> u = U.exp((Integer(3),Integer(1),Integer(4),Integer(1),Integer(5))); u
-6*a^2 + 18*a - 54
>>> u.norm().factor()
-1 * 2^9 * 3^5
>>> U.log(u)
(1, 1, 4, 1, 5)
S_unit_solutions(S=[], prec=106, include_exponents=False, include_bound=False, proof=None)[source]

Return all solutions to the \(S\)-unit equation \(x + y = 1\) over self.

INPUT:

  • S – list of finite primes in this number field

  • prec – precision used for computations in real, complex, and \(p\)-adic fields (default: 106)

  • include_exponents – whether to include the exponent vectors in the returned value (default: True)

  • include_bound – whether to return the final computed bound (default: False)

  • proof – if False, assume the GRH in computing the class group; default is True

OUTPUT:

A list \([(A_1, B_1, x_1, y_1), (A_2, B_2, x_2, y_2), \dots, (A_n, B_n, x_n, y_n)]\) of tuples such that:

  1. The first two entries are tuples \(A_i = (a_0, a_1, \dots, a_t)\) and \(B_i = (b_0, b_1, \dots, b_t)\) of exponents. These will be omitted if include_exponents is False.

  2. The last two entries are \(S\)-units \(x_i\) and \(y_i\) in self with \(x_i + y_i = 1\).

  3. If the default generators for the \(S\)-units of self are \((\rho_0, \rho_1, \dots, \rho_t)`\), then these satisfy \(x_i = \prod(\rho_i)^{(a_i)}\) and \(y_i = \prod(\rho_i)^{(b_i)}\).

If include_bound is True, will return a pair (sols, bound) where sols is as above and bound is the bound used for the entries in the exponent vectors.

EXAMPLES:

sage: # needs sage.rings.padics
sage: x = polygen(QQ, 'x')
sage: K.<xi> = NumberField(x^2 + x + 1)
sage: S = K.primes_above(3)
sage: K.S_unit_solutions(S)  # random, due to ordering
[(xi + 2, -xi - 1), (1/3*xi + 2/3, -1/3*xi + 1/3), (-xi, xi + 1), (-xi + 1, xi)]
>>> from sage.all import *
>>> # needs sage.rings.padics
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(2) + x + Integer(1), names=('xi',)); (xi,) = K._first_ngens(1)
>>> S = K.primes_above(Integer(3))
>>> K.S_unit_solutions(S)  # random, due to ordering
[(xi + 2, -xi - 1), (1/3*xi + 2/3, -1/3*xi + 1/3), (-xi, xi + 1), (-xi + 1, xi)]

You can get the exponent vectors:

sage: # needs sage.rings.padics
sage: K.S_unit_solutions(S, include_exponents=True)  # random, due to ordering
[((2, 1), (4, 0), xi + 2, -xi - 1),
 ((5, -1), (4, -1), 1/3*xi + 2/3, -1/3*xi + 1/3),
 ((5, 0), (1, 0), -xi, xi + 1),
 ((1, 1), (2, 0), -xi + 1, xi)]
>>> from sage.all import *
>>> # needs sage.rings.padics
>>> K.S_unit_solutions(S, include_exponents=True)  # random, due to ordering
[((2, 1), (4, 0), xi + 2, -xi - 1),
 ((5, -1), (4, -1), 1/3*xi + 2/3, -1/3*xi + 1/3),
 ((5, 0), (1, 0), -xi, xi + 1),
 ((1, 1), (2, 0), -xi + 1, xi)]

And the computed bound:

sage: # needs sage.rings.padics
sage: solutions, bound = K.S_unit_solutions(S, prec=100, include_bound=True)
sage: bound
7
>>> from sage.all import *
>>> # needs sage.rings.padics
>>> solutions, bound = K.S_unit_solutions(S, prec=Integer(100), include_bound=True)
>>> bound
7
S_units(S, proof=True)[source]

Return a list of generators of the S-units.

INPUT:

  • S – set of primes of the base field

  • proof – if False, assume the GRH in computing the class group

OUTPUT: list of generators of the unit group

Note

For more functionality see the function S_unit_group().

EXAMPLES:

sage: K.<a> = QuadraticField(-3)
sage: K.unit_group()
Unit group with structure C6 of Number Field in a
 with defining polynomial x^2 + 3 with a = 1.732050807568878?*I
sage: K.S_units([])  # random
[1/2*a + 1/2]
sage: K.S_units([])[0].multiplicative_order()
6
>>> from sage.all import *
>>> K = QuadraticField(-Integer(3), names=('a',)); (a,) = K._first_ngens(1)
>>> K.unit_group()
Unit group with structure C6 of Number Field in a
 with defining polynomial x^2 + 3 with a = 1.732050807568878?*I
>>> K.S_units([])  # random
[1/2*a + 1/2]
>>> K.S_units([])[Integer(0)].multiplicative_order()
6

An example in a relative extension (see Issue #8722):

sage: x = polygen(QQ, 'x')
sage: L.<a,b> = NumberField([x^2 + 1, x^2 - 5])
sage: p = L.ideal((-1/2*b - 1/2)*a + 1/2*b - 1/2)
sage: W = L.S_units([p]); [x.norm() for x in W]
[9, 1, 1]
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> L = NumberField([x**Integer(2) + Integer(1), x**Integer(2) - Integer(5)], names=('a', 'b',)); (a, b,) = L._first_ngens(2)
>>> p = L.ideal((-Integer(1)/Integer(2)*b - Integer(1)/Integer(2))*a + Integer(1)/Integer(2)*b - Integer(1)/Integer(2))
>>> W = L.S_units([p]); [x.norm() for x in W]
[9, 1, 1]

Our generators should have the correct parent (Issue #9367):

sage: _.<x> = QQ[]
sage: L.<alpha> = NumberField(x^3 + x + 1)
sage: p = L.S_units([ L.ideal(7) ])
sage: p[0].parent()
Number Field in alpha with defining polynomial x^3 + x + 1
>>> from sage.all import *
>>> _ = QQ['x']; (x,) = _._first_ngens(1)
>>> L = NumberField(x**Integer(3) + x + Integer(1), names=('alpha',)); (alpha,) = L._first_ngens(1)
>>> p = L.S_units([ L.ideal(Integer(7)) ])
>>> p[Integer(0)].parent()
Number Field in alpha with defining polynomial x^3 + x + 1
absolute_degree()[source]

Return the degree of self over \(\QQ\).

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: NumberField(x^3 + x^2 + 997*x + 1, 'a').absolute_degree()
3
sage: NumberField(x + 1, 'a').absolute_degree()
1
sage: NumberField(x^997 + 17*x + 3, 'a', check=False).absolute_degree()
997
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> NumberField(x**Integer(3) + x**Integer(2) + Integer(997)*x + Integer(1), 'a').absolute_degree()
3
>>> NumberField(x + Integer(1), 'a').absolute_degree()
1
>>> NumberField(x**Integer(997) + Integer(17)*x + Integer(3), 'a', check=False).absolute_degree()
997
absolute_field(names)[source]

Return self as an absolute number field.

INPUT:

  • names – string; name of generator of the absolute field

OUTPUT:

  • K – this number field (since it is already absolute)

Also, K.structure() returns from_K and to_K, where from_K is an isomorphism from \(K\) to self and to_K is an isomorphism from self to \(K\).

EXAMPLES:

sage: K = CyclotomicField(5)
sage: K.absolute_field('a')
Number Field in a with defining polynomial x^4 + x^3 + x^2 + x + 1
>>> from sage.all import *
>>> K = CyclotomicField(Integer(5))
>>> K.absolute_field('a')
Number Field in a with defining polynomial x^4 + x^3 + x^2 + x + 1
absolute_polynomial_ntl()[source]

Alias for polynomial_ntl(). Mostly for internal use.

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: NumberField(x^2 + (2/3)*x - 9/17,'a').absolute_polynomial_ntl()
([-27 34 51], 51)
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> NumberField(x**Integer(2) + (Integer(2)/Integer(3))*x - Integer(9)/Integer(17),'a').absolute_polynomial_ntl()
([-27 34 51], 51)
algebraic_closure()[source]

Return the algebraic closure of self (which is QQbar).

EXAMPLES:

sage: K.<i> = QuadraticField(-1)
sage: K.algebraic_closure()
Algebraic Field
sage: x = polygen(QQ, 'x')
sage: K.<a> = NumberField(x^3 - 2)
sage: K.algebraic_closure()
Algebraic Field
sage: K = CyclotomicField(23)
sage: K.algebraic_closure()
Algebraic Field
>>> from sage.all import *
>>> K = QuadraticField(-Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> K.algebraic_closure()
Algebraic Field
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(3) - Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> K.algebraic_closure()
Algebraic Field
>>> K = CyclotomicField(Integer(23))
>>> K.algebraic_closure()
Algebraic Field
change_generator(alpha, name=None, names=None)[source]

Given the number field self, construct another isomorphic number field \(K\) generated by the element alpha of self, along with isomorphisms from \(K\) to self and from self to \(K\).

EXAMPLES:

sage: x = polygen(ZZ, 'x')
sage: L.<i> = NumberField(x^2 + 1); L
Number Field in i with defining polynomial x^2 + 1
sage: K, from_K, to_K = L.change_generator(i/2 + 3)
sage: K
Number Field in i0 with defining polynomial x^2 - 6*x + 37/4 with i0 = 1/2*i + 3
sage: from_K
Ring morphism:
  From: Number Field in i0 with defining polynomial x^2 - 6*x + 37/4
        with i0 = 1/2*i + 3
  To:   Number Field in i with defining polynomial x^2 + 1
  Defn: i0 |--> 1/2*i + 3
sage: to_K
Ring morphism:
  From: Number Field in i with defining polynomial x^2 + 1
  To:   Number Field in i0 with defining polynomial x^2 - 6*x + 37/4
        with i0 = 1/2*i + 3
  Defn: i |--> 2*i0 - 6
>>> from sage.all import *
>>> x = polygen(ZZ, 'x')
>>> L = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = L._first_ngens(1); L
Number Field in i with defining polynomial x^2 + 1
>>> K, from_K, to_K = L.change_generator(i/Integer(2) + Integer(3))
>>> K
Number Field in i0 with defining polynomial x^2 - 6*x + 37/4 with i0 = 1/2*i + 3
>>> from_K
Ring morphism:
  From: Number Field in i0 with defining polynomial x^2 - 6*x + 37/4
        with i0 = 1/2*i + 3
  To:   Number Field in i with defining polynomial x^2 + 1
  Defn: i0 |--> 1/2*i + 3
>>> to_K
Ring morphism:
  From: Number Field in i with defining polynomial x^2 + 1
  To:   Number Field in i0 with defining polynomial x^2 - 6*x + 37/4
        with i0 = 1/2*i + 3
  Defn: i |--> 2*i0 - 6

We can also do

sage: K.<c>, from_K, to_K = L.change_generator(i/2 + 3); K
Number Field in c with defining polynomial x^2 - 6*x + 37/4 with c = 1/2*i + 3
>>> from sage.all import *
>>> K, from_K, to_K  = L.change_generator(i/Integer(2) + Integer(3), names=('c',)); (c,) = K._first_ngens(1); K
Number Field in c with defining polynomial x^2 - 6*x + 37/4 with c = 1/2*i + 3

We compute the image of the generator \(\sqrt{-1}\) of \(L\).

sage: to_K(i)
2*c - 6
>>> from sage.all import *
>>> to_K(i)
2*c - 6

Note that the image is indeed a square root of \(-1\).

sage: to_K(i)^2
-1
sage: from_K(to_K(i))
i
sage: to_K(from_K(c))
c
>>> from sage.all import *
>>> to_K(i)**Integer(2)
-1
>>> from_K(to_K(i))
i
>>> to_K(from_K(c))
c
characteristic()[source]

Return the characteristic of this number field, which is of course 0.

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: k.<a> = NumberField(x^99 + 2); k
Number Field in a with defining polynomial x^99 + 2
sage: k.characteristic()
0
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> k = NumberField(x**Integer(99) + Integer(2), names=('a',)); (a,) = k._first_ngens(1); k
Number Field in a with defining polynomial x^99 + 2
>>> k.characteristic()
0
class_group(proof=None, names='c')[source]

Return the class group of the ring of integers of this number field.

INPUT:

  • proof – if True (default), then compute the class group provably correctly; call number_field_proof() to change this default globally

  • names – names of the generators of this class group

OUTPUT: the class group of this number field

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<a> = NumberField(x^2 + 23)
sage: G = K.class_group(); G
Class group of order 3 with structure C3 of
 Number Field in a with defining polynomial x^2 + 23
sage: G.0
Fractional ideal class (2, 1/2*a - 1/2)
sage: G.gens()
(Fractional ideal class (2, 1/2*a - 1/2),)
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(2) + Integer(23), names=('a',)); (a,) = K._first_ngens(1)
>>> G = K.class_group(); G
Class group of order 3 with structure C3 of
 Number Field in a with defining polynomial x^2 + 23
>>> G.gen(0)
Fractional ideal class (2, 1/2*a - 1/2)
>>> G.gens()
(Fractional ideal class (2, 1/2*a - 1/2),)

sage: G.number_field()
Number Field in a with defining polynomial x^2 + 23
sage: G is K.class_group()
True
sage: G is K.class_group(proof=False)
False
sage: G.gens()
(Fractional ideal class (2, 1/2*a - 1/2),)
>>> from sage.all import *
>>> G.number_field()
Number Field in a with defining polynomial x^2 + 23
>>> G is K.class_group()
True
>>> G is K.class_group(proof=False)
False
>>> G.gens()
(Fractional ideal class (2, 1/2*a - 1/2),)

There can be multiple generators:

sage: k.<a> = NumberField(x^2 + 20072)
sage: G = k.class_group(); G
Class group of order 76 with structure C38 x C2 of
 Number Field in a with defining polynomial x^2 + 20072
sage: G.0 # random
Fractional ideal class (41, a + 10)
sage: G.0^38
Trivial principal fractional ideal class
sage: G.1 # random
Fractional ideal class (2, -1/2*a)
sage: G.1^2
Trivial principal fractional ideal class
>>> from sage.all import *
>>> k = NumberField(x**Integer(2) + Integer(20072), names=('a',)); (a,) = k._first_ngens(1)
>>> G = k.class_group(); G
Class group of order 76 with structure C38 x C2 of
 Number Field in a with defining polynomial x^2 + 20072
>>> G.gen(0) # random
Fractional ideal class (41, a + 10)
>>> G.gen(0)**Integer(38)
Trivial principal fractional ideal class
>>> G.gen(1) # random
Fractional ideal class (2, -1/2*a)
>>> G.gen(1)**Integer(2)
Trivial principal fractional ideal class

Class groups of Hecke polynomials tend to be very small:

sage: # needs sage.modular
sage: f = ModularForms(97, 2).T(2).charpoly()
sage: f.factor()
(x - 3) * (x^3 + 4*x^2 + 3*x - 1) * (x^4 - 3*x^3 - x^2 + 6*x - 1)
sage: [NumberField(g,'a').class_group().order() for g,_ in f.factor()]
[1, 1, 1]
>>> from sage.all import *
>>> # needs sage.modular
>>> f = ModularForms(Integer(97), Integer(2)).T(Integer(2)).charpoly()
>>> f.factor()
(x - 3) * (x^3 + 4*x^2 + 3*x - 1) * (x^4 - 3*x^3 - x^2 + 6*x - 1)
>>> [NumberField(g,'a').class_group().order() for g,_ in f.factor()]
[1, 1, 1]

Note

Unlike in PARI/GP, class group computations in Sage do not by default assume the Generalized Riemann Hypothesis. To do class groups computations not provably correctly you must often pass the flag proof=False to functions or call the function proof.number_field(False). It can easily take 1000s of times longer to do computations with proof=True (the default).

class_number(proof=None)[source]

Return the class number of this number field, as an integer.

INPUT:

  • proof – boolean (default: True, unless you called number_field_proof)

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: NumberField(x^2 + 23, 'a').class_number()
3
sage: NumberField(x^2 + 163, 'a').class_number()
1
sage: NumberField(x^3 + x^2 + 997*x + 1, 'a').class_number(proof=False)
1539
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> NumberField(x**Integer(2) + Integer(23), 'a').class_number()
3
>>> NumberField(x**Integer(2) + Integer(163), 'a').class_number()
1
>>> NumberField(x**Integer(3) + x**Integer(2) + Integer(997)*x + Integer(1), 'a').class_number(proof=False)
1539
completely_split_primes(B=200)[source]

Return a list of rational primes which split completely in the number field \(K\).

INPUT:

  • B – positive integer bound (default: 200)

OUTPUT: list of all primes \(p < B\) which split completely in K

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<xi> = NumberField(x^3 - 3*x + 1)
sage: K.completely_split_primes(100)
[17, 19, 37, 53, 71, 73, 89]
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(3) - Integer(3)*x + Integer(1), names=('xi',)); (xi,) = K._first_ngens(1)
>>> K.completely_split_primes(Integer(100))
[17, 19, 37, 53, 71, 73, 89]
completion(p, prec, extras={})[source]

Return the completion of self at \(p\) to the specified precision.

Only implemented at archimedean places, and then only if an embedding has been fixed.

EXAMPLES:

sage: K.<a> = QuadraticField(2)
sage: K.completion(infinity, 100)
Real Field with 100 bits of precision
sage: K.<zeta> = CyclotomicField(12)
sage: K.completion(infinity, 53, extras={'type': 'RDF'})
Complex Double Field
sage: zeta + 1.5                            # implicit test
2.36602540378444 + 0.500000000000000*I
>>> from sage.all import *
>>> K = QuadraticField(Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> K.completion(infinity, Integer(100))
Real Field with 100 bits of precision
>>> K = CyclotomicField(Integer(12), names=('zeta',)); (zeta,) = K._first_ngens(1)
>>> K.completion(infinity, Integer(53), extras={'type': 'RDF'})
Complex Double Field
>>> zeta + RealNumber('1.5')                            # implicit test
2.36602540378444 + 0.500000000000000*I
complex_conjugation()[source]

Return the complex conjugation of self.

This is only well-defined for fields contained in CM fields (i.e. for totally real fields and CM fields). Recall that a CM field is a totally imaginary quadratic extension of a totally real field. For other fields, a ValueError is raised.

EXAMPLES:

sage: QuadraticField(-1, 'I').complex_conjugation()
Ring endomorphism of
 Number Field in I with defining polynomial x^2 + 1 with I = 1*I
  Defn: I |--> -I
sage: CyclotomicField(8).complex_conjugation()
Ring endomorphism of Cyclotomic Field of order 8 and degree 4
  Defn: zeta8 |--> -zeta8^3
sage: QuadraticField(5, 'a').complex_conjugation()
Identity endomorphism of Number Field in a with defining
 polynomial x^2 - 5 with a = 2.236067977499790?
sage: x = polygen(QQ, 'x')
sage: F = NumberField(x^4 + x^3 - 3*x^2 - x + 1, 'a')
sage: F.is_totally_real()
True
sage: F.complex_conjugation()
Identity endomorphism of Number Field in a with defining
 polynomial x^4 + x^3 - 3*x^2 - x + 1
sage: F.<b> = NumberField(x^2 - 2)
sage: F.extension(x^2 + 1, 'a').complex_conjugation()
Relative number field endomorphism of Number Field in a
 with defining polynomial x^2 + 1 over its base field
  Defn: a |--> -a
        b |--> b
sage: F2.<b> = NumberField(x^2 + 2)
sage: K2.<a> = F2.extension(x^2 + 1)
sage: cc = K2.complex_conjugation()
sage: cc(a)
-a
sage: cc(b)
-b
>>> from sage.all import *
>>> QuadraticField(-Integer(1), 'I').complex_conjugation()
Ring endomorphism of
 Number Field in I with defining polynomial x^2 + 1 with I = 1*I
  Defn: I |--> -I
>>> CyclotomicField(Integer(8)).complex_conjugation()
Ring endomorphism of Cyclotomic Field of order 8 and degree 4
  Defn: zeta8 |--> -zeta8^3
>>> QuadraticField(Integer(5), 'a').complex_conjugation()
Identity endomorphism of Number Field in a with defining
 polynomial x^2 - 5 with a = 2.236067977499790?
>>> x = polygen(QQ, 'x')
>>> F = NumberField(x**Integer(4) + x**Integer(3) - Integer(3)*x**Integer(2) - x + Integer(1), 'a')
>>> F.is_totally_real()
True
>>> F.complex_conjugation()
Identity endomorphism of Number Field in a with defining
 polynomial x^4 + x^3 - 3*x^2 - x + 1
>>> F = NumberField(x**Integer(2) - Integer(2), names=('b',)); (b,) = F._first_ngens(1)
>>> F.extension(x**Integer(2) + Integer(1), 'a').complex_conjugation()
Relative number field endomorphism of Number Field in a
 with defining polynomial x^2 + 1 over its base field
  Defn: a |--> -a
        b |--> b
>>> F2 = NumberField(x**Integer(2) + Integer(2), names=('b',)); (b,) = F2._first_ngens(1)
>>> K2 = F2.extension(x**Integer(2) + Integer(1), names=('a',)); (a,) = K2._first_ngens(1)
>>> cc = K2.complex_conjugation()
>>> cc(a)
-a
>>> cc(b)
-b
complex_embeddings(prec=53)[source]

Return all homomorphisms of this number field into the approximate complex field with precision prec.

This always embeds into an MPFR based complex field. If you want embeddings into the 53-bit double precision, which is faster, use self.embeddings(CDF).

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: k.<a> = NumberField(x^5 + x + 17)
sage: v = k.complex_embeddings()
sage: ls = [phi(k.0^2) for phi in v]; ls  # random order
[2.97572074038...,
 -2.40889943716 + 1.90254105304*I,
 -2.40889943716 - 1.90254105304*I,
 0.921039066973 + 3.07553311885*I,
 0.921039066973 - 3.07553311885*I]
sage: K.<a> = NumberField(x^3 + 2)
sage: ls = K.complex_embeddings(); ls  # random order
[
Ring morphism:
  From: Number Field in a with defining polynomial x^3 + 2
  To:   Complex Double Field
  Defn: a |--> -1.25992104989...,
Ring morphism:
  From: Number Field in a with defining polynomial x^3 + 2
  To:   Complex Double Field
  Defn: a |--> 0.629960524947 - 1.09112363597*I,
Ring morphism:
  From: Number Field in a with defining polynomial x^3 + 2
  To:   Complex Double Field
  Defn: a |--> 0.629960524947 + 1.09112363597*I
]
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> k = NumberField(x**Integer(5) + x + Integer(17), names=('a',)); (a,) = k._first_ngens(1)
>>> v = k.complex_embeddings()
>>> ls = [phi(k.gen(0)**Integer(2)) for phi in v]; ls  # random order
[2.97572074038...,
 -2.40889943716 + 1.90254105304*I,
 -2.40889943716 - 1.90254105304*I,
 0.921039066973 + 3.07553311885*I,
 0.921039066973 - 3.07553311885*I]
>>> K = NumberField(x**Integer(3) + Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> ls = K.complex_embeddings(); ls  # random order
[
Ring morphism:
  From: Number Field in a with defining polynomial x^3 + 2
  To:   Complex Double Field
  Defn: a |--> -1.25992104989...,
Ring morphism:
  From: Number Field in a with defining polynomial x^3 + 2
  To:   Complex Double Field
  Defn: a |--> 0.629960524947 - 1.09112363597*I,
Ring morphism:
  From: Number Field in a with defining polynomial x^3 + 2
  To:   Complex Double Field
  Defn: a |--> 0.629960524947 + 1.09112363597*I
]
composite_fields(other, names=None, both_maps=False, preserve_embedding=True)[source]

Return the possible composite number fields formed from self and other.

INPUT:

  • other – number field

  • names – generator name for composite fields

  • both_maps – boolean (default: False)

  • preserve_embedding – boolean (default: True)

OUTPUT: list of the composite fields, possibly with maps

If both_maps is True, the list consists of quadruples (F, self_into_F, other_into_F, k) such that self_into_F is an embedding of self in F, other_into_F is an embedding of in F, and k is one of the following:

  • an integer such that F.gen() equals other_into_F(other.gen()) + k*self_into_F(self.gen());

  • Infinity, in which case F.gen() equals self_into_F(self.gen());

  • None (when other is a relative number field).

If both self and other have embeddings into an ambient field, then each F will have an embedding with respect to which both self_into_F and other_into_F will be compatible with the ambient embeddings.

If preserve_embedding is True and if self and other both have embeddings into the same ambient field, or into fields which are contained in a common field, only the compositum respecting both embeddings is returned. In all other cases, all possible composite number fields are returned.

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: K.<a> = NumberField(x^4 - 2)
sage: K.composite_fields(K)
[Number Field in a with defining polynomial x^4 - 2,
 Number Field in a0 with defining polynomial x^8 + 28*x^4 + 2500]
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(4) - Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> K.composite_fields(K)
[Number Field in a with defining polynomial x^4 - 2,
 Number Field in a0 with defining polynomial x^8 + 28*x^4 + 2500]

A particular compositum is selected, together with compatible maps into the compositum, if the fields are endowed with a real or complex embedding:

sage: # needs sage.symbolic
sage: K1 = NumberField(x^4 - 2, 'a', embedding=RR(2^(1/4)))
sage: K2 = NumberField(x^4 - 2, 'a', embedding=RR(-2^(1/4)))
sage: K1.composite_fields(K2)
[Number Field in a with defining polynomial x^4 - 2 with a = 1.189207115002722?]
sage: [F, f, g, k], = K1.composite_fields(K2, both_maps=True); F
Number Field in a with defining polynomial x^4 - 2 with a = 1.189207115002722?
sage: f(K1.0), g(K2.0)
(a, -a)
>>> from sage.all import *
>>> # needs sage.symbolic
>>> K1 = NumberField(x**Integer(4) - Integer(2), 'a', embedding=RR(Integer(2)**(Integer(1)/Integer(4))))
>>> K2 = NumberField(x**Integer(4) - Integer(2), 'a', embedding=RR(-Integer(2)**(Integer(1)/Integer(4))))
>>> K1.composite_fields(K2)
[Number Field in a with defining polynomial x^4 - 2 with a = 1.189207115002722?]
>>> [F, f, g, k], = K1.composite_fields(K2, both_maps=True); F
Number Field in a with defining polynomial x^4 - 2 with a = 1.189207115002722?
>>> f(K1.gen(0)), g(K2.gen(0))
(a, -a)

With preserve_embedding set to False, the embeddings are ignored:

sage: K1.composite_fields(K2, preserve_embedding=False)                     # needs sage.symbolic
[Number Field in a with defining polynomial x^4 - 2 with a = 1.189207115002722?,
 Number Field in a0 with defining polynomial x^8 + 28*x^4 + 2500]
>>> from sage.all import *
>>> K1.composite_fields(K2, preserve_embedding=False)                     # needs sage.symbolic
[Number Field in a with defining polynomial x^4 - 2 with a = 1.189207115002722?,
 Number Field in a0 with defining polynomial x^8 + 28*x^4 + 2500]

Changing the embedding selects a different compositum:

sage: K3 = NumberField(x^4 - 2, 'a', embedding=CC(2^(1/4)*I))               # needs sage.symbolic
sage: [F, f, g, k], = K1.composite_fields(K3, both_maps=True); F            # needs sage.symbolic
Number Field in a0 with defining polynomial x^8 + 28*x^4 + 2500
 with a0 = -2.378414230005443? + 1.189207115002722?*I
sage: f(K1.0), g(K3.0)                                                      # needs sage.symbolic
(1/240*a0^5 - 41/120*a0, 1/120*a0^5 + 19/60*a0)
>>> from sage.all import *
>>> K3 = NumberField(x**Integer(4) - Integer(2), 'a', embedding=CC(Integer(2)**(Integer(1)/Integer(4))*I))               # needs sage.symbolic
>>> [F, f, g, k], = K1.composite_fields(K3, both_maps=True); F            # needs sage.symbolic
Number Field in a0 with defining polynomial x^8 + 28*x^4 + 2500
 with a0 = -2.378414230005443? + 1.189207115002722?*I
>>> f(K1.gen(0)), g(K3.gen(0))                                                      # needs sage.symbolic
(1/240*a0^5 - 41/120*a0, 1/120*a0^5 + 19/60*a0)

If no embeddings are specified, the maps into the compositum are chosen arbitrarily:

sage: Q1.<a> = NumberField(x^4 + 10*x^2 + 1)
sage: Q2.<b> = NumberField(x^4 + 16*x^2 + 4)
sage: Q1.composite_fields(Q2, 'c')
[Number Field in c with defining polynomial
  x^8 + 64*x^6 + 904*x^4 + 3840*x^2 + 3600]
sage: F, Q1_into_F, Q2_into_F, k = Q1.composite_fields(Q2, 'c',
....:                                                  both_maps=True)[0]
sage: Q1_into_F
Ring morphism:
  From: Number Field in a with defining polynomial x^4 + 10*x^2 + 1
  To:   Number Field in c with defining polynomial
        x^8 + 64*x^6 + 904*x^4 + 3840*x^2 + 3600
  Defn: a |--> 19/14400*c^7 + 137/1800*c^5 + 2599/3600*c^3 + 8/15*c
>>> from sage.all import *
>>> Q1 = NumberField(x**Integer(4) + Integer(10)*x**Integer(2) + Integer(1), names=('a',)); (a,) = Q1._first_ngens(1)
>>> Q2 = NumberField(x**Integer(4) + Integer(16)*x**Integer(2) + Integer(4), names=('b',)); (b,) = Q2._first_ngens(1)
>>> Q1.composite_fields(Q2, 'c')
[Number Field in c with defining polynomial
  x^8 + 64*x^6 + 904*x^4 + 3840*x^2 + 3600]
>>> F, Q1_into_F, Q2_into_F, k = Q1.composite_fields(Q2, 'c',
...                                                  both_maps=True)[Integer(0)]
>>> Q1_into_F
Ring morphism:
  From: Number Field in a with defining polynomial x^4 + 10*x^2 + 1
  To:   Number Field in c with defining polynomial
        x^8 + 64*x^6 + 904*x^4 + 3840*x^2 + 3600
  Defn: a |--> 19/14400*c^7 + 137/1800*c^5 + 2599/3600*c^3 + 8/15*c

This is just one of four embeddings of Q1 into F:

sage: Hom(Q1, F).order()
4
>>> from sage.all import *
>>> Hom(Q1, F).order()
4

Note that even with preserve_embedding=True, this method may fail to recognize that the two number fields have compatible embeddings, and hence return several composite number fields:

sage: x = polygen(ZZ)
sage: A.<a> = NumberField(x^3 - 7, embedding=CC(-0.95+1.65*I))
sage: r = QQbar.polynomial_root(x^9 - 7, RIF(1.2, 1.3))
sage: B.<a> = NumberField(x^9 - 7, embedding=r)
sage: len(A.composite_fields(B, preserve_embedding=True))
2
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> A = NumberField(x**Integer(3) - Integer(7), embedding=CC(-RealNumber('0.95')+RealNumber('1.65')*I), names=('a',)); (a,) = A._first_ngens(1)
>>> r = QQbar.polynomial_root(x**Integer(9) - Integer(7), RIF(RealNumber('1.2'), RealNumber('1.3')))
>>> B = NumberField(x**Integer(9) - Integer(7), embedding=r, names=('a',)); (a,) = B._first_ngens(1)
>>> len(A.composite_fields(B, preserve_embedding=True))
2
conductor(check_abelian=True)[source]

Compute the conductor of the abelian field \(K\). If check_abelian is set to False and the field is not an abelian extension of \(\QQ\), the output is not meaningful.

INPUT:

  • check_abelian – boolean (default: True); check to see that this is an abelian extension of \(\QQ\)

OUTPUT: integer which is the conductor of the field

EXAMPLES:

sage: # needs sage.groups
sage: K = CyclotomicField(27)
sage: k = K.subfields(9)[0][0]
sage: k.conductor()
27
sage: x = polygen(QQ, 'x')
sage: K.<t> = NumberField(x^3 + x^2 - 2*x - 1)
sage: K.conductor()
7
sage: K.<t> = NumberField(x^3 + x^2 - 36*x - 4)
sage: K.conductor()
109
sage: K = CyclotomicField(48)
sage: k = K.subfields(16)[0][0]
sage: k.conductor()
48
sage: NumberField(x,'a').conductor()
1
sage: NumberField(x^8 - 8*x^6 + 19*x^4 - 12*x^2 + 1, 'a').conductor()
40
sage: NumberField(x^8 + 7*x^4 + 1, 'a').conductor()
40
sage: NumberField(x^8 - 40*x^6 + 500*x^4 - 2000*x^2 + 50, 'a').conductor()
160
>>> from sage.all import *
>>> # needs sage.groups
>>> K = CyclotomicField(Integer(27))
>>> k = K.subfields(Integer(9))[Integer(0)][Integer(0)]
>>> k.conductor()
27
>>> x = polygen(QQ, 'x')
>>> K = NumberField(x**Integer(3) + x**Integer(2) - Integer(2)*x - Integer(1), names=('t',)); (t,) = K._first_ngens(1)
>>> K.conductor()
7
>>> K = NumberField(x**Integer(3) + x**Integer(2) - Integer(36)*x - Integer(4), names=('t',)); (t,) = K._first_ngens(1)
>>> K.conductor()
109
>>> K = CyclotomicField(Integer(48))
>>> k = K.subfields(Integer(16))[Integer(0)][Integer(0)]
>>> k.conductor()
48
>>> NumberField(x,'a').conductor()
1
>>> NumberField(x**Integer(8) - Integer(8)*x**Integer(6) + Integer(19)*x**Integer(4) - Integer(12)*x**Integer(2) + Integer(1), 'a').conductor()
40
>>> NumberField(x**Integer(8) + Integer(7)*x**Integer(4) + Integer(1), 'a').conductor()
40
>>> NumberField(x**Integer(8) - Integer(40)*x**Integer(6) + Integer(500)*x**Integer(4) - Integer(2000)*x**Integer(2) + Integer(50), 'a').conductor()
160

ALGORITHM:

For odd primes, it is easy to compute from the ramification index because the \(p\)-Sylow subgroup is cyclic. For \(p=2\), there are two choices for a given ramification index. They can be distinguished by the parity of the exponent in the discriminant of a 2-adic completion.

construction()[source]

Construction of self.

EXAMPLES:

sage: x = polygen(ZZ, 'x')
sage: K.<a> = NumberField(x^3 + x^2 + 1, embedding=CC.gen())
sage: F, R = K.construction()
sage: F
AlgebraicExtensionFunctor
sage: R
Rational Field
>>> from sage.all import *
>>> x = polygen(ZZ, 'x')
>>> K = NumberField(x**Integer(3) + x**Integer(2) + Integer(1), embedding=CC.gen(), names=('a',)); (a,) = K._first_ngens(1)
>>> F, R = K.construction()
>>> F
AlgebraicExtensionFunctor
>>> R
Rational Field

The construction functor respects distinguished embeddings:

sage: F(R) is K
True
sage: F.embeddings
[0.2327856159383841? + 0.7925519925154479?*I]
>>> from sage.all import *
>>> F(R) is K
True
>>> F.embeddings
[0.2327856159383841? + 0.7925519925154479?*I]
decomposition_type(p)[source]

Return how the given prime of the base field splits in this number field.

INPUT:

  • p – a prime element or ideal of the base field

OUTPUT:

A list of triples \((e, f, g)\) where

  • \(e\) is the ramification index,

  • \(f\) is the residue class degree,

  • \(g\) is the number of primes above \(p\) with given \(e\) and \(f\)

EXAMPLES:

sage: R.<x> = ZZ[]
sage: K.<a> = NumberField(x^20 + 3*x^18 + 15*x^16 + 28*x^14 + 237*x^12 + 579*x^10
....:                      + 1114*x^8 + 1470*x^6 + 2304*x^4 + 1296*x^2 + 729)
sage: K.is_galois()                                                         # needs sage.groups
True
sage: K.discriminant().factor()
2^20 * 3^10 * 53^10
sage: K.decomposition_type(2)
[(2, 5, 2)]
sage: K.decomposition_type(3)
[(2, 1, 10)]
sage: K.decomposition_type(53)
[(2, 2, 5)]
>>> from sage.all import *
>>> R = ZZ['x']; (x,) = R._first_ngens(1)
>>> K = NumberField(x**Integer(20) + Integer(3)*x**Integer(18) + Integer(15)*x**Integer(16) + Integer(28)*x**Integer(14) + Integer(237)*x**Integer(12) + Integer(579)*x**Integer(10)
...                      + Integer(1114)*x**Integer(8) + Integer(1470)*x**Integer(6) + Integer(2304)*x**Integer(4) + Integer(1296)*x**Integer(2) + Integer(729), names=('a',)); (a,) = K._first_ngens(1)
>>> K.is_galois()                                                         # needs sage.groups
True
>>> K.discriminant().factor()
2^20 * 3^10 * 53^10
>>> K.decomposition_type(Integer(2))
[(2, 5, 2)]
>>> K.decomposition_type(Integer(3))
[(2, 1, 10)]
>>> K.decomposition_type(Integer(53))
[(2, 2, 5)]

This example is only ramified at 11:

sage: K.<a> = NumberField(x^24 + 11^2*(90*x^12 - 640*x^8 + 2280*x^6
....:                                   - 512*x^4 + 2432/11*x^2 - 11))
sage: K.discriminant().factor()
-1 * 11^43
sage: K.decomposition_type(11)
[(1, 1, 2), (22, 1, 1)]
>>> from sage.all import *
>>> K = NumberField(x**Integer(24) + Integer(11)**Integer(2)*(Integer(90)*x**Integer(12) - Integer(640)*x**Integer(8) + Integer(2280)*x**Integer(6)
...                                   - Integer(512)*x**Integer(4) + Integer(2432)/Integer(11)*x**Integer(2) - Integer(11)), names=('a',)); (a,) = K._first_ngens(1)
>>> K.discriminant().factor()
-1 * 11^43
>>> K.decomposition_type(Integer(11))
[(1, 1, 2), (22, 1, 1)]

Computing the decomposition type is feasible even in large degree:

sage: K.<a> = NumberField(x^144 + 123*x^72 + 321*x^36 + 13*x^18 + 11)
sage: K.discriminant().factor(limit=100000)
2^144 * 3^288 * 7^18 * 11^17 * 31^18 * 157^18 * 2153^18 * 13907^18 * ...
sage: K.decomposition_type(2)
[(2, 4, 3), (2, 12, 2), (2, 36, 1)]
sage: K.decomposition_type(3)
[(9, 3, 2), (9, 10, 1)]
sage: K.decomposition_type(7)
[(1, 18, 1), (1, 90, 1), (2, 1, 6), (2, 3, 4)]
>>> from sage.all import *
>>> K = NumberField(x**Integer(144) + Integer(123)*x**Integer(72) + Integer(321)*x**Integer(36) + Integer(13)*x**Integer(18) + Integer(11), names=('a',)); (a,) = K._first_ngens(1)
>>> K.discriminant().factor(limit=Integer(100000))
2^144 * 3^288 * 7^18 * 11^17 * 31^18 * 157^18 * 2153^18 * 13907^18 * ...
>>> K.decomposition_type(Integer(2))
[(2, 4, 3), (2, 12, 2), (2, 36, 1)]
>>> K.decomposition_type(Integer(3))
[(9, 3, 2), (9, 10, 1)]
>>> K.decomposition_type(Integer(7))
[(1, 18, 1), (1, 90, 1), (2, 1, 6), (2, 3, 4)]

It also works for relative extensions:

sage: K.<a> = QuadraticField(-143)
sage: M.<c> = K.extension(x^10 - 6*x^8 + (a + 12)*x^6 + (-7/2*a - 89/2)*x^4
....:                      + (13/2*a - 77/2)*x^2 + 25)
>>> from sage.all import *
>>> K = QuadraticField(-Integer(143), names=('a',)); (a,) = K._first_ngens(1)
>>> M = K.extension(x**Integer(10) - Integer(6)*x**Integer(8) + (a + Integer(12))*x**Integer(6) + (-Integer(7)/Integer(2)*a - Integer(89)/Integer(2))*x**Integer(4)
...                      + (Integer(13)/Integer(2)*a - Integer(77)/Integer(2))*x**Integer(2) + Integer(25), names=('c',)); (c,) = M._first_ngens(1)

There is a unique prime above \(11\) and above \(13\) in \(K\), each of which is unramified in \(M\):

sage: M.decomposition_type(11)
[(1, 2, 5)]
sage: P11 = K.primes_above(11)[0]
sage: len(M.primes_above(P11))
5
sage: M.decomposition_type(13)
[(1, 1, 10)]
sage: P13 = K.primes_above(13)[0]
sage: len(M.primes_above(P13))
10
>>> from sage.all import *
>>> M.decomposition_type(Integer(11))
[(1, 2, 5)]
>>> P11 = K.primes_above(Integer(11))[Integer(0)]
>>> len(M.primes_above(P11))
5
>>> M.decomposition_type(Integer(13))
[(1, 1, 10)]
>>> P13 = K.primes_above(Integer(13))[Integer(0)]
>>> len(M.primes_above(P13))
10

There are two primes above \(2\), each of which ramifies in \(M\):

sage: Q0, Q1 = K.primes_above(2)
sage: M.decomposition_type(Q0)
[(2, 5, 1)]
sage: q0, = M.primes_above(Q0)
sage: q0.residue_class_degree()
5
sage: q0.relative_ramification_index()
2
sage: M.decomposition_type(Q1)
[(2, 5, 1)]
>>> from sage.all import *
>>> Q0, Q1 = K.primes_above(Integer(2))
>>> M.decomposition_type(Q0)
[(2, 5, 1)]
>>> q0, = M.primes_above(Q0)
>>> q0.residue_class_degree()
5
>>> q0.relative_ramification_index()
2
>>> M.decomposition_type(Q1)
[(2, 5, 1)]

Check that Issue #34514 is fixed:

sage: K.<a> = NumberField(x^4 + 18*x^2 - 1)
sage: R.<y> = K[]
sage: L.<b> = K.extension(y^2 + 9*a^3 - 2*a^2 + 162*a - 38)
sage: [L.decomposition_type(i) for i in K.primes_above(3)]
[[(1, 1, 2)], [(1, 1, 2)], [(1, 2, 1)]]
>>> from sage.all import *
>>> K = NumberField(x**Integer(4) + Integer(18)*x**Integer(2) - Integer(1), names=('a',)); (a,) = K._first_ngens(1)
>>> R = K['y']; (y,) = R._first_ngens(1)
>>> L = K.extension(y**Integer(2) + Integer(9)*a**Integer(3) - Integer(2)*a**Integer(2) + Integer(162)*a - Integer(38), names=('b',)); (b,) = L._first_ngens(1)
>>> [L.decomposition_type(i) for i in K.primes_above(Integer(3))]
[[(1, 1, 2)], [(1, 1, 2)], [(1, 2, 1)]]
defining_polynomial()[source]

Return the defining polynomial of this number field.

This is exactly the same as polynomial().

EXAMPLES:

sage: k5.<z> = CyclotomicField(5)
sage: k5.defining_polynomial()
x^4 + x^3 + x^2 + x + 1
sage: y = polygen(QQ, 'y')
sage: k.<a> = NumberField(y^9 - 3*y + 5); k
Number Field in a with defining polynomial y^9 - 3*y + 5
sage: k.defining_polynomial()
y^9 - 3*y + 5
>>> from sage.all import *
>>> k5 = CyclotomicField(Integer(5), names=('z',)); (z,) = k5._first_ngens(1)
>>> k5.defining_polynomial()
x^4 + x^3 + x^2 + x + 1
>>> y = polygen(QQ, 'y')
>>> k = NumberField(y**Integer(9) - Integer(3)*y + Integer(5), names=('a',)); (a,) = k._first_ngens(1); k
Number Field in a with defining polynomial y^9 - 3*y + 5
>>> k.defining_polynomial()
y^9 - 3*y + 5
degree()[source]

Return the degree of this number field.

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: NumberField(x^3 + x^2 + 997*x + 1, 'a').degree()
3
sage: NumberField(x + 1, 'a').degree()
1
sage: NumberField(x^997 + 17*x + 3, 'a', check=False).degree()
997
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> NumberField(x**Integer(3) + x**Integer(2) + Integer(997)*x + Integer(1), 'a').degree()
3
>>> NumberField(x + Integer(1), 'a').degree()
1
>>> NumberField(x**Integer(997) + Integer(17)*x + Integer(3), 'a', check=False).degree()
997
different()[source]

Compute the different fractional ideal of this number field.

The codifferent is the fractional ideal of all \(x\) in \(K\) such that the trace of \(xy\) is an integer for all \(y \in O_K\).

The different is the integral ideal which is the inverse of the codifferent.

See Wikipedia article Different_ideal

EXAMPLES:

sage: x = polygen(QQ, 'x')
sage: k.<a> = NumberField(x^2 + 23)
sage: d = k.different()
sage: d
Fractional ideal (-a)
sage: d.norm()
23
sage: k.disc()
-23
>>> from sage.all import *
>>> x = polygen(QQ, 'x')
>>> k = NumberField(x**Integer(2) + Integer(23), names=('a',)); (a,) = k._first_ngens(1)
>>> d = k.different()
>>> d
Fractional ideal (-a)
>>> d.norm()
23
>>> k.disc()
-23

The different is cached:

sage: d is k.different()
True
>>> from sage.all import *
>>> d is k.different()
True

Another example:

sage: k.<b> = NumberField(x^2 - 123)
sage: d = k.different(); d
Fractional ideal (2*b)
sage: d.norm()
492
sage: k.disc()
492
>>> from sage.all import *
>>> k = NumberField(x**Integer(2) - Integer(123), names=('b',)); (b,) = k._first_ngens(1)
>>> d = k.different(); d
Fractional ideal (2*b)
>>> d.norm()
492
>>> k.disc()
492
dirichlet_group()[source]

Given a abelian field \(K\), compute and return the set of all Dirichlet characters corresponding to the characters of the Galois group of \(K/\QQ\).

The output is random if the field is not abelian.

OUTPUT: list of Dirichlet characters

EXAMPLES:

sage: # needs sage.groups sage.modular
sage: x = polygen(QQ, 'x')
sage: K.<t> = NumberField(x^3 + x^2 - 36*x - 4)
sage: K.conductor()
109
sage: K.dirichlet_group()  # optional - gap_package_polycyclic
[Dirichlet character modulo 109 of conductor 1 mapping 6 |--> 1,
 Dirichlet character modulo 109 of conductor 109 mapping 6 |--> zeta3,
 Dirichlet character modulo 109 of conductor 109 mapping 6 |--> -zeta3 - 1]

sage: # needs sage.modular
sage: K = CyclotomicField(44)
sage: L = K.subfields(5)[0][0]
sage: X = L.dirichlet_group(); X  # optional - gap_package_polycyclic
[Dirichlet character modulo 11 of conductor 1 mapping 2 |--> 1,
 Dirichlet character modulo 11 of conductor 11 mapping 2 |--> zeta5,
 Dirichlet character modulo 11 of conductor 11 mapping 2 |--> zeta5^2,
 Dirichlet character modulo 11 of conductor 11 mapping 2 |--> zeta5^3,
 Dirichlet character modulo 11 of conductor 11
   mapping 2 |--> -zeta5^3 - zeta5^2 - zeta5 - 1]
sage: X[4]^2  # optional - gap_package_polycyclic
Dirichlet character modulo 11 of conductor 11 mapping 2 |--> zeta5^3
sage: X