Ideals of number fields

AUTHORS:

  • Steven Sivek (2005-05-16): initial version

  • William Stein (2007-09-06): vastly improved the doctesting

  • William Stein and John Cremona (2007-01-28): new class NumberFieldFractionalIdeal now used for all except the 0 ideal

  • Radoslav Kirov and Alyson Deines (2010-06-22): prime_to_S_part, is_S_unit, is_S_integral

class sage.rings.number_field.number_field_ideal.LiftMap(OK, M_OK_map, Q, I)[source]

Bases: object

Class to hold data needed by lifting maps from residue fields to number field orders.

class sage.rings.number_field.number_field_ideal.NumberFieldFractionalIdeal(field, gens, coerce=True)[source]

Bases: MultiplicativeGroupElement, NumberFieldIdeal, Ideal_fractional

A fractional ideal in a number field.

EXAMPLES:

sage: x = polygen(ZZ)
sage: R.<x> = PolynomialRing(QQ)
sage: K.<a> = NumberField(x^3 - 2)
sage: I = K.ideal(2/(5+a))
sage: J = I^2
sage: Jinv = I^(-2)
sage: J*Jinv
Fractional ideal (1)
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> K = NumberField(x**Integer(3) - Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.ideal(Integer(2)/(Integer(5)+a))
>>> J = I**Integer(2)
>>> Jinv = I**(-Integer(2))
>>> J*Jinv
Fractional ideal (1)
x = polygen(ZZ)
R.<x> = PolynomialRing(QQ)
K.<a> = NumberField(x^3 - 2)
I = K.ideal(2/(5+a))
J = I^2
Jinv = I^(-2)
J*Jinv
denominator()[source]

Return the denominator ideal of this fractional ideal. Each fractional ideal has a unique expression as \(N/D\) where \(N\), \(D\) are coprime integral ideals; the denominator is \(D\).

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<i> = NumberField(x^2 + 1)
sage: I = K.ideal((3+4*i)/5); I
Fractional ideal (4/5*i + 3/5)
sage: I.denominator()
Fractional ideal (2*i + 1)
sage: I.numerator()
Fractional ideal (-i - 2)
sage: I.numerator().is_integral() and I.denominator().is_integral()
True
sage: I.numerator() + I.denominator() == K.unit_ideal()
True
sage: I.numerator()/I.denominator() == I
True
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> I = K.ideal((Integer(3)+Integer(4)*i)/Integer(5)); I
Fractional ideal (4/5*i + 3/5)
>>> I.denominator()
Fractional ideal (2*i + 1)
>>> I.numerator()
Fractional ideal (-i - 2)
>>> I.numerator().is_integral() and I.denominator().is_integral()
True
>>> I.numerator() + I.denominator() == K.unit_ideal()
True
>>> I.numerator()/I.denominator() == I
True
x = polygen(ZZ)
K.<i> = NumberField(x^2 + 1)
I = K.ideal((3+4*i)/5); I
I.denominator()
I.numerator()
I.numerator().is_integral() and I.denominator().is_integral()
I.numerator() + I.denominator() == K.unit_ideal()
I.numerator()/I.denominator() == I
divides(other)[source]

Return True if this ideal divides other and False otherwise.

EXAMPLES:

sage: K.<a> = CyclotomicField(11); K
Cyclotomic Field of order 11 and degree 10
sage: I = K.factor(31)[0][0]; I
Fractional ideal (31, a^5 + 10*a^4 - a^3 + a^2 + 9*a - 1)
sage: I.divides(I)
True
sage: I.divides(31)
True
sage: I.divides(29)
False
>>> from sage.all import *
>>> K = CyclotomicField(Integer(11), names=('a',)); (a,) = K._first_ngens(1); K
Cyclotomic Field of order 11 and degree 10
>>> I = K.factor(Integer(31))[Integer(0)][Integer(0)]; I
Fractional ideal (31, a^5 + 10*a^4 - a^3 + a^2 + 9*a - 1)
>>> I.divides(I)
True
>>> I.divides(Integer(31))
True
>>> I.divides(Integer(29))
False
K.<a> = CyclotomicField(11); K
I = K.factor(31)[0][0]; I
I.divides(I)
I.divides(31)
I.divides(29)
element_1_mod(other)[source]

Return an element \(r\) in this ideal such that \(1-r\) is in other.

An error is raised if either ideal is not integral of if they are not coprime.

INPUT:

  • other – another ideal of the same field, or generators of an ideal

OUTPUT: an element \(r\) of the ideal self such that \(1-r\) is in the ideal other

AUTHOR: Maite Aranes (modified to use PARI’s pari:idealaddtoone by Francis Clarke)

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^3 - 2)
sage: A = K.ideal(a + 1); A; A.norm()
Fractional ideal (a + 1)
3
sage: B = K.ideal(a^2 - 4*a + 2); B; B.norm()
Fractional ideal (a^2 - 4*a + 2)
68
sage: r = A.element_1_mod(B); r
-33
sage: r in A
True
sage: 1 - r in B
True
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(3) - Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> A = K.ideal(a + Integer(1)); A; A.norm()
Fractional ideal (a + 1)
3
>>> B = K.ideal(a**Integer(2) - Integer(4)*a + Integer(2)); B; B.norm()
Fractional ideal (a^2 - 4*a + 2)
68
>>> r = A.element_1_mod(B); r
-33
>>> r in A
True
>>> Integer(1) - r in B
True
x = polygen(ZZ)
K.<a> = NumberField(x^3 - 2)
A = K.ideal(a + 1); A; A.norm()
B = K.ideal(a^2 - 4*a + 2); B; B.norm()
r = A.element_1_mod(B); r
r in A
1 - r in B
euler_phi()[source]

Return the Euler \(\varphi\)-function of this integral ideal.

This is the order of the multiplicative group of the quotient modulo the ideal.

An error is raised if the ideal is not integral.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<i> = NumberField(x^2 + 1)
sage: I = K.ideal(2 + i)
sage: [r for r in I.residues() if I.is_coprime(r)]
[-2*i, -i, i, 2*i]
sage: I.euler_phi()
4
sage: J = I^3
sage: J.euler_phi()
100
sage: len([r for r in J.residues() if J.is_coprime(r)])
100
sage: J = K.ideal(3 - 2*i)
sage: I.is_coprime(J)
True
sage: I.euler_phi()*J.euler_phi() == (I*J).euler_phi()
True
sage: L.<b> = K.extension(x^2 - 7)
sage: L.ideal(3).euler_phi()
64
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> I = K.ideal(Integer(2) + i)
>>> [r for r in I.residues() if I.is_coprime(r)]
[-2*i, -i, i, 2*i]
>>> I.euler_phi()
4
>>> J = I**Integer(3)
>>> J.euler_phi()
100
>>> len([r for r in J.residues() if J.is_coprime(r)])
100
>>> J = K.ideal(Integer(3) - Integer(2)*i)
>>> I.is_coprime(J)
True
>>> I.euler_phi()*J.euler_phi() == (I*J).euler_phi()
True
>>> L = K.extension(x**Integer(2) - Integer(7), names=('b',)); (b,) = L._first_ngens(1)
>>> L.ideal(Integer(3)).euler_phi()
64
x = polygen(ZZ)
K.<i> = NumberField(x^2 + 1)
I = K.ideal(2 + i)
[r for r in I.residues() if I.is_coprime(r)]
I.euler_phi()
J = I^3
J.euler_phi()
len([r for r in J.residues() if J.is_coprime(r)])
J = K.ideal(3 - 2*i)
I.is_coprime(J)
I.euler_phi()*J.euler_phi() == (I*J).euler_phi()
L.<b> = K.extension(x^2 - 7)
L.ideal(3).euler_phi()
factor()[source]

Factorization of this ideal in terms of prime ideals.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^4 + 23); K
Number Field in a with defining polynomial x^4 + 23
sage: I = K.ideal(19); I
Fractional ideal (19)
sage: F = I.factor(); F
(Fractional ideal (19, 1/2*a^2 + a - 17/2))
 * (Fractional ideal (19, 1/2*a^2 - a - 17/2))
sage: type(F)
<class 'sage.structure.factorization.Factorization'>
sage: list(F)
[(Fractional ideal (19, 1/2*a^2 + a - 17/2), 1),
 (Fractional ideal (19, 1/2*a^2 - a - 17/2), 1)]
sage: F.prod()
Fractional ideal (19)
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(4) + Integer(23), names=('a',)); (a,) = K._first_ngens(1); K
Number Field in a with defining polynomial x^4 + 23
>>> I = K.ideal(Integer(19)); I
Fractional ideal (19)
>>> F = I.factor(); F
(Fractional ideal (19, 1/2*a^2 + a - 17/2))
 * (Fractional ideal (19, 1/2*a^2 - a - 17/2))
>>> type(F)
<class 'sage.structure.factorization.Factorization'>
>>> list(F)
[(Fractional ideal (19, 1/2*a^2 + a - 17/2), 1),
 (Fractional ideal (19, 1/2*a^2 - a - 17/2), 1)]
>>> F.prod()
Fractional ideal (19)
x = polygen(ZZ)
K.<a> = NumberField(x^4 + 23); K
I = K.ideal(19); I
F = I.factor(); F
type(F)
list(F)
F.prod()
idealcoprime(J)[source]

Return \(l\) such that l*self is coprime to \(J\).

INPUT:

  • J – another integral ideal of the same field as self, which must also be integral

OUTPUT: an element \(l\) such that l*self is coprime to the ideal \(J\)

Todo

Extend the implementation to non-integral ideals.

EXAMPLES:

sage: x = polygen(ZZ)
sage: k.<a> = NumberField(x^2 + 23)
sage: A = k.ideal(a + 1)
sage: B = k.ideal(3)
sage: A.is_coprime(B)
False
sage: lam = A.idealcoprime(B)
sage: lam  # representation depends, not tested
-1/6*a + 1/6
sage: (lam*A).is_coprime(B)
True
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> k = NumberField(x**Integer(2) + Integer(23), names=('a',)); (a,) = k._first_ngens(1)
>>> A = k.ideal(a + Integer(1))
>>> B = k.ideal(Integer(3))
>>> A.is_coprime(B)
False
>>> lam = A.idealcoprime(B)
>>> lam  # representation depends, not tested
-1/6*a + 1/6
>>> (lam*A).is_coprime(B)
True
x = polygen(ZZ)
k.<a> = NumberField(x^2 + 23)
A = k.ideal(a + 1)
B = k.ideal(3)
A.is_coprime(B)
lam = A.idealcoprime(B)
lam  # representation depends, not tested
(lam*A).is_coprime(B)

ALGORITHM: Uses Pari function pari:idealcoprime.

ideallog(x, gens=None, check=True)[source]

Return the discrete logarithm of \(x\) with respect to the generators given in the bid structure of the ideal self, or with respect to the generators gens if these are given.

INPUT:

  • x – a nonzero element of the number field of self, which must have valuation equal to 0 at all prime ideals in the support of the ideal self

  • gens – list of elements of the number field which generate \((R / I)^*\), where \(R\) is the ring of integers of the field and \(I\) is this ideal, or None. If None, use the generators calculated by idealstar().

  • check – if True, do a consistency check on the results. Ignored if gens is None.

OUTPUT:

a list of nonnegative integers \((x_i)\) such that \(x = \prod_i g_i^{x_i}\) in \((R/I)^*\), where \(x_i\) are the generators, and the list \((x_i)\) is lexicographically minimal with respect to this requirement. If the \(x_i\) generate independent cyclic factors of order \(d_i\), as is the case for the default generators calculated by idealstar(), this just means that \(0 \le x_i < d_i\).

A ValueError will be raised if the elements specified in gens do not in fact generate the unit group (even if the element \(x\) is in the subgroup they generate).

EXAMPLES:

sage: x = polygen(ZZ)
sage: k.<a> = NumberField(x^3 - 11)
sage: A = k.ideal(5)
sage: G = A.idealstar(2)
sage: l = A.ideallog(a^2 + 3)
sage: r = G(l).value()
sage: (a^2 + 3) - r in A
True
sage: A.small_residue(r) # random
a^2 - 2
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> k = NumberField(x**Integer(3) - Integer(11), names=('a',)); (a,) = k._first_ngens(1)
>>> A = k.ideal(Integer(5))
>>> G = A.idealstar(Integer(2))
>>> l = A.ideallog(a**Integer(2) + Integer(3))
>>> r = G(l).value()
>>> (a**Integer(2) + Integer(3)) - r in A
True
>>> A.small_residue(r) # random
a^2 - 2
x = polygen(ZZ)
k.<a> = NumberField(x^3 - 11)
A = k.ideal(5)
G = A.idealstar(2)
l = A.ideallog(a^2 + 3)
r = G(l).value()
(a^2 + 3) - r in A
A.small_residue(r) # random

Examples with custom generators:

sage: K.<a> = NumberField(x^2 - 7)
sage: I = K.ideal(17)
sage: I.ideallog(a + 7, [1 + a, 2])
[10, 3]
sage: I.ideallog(a + 7, [2, 1 + a])
[0, 118]

sage: L.<b> = NumberField(x^4 - x^3 - 7*x^2 + 3*x + 2)
sage: J = L.ideal(-b^3 - b^2 - 2)
sage: u = -14*b^3 + 21*b^2 + b - 1
sage: v = 4*b^2 + 2*b - 1
sage: J.ideallog(5 + 2*b, [u, v], check=True)
[4, 13]
>>> from sage.all import *
>>> K = NumberField(x**Integer(2) - Integer(7), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.ideal(Integer(17))
>>> I.ideallog(a + Integer(7), [Integer(1) + a, Integer(2)])
[10, 3]
>>> I.ideallog(a + Integer(7), [Integer(2), Integer(1) + a])
[0, 118]

>>> L = NumberField(x**Integer(4) - x**Integer(3) - Integer(7)*x**Integer(2) + Integer(3)*x + Integer(2), names=('b',)); (b,) = L._first_ngens(1)
>>> J = L.ideal(-b**Integer(3) - b**Integer(2) - Integer(2))
>>> u = -Integer(14)*b**Integer(3) + Integer(21)*b**Integer(2) + b - Integer(1)
>>> v = Integer(4)*b**Integer(2) + Integer(2)*b - Integer(1)
>>> J.ideallog(Integer(5) + Integer(2)*b, [u, v], check=True)
[4, 13]
K.<a> = NumberField(x^2 - 7)
I = K.ideal(17)
I.ideallog(a + 7, [1 + a, 2])
I.ideallog(a + 7, [2, 1 + a])
L.<b> = NumberField(x^4 - x^3 - 7*x^2 + 3*x + 2)
J = L.ideal(-b^3 - b^2 - 2)
u = -14*b^3 + 21*b^2 + b - 1
v = 4*b^2 + 2*b - 1
J.ideallog(5 + 2*b, [u, v], check=True)

A non-example:

sage: I.ideallog(a + 7, [2])
Traceback (most recent call last):
...
ValueError: Given elements do not generate unit group --
they generate a subgroup of index 36
>>> from sage.all import *
>>> I.ideallog(a + Integer(7), [Integer(2)])
Traceback (most recent call last):
...
ValueError: Given elements do not generate unit group --
they generate a subgroup of index 36
I.ideallog(a + 7, [2])

ALGORITHM: Uses PARI function pari:ideallog, and (if gens is not None) a Hermite normal form calculation to express the result in terms of the generators gens.

idealstar(flag=1)[source]

Return the finite abelian group \((O_K/I)^*\), where \(I\) is the ideal self of the number field \(K\), and \(O_K\) is the ring of integers of \(K\).

INPUT:

  • flag – integer (default: 1); when flag==2, it also computes the generators of the group \((O_K/I)^*\), which takes more time. By default flag is 1 (no generators are computed). In both cases the special PARI structure bid is computed as well. If flag is 0 (deprecated) it computes only the group structure of \((O_K/I)^*\) (with generators) and not the special bid structure.

OUTPUT:

The finite abelian group \((O_K/I)^*\).

Note

Uses the PARI function pari:idealstar. The PARI function outputs a special bid structure which is stored in the internal field _bid of the ideal (when flag = 1,2). The special structure bid is used in the PARI function pari:ideallog to compute discrete logarithms.

EXAMPLES:

sage: x = polygen(ZZ)
sage: k.<a> = NumberField(x^3 - 11)
sage: A = k.ideal(5)
sage: G = A.idealstar(); G
Multiplicative Abelian group isomorphic to C24 x C4
sage: G.gens()
(f0, f1)

sage: G = A.idealstar(2)
sage: G.gens()
(f0, f1)
sage: G.gens_values()   # random output
(2*a^2 - 1, 2*a^2 + 2*a - 2)
sage: all(G.gen(i).value() in k for i in range(G.ngens()))
True
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> k = NumberField(x**Integer(3) - Integer(11), names=('a',)); (a,) = k._first_ngens(1)
>>> A = k.ideal(Integer(5))
>>> G = A.idealstar(); G
Multiplicative Abelian group isomorphic to C24 x C4
>>> G.gens()
(f0, f1)

>>> G = A.idealstar(Integer(2))
>>> G.gens()
(f0, f1)
>>> G.gens_values()   # random output
(2*a^2 - 1, 2*a^2 + 2*a - 2)
>>> all(G.gen(i).value() in k for i in range(G.ngens()))
True
x = polygen(ZZ)
k.<a> = NumberField(x^3 - 11)
A = k.ideal(5)
G = A.idealstar(); G
G.gens()
G = A.idealstar(2)
G.gens()
G.gens_values()   # random output
all(G.gen(i).value() in k for i in range(G.ngens()))

ALGORITHM: Uses Pari function pari:idealstar

invertible_residues(reduce=True)[source]

Return an iterator through a list of invertible residues modulo this integral ideal.

An error is raised if this fractional ideal is not integral.

INPUT:

  • reduce – boolean; if True (default), use small_residue to get small representatives of the residues

OUTPUT:

An iterator through a list of invertible residues modulo this ideal \(I\), i.e. a list of elements in the ring of integers \(R\) representing the elements of \((R/I)^*\).

ALGORITHM: Use pari:idealstar to find the group structure and generators of the multiplicative group modulo the ideal.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<i> = NumberField(x^2 + 1)
sage: ires = K.ideal(2).invertible_residues(); ires
xmrange_iter([[0, 1]], <function ...<lambda> at 0x...>)
sage: list(ires)
[1, -i]
sage: list(K.ideal(2 + i).invertible_residues())
[1, 2, 4, 3]
sage: list(K.ideal(i).residues())
[0]
sage: list(K.ideal(i).invertible_residues())
[1]
sage: I = K.ideal(3 + 6*i)
sage: units = I.invertible_residues()
sage: len(list(units)) == I.euler_phi()
True

sage: K.<a> = NumberField(x^3 - 10)
sage: I = K.ideal(a - 1)
sage: len(list(I.invertible_residues())) == I.euler_phi()
True

sage: K.<z> = CyclotomicField(10)
sage: len(list(K.primes_above(3)[0].invertible_residues()))
80
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> ires = K.ideal(Integer(2)).invertible_residues(); ires
xmrange_iter([[0, 1]], <function ...<lambda> at 0x...>)
>>> list(ires)
[1, -i]
>>> list(K.ideal(Integer(2) + i).invertible_residues())
[1, 2, 4, 3]
>>> list(K.ideal(i).residues())
[0]
>>> list(K.ideal(i).invertible_residues())
[1]
>>> I = K.ideal(Integer(3) + Integer(6)*i)
>>> units = I.invertible_residues()
>>> len(list(units)) == I.euler_phi()
True

>>> K = NumberField(x**Integer(3) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.ideal(a - Integer(1))
>>> len(list(I.invertible_residues())) == I.euler_phi()
True

>>> K = CyclotomicField(Integer(10), names=('z',)); (z,) = K._first_ngens(1)
>>> len(list(K.primes_above(Integer(3))[Integer(0)].invertible_residues()))
80
x = polygen(ZZ)
K.<i> = NumberField(x^2 + 1)
ires = K.ideal(2).invertible_residues(); ires
list(ires)
list(K.ideal(2 + i).invertible_residues())
list(K.ideal(i).residues())
list(K.ideal(i).invertible_residues())
I = K.ideal(3 + 6*i)
units = I.invertible_residues()
len(list(units)) == I.euler_phi()
K.<a> = NumberField(x^3 - 10)
I = K.ideal(a - 1)
len(list(I.invertible_residues())) == I.euler_phi()
K.<z> = CyclotomicField(10)
len(list(K.primes_above(3)[0].invertible_residues()))

AUTHOR: John Cremona

invertible_residues_mod(subgp_gens=[], reduce=True)[source]

Return a iterator through a list of representatives for the invertible residues modulo this integral ideal, modulo the subgroup generated by the elements in the list subgp_gens.

INPUT:

  • subgp_gens – either None or a list of elements of the number field of self. These need not be integral, but should be coprime to the ideal self. If the list is empty or None, the function returns an iterator through a list of representatives for the invertible residues modulo the integral ideal self.

  • reduce – boolean; if True (default), use small_residues to get small representatives of the residues

Note

See also invertible_residues() for a simpler version without the subgroup.

OUTPUT:

An iterator through a list of representatives for the invertible residues modulo self and modulo the group generated by subgp_gens, i.e. a list of elements in the ring of integers \(R\) representing the elements of \((R/I)^*/U\), where \(I\) is this ideal and \(U\) is the subgroup of \((R/I)^*\) generated by subgp_gens.

EXAMPLES:

sage: x = polygen(ZZ)
sage: k.<a> = NumberField(x^2 + 23)
sage: I = k.ideal(a)
sage: list(I.invertible_residues_mod([-1]))
[1, 5, 2, 10, 4, 20, 8, 17, 16, 11, 9]
sage: list(I.invertible_residues_mod([1/2]))
[1, 5]
sage: list(I.invertible_residues_mod([23]))
Traceback (most recent call last):
...
TypeError: the element must be invertible mod the ideal
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> k = NumberField(x**Integer(2) + Integer(23), names=('a',)); (a,) = k._first_ngens(1)
>>> I = k.ideal(a)
>>> list(I.invertible_residues_mod([-Integer(1)]))
[1, 5, 2, 10, 4, 20, 8, 17, 16, 11, 9]
>>> list(I.invertible_residues_mod([Integer(1)/Integer(2)]))
[1, 5]
>>> list(I.invertible_residues_mod([Integer(23)]))
Traceback (most recent call last):
...
TypeError: the element must be invertible mod the ideal
x = polygen(ZZ)
k.<a> = NumberField(x^2 + 23)
I = k.ideal(a)
list(I.invertible_residues_mod([-1]))
list(I.invertible_residues_mod([1/2]))
list(I.invertible_residues_mod([23]))
sage: K.<a> = NumberField(x^3 - 10)
sage: I = K.ideal(a - 1)
sage: len(list(I.invertible_residues_mod([]))) == I.euler_phi()
True

sage: I = K.ideal(1)
sage: list(I.invertible_residues_mod([]))
[1]
>>> from sage.all import *
>>> K = NumberField(x**Integer(3) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.ideal(a - Integer(1))
>>> len(list(I.invertible_residues_mod([]))) == I.euler_phi()
True

>>> I = K.ideal(Integer(1))
>>> list(I.invertible_residues_mod([]))
[1]
K.<a> = NumberField(x^3 - 10)
I = K.ideal(a - 1)
len(list(I.invertible_residues_mod([]))) == I.euler_phi()
I = K.ideal(1)
list(I.invertible_residues_mod([]))
>>> from sage.all import *
>>> K = NumberField(x**Integer(3) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.ideal(a - Integer(1))
>>> len(list(I.invertible_residues_mod([]))) == I.euler_phi()
True

>>> I = K.ideal(Integer(1))
>>> list(I.invertible_residues_mod([]))
[1]
K.<a> = NumberField(x^3 - 10)
I = K.ideal(a - 1)
len(list(I.invertible_residues_mod([]))) == I.euler_phi()
I = K.ideal(1)
list(I.invertible_residues_mod([]))
sage: K.<z> = CyclotomicField(10)
sage: len(list(K.primes_above(3)[0].invertible_residues_mod([])))
80
>>> from sage.all import *
>>> K = CyclotomicField(Integer(10), names=('z',)); (z,) = K._first_ngens(1)
>>> len(list(K.primes_above(Integer(3))[Integer(0)].invertible_residues_mod([])))
80
K.<z> = CyclotomicField(10)
len(list(K.primes_above(3)[0].invertible_residues_mod([])))
>>> from sage.all import *
>>> K = CyclotomicField(Integer(10), names=('z',)); (z,) = K._first_ngens(1)
>>> len(list(K.primes_above(Integer(3))[Integer(0)].invertible_residues_mod([])))
80
K.<z> = CyclotomicField(10)
len(list(K.primes_above(3)[0].invertible_residues_mod([])))

AUTHOR: Maite Aranes.

is_S_integral(S)[source]

Return True if this fractional ideal is integral with respect to the list of primes \(S\).

INPUT:

  • S – list of prime ideals (not checked if they are indeed prime)

Note

This function assumes that \(S\) is a list of prime ideals, but does not check this. This function will fail if \(S\) is not a list of prime ideals.

OUTPUT:

True, if the ideal is \(S\)-integral: that is, if the valuations of the ideal at all primes not in \(S\) are nonnegative. False, otherwise.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^2 + 23)
sage: I = K.ideal(1/2)
sage: P = K.ideal(2, 1/2*a - 1/2)
sage: I.is_S_integral([P])
False

sage: J = K.ideal(1/5)
sage: J.is_S_integral([K.ideal(5)])
True
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(23), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.ideal(Integer(1)/Integer(2))
>>> P = K.ideal(Integer(2), Integer(1)/Integer(2)*a - Integer(1)/Integer(2))
>>> I.is_S_integral([P])
False

>>> J = K.ideal(Integer(1)/Integer(5))
>>> J.is_S_integral([K.ideal(Integer(5))])
True
x = polygen(ZZ)
K.<a> = NumberField(x^2 + 23)
I = K.ideal(1/2)
P = K.ideal(2, 1/2*a - 1/2)
I.is_S_integral([P])
J = K.ideal(1/5)
J.is_S_integral([K.ideal(5)])
is_S_unit(S)[source]

Return True if this fractional ideal is a unit with respect to the list of primes \(S\).

INPUT:

  • S – list of prime ideals (not checked if they are indeed prime)

Note

This function assumes that \(S\) is a list of prime ideals, but does not check this. This function will fail if \(S\) is not a list of prime ideals.

OUTPUT:

True, if the ideal is an \(S\)-unit: that is, if the valuations of the ideal at all primes not in \(S\) are zero. False, otherwise.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^2 + 23)
sage: I = K.ideal(2)
sage: P = I.factor()[0][0]
sage: I.is_S_unit([P])
False
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(23), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.ideal(Integer(2))
>>> P = I.factor()[Integer(0)][Integer(0)]
>>> I.is_S_unit([P])
False
x = polygen(ZZ)
K.<a> = NumberField(x^2 + 23)
I = K.ideal(2)
P = I.factor()[0][0]
I.is_S_unit([P])
is_coprime(other)[source]

Return True if this ideal is coprime to other, else False.

INPUT:

  • other – another ideal of the same field, or generators of an ideal

OUTPUT: True if self and other are coprime, else False

Note

This function works for fractional ideals as well as integral ideals.

AUTHOR: John Cremona

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<i> = NumberField(x^2 + 1)
sage: I = K.ideal(2 + i)
sage: J = K.ideal(2 - i)
sage: I.is_coprime(J)
True
sage: (I^-1).is_coprime(J^3)
True
sage: I.is_coprime(5)
False
sage: I.is_coprime(6 + i)
True
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> I = K.ideal(Integer(2) + i)
>>> J = K.ideal(Integer(2) - i)
>>> I.is_coprime(J)
True
>>> (I**-Integer(1)).is_coprime(J**Integer(3))
True
>>> I.is_coprime(Integer(5))
False
>>> I.is_coprime(Integer(6) + i)
True
x = polygen(ZZ)
K.<i> = NumberField(x^2 + 1)
I = K.ideal(2 + i)
J = K.ideal(2 - i)
I.is_coprime(J)
(I^-1).is_coprime(J^3)
I.is_coprime(5)
I.is_coprime(6 + i)

See Issue #4536:

sage: E.<a> = NumberField(x^5 + 7*x^4 + 18*x^2 + x - 3)
sage: i,j,k = [u[0] for u in factor(3*E)]
sage: (i/j).is_coprime(j/k)
False
sage: (j/k).is_coprime(j/k)
False

sage: F.<a, b> = NumberField([x^2 - 2, x^2 - 3])
sage: F.ideal(3 - a*b).is_coprime(F.ideal(3))
False
>>> from sage.all import *
>>> E = NumberField(x**Integer(5) + Integer(7)*x**Integer(4) + Integer(18)*x**Integer(2) + x - Integer(3), names=('a',)); (a,) = E._first_ngens(1)
>>> i,j,k = [u[Integer(0)] for u in factor(Integer(3)*E)]
>>> (i/j).is_coprime(j/k)
False
>>> (j/k).is_coprime(j/k)
False

>>> F = NumberField([x**Integer(2) - Integer(2), x**Integer(2) - Integer(3)], names=('a', 'b',)); (a, b,) = F._first_ngens(2)
>>> F.ideal(Integer(3) - a*b).is_coprime(F.ideal(Integer(3)))
False
E.<a> = NumberField(x^5 + 7*x^4 + 18*x^2 + x - 3)
i,j,k = [u[0] for u in factor(3*E)]
(i/j).is_coprime(j/k)
(j/k).is_coprime(j/k)
F.<a, b> = NumberField([x^2 - 2, x^2 - 3])
F.ideal(3 - a*b).is_coprime(F.ideal(3))
is_maximal()[source]

Return True if this ideal is maximal. This is equivalent to self being prime, since it is nonzero.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^3 + 3); K
Number Field in a with defining polynomial x^3 + 3
sage: K.ideal(5).is_maximal()
False
sage: K.ideal(7).is_maximal()
True
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(3) + Integer(3), names=('a',)); (a,) = K._first_ngens(1); K
Number Field in a with defining polynomial x^3 + 3
>>> K.ideal(Integer(5)).is_maximal()
False
>>> K.ideal(Integer(7)).is_maximal()
True
x = polygen(ZZ)
K.<a> = NumberField(x^3 + 3); K
K.ideal(5).is_maximal()
K.ideal(7).is_maximal()
is_trivial(proof=None)[source]

Return True if this is a trivial ideal.

EXAMPLES:

sage: F.<a> = QuadraticField(-5)
sage: I = F.ideal(3)
sage: I.is_trivial()
False
sage: J = F.ideal(5)
sage: J.is_trivial()
False
sage: (I + J).is_trivial()
True
>>> from sage.all import *
>>> F = QuadraticField(-Integer(5), names=('a',)); (a,) = F._first_ngens(1)
>>> I = F.ideal(Integer(3))
>>> I.is_trivial()
False
>>> J = F.ideal(Integer(5))
>>> J.is_trivial()
False
>>> (I + J).is_trivial()
True
F.<a> = QuadraticField(-5)
I = F.ideal(3)
I.is_trivial()
J = F.ideal(5)
J.is_trivial()
(I + J).is_trivial()
numerator()[source]

Return the numerator ideal of this fractional ideal.

Each fractional ideal has a unique expression as \(N/D\) where \(N\), \(D\) are coprime integral ideals. The numerator is \(N\).

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<i> = NumberField(x^2 + 1)
sage: I = K.ideal((3+4*i)/5); I
Fractional ideal (4/5*i + 3/5)
sage: I.denominator()
Fractional ideal (2*i + 1)
sage: I.numerator()
Fractional ideal (-i - 2)
sage: I.numerator().is_integral() and I.denominator().is_integral()
True
sage: I.numerator() + I.denominator() == K.unit_ideal()
True
sage: I.numerator()/I.denominator() == I
True
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> I = K.ideal((Integer(3)+Integer(4)*i)/Integer(5)); I
Fractional ideal (4/5*i + 3/5)
>>> I.denominator()
Fractional ideal (2*i + 1)
>>> I.numerator()
Fractional ideal (-i - 2)
>>> I.numerator().is_integral() and I.denominator().is_integral()
True
>>> I.numerator() + I.denominator() == K.unit_ideal()
True
>>> I.numerator()/I.denominator() == I
True
x = polygen(ZZ)
K.<i> = NumberField(x^2 + 1)
I = K.ideal((3+4*i)/5); I
I.denominator()
I.numerator()
I.numerator().is_integral() and I.denominator().is_integral()
I.numerator() + I.denominator() == K.unit_ideal()
I.numerator()/I.denominator() == I
prime_factors()[source]

Return a list of the prime ideal factors of self.

OUTPUT:

list of prime ideals (a new list is returned each time this function is called)

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<w> = NumberField(x^2 + 23)
sage: I = ideal(w+1)
sage: I.prime_factors()
[Fractional ideal (2, 1/2*w - 1/2),
 Fractional ideal (2, 1/2*w + 1/2),
 Fractional ideal (3, 1/2*w + 1/2)]
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(23), names=('w',)); (w,) = K._first_ngens(1)
>>> I = ideal(w+Integer(1))
>>> I.prime_factors()
[Fractional ideal (2, 1/2*w - 1/2),
 Fractional ideal (2, 1/2*w + 1/2),
 Fractional ideal (3, 1/2*w + 1/2)]
x = polygen(ZZ)
K.<w> = NumberField(x^2 + 23)
I = ideal(w+1)
I.prime_factors()
prime_to_S_part(S)[source]

Return the part of this fractional ideal which is coprime to the prime ideals in the list \(S\).

Note

This function assumes that \(S\) is a list of prime ideals, but does not check this. This function will fail if \(S\) is not a list of prime ideals.

INPUT:

  • S – list of prime ideals

OUTPUT:

A fractional ideal coprime to the primes in \(S\), whose prime factorization is that of self with the primes in \(S\) removed.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^2 - 23)
sage: I = K.ideal(24)
sage: S = [K.ideal(-a + 5), K.ideal(5)]
sage: I.prime_to_S_part(S)
Fractional ideal (3)
sage: J = K.ideal(15)
sage: J.prime_to_S_part(S)
Fractional ideal (3)

sage: K.<a> = NumberField(x^5 - 23)
sage: I = K.ideal(24)
sage: S = [K.ideal(15161*a^4 + 28383*a^3 + 53135*a^2 + 99478*a + 186250),
....:      K.ideal(2*a^4 + 3*a^3 + 4*a^2 + 15*a + 11),
....:      K.ideal(101)]
sage: I.prime_to_S_part(S)
Fractional ideal (24)
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) - Integer(23), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.ideal(Integer(24))
>>> S = [K.ideal(-a + Integer(5)), K.ideal(Integer(5))]
>>> I.prime_to_S_part(S)
Fractional ideal (3)
>>> J = K.ideal(Integer(15))
>>> J.prime_to_S_part(S)
Fractional ideal (3)

>>> K = NumberField(x**Integer(5) - Integer(23), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.ideal(Integer(24))
>>> S = [K.ideal(Integer(15161)*a**Integer(4) + Integer(28383)*a**Integer(3) + Integer(53135)*a**Integer(2) + Integer(99478)*a + Integer(186250)),
...      K.ideal(Integer(2)*a**Integer(4) + Integer(3)*a**Integer(3) + Integer(4)*a**Integer(2) + Integer(15)*a + Integer(11)),
...      K.ideal(Integer(101))]
>>> I.prime_to_S_part(S)
Fractional ideal (24)
x = polygen(ZZ)
K.<a> = NumberField(x^2 - 23)
I = K.ideal(24)
S = [K.ideal(-a + 5), K.ideal(5)]
I.prime_to_S_part(S)
J = K.ideal(15)
J.prime_to_S_part(S)
K.<a> = NumberField(x^5 - 23)
I = K.ideal(24)
S = [K.ideal(15161*a^4 + 28383*a^3 + 53135*a^2 + 99478*a + 186250),
     K.ideal(2*a^4 + 3*a^3 + 4*a^2 + 15*a + 11),
     K.ideal(101)]
I.prime_to_S_part(S)
prime_to_idealM_part(M)[source]

Version for integral ideals of the prime_to_m_part function over \(\ZZ\). Return the largest divisor of self that is coprime to the ideal \(M\).

INPUT:

  • M – an integral ideal of the same field, or generators of an ideal

OUTPUT: an ideal which is the largest divisor of self that is coprime to \(M\)

AUTHOR: Maite Aranes

EXAMPLES:

sage: x = polygen(ZZ)
sage: k.<a> = NumberField(x^2 + 23)
sage: I = k.ideal(a + 1)
sage: M = k.ideal(2, 1/2*a - 1/2)
sage: J = I.prime_to_idealM_part(M); J
Fractional ideal (12, 1/2*a + 13/2)
sage: J.is_coprime(M)
True

sage: J = I.prime_to_idealM_part(2); J
Fractional ideal (3, 1/2*a + 1/2)
sage: J.is_coprime(M)
True
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> k = NumberField(x**Integer(2) + Integer(23), names=('a',)); (a,) = k._first_ngens(1)
>>> I = k.ideal(a + Integer(1))
>>> M = k.ideal(Integer(2), Integer(1)/Integer(2)*a - Integer(1)/Integer(2))
>>> J = I.prime_to_idealM_part(M); J
Fractional ideal (12, 1/2*a + 13/2)
>>> J.is_coprime(M)
True

>>> J = I.prime_to_idealM_part(Integer(2)); J
Fractional ideal (3, 1/2*a + 1/2)
>>> J.is_coprime(M)
True
x = polygen(ZZ)
k.<a> = NumberField(x^2 + 23)
I = k.ideal(a + 1)
M = k.ideal(2, 1/2*a - 1/2)
J = I.prime_to_idealM_part(M); J
J.is_coprime(M)
J = I.prime_to_idealM_part(2); J
J.is_coprime(M)
ramification_index()[source]

Return the ramification index of this fractional ideal, assuming it is prime. Otherwise, raise a ValueError.

The ramification index is the power of this prime appearing in the factorization of the prime in \(\ZZ\) that this prime lies over.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^2 + 2); K
Number Field in a with defining polynomial x^2 + 2
sage: f = K.factor(2); f
(Fractional ideal (a))^2
sage: f[0][0].ramification_index()
2
sage: K.ideal(13).ramification_index()
1
sage: K.ideal(17).ramification_index()
Traceback (most recent call last):
...
ValueError: Fractional ideal (17) is not a prime ideal
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(2), names=('a',)); (a,) = K._first_ngens(1); K
Number Field in a with defining polynomial x^2 + 2
>>> f = K.factor(Integer(2)); f
(Fractional ideal (a))^2
>>> f[Integer(0)][Integer(0)].ramification_index()
2
>>> K.ideal(Integer(13)).ramification_index()
1
>>> K.ideal(Integer(17)).ramification_index()
Traceback (most recent call last):
...
ValueError: Fractional ideal (17) is not a prime ideal
x = polygen(ZZ)
K.<a> = NumberField(x^2 + 2); K
f = K.factor(2); f
f[0][0].ramification_index()
K.ideal(13).ramification_index()
K.ideal(17).ramification_index()
ray_class_number()[source]

Return the order of the ray class group modulo this ideal. This is a wrapper around PARI’s pari:bnrclassno function.

EXAMPLES:

sage: K.<z> = QuadraticField(-23)
sage: p = K.primes_above(3)[0]
sage: p.ray_class_number()
3

sage: x = polygen(K)
sage: L.<w> = K.extension(x^3 - z)
sage: I = L.ideal(5)
sage: I.ray_class_number()
5184
>>> from sage.all import *
>>> K = QuadraticField(-Integer(23), names=('z',)); (z,) = K._first_ngens(1)
>>> p = K.primes_above(Integer(3))[Integer(0)]
>>> p.ray_class_number()
3

>>> x = polygen(K)
>>> L = K.extension(x**Integer(3) - z, names=('w',)); (w,) = L._first_ngens(1)
>>> I = L.ideal(Integer(5))
>>> I.ray_class_number()
5184
K.<z> = QuadraticField(-23)
p = K.primes_above(3)[0]
p.ray_class_number()
x = polygen(K)
L.<w> = K.extension(x^3 - z)
I = L.ideal(5)
I.ray_class_number()
reduce(f)[source]

Return the canonical reduction of the element \(f\) modulo the ideal \(I\) (= self). This is an element of \(R\) (the ring of integers of the number field) that is equivalent modulo \(I\) to \(f\).

An error is raised if this fractional ideal is not integral or the element \(f\) is not integral.

INPUT:

  • f – an integral element of the number field

OUTPUT:

An integral element \(g\), such that \(f - g\) belongs to the ideal self and such that \(g\) is a canonical reduced representative of the coset \(f + I\) (where \(I\) = self) as described in the method residues(), namely an integral element with coordinates \((r_0, \dots,r_{n-1})\), where:

  • \(r_i\) is reduced modulo \(d_i\)

  • \(d_i = b_i[i]\), with \(\{b_0, b_1, \dots, b_n\}\) HNF basis of the ideal self.

Note

The reduced element \(g\) is not necessarily small. To get a small \(g\) use the method small_residue().

EXAMPLES:

sage: x = polygen(ZZ)
sage: k.<a> = NumberField(x^3 + 11)
sage: I = k.ideal(5, a^2 - a + 1)
sage: c = 4*a + 9
sage: I.reduce(c)
a^2 - 2*a
sage: c - I.reduce(c) in I
True
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> k = NumberField(x**Integer(3) + Integer(11), names=('a',)); (a,) = k._first_ngens(1)
>>> I = k.ideal(Integer(5), a**Integer(2) - a + Integer(1))
>>> c = Integer(4)*a + Integer(9)
>>> I.reduce(c)
a^2 - 2*a
>>> c - I.reduce(c) in I
True
x = polygen(ZZ)
k.<a> = NumberField(x^3 + 11)
I = k.ideal(5, a^2 - a + 1)
c = 4*a + 9
I.reduce(c)
c - I.reduce(c) in I

The reduced element is in the list of canonical representatives returned by the residues method:

sage: I.reduce(c) in list(I.residues())
True
>>> from sage.all import *
>>> I.reduce(c) in list(I.residues())
True
I.reduce(c) in list(I.residues())

The reduced element does not necessarily have smaller norm (use small_residue() for that)

sage: c.norm()
25
sage: (I.reduce(c)).norm()
209
sage: (I.small_residue(c)).norm()
10
>>> from sage.all import *
>>> c.norm()
25
>>> (I.reduce(c)).norm()
209
>>> (I.small_residue(c)).norm()
10
c.norm()
(I.reduce(c)).norm()
(I.small_residue(c)).norm()

Sometimes the canonical reduced representative of \(1\) won’t be \(1\) (it depends on the choice of basis for the ring of integers):

sage: k.<a> = NumberField(x^2 + 23)
sage: I = k.ideal(3)
sage: I.reduce(3*a + 1)
-3/2*a - 1/2
sage: k.ring_of_integers().basis()
[1/2*a + 1/2, a]
>>> from sage.all import *
>>> k = NumberField(x**Integer(2) + Integer(23), names=('a',)); (a,) = k._first_ngens(1)
>>> I = k.ideal(Integer(3))
>>> I.reduce(Integer(3)*a + Integer(1))
-3/2*a - 1/2
>>> k.ring_of_integers().basis()
[1/2*a + 1/2, a]
k.<a> = NumberField(x^2 + 23)
I = k.ideal(3)
I.reduce(3*a + 1)
k.ring_of_integers().basis()

AUTHOR: Maite Aranes.

residue_class_degree()[source]

Return the residue class degree of this fractional ideal, assuming it is prime. Otherwise, raise a ValueError.

The residue class degree of a prime ideal \(I\) is the degree of the extension \(O_K/I\) of its prime subfield.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^5 + 2); K
Number Field in a with defining polynomial x^5 + 2
sage: f = K.factor(19); f
(Fractional ideal (a^2 + a - 3))
 * (Fractional ideal (2*a^4 + a^2 - 2*a + 1))
 * (Fractional ideal (a^2 + a - 1))
sage: [i.residue_class_degree() for i, _ in f]
[2, 2, 1]
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(5) + Integer(2), names=('a',)); (a,) = K._first_ngens(1); K
Number Field in a with defining polynomial x^5 + 2
>>> f = K.factor(Integer(19)); f
(Fractional ideal (a^2 + a - 3))
 * (Fractional ideal (2*a^4 + a^2 - 2*a + 1))
 * (Fractional ideal (a^2 + a - 1))
>>> [i.residue_class_degree() for i, _ in f]
[2, 2, 1]
x = polygen(ZZ)
K.<a> = NumberField(x^5 + 2); K
f = K.factor(19); f
[i.residue_class_degree() for i, _ in f]
residue_field(names=None)[source]

Return the residue class field of this fractional ideal, which must be prime.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^3 - 7)
sage: P = K.ideal(29).factor()[0][0]
sage: P.residue_field()
Residue field in abar of Fractional ideal (2*a^2 + 3*a - 10)
sage: P.residue_field('z')
Residue field in z of Fractional ideal (2*a^2 + 3*a - 10)
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(3) - Integer(7), names=('a',)); (a,) = K._first_ngens(1)
>>> P = K.ideal(Integer(29)).factor()[Integer(0)][Integer(0)]
>>> P.residue_field()
Residue field in abar of Fractional ideal (2*a^2 + 3*a - 10)
>>> P.residue_field('z')
Residue field in z of Fractional ideal (2*a^2 + 3*a - 10)
x = polygen(ZZ)
K.<a> = NumberField(x^3 - 7)
P = K.ideal(29).factor()[0][0]
P.residue_field()
P.residue_field('z')

Another example:

sage: K.<a> = NumberField(x^3 - 7)
sage: P = K.ideal(389).factor()[0][0]; P
Fractional ideal (389, a^2 - 44*a - 9)
sage: P.residue_class_degree()
2
sage: P.residue_field()
Residue field in abar of Fractional ideal (389, a^2 - 44*a - 9)
sage: P.residue_field('z')
Residue field in z of Fractional ideal (389, a^2 - 44*a - 9)
sage: FF.<w> = P.residue_field()
sage: FF
Residue field in w of Fractional ideal (389, a^2 - 44*a - 9)
sage: FF((a+1)^390)
36
sage: FF(a)
w
>>> from sage.all import *
>>> K = NumberField(x**Integer(3) - Integer(7), names=('a',)); (a,) = K._first_ngens(1)
>>> P = K.ideal(Integer(389)).factor()[Integer(0)][Integer(0)]; P
Fractional ideal (389, a^2 - 44*a - 9)
>>> P.residue_class_degree()
2
>>> P.residue_field()
Residue field in abar of Fractional ideal (389, a^2 - 44*a - 9)
>>> P.residue_field('z')
Residue field in z of Fractional ideal (389, a^2 - 44*a - 9)
>>> FF = P.residue_field(names=('w',)); (w,) = FF._first_ngens(1)
>>> FF
Residue field in w of Fractional ideal (389, a^2 - 44*a - 9)
>>> FF((a+Integer(1))**Integer(390))
36
>>> FF(a)
w
K.<a> = NumberField(x^3 - 7)
P = K.ideal(389).factor()[0][0]; P
P.residue_class_degree()
P.residue_field()
P.residue_field('z')
FF.<w> = P.residue_field()
FF
FF((a+1)^390)
FF(a)

An example of reduction maps to the residue field: these are defined on the whole valuation ring, i.e. the subring of the number field consisting of elements with nonnegative valuation. This shows that the issue raised in Issue #1951 has been fixed:

sage: K.<i> = NumberField(x^2 + 1)
sage: P1, P2 = [g[0] for g in K.factor(5)]; P1, P2
(Fractional ideal (-i - 2), Fractional ideal (2*i + 1))
sage: a = 1/(1+2*i)
sage: F1, F2 = [g.residue_field() for g in [P1, P2]]; F1, F2
(Residue field of Fractional ideal (-i - 2),
 Residue field of Fractional ideal (2*i + 1))
sage: a.valuation(P1)
0
sage: F1(i/7)
4
sage: F1(a)
3
sage: a.valuation(P2)
-1
sage: F2(a)
Traceback (most recent call last):
...
ZeroDivisionError: Cannot reduce field element -2/5*i + 1/5
modulo Fractional ideal (2*i + 1): it has negative valuation
>>> from sage.all import *
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> P1, P2 = [g[Integer(0)] for g in K.factor(Integer(5))]; P1, P2
(Fractional ideal (-i - 2), Fractional ideal (2*i + 1))
>>> a = Integer(1)/(Integer(1)+Integer(2)*i)
>>> F1, F2 = [g.residue_field() for g in [P1, P2]]; F1, F2
(Residue field of Fractional ideal (-i - 2),
 Residue field of Fractional ideal (2*i + 1))
>>> a.valuation(P1)
0
>>> F1(i/Integer(7))
4
>>> F1(a)
3
>>> a.valuation(P2)
-1
>>> F2(a)
Traceback (most recent call last):
...
ZeroDivisionError: Cannot reduce field element -2/5*i + 1/5
modulo Fractional ideal (2*i + 1): it has negative valuation
K.<i> = NumberField(x^2 + 1)
P1, P2 = [g[0] for g in K.factor(5)]; P1, P2
a = 1/(1+2*i)
F1, F2 = [g.residue_field() for g in [P1, P2]]; F1, F2
a.valuation(P1)
F1(i/7)
F1(a)
a.valuation(P2)
F2(a)

An example with a relative number field:

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: R = p.residue_field(); R
Residue field in abar of Fractional ideal ((-1/2*b - 1/2)*a + 1/2*b - 1/2)
sage: R.cardinality()
9
sage: R(17)
2
sage: R((a + b)/17)
abar
sage: R(1/b)
2*abar
>>> from sage.all import *
>>> 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))
>>> R = p.residue_field(); R
Residue field in abar of Fractional ideal ((-1/2*b - 1/2)*a + 1/2*b - 1/2)
>>> R.cardinality()
9
>>> R(Integer(17))
2
>>> R((a + b)/Integer(17))
abar
>>> R(Integer(1)/b)
2*abar
L.<a,b> = NumberField([x^2 + 1, x^2 - 5])
p = L.ideal((-1/2*b - 1/2)*a + 1/2*b - 1/2)
R = p.residue_field(); R
R.cardinality()
R(17)
R((a + b)/17)
R(1/b)

We verify that Issue #8721 is fixed:

sage: L.<a, b> = NumberField([x^2 - 3, x^2 - 5])
sage: L.ideal(a).residue_field()
Residue field in abar of Fractional ideal (a)
>>> from sage.all import *
>>> L = NumberField([x**Integer(2) - Integer(3), x**Integer(2) - Integer(5)], names=('a', 'b',)); (a, b,) = L._first_ngens(2)
>>> L.ideal(a).residue_field()
Residue field in abar of Fractional ideal (a)
L.<a, b> = NumberField([x^2 - 3, x^2 - 5])
L.ideal(a).residue_field()
residues()[source]

Return a iterator through a complete list of residues modulo this integral ideal.

An error is raised if this fractional ideal is not integral.

OUTPUT:

An iterator through a complete list of residues modulo the integral ideal self. This list is the set of canonical reduced representatives given by all integral elements with coordinates \((r_0, \dots,r_{n-1})\), where:

  • \(r_i\) is reduced modulo \(d_i\)

  • \(d_i = b_i[i]\), with \(\{b_0, b_1, \dots, b_n\}\) HNF basis of the ideal.

AUTHOR: John Cremona (modified by Maite Aranes)

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<i> = NumberField(x^2 + 1)
sage: res = K.ideal(2).residues(); res
xmrange_iter([[0, 1], [0, 1]], <function ...<lambda> at 0x...>)
sage: list(res)
[0, i, 1, i + 1]
sage: list(K.ideal(2 + i).residues())
[-2*i, -i, 0, i, 2*i]
sage: list(K.ideal(i).residues())
[0]
sage: I = K.ideal(3 + 6*i)
sage: reps = I.residues()
sage: len(list(reps)) == I.norm()
True
sage: all(r == s or not (r-s) in I      # long time (6s on sage.math, 2011)
....:     for r in reps for s in reps)
True

sage: K.<a> = NumberField(x^3 - 10)
sage: I = K.ideal(a - 1)
sage: len(list(I.residues())) == I.norm()
True

sage: K.<z> = CyclotomicField(11)
sage: len(list(K.primes_above(3)[0].residues())) == 3**5  # long time (5s on sage.math, 2011)
True
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> res = K.ideal(Integer(2)).residues(); res
xmrange_iter([[0, 1], [0, 1]], <function ...<lambda> at 0x...>)
>>> list(res)
[0, i, 1, i + 1]
>>> list(K.ideal(Integer(2) + i).residues())
[-2*i, -i, 0, i, 2*i]
>>> list(K.ideal(i).residues())
[0]
>>> I = K.ideal(Integer(3) + Integer(6)*i)
>>> reps = I.residues()
>>> len(list(reps)) == I.norm()
True
>>> all(r == s or not (r-s) in I      # long time (6s on sage.math, 2011)
...     for r in reps for s in reps)
True

>>> K = NumberField(x**Integer(3) - Integer(10), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.ideal(a - Integer(1))
>>> len(list(I.residues())) == I.norm()
True

>>> K = CyclotomicField(Integer(11), names=('z',)); (z,) = K._first_ngens(1)
>>> len(list(K.primes_above(Integer(3))[Integer(0)].residues())) == Integer(3)**Integer(5)  # long time (5s on sage.math, 2011)
True
x = polygen(ZZ)
K.<i> = NumberField(x^2 + 1)
res = K.ideal(2).residues(); res
list(res)
list(K.ideal(2 + i).residues())
list(K.ideal(i).residues())
I = K.ideal(3 + 6*i)
reps = I.residues()
len(list(reps)) == I.norm()
all(r == s or not (r-s) in I      # long time (6s on sage.math, 2011)
    for r in reps for s in reps)
K.<a> = NumberField(x^3 - 10)
I = K.ideal(a - 1)
len(list(I.residues())) == I.norm()
K.<z> = CyclotomicField(11)
len(list(K.primes_above(3)[0].residues())) == 3**5  # long time (5s on sage.math, 2011)
small_residue(f)[source]

Given an element \(f\) of the ambient number field, return an element \(g\) such that \(f - g\) belongs to the ideal self (which must be integral), and \(g\) is small.

Note

The reduced representative returned is not uniquely determined.

ALGORITHM: Uses PARI function pari:nfeltreduce.

EXAMPLES:

sage: x = polygen(ZZ)
sage: k.<a> = NumberField(x^2 + 5)
sage: I = k.ideal(a)
sage: I.small_residue(14)
4
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> k = NumberField(x**Integer(2) + Integer(5), names=('a',)); (a,) = k._first_ngens(1)
>>> I = k.ideal(a)
>>> I.small_residue(Integer(14))
4
x = polygen(ZZ)
k.<a> = NumberField(x^2 + 5)
I = k.ideal(a)
I.small_residue(14)
sage: K.<a> = NumberField(x^5 + 7*x^4 + 18*x^2 + x - 3)
sage: I = K.ideal(5)
sage: I.small_residue(a^2 -13)
a^2 + 5*a - 3
>>> from sage.all import *
>>> K = NumberField(x**Integer(5) + Integer(7)*x**Integer(4) + Integer(18)*x**Integer(2) + x - Integer(3), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.ideal(Integer(5))
>>> I.small_residue(a**Integer(2) -Integer(13))
a^2 + 5*a - 3
K.<a> = NumberField(x^5 + 7*x^4 + 18*x^2 + x - 3)
I = K.ideal(5)
I.small_residue(a^2 -13)
>>> from sage.all import *
>>> K = NumberField(x**Integer(5) + Integer(7)*x**Integer(4) + Integer(18)*x**Integer(2) + x - Integer(3), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.ideal(Integer(5))
>>> I.small_residue(a**Integer(2) -Integer(13))
a^2 + 5*a - 3
K.<a> = NumberField(x^5 + 7*x^4 + 18*x^2 + x - 3)
I = K.ideal(5)
I.small_residue(a^2 -13)
support()[source]

Return a list of the prime ideal factors of self.

OUTPUT:

list of prime ideals (a new list is returned each time this function is called)

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<w> = NumberField(x^2 + 23)
sage: I = ideal(w+1)
sage: I.prime_factors()
[Fractional ideal (2, 1/2*w - 1/2),
 Fractional ideal (2, 1/2*w + 1/2),
 Fractional ideal (3, 1/2*w + 1/2)]
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(23), names=('w',)); (w,) = K._first_ngens(1)
>>> I = ideal(w+Integer(1))
>>> I.prime_factors()
[Fractional ideal (2, 1/2*w - 1/2),
 Fractional ideal (2, 1/2*w + 1/2),
 Fractional ideal (3, 1/2*w + 1/2)]
x = polygen(ZZ)
K.<w> = NumberField(x^2 + 23)
I = ideal(w+1)
I.prime_factors()
class sage.rings.number_field.number_field_ideal.NumberFieldIdeal(field, gens, coerce=True)[source]

Bases: Ideal_generic

An ideal of a number field.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<i> = NumberField(x^2 + 1)
sage: K.ideal(7)
Fractional ideal (7)
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> K.ideal(Integer(7))
Fractional ideal (7)
x = polygen(ZZ)
K.<i> = NumberField(x^2 + 1)
K.ideal(7)

Initialization from PARI:

sage: K.ideal(pari(7))
Fractional ideal (7)
sage: K.ideal(pari(4), pari(4 + 2*i))
Fractional ideal (2)
sage: K.ideal(pari("i + 2"))
Fractional ideal (i + 2)
sage: K.ideal(pari("[3,0;0,3]"))
Fractional ideal (3)
sage: F = pari(K).idealprimedec(5)
sage: K.ideal(F[0])
Fractional ideal (2*i + 1)
>>> from sage.all import *
>>> K.ideal(pari(Integer(7)))
Fractional ideal (7)
>>> K.ideal(pari(Integer(4)), pari(Integer(4) + Integer(2)*i))
Fractional ideal (2)
>>> K.ideal(pari("i + 2"))
Fractional ideal (i + 2)
>>> K.ideal(pari("[3,0;0,3]"))
Fractional ideal (3)
>>> F = pari(K).idealprimedec(Integer(5))
>>> K.ideal(F[Integer(0)])
Fractional ideal (2*i + 1)
K.ideal(pari(7))
K.ideal(pari(4), pari(4 + 2*i))
K.ideal(pari("i + 2"))
K.ideal(pari("[3,0;0,3]"))
F = pari(K).idealprimedec(5)
K.ideal(F[0])
S_ideal_class_log(S)[source]

S-class group version of ideal_class_log().

EXAMPLES:

sage: K.<a> = QuadraticField(-14)
sage: S = K.primes_above(2)
sage: I = K.ideal(3, a + 1)
sage: I.S_ideal_class_log(S)
[1]
sage: I.S_ideal_class_log([])
[3]
>>> from sage.all import *
>>> K = QuadraticField(-Integer(14), names=('a',)); (a,) = K._first_ngens(1)
>>> S = K.primes_above(Integer(2))
>>> I = K.ideal(Integer(3), a + Integer(1))
>>> I.S_ideal_class_log(S)
[1]
>>> I.S_ideal_class_log([])
[3]
K.<a> = QuadraticField(-14)
S = K.primes_above(2)
I = K.ideal(3, a + 1)
I.S_ideal_class_log(S)
I.S_ideal_class_log([])
absolute_norm()[source]

A synonym for norm().

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<i> = NumberField(x^2 + 1)
sage: K.ideal(1 + 2*i).absolute_norm()
5
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> K.ideal(Integer(1) + Integer(2)*i).absolute_norm()
5
x = polygen(ZZ)
K.<i> = NumberField(x^2 + 1)
K.ideal(1 + 2*i).absolute_norm()
absolute_ramification_index()[source]

A synonym for ramification_index().

EXAMPLES:

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

Return the Artin symbol \((K / \QQ, P)\), where \(K\) is the number field of \(P\) = self. This is the unique element \(s\) of the decomposition group of \(P\) such that \(s(x) = x^p \pmod{P}\) where \(p\) is the residue characteristic of \(P\). (Here \(P\) (self) should be prime and unramified.)

See the GaloisGroup_v2.artin_symbol() method for further documentation and examples.

EXAMPLES:

sage: QuadraticField(-23, 'w').primes_above(7)[0].artin_symbol()            # needs sage.groups
(1,2)
>>> from sage.all import *
>>> QuadraticField(-Integer(23), 'w').primes_above(Integer(7))[Integer(0)].artin_symbol()            # needs sage.groups
(1,2)
QuadraticField(-23, 'w').primes_above(7)[0].artin_symbol()            # needs sage.groups
basis()[source]

Return a basis for this ideal viewed as a \(\ZZ\)-module.

OUTPUT:

An immutable sequence of elements of this ideal (note: their parent is the number field) forming a basis for this ideal.

EXAMPLES:

sage: K.<z> = CyclotomicField(7)
sage: I = K.factor(11)[0][0]
sage: I.basis()           # warning -- choice of basis can be somewhat random
[11, 11*z, 11*z^2, z^3 + 5*z^2 + 4*z + 10,
 z^4 + z^2 + z + 5, z^5 + z^4 + z^3 + 2*z^2 + 6*z + 5]
>>> from sage.all import *
>>> K = CyclotomicField(Integer(7), names=('z',)); (z,) = K._first_ngens(1)
>>> I = K.factor(Integer(11))[Integer(0)][Integer(0)]
>>> I.basis()           # warning -- choice of basis can be somewhat random
[11, 11*z, 11*z^2, z^3 + 5*z^2 + 4*z + 10,
 z^4 + z^2 + z + 5, z^5 + z^4 + z^3 + 2*z^2 + 6*z + 5]
K.<z> = CyclotomicField(7)
I = K.factor(11)[0][0]
I.basis()           # warning -- choice of basis can be somewhat random

An example of a non-integral ideal.:

sage: J = 1/I
sage: J          # warning -- choice of generators can be somewhat random
Fractional ideal (2/11*z^5 + 2/11*z^4 + 3/11*z^3 + 2/11)
sage: J.basis()           # warning -- choice of basis can be somewhat random
[1, z, z^2, 1/11*z^3 + 7/11*z^2 + 6/11*z + 10/11,
 1/11*z^4 + 1/11*z^2 + 1/11*z + 7/11,
 1/11*z^5 + 1/11*z^4 + 1/11*z^3 + 2/11*z^2 + 8/11*z + 7/11]
>>> from sage.all import *
>>> J = Integer(1)/I
>>> J          # warning -- choice of generators can be somewhat random
Fractional ideal (2/11*z^5 + 2/11*z^4 + 3/11*z^3 + 2/11)
>>> J.basis()           # warning -- choice of basis can be somewhat random
[1, z, z^2, 1/11*z^3 + 7/11*z^2 + 6/11*z + 10/11,
 1/11*z^4 + 1/11*z^2 + 1/11*z + 7/11,
 1/11*z^5 + 1/11*z^4 + 1/11*z^3 + 2/11*z^2 + 8/11*z + 7/11]
J = 1/I
J          # warning -- choice of generators can be somewhat random
J.basis()           # warning -- choice of basis can be somewhat random

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

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(2*x^2 - 1/3)
sage: K.ideal(a).basis()
[1, a]
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(Integer(2)*x**Integer(2) - Integer(1)/Integer(3), names=('a',)); (a,) = K._first_ngens(1)
>>> K.ideal(a).basis()
[1, a]
x = polygen(ZZ)
K.<a> = NumberField(2*x^2 - 1/3)
K.ideal(a).basis()
coordinates(x)[source]

Return the coordinate vector of \(x\) with respect to this ideal.

INPUT:

  • x – an element of the number field (or ring of integers) of this ideal

OUTPUT:

List giving the coordinates of \(x\) with respect to the integral basis of the ideal. In general this will be a vector of rationals; it will consist of integers if and only if \(x\) is in the ideal.

AUTHOR: John Cremona 2008-10-31

ALGORITHM:

Uses linear algebra. Provides simpler implementations for _contains_(), is_integral() and smallest_integer().

EXAMPLES:

sage: K.<i> = QuadraticField(-1)
sage: I = K.ideal(7 + 3*i)
sage: Ibasis = I.integral_basis(); Ibasis
[58, i + 41]
sage: a = 23 - 14*i
sage: acoords = I.coordinates(a); acoords
(597/58, -14)
sage: sum([Ibasis[j]*acoords[j] for j in range(2)]) == a
True
sage: b = 123 + 456*i
sage: bcoords = I.coordinates(b); bcoords
(-18573/58, 456)
sage: sum([Ibasis[j]*bcoords[j] for j in range(2)]) == b
True
sage: J = K.ideal(0)
sage: J.coordinates(0)
()
sage: J.coordinates(1)
Traceback (most recent call last):
...
TypeError: vector is not in free module
>>> from sage.all import *
>>> K = QuadraticField(-Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> I = K.ideal(Integer(7) + Integer(3)*i)
>>> Ibasis = I.integral_basis(); Ibasis
[58, i + 41]
>>> a = Integer(23) - Integer(14)*i
>>> acoords = I.coordinates(a); acoords
(597/58, -14)
>>> sum([Ibasis[j]*acoords[j] for j in range(Integer(2))]) == a
True
>>> b = Integer(123) + Integer(456)*i
>>> bcoords = I.coordinates(b); bcoords
(-18573/58, 456)
>>> sum([Ibasis[j]*bcoords[j] for j in range(Integer(2))]) == b
True
>>> J = K.ideal(Integer(0))
>>> J.coordinates(Integer(0))
()
>>> J.coordinates(Integer(1))
Traceback (most recent call last):
...
TypeError: vector is not in free module
K.<i> = QuadraticField(-1)
I = K.ideal(7 + 3*i)
Ibasis = I.integral_basis(); Ibasis
a = 23 - 14*i
acoords = I.coordinates(a); acoords
sum([Ibasis[j]*acoords[j] for j in range(2)]) == a
b = 123 + 456*i
bcoords = I.coordinates(b); bcoords
sum([Ibasis[j]*bcoords[j] for j in range(2)]) == b
J = K.ideal(0)
J.coordinates(0)
J.coordinates(1)
decomposition_group()[source]

Return the decomposition group of self, as a subset of the automorphism group of the number field of self. Raises an error if the field isn’t Galois. See the GaloisGroup_v2.decomposition_group() method for further examples and doctests.

EXAMPLES:

sage: QuadraticField(-23, 'w').primes_above(7)[0].decomposition_group()     # needs sage.groups
Subgroup generated by [(1,2)] of (Galois group 2T1 (S2) with order 2 of x^2 + 23)
>>> from sage.all import *
>>> QuadraticField(-Integer(23), 'w').primes_above(Integer(7))[Integer(0)].decomposition_group()     # needs sage.groups
Subgroup generated by [(1,2)] of (Galois group 2T1 (S2) with order 2 of x^2 + 23)
QuadraticField(-23, 'w').primes_above(7)[0].decomposition_group()     # needs sage.groups
free_module()[source]

Return the free \(\ZZ\)-module contained in the vector space associated to the ambient number field, that corresponds to this ideal.

EXAMPLES:

sage: K.<z> = CyclotomicField(7)
sage: I = K.factor(11)[0][0]; I
Fractional ideal (-3*z^4 - 2*z^3 - 2*z^2 - 2)
sage: A = I.free_module()
sage: A              # warning -- choice of basis can be somewhat random
Free module of degree 6 and rank 6 over Integer Ring
User basis matrix:
[11  0  0  0  0  0]
[ 0 11  0  0  0  0]
[ 0  0 11  0  0  0]
[10  4  5  1  0  0]
[ 5  1  1  0  1  0]
[ 5  6  2  1  1  1]
>>> from sage.all import *
>>> K = CyclotomicField(Integer(7), names=('z',)); (z,) = K._first_ngens(1)
>>> I = K.factor(Integer(11))[Integer(0)][Integer(0)]; I
Fractional ideal (-3*z^4 - 2*z^3 - 2*z^2 - 2)
>>> A = I.free_module()
>>> A              # warning -- choice of basis can be somewhat random
Free module of degree 6 and rank 6 over Integer Ring
User basis matrix:
[11  0  0  0  0  0]
[ 0 11  0  0  0  0]
[ 0  0 11  0  0  0]
[10  4  5  1  0  0]
[ 5  1  1  0  1  0]
[ 5  6  2  1  1  1]
K.<z> = CyclotomicField(7)
I = K.factor(11)[0][0]; I
A = I.free_module()
A              # warning -- choice of basis can be somewhat random

However, the actual \(\ZZ\)-module is not at all random:

sage: A.basis_matrix().change_ring(ZZ).echelon_form()
[ 1  0  0  5  1  1]
[ 0  1  0  1  1  7]
[ 0  0  1  7  6 10]
[ 0  0  0 11  0  0]
[ 0  0  0  0 11  0]
[ 0  0  0  0  0 11]
>>> from sage.all import *
>>> A.basis_matrix().change_ring(ZZ).echelon_form()
[ 1  0  0  5  1  1]
[ 0  1  0  1  1  7]
[ 0  0  1  7  6 10]
[ 0  0  0 11  0  0]
[ 0  0  0  0 11  0]
[ 0  0  0  0  0 11]
A.basis_matrix().change_ring(ZZ).echelon_form()

The ideal doesn’t have to be integral:

sage: J = I^(-1)
sage: B = J.free_module()
sage: B.echelonized_basis_matrix()
[ 1/11     0     0  7/11  1/11  1/11]
[    0  1/11     0  1/11  1/11  5/11]
[    0     0  1/11  5/11  4/11 10/11]
[    0     0     0     1     0     0]
[    0     0     0     0     1     0]
[    0     0     0     0     0     1]
>>> from sage.all import *
>>> J = I**(-Integer(1))
>>> B = J.free_module()
>>> B.echelonized_basis_matrix()
[ 1/11     0     0  7/11  1/11  1/11]
[    0  1/11     0  1/11  1/11  5/11]
[    0     0  1/11  5/11  4/11 10/11]
[    0     0     0     1     0     0]
[    0     0     0     0     1     0]
[    0     0     0     0     0     1]
J = I^(-1)
B = J.free_module()
B.echelonized_basis_matrix()

This also works for relative extensions:

sage: x = polygen(ZZ)
sage: K.<a,b> = NumberField([x^2 + 1, x^2 + 2])
sage: I = K.fractional_ideal(4)
sage: I.free_module()
Free module of degree 4 and rank 4 over Integer Ring
User basis matrix:
[  4   0   0   0]
[ -3   7  -1   1]
[  3   7   1   1]
[  0 -10   0  -2]
sage: J = I^(-1); J.free_module()
Free module of degree 4 and rank 4 over Integer Ring
User basis matrix:
[  1/4     0     0     0]
[-3/16  7/16 -1/16  1/16]
[ 3/16  7/16  1/16  1/16]
[    0  -5/8     0  -1/8]
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField([x**Integer(2) + Integer(1), x**Integer(2) + Integer(2)], names=('a', 'b',)); (a, b,) = K._first_ngens(2)
>>> I = K.fractional_ideal(Integer(4))
>>> I.free_module()
Free module of degree 4 and rank 4 over Integer Ring
User basis matrix:
[  4   0   0   0]
[ -3   7  -1   1]
[  3   7   1   1]
[  0 -10   0  -2]
>>> J = I**(-Integer(1)); J.free_module()
Free module of degree 4 and rank 4 over Integer Ring
User basis matrix:
[  1/4     0     0     0]
[-3/16  7/16 -1/16  1/16]
[ 3/16  7/16  1/16  1/16]
[    0  -5/8     0  -1/8]
x = polygen(ZZ)
K.<a,b> = NumberField([x^2 + 1, x^2 + 2])
I = K.fractional_ideal(4)
I.free_module()
J = I^(-1); J.free_module()

An example of intersecting ideals by intersecting free modules.:

sage: K.<a> = NumberField(x^3 + x^2 - 2*x + 8)
sage: I = K.factor(2)
sage: p1 = I[0][0]; p2 = I[1][0]
sage: N = p1.free_module().intersection(p2.free_module()); N
Free module of degree 3 and rank 3 over Integer Ring
Echelon basis matrix:
[  1 1/2 1/2]
[  0   1   1]
[  0   0   2]
sage: N.index_in(p1.free_module()).abs()
2
>>> from sage.all import *
>>> K = NumberField(x**Integer(3) + x**Integer(2) - Integer(2)*x + Integer(8), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.factor(Integer(2))
>>> p1 = I[Integer(0)][Integer(0)]; p2 = I[Integer(1)][Integer(0)]
>>> N = p1.free_module().intersection(p2.free_module()); N
Free module of degree 3 and rank 3 over Integer Ring
Echelon basis matrix:
[  1 1/2 1/2]
[  0   1   1]
[  0   0   2]
>>> N.index_in(p1.free_module()).abs()
2
K.<a> = NumberField(x^3 + x^2 - 2*x + 8)
I = K.factor(2)
p1 = I[0][0]; p2 = I[1][0]
N = p1.free_module().intersection(p2.free_module()); N
N.index_in(p1.free_module()).abs()
gens_reduced(proof=None)[source]

Express this ideal in terms of at most two generators, and one if possible.

This function indirectly uses pari:bnfisprincipal, so set proof=True if you want to prove correctness (which is the default).

EXAMPLES:

sage: x = polygen(ZZ)
sage: R.<x> = PolynomialRing(QQ)
sage: K.<a> = NumberField(x^2 + 5)
sage: K.ideal(0).gens_reduced()
(0,)
sage: J = K.ideal([a + 2, 9])
sage: J.gens()
(a + 2, 9)
sage: J.gens_reduced()  # random sign
(a + 2,)
sage: K.ideal([a + 2, 3]).gens_reduced()
(3, a + 2)
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> K = NumberField(x**Integer(2) + Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> K.ideal(Integer(0)).gens_reduced()
(0,)
>>> J = K.ideal([a + Integer(2), Integer(9)])
>>> J.gens()
(a + 2, 9)
>>> J.gens_reduced()  # random sign
(a + 2,)
>>> K.ideal([a + Integer(2), Integer(3)]).gens_reduced()
(3, a + 2)
x = polygen(ZZ)
R.<x> = PolynomialRing(QQ)
K.<a> = NumberField(x^2 + 5)
K.ideal(0).gens_reduced()
J = K.ideal([a + 2, 9])
J.gens()
J.gens_reduced()  # random sign
K.ideal([a + 2, 3]).gens_reduced()
gens_two()[source]

Express this ideal using exactly two generators, the first of which is a generator for the intersection of the ideal with \(\QQ\).

ALGORITHM: uses PARI’s pari:idealtwoelt function, which runs in randomized polynomial time and is very fast in practice.

EXAMPLES:

sage: x = polygen(ZZ)
sage: R.<x> = PolynomialRing(QQ)
sage: K.<a> = NumberField(x^2 + 5)
sage: J = K.ideal([a + 2, 9])
sage: J.gens()
(a + 2, 9)
sage: J.gens_two()
(9, a + 2)
sage: K.ideal([a + 5, a + 8]).gens_two()
(3, a + 2)
sage: K.ideal(0).gens_two()
(0, 0)
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> K = NumberField(x**Integer(2) + Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> J = K.ideal([a + Integer(2), Integer(9)])
>>> J.gens()
(a + 2, 9)
>>> J.gens_two()
(9, a + 2)
>>> K.ideal([a + Integer(5), a + Integer(8)]).gens_two()
(3, a + 2)
>>> K.ideal(Integer(0)).gens_two()
(0, 0)
x = polygen(ZZ)
R.<x> = PolynomialRing(QQ)
K.<a> = NumberField(x^2 + 5)
J = K.ideal([a + 2, 9])
J.gens()
J.gens_two()
K.ideal([a + 5, a + 8]).gens_two()
K.ideal(0).gens_two()

The second generator is zero if and only if the ideal is generated by a rational, in contrast to the PARI function pari:idealtwoelt:

sage: I = K.ideal(12)
sage: pari(K).idealtwoelt(I)  # Note that second element is not zero
[12, [0, 12]~]
sage: I.gens_two()
(12, 0)
>>> from sage.all import *
>>> I = K.ideal(Integer(12))
>>> pari(K).idealtwoelt(I)  # Note that second element is not zero
[12, [0, 12]~]
>>> I.gens_two()
(12, 0)
I = K.ideal(12)
pari(K).idealtwoelt(I)  # Note that second element is not zero
I.gens_two()
ideal_class_log(proof=None)[source]

Return the output of PARI’s pari:bnfisprincipal for this ideal, i.e. a vector expressing the class of this ideal in terms of a set of generators for the class group.

Since it uses the PARI method pari:bnfisprincipal, specify proof=True (this is the default setting) to prove the correctness of the output.

EXAMPLES:

When the class number is 1, the result is always the empty list:

sage: K.<a> = QuadraticField(-163)
sage: J = K.primes_above(random_prime(10^6))[0]
sage: J.ideal_class_log()
[]
>>> from sage.all import *
>>> K = QuadraticField(-Integer(163), names=('a',)); (a,) = K._first_ngens(1)
>>> J = K.primes_above(random_prime(Integer(10)**Integer(6)))[Integer(0)]
>>> J.ideal_class_log()
[]
K.<a> = QuadraticField(-163)
J = K.primes_above(random_prime(10^6))[0]
J.ideal_class_log()

An example with class group of order 2. The first ideal is not principal, the second one is:

sage: K.<a> = QuadraticField(-5)
sage: J = K.ideal(23).factor()[0][0]
sage: J.ideal_class_log()
[1]
sage: (J^10).ideal_class_log()
[0]
>>> from sage.all import *
>>> K = QuadraticField(-Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> J = K.ideal(Integer(23)).factor()[Integer(0)][Integer(0)]
>>> J.ideal_class_log()
[1]
>>> (J**Integer(10)).ideal_class_log()
[0]
K.<a> = QuadraticField(-5)
J = K.ideal(23).factor()[0][0]
J.ideal_class_log()
(J^10).ideal_class_log()

An example with a more complicated class group:

sage: x = polygen(ZZ)
sage: K.<a, b> = NumberField([x^3 - x + 1, x^2 + 26])
sage: K.class_group()
Class group of order 18 with structure C6 x C3 of
 Number Field in a with defining polynomial x^3 - x + 1 over its base field
sage: K.primes_above(7)[0].ideal_class_log() # random
[1, 2]
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField([x**Integer(3) - x + Integer(1), x**Integer(2) + Integer(26)], names=('a', 'b',)); (a, b,) = K._first_ngens(2)
>>> K.class_group()
Class group of order 18 with structure C6 x C3 of
 Number Field in a with defining polynomial x^3 - x + 1 over its base field
>>> K.primes_above(Integer(7))[Integer(0)].ideal_class_log() # random
[1, 2]
x = polygen(ZZ)
K.<a, b> = NumberField([x^3 - x + 1, x^2 + 26])
K.class_group()
K.primes_above(7)[0].ideal_class_log() # random
inertia_group()[source]

Return the inertia group of self, i.e. the set of elements \(s\) of the Galois group of the number field of self (which we assume is Galois) such that \(s\) acts trivially modulo self. This is the same as the 0th ramification group of self. See the GaloisGroup_v2.inertia_group() method further examples and doctests.

EXAMPLES:

sage: QuadraticField(-23, 'w').primes_above(23)[0].inertia_group()          # needs sage.groups
Subgroup generated by [(1,2)] of (Galois group 2T1 (S2) with order 2 of x^2 + 23)
>>> from sage.all import *
>>> QuadraticField(-Integer(23), 'w').primes_above(Integer(23))[Integer(0)].inertia_group()          # needs sage.groups
Subgroup generated by [(1,2)] of (Galois group 2T1 (S2) with order 2 of x^2 + 23)
QuadraticField(-23, 'w').primes_above(23)[0].inertia_group()          # needs sage.groups
integral_basis()[source]

Return a list of generators for this ideal as a \(\ZZ\)-module.

EXAMPLES:

sage: x = polygen(ZZ)
sage: R.<x> = PolynomialRing(QQ)
sage: K.<i> = NumberField(x^2 + 1)
sage: J = K.ideal(i + 1)
sage: J.integral_basis()
[2, i + 1]
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> J = K.ideal(i + Integer(1))
>>> J.integral_basis()
[2, i + 1]
x = polygen(ZZ)
R.<x> = PolynomialRing(QQ)
K.<i> = NumberField(x^2 + 1)
J = K.ideal(i + 1)
J.integral_basis()
integral_split()[source]

Return a tuple \((I, d)\), where \(I\) is an integral ideal, and \(d\) is the smallest positive integer such that this ideal is equal to \(I/d\).

EXAMPLES:

sage: x = polygen(ZZ)
sage: R.<x> = PolynomialRing(QQ)
sage: K.<a> = NumberField(x^2 - 5)
sage: I = K.ideal(2/(5+a))
sage: I.is_integral()
False
sage: J, d = I.integral_split()
sage: J
Fractional ideal (-1/2*a + 5/2)
sage: J.is_integral()
True
sage: d
5
sage: I == J/d
True
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> K = NumberField(x**Integer(2) - Integer(5), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.ideal(Integer(2)/(Integer(5)+a))
>>> I.is_integral()
False
>>> J, d = I.integral_split()
>>> J
Fractional ideal (-1/2*a + 5/2)
>>> J.is_integral()
True
>>> d
5
>>> I == J/d
True
x = polygen(ZZ)
R.<x> = PolynomialRing(QQ)
K.<a> = NumberField(x^2 - 5)
I = K.ideal(2/(5+a))
I.is_integral()
J, d = I.integral_split()
J
J.is_integral()
d
I == J/d
intersection(other)[source]

Return the intersection of self and other.

EXAMPLES:

sage: K.<a> = QuadraticField(-11)
sage: p = K.ideal((a + 1)/2); q = K.ideal((a + 3)/2)
sage: p.intersection(q) == q.intersection(p) == K.ideal(a - 2)
True
>>> from sage.all import *
>>> K = QuadraticField(-Integer(11), names=('a',)); (a,) = K._first_ngens(1)
>>> p = K.ideal((a + Integer(1))/Integer(2)); q = K.ideal((a + Integer(3))/Integer(2))
>>> p.intersection(q) == q.intersection(p) == K.ideal(a - Integer(2))
True
K.<a> = QuadraticField(-11)
p = K.ideal((a + 1)/2); q = K.ideal((a + 3)/2)
p.intersection(q) == q.intersection(p) == K.ideal(a - 2)

An example with non-principal ideals:

sage: x = polygen(ZZ)
sage: L.<a> = NumberField(x^3 - 7)
sage: p = L.ideal(a^2 + a + 1, 2)
sage: q = L.ideal(a + 1)
sage: p.intersection(q) == L.ideal(8, 2*a + 2)
True
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> L = NumberField(x**Integer(3) - Integer(7), names=('a',)); (a,) = L._first_ngens(1)
>>> p = L.ideal(a**Integer(2) + a + Integer(1), Integer(2))
>>> q = L.ideal(a + Integer(1))
>>> p.intersection(q) == L.ideal(Integer(8), Integer(2)*a + Integer(2))
True
x = polygen(ZZ)
L.<a> = NumberField(x^3 - 7)
p = L.ideal(a^2 + a + 1, 2)
q = L.ideal(a + 1)
p.intersection(q) == L.ideal(8, 2*a + 2)

A relative example:

sage: L.<a,b> = NumberField([x^2 + 11, x^2 - 5])
sage: A = L.ideal([15, (-3/2*b + 7/2)*a - 8])
sage: B = L.ideal([6, (-1/2*b + 1)*a - b - 5/2])
sage: A.intersection(B) == L.ideal(-1/2*a - 3/2*b - 1)
True
>>> from sage.all import *
>>> L = NumberField([x**Integer(2) + Integer(11), x**Integer(2) - Integer(5)], names=('a', 'b',)); (a, b,) = L._first_ngens(2)
>>> A = L.ideal([Integer(15), (-Integer(3)/Integer(2)*b + Integer(7)/Integer(2))*a - Integer(8)])
>>> B = L.ideal([Integer(6), (-Integer(1)/Integer(2)*b + Integer(1))*a - b - Integer(5)/Integer(2)])
>>> A.intersection(B) == L.ideal(-Integer(1)/Integer(2)*a - Integer(3)/Integer(2)*b - Integer(1))
True
L.<a,b> = NumberField([x^2 + 11, x^2 - 5])
A = L.ideal([15, (-3/2*b + 7/2)*a - 8])
B = L.ideal([6, (-1/2*b + 1)*a - b - 5/2])
A.intersection(B) == L.ideal(-1/2*a - 3/2*b - 1)
is_integral()[source]

Return True if this ideal is integral.

EXAMPLES:

sage: R.<x> = PolynomialRing(QQ)
sage: K.<a> = NumberField(x^5 - x + 1)
sage: K.ideal(a).is_integral()
True
sage: (K.ideal(1) / (3*a+1)).is_integral()
False
>>> from sage.all import *
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> K = NumberField(x**Integer(5) - x + Integer(1), names=('a',)); (a,) = K._first_ngens(1)
>>> K.ideal(a).is_integral()
True
>>> (K.ideal(Integer(1)) / (Integer(3)*a+Integer(1))).is_integral()
False
R.<x> = PolynomialRing(QQ)
K.<a> = NumberField(x^5 - x + 1)
K.ideal(a).is_integral()
(K.ideal(1) / (3*a+1)).is_integral()
is_maximal()[source]

Return True if this ideal is maximal. This is equivalent to self being prime and nonzero.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^3 + 3); K
Number Field in a with defining polynomial x^3 + 3
sage: K.ideal(5).is_maximal()
False
sage: K.ideal(7).is_maximal()
True
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(3) + Integer(3), names=('a',)); (a,) = K._first_ngens(1); K
Number Field in a with defining polynomial x^3 + 3
>>> K.ideal(Integer(5)).is_maximal()
False
>>> K.ideal(Integer(7)).is_maximal()
True
x = polygen(ZZ)
K.<a> = NumberField(x^3 + 3); K
K.ideal(5).is_maximal()
K.ideal(7).is_maximal()
is_prime()[source]

Return True if this ideal is prime.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^2 - 17); K
Number Field in a with defining polynomial x^2 - 17
sage: K.ideal(5).is_prime()   # inert prime
True
sage: K.ideal(13).is_prime()  # split
False
sage: K.ideal(17).is_prime()  # ramified
False
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) - Integer(17), names=('a',)); (a,) = K._first_ngens(1); K
Number Field in a with defining polynomial x^2 - 17
>>> K.ideal(Integer(5)).is_prime()   # inert prime
True
>>> K.ideal(Integer(13)).is_prime()  # split
False
>>> K.ideal(Integer(17)).is_prime()  # ramified
False
x = polygen(ZZ)
K.<a> = NumberField(x^2 - 17); K
K.ideal(5).is_prime()   # inert prime
K.ideal(13).is_prime()  # split
K.ideal(17).is_prime()  # ramified
is_principal(proof=None)[source]

Return True if this ideal is principal.

Since it uses the PARI method pari:bnfisprincipal, specify proof=True (this is the default setting) to prove the correctness of the output.

EXAMPLES:

sage: K = QuadraticField(-119,'a')
sage: P = K.factor(2)[1][0]
sage: P.is_principal()
False
sage: I = P^5
sage: I.is_principal()
True
sage: I  # random
Fractional ideal (-1/2*a + 3/2)
sage: P = K.ideal([2]).factor()[1][0]
sage: I = P^5
sage: I.is_principal()
True
>>> from sage.all import *
>>> K = QuadraticField(-Integer(119),'a')
>>> P = K.factor(Integer(2))[Integer(1)][Integer(0)]
>>> P.is_principal()
False
>>> I = P**Integer(5)
>>> I.is_principal()
True
>>> I  # random
Fractional ideal (-1/2*a + 3/2)
>>> P = K.ideal([Integer(2)]).factor()[Integer(1)][Integer(0)]
>>> I = P**Integer(5)
>>> I.is_principal()
True
K = QuadraticField(-119,'a')
P = K.factor(2)[1][0]
P.is_principal()
I = P^5
I.is_principal()
I  # random
P = K.ideal([2]).factor()[1][0]
I = P^5
I.is_principal()
is_zero()[source]

Return True iff self is the zero ideal.

Note that \((0)\) is a NumberFieldIdeal, not a NumberFieldFractionalIdeal.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^2 + 2); K
Number Field in a with defining polynomial x^2 + 2
sage: K.ideal(3).is_zero()
False
sage: I = K.ideal(0); I.is_zero()
True
sage: I
Ideal (0) of Number Field in a with defining polynomial x^2 + 2
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(2), names=('a',)); (a,) = K._first_ngens(1); K
Number Field in a with defining polynomial x^2 + 2
>>> K.ideal(Integer(3)).is_zero()
False
>>> I = K.ideal(Integer(0)); I.is_zero()
True
>>> I
Ideal (0) of Number Field in a with defining polynomial x^2 + 2
x = polygen(ZZ)
K.<a> = NumberField(x^2 + 2); K
K.ideal(3).is_zero()
I = K.ideal(0); I.is_zero()
I
norm()[source]

Return the norm of this fractional ideal as a rational number.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^4 + 23); K
Number Field in a with defining polynomial x^4 + 23
sage: I = K.ideal(19); I
Fractional ideal (19)
sage: factor(I.norm())
19^4
sage: F = I.factor()
sage: F[0][0].norm().factor()
19^2
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(4) + Integer(23), names=('a',)); (a,) = K._first_ngens(1); K
Number Field in a with defining polynomial x^4 + 23
>>> I = K.ideal(Integer(19)); I
Fractional ideal (19)
>>> factor(I.norm())
19^4
>>> F = I.factor()
>>> F[Integer(0)][Integer(0)].norm().factor()
19^2
x = polygen(ZZ)
K.<a> = NumberField(x^4 + 23); K
I = K.ideal(19); I
factor(I.norm())
F = I.factor()
F[0][0].norm().factor()
number_field()[source]

Return the number field that this is a fractional ideal in.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^2 + 2); K
Number Field in a with defining polynomial x^2 + 2
sage: K.ideal(3).number_field()
Number Field in a with defining polynomial x^2 + 2
sage: K.ideal(0).number_field()  # not tested (not implemented)
Number Field in a with defining polynomial x^2 + 2
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(2), names=('a',)); (a,) = K._first_ngens(1); K
Number Field in a with defining polynomial x^2 + 2
>>> K.ideal(Integer(3)).number_field()
Number Field in a with defining polynomial x^2 + 2
>>> K.ideal(Integer(0)).number_field()  # not tested (not implemented)
Number Field in a with defining polynomial x^2 + 2
x = polygen(ZZ)
K.<a> = NumberField(x^2 + 2); K
K.ideal(3).number_field()
K.ideal(0).number_field()  # not tested (not implemented)
pari_hnf()[source]

Return PARI’s representation of this ideal in Hermite normal form.

EXAMPLES:

sage: x = polygen(ZZ)
sage: R.<x> = PolynomialRing(QQ)
sage: K.<a> = NumberField(x^3 - 2)
sage: I = K.ideal(2/(5+a))
sage: I.pari_hnf()
[2, 0, 50/127; 0, 2, 244/127; 0, 0, 2/127]
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> K = NumberField(x**Integer(3) - Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.ideal(Integer(2)/(Integer(5)+a))
>>> I.pari_hnf()
[2, 0, 50/127; 0, 2, 244/127; 0, 0, 2/127]
x = polygen(ZZ)
R.<x> = PolynomialRing(QQ)
K.<a> = NumberField(x^3 - 2)
I = K.ideal(2/(5+a))
I.pari_hnf()
pari_prime()[source]

Return a PARI prime ideal corresponding to the ideal self.

INPUT:

  • self – a prime ideal

OUTPUT: a PARI “prime ideal”, i.e. a five-component vector \([p,a,e,f,b]\) representing the prime ideal \(p O_K + a O_K\), \(e\), \(f\) as usual, \(a\) as vector of components on the integral basis, \(b\) Lenstra’s constant.

EXAMPLES:

sage: K.<i> = QuadraticField(-1)
sage: K.ideal(3).pari_prime()
[3, [3, 0]~, 1, 2, 1]
sage: K.ideal(2+i).pari_prime()
[5, [2, 1]~, 1, 1, [-2, -1; 1, -2]]
sage: K.ideal(2).pari_prime()
Traceback (most recent call last):
...
ValueError: Fractional ideal (2) is not a prime ideal
>>> from sage.all import *
>>> K = QuadraticField(-Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> K.ideal(Integer(3)).pari_prime()
[3, [3, 0]~, 1, 2, 1]
>>> K.ideal(Integer(2)+i).pari_prime()
[5, [2, 1]~, 1, 1, [-2, -1; 1, -2]]
>>> K.ideal(Integer(2)).pari_prime()
Traceback (most recent call last):
...
ValueError: Fractional ideal (2) is not a prime ideal
K.<i> = QuadraticField(-1)
K.ideal(3).pari_prime()
K.ideal(2+i).pari_prime()
K.ideal(2).pari_prime()
ramification_group(v)[source]

Return the \(v\)-th ramification group of self, i.e. the set of elements \(s\) of the Galois group of the number field of self (which we assume is Galois) such that \(s\) acts trivially modulo the \((v+1)\)’st power of self. See the GaloisGroup.ramification_group() method for further examples and doctests.

EXAMPLES:

sage: QuadraticField(-23, 'w').primes_above(23)[0].ramification_group(0)    # needs sage.groups
Subgroup generated by [(1,2)] of (Galois group 2T1 (S2) with order 2 of x^2 + 23)
sage: QuadraticField(-23, 'w').primes_above(23)[0].ramification_group(1)    # needs sage.groups
Subgroup generated by [()] of (Galois group 2T1 (S2) with order 2 of x^2 + 23)
>>> from sage.all import *
>>> QuadraticField(-Integer(23), 'w').primes_above(Integer(23))[Integer(0)].ramification_group(Integer(0))    # needs sage.groups
Subgroup generated by [(1,2)] of (Galois group 2T1 (S2) with order 2 of x^2 + 23)
>>> QuadraticField(-Integer(23), 'w').primes_above(Integer(23))[Integer(0)].ramification_group(Integer(1))    # needs sage.groups
Subgroup generated by [()] of (Galois group 2T1 (S2) with order 2 of x^2 + 23)
QuadraticField(-23, 'w').primes_above(23)[0].ramification_group(0)    # needs sage.groups
QuadraticField(-23, 'w').primes_above(23)[0].ramification_group(1)    # needs sage.groups
random_element(*args, **kwds)[source]

Return a random element of this ideal.

INPUT:

  • *args, *kwds – parameters passed to the random integer function. See the documentation of ZZ.random_element() for details.

OUTPUT:

A random element of this fractional ideal, computed as a random \(\ZZ\)-linear combination of the basis.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^3 + 2)
sage: I = K.ideal(1 - a)
sage: I.random_element() # random output
-a^2 - a - 19
sage: I.random_element(distribution='uniform') # random output
a^2 - 2*a - 8
sage: I.random_element(-30, 30) # random output
-7*a^2 - 17*a - 75
sage: I.random_element(-100, 200).is_integral()
True
sage: I.random_element(-30, 30).parent() is K
True
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(3) + Integer(2), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.ideal(Integer(1) - a)
>>> I.random_element() # random output
-a^2 - a - 19
>>> I.random_element(distribution='uniform') # random output
a^2 - 2*a - 8
>>> I.random_element(-Integer(30), Integer(30)) # random output
-7*a^2 - 17*a - 75
>>> I.random_element(-Integer(100), Integer(200)).is_integral()
True
>>> I.random_element(-Integer(30), Integer(30)).parent() is K
True
x = polygen(ZZ)
K.<a> = NumberField(x^3 + 2)
I = K.ideal(1 - a)
I.random_element() # random output
I.random_element(distribution='uniform') # random output
I.random_element(-30, 30) # random output
I.random_element(-100, 200).is_integral()
I.random_element(-30, 30).parent() is K

A relative example:

sage: K.<a, b> = NumberField([x^2 + 2, x^2 + 1000*x + 1])
sage: I = K.ideal(1 - a)
sage: I.random_element()  # random output
17/500002*a^3 + 737253/250001*a^2 - 1494505893/500002*a + 752473260/250001
sage: I.random_element().is_integral()
True
sage: I.random_element(-100, 200).parent() is K
True
>>> from sage.all import *
>>> K = NumberField([x**Integer(2) + Integer(2), x**Integer(2) + Integer(1000)*x + Integer(1)], names=('a', 'b',)); (a, b,) = K._first_ngens(2)
>>> I = K.ideal(Integer(1) - a)
>>> I.random_element()  # random output
17/500002*a^3 + 737253/250001*a^2 - 1494505893/500002*a + 752473260/250001
>>> I.random_element().is_integral()
True
>>> I.random_element(-Integer(100), Integer(200)).parent() is K
True
K.<a, b> = NumberField([x^2 + 2, x^2 + 1000*x + 1])
I = K.ideal(1 - a)
I.random_element()  # random output
I.random_element().is_integral()
I.random_element(-100, 200).parent() is K
reduce_equiv()[source]

Return a small ideal that is equivalent to self in the group of fractional ideals modulo principal ideals. Very often (but not always) if self is principal then this function returns the unit ideal.

ALGORITHM: Calls pari:idealred function.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<w> = NumberField(x^2 + 23)
sage: I = ideal(w*23^5); I
Fractional ideal (6436343*w)
sage: I.reduce_equiv()
Fractional ideal (1)
sage: I = K.class_group().0.ideal()^10; I
Fractional ideal (1024, 1/2*w + 979/2)
sage: I.reduce_equiv()
Fractional ideal (2, 1/2*w - 1/2)
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(23), names=('w',)); (w,) = K._first_ngens(1)
>>> I = ideal(w*Integer(23)**Integer(5)); I
Fractional ideal (6436343*w)
>>> I.reduce_equiv()
Fractional ideal (1)
>>> I = K.class_group().gen(0).ideal()**Integer(10); I
Fractional ideal (1024, 1/2*w + 979/2)
>>> I.reduce_equiv()
Fractional ideal (2, 1/2*w - 1/2)
x = polygen(ZZ)
K.<w> = NumberField(x^2 + 23)
I = ideal(w*23^5); I
I.reduce_equiv()
I = K.class_group().0.ideal()^10; I
I.reduce_equiv()
relative_norm()[source]

A synonym for norm().

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<i> = NumberField(x^2 + 1)
sage: K.ideal(1 + 2*i).relative_norm()
5
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> K.ideal(Integer(1) + Integer(2)*i).relative_norm()
5
x = polygen(ZZ)
K.<i> = NumberField(x^2 + 1)
K.ideal(1 + 2*i).relative_norm()
relative_ramification_index()[source]

A synonym for ramification_index().

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<i> = NumberField(x^2 + 1)
sage: K.ideal(1 + i).relative_ramification_index()
2
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1)
>>> K.ideal(Integer(1) + i).relative_ramification_index()
2
x = polygen(ZZ)
K.<i> = NumberField(x^2 + 1)
K.ideal(1 + i).relative_ramification_index()
residue_symbol(e, m, check=True)[source]

The \(m\)-th power residue symbol for an element \(e\) and the proper ideal.

\[\left(\frac{\alpha}{\mathbf{P}}\right) \equiv \alpha^{\frac{N(\mathbf{P})-1}{m}} \operatorname{mod} \mathbf{P}\]

Note

accepts \(m=1\), in which case returns 1

Note

can also be called for an element from sage.rings.number_field_element.residue_symbol

Note

\(e\) is coerced into the number field of self

Note

if \(m=2\), \(e\) is an integer, and self.number_field() has absolute degree 1 (i.e. it is a copy of the rationals), then this calls kronecker_symbol(), which is implemented using GMP.

INPUT:

  • e – element of the number field

  • m – positive integer

OUTPUT: an \(m\)-th root of unity in the number field

EXAMPLES:

Quadratic Residue (7 is not a square modulo 11):

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x - 1)
sage: K.ideal(11).residue_symbol(7,2)
-1
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x - Integer(1), names=('a',)); (a,) = K._first_ngens(1)
>>> K.ideal(Integer(11)).residue_symbol(Integer(7),Integer(2))
-1
x = polygen(ZZ)
K.<a> = NumberField(x - 1)
K.ideal(11).residue_symbol(7,2)

Cubic Residue:

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

The field must contain the \(m\)-th roots of unity:

sage: K.<w> = NumberField(x^2 - x + 1)
sage: K.ideal(17).residue_symbol(w^2 + 3, 5)
Traceback (most recent call last):
...
ValueError: The residue symbol to that power is not defined for the number field
>>> from sage.all import *
>>> K = NumberField(x**Integer(2) - x + Integer(1), names=('w',)); (w,) = K._first_ngens(1)
>>> K.ideal(Integer(17)).residue_symbol(w**Integer(2) + Integer(3), Integer(5))
Traceback (most recent call last):
...
ValueError: The residue symbol to that power is not defined for the number field
K.<w> = NumberField(x^2 - x + 1)
K.ideal(17).residue_symbol(w^2 + 3, 5)
smallest_integer()[source]

Return the smallest nonnegative integer in \(I \cap \ZZ\), where \(I\) is this ideal. If \(I = 0\), returns 0.

EXAMPLES:

sage: R.<x> = PolynomialRing(QQ)
sage: K.<a> = NumberField(x^2 + 6)
sage: I = K.ideal([4, a])/7; I
Fractional ideal (2/7, 1/7*a)
sage: I.smallest_integer()
2
>>> from sage.all import *
>>> R = PolynomialRing(QQ, names=('x',)); (x,) = R._first_ngens(1)
>>> K = NumberField(x**Integer(2) + Integer(6), names=('a',)); (a,) = K._first_ngens(1)
>>> I = K.ideal([Integer(4), a])/Integer(7); I
Fractional ideal (2/7, 1/7*a)
>>> I.smallest_integer()
2
R.<x> = PolynomialRing(QQ)
K.<a> = NumberField(x^2 + 6)
I = K.ideal([4, a])/7; I
I.smallest_integer()
valuation(p)[source]

Return the valuation of self at p.

INPUT:

  • p – a prime ideal \(\mathfrak{p}\) of this number field

OUTPUT:

(integer) The valuation of this fractional ideal at the prime \(\mathfrak{p}\). If \(\mathfrak{p}\) is not prime, raise a ValueError.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<a> = NumberField(x^5 + 2); K
Number Field in a with defining polynomial x^5 + 2
sage: i = K.ideal(38); i
Fractional ideal (38)
sage: i.valuation(K.factor(19)[0][0])
1
sage: i.valuation(K.factor(2)[0][0])
5
sage: i.valuation(K.factor(3)[0][0])
0
sage: i.valuation(0)
Traceback (most recent call last):
...
ValueError: p (= Ideal (0) of Number Field in a
with defining polynomial x^5 + 2) must be nonzero
sage: K.ideal(0).valuation(K.factor(2)[0][0])
+Infinity
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(5) + Integer(2), names=('a',)); (a,) = K._first_ngens(1); K
Number Field in a with defining polynomial x^5 + 2
>>> i = K.ideal(Integer(38)); i
Fractional ideal (38)
>>> i.valuation(K.factor(Integer(19))[Integer(0)][Integer(0)])
1
>>> i.valuation(K.factor(Integer(2))[Integer(0)][Integer(0)])
5
>>> i.valuation(K.factor(Integer(3))[Integer(0)][Integer(0)])
0
>>> i.valuation(Integer(0))
Traceback (most recent call last):
...
ValueError: p (= Ideal (0) of Number Field in a
with defining polynomial x^5 + 2) must be nonzero
>>> K.ideal(Integer(0)).valuation(K.factor(Integer(2))[Integer(0)][Integer(0)])
+Infinity
x = polygen(ZZ)
K.<a> = NumberField(x^5 + 2); K
i = K.ideal(38); i
i.valuation(K.factor(19)[0][0])
i.valuation(K.factor(2)[0][0])
i.valuation(K.factor(3)[0][0])
i.valuation(0)
K.ideal(0).valuation(K.factor(2)[0][0])
class sage.rings.number_field.number_field_ideal.QuotientMap(K, M_OK_change, Q, I)[source]

Bases: object

Class to hold data needed by quotient maps from number field orders to residue fields. These are only partial maps: the exact domain is the appropriate valuation ring. For examples, see residue_field().

sage.rings.number_field.number_field_ideal.basis_to_module(B, K)[source]

Given a basis \(B\) of elements for a \(\ZZ\)-submodule of a number field \(K\), return the corresponding \(\ZZ\)-submodule.

EXAMPLES:

sage: x = polygen(ZZ)
sage: K.<w> = NumberField(x^4 + 1)
sage: from sage.rings.number_field.number_field_ideal import basis_to_module
sage: basis_to_module([K.0, K.0^2 + 3], K)
Free module of degree 4 and rank 2 over Integer Ring
User basis matrix:
[0 1 0 0]
[3 0 1 0]
>>> from sage.all import *
>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(4) + Integer(1), names=('w',)); (w,) = K._first_ngens(1)
>>> from sage.rings.number_field.number_field_ideal import basis_to_module
>>> basis_to_module([K.gen(0), K.gen(0)**Integer(2) + Integer(3)], K)
Free module of degree 4 and rank 2 over Integer Ring
User basis matrix:
[0 1 0 0]
[3 0 1 0]
x = polygen(ZZ)
K.<w> = NumberField(x^4 + 1)
from sage.rings.number_field.number_field_ideal import basis_to_module
basis_to_module([K.0, K.0^2 + 3], K)
sage.rings.number_field.number_field_ideal.is_NumberFieldFractionalIdeal(x)[source]

Return True if \(x\) is a fractional ideal of a number field.

EXAMPLES:

sage: from sage.rings.number_field.number_field_ideal import is_NumberFieldFractionalIdeal
sage: is_NumberFieldFractionalIdeal(2/3)
doctest:warning...
DeprecationWarning: The function is_NumberFieldFractionalIdeal is deprecated;
use 'isinstance(..., NumberFieldFractionalIdeal)' instead.
See https://github.com/sagemath/sage/issues/38124 for details.
False
sage: is_NumberFieldFractionalIdeal(ideal(5))
False
sage: x = polygen(ZZ)
sage: k.<a> = NumberField(x^2 + 2)
sage: I = k.ideal([a + 1]); I
Fractional ideal (a + 1)
sage: is_NumberFieldFractionalIdeal(I)
True
sage: Z = k.ideal(0); Z
Ideal (0) of Number Field in a with defining polynomial x^2 + 2
sage: is_NumberFieldFractionalIdeal(Z)
False
>>> from sage.all import *
>>> from sage.rings.number_field.number_field_ideal import is_NumberFieldFractionalIdeal
>>> is_NumberFieldFractionalIdeal(Integer(2)/Integer(3))
doctest:warning...
DeprecationWarning: The function is_NumberFieldFractionalIdeal is deprecated;
use 'isinstance(..., NumberFieldFractionalIdeal)' instead.
See https://github.com/sagemath/sage/issues/38124 for details.
False
>>> is_NumberFieldFractionalIdeal(ideal(Integer(5)))
False
>>> x = polygen(ZZ)
>>> k = NumberField(x**Integer(2) + Integer(2), names=('a',)); (a,) = k._first_ngens(1)
>>> I = k.ideal([a + Integer(1)]); I
Fractional ideal (a + 1)
>>> is_NumberFieldFractionalIdeal(I)
True
>>> Z = k.ideal(Integer(0)); Z
Ideal (0) of Number Field in a with defining polynomial x^2 + 2
>>> is_NumberFieldFractionalIdeal(Z)
False
from sage.rings.number_field.number_field_ideal import is_NumberFieldFractionalIdeal
is_NumberFieldFractionalIdeal(2/3)
is_NumberFieldFractionalIdeal(ideal(5))
x = polygen(ZZ)
k.<a> = NumberField(x^2 + 2)
I = k.ideal([a + 1]); I
is_NumberFieldFractionalIdeal(I)
Z = k.ideal(0); Z
is_NumberFieldFractionalIdeal(Z)
sage.rings.number_field.number_field_ideal.is_NumberFieldIdeal(x)[source]

Return True if \(x\) is an ideal of a number field.

EXAMPLES:

sage: from sage.rings.number_field.number_field_ideal import is_NumberFieldIdeal
sage: is_NumberFieldIdeal(2/3)
doctest:warning...
DeprecationWarning: The function is_NumberFieldIdeal is deprecated;
use 'isinstance(..., NumberFieldIdeal)' instead.
See https://github.com/sagemath/sage/issues/38124 for details.
False
sage: is_NumberFieldIdeal(ideal(5))
False

sage: x = polygen(ZZ)
sage: k.<a> = NumberField(x^2 + 2)
sage: I = k.ideal([a + 1]); I
Fractional ideal (a + 1)
sage: is_NumberFieldIdeal(I)
True
sage: Z = k.ideal(0); Z
Ideal (0) of Number Field in a with defining polynomial x^2 + 2
sage: is_NumberFieldIdeal(Z)
True
>>> from sage.all import *
>>> from sage.rings.number_field.number_field_ideal import is_NumberFieldIdeal
>>> is_NumberFieldIdeal(Integer(2)/Integer(3))
doctest:warning...
DeprecationWarning: The function is_NumberFieldIdeal is deprecated;
use 'isinstance(..., NumberFieldIdeal)' instead.
See https://github.com/sagemath/sage/issues/38124 for details.
False
>>> is_NumberFieldIdeal(ideal(Integer(5)))
False

>>> x = polygen(ZZ)
>>> k = NumberField(x**Integer(2) + Integer(2), names=('a',)); (a,) = k._first_ngens(1)
>>> I = k.ideal([a + Integer(1)]); I
Fractional ideal (a + 1)
>>> is_NumberFieldIdeal(I)
True
>>> Z = k.ideal(Integer(0)); Z
Ideal (0) of Number Field in a with defining polynomial x^2 + 2
>>> is_NumberFieldIdeal(Z)
True
from sage.rings.number_field.number_field_ideal import is_NumberFieldIdeal
is_NumberFieldIdeal(2/3)
is_NumberFieldIdeal(ideal(5))
x = polygen(ZZ)
k.<a> = NumberField(x^2 + 2)
I = k.ideal([a + 1]); I
is_NumberFieldIdeal(I)
Z = k.ideal(0); Z
is_NumberFieldIdeal(Z)
sage.rings.number_field.number_field_ideal.quotient_char_p(I, p)[source]

Given an integral ideal \(I\) that contains a prime number \(p\), compute a vector space \(V = (O_K \mod p) / (I \mod p)\), along with a homomorphism \(O_K \to V\) and a section \(V \to O_K\).

EXAMPLES:

sage: from sage.rings.number_field.number_field_ideal import quotient_char_p

sage: x = polygen(ZZ)
sage: K.<i> = NumberField(x^2 + 1); O = K.maximal_order(); I = K.fractional_ideal(15)
sage: quotient_char_p(I, 5)[0]
Vector space quotient V/W of dimension 2 over Finite Field of size 5 where
V: Vector space of dimension 2 over Finite Field of size 5
W: Vector space of degree 2 and dimension 0 over Finite Field of size 5
Basis matrix:
[]
sage: quotient_char_p(I, 3)[0]
Vector space quotient V/W of dimension 2 over Finite Field of size 3 where
V: Vector space of dimension 2 over Finite Field of size 3
W: Vector space of degree 2 and dimension 0 over Finite Field of size 3
Basis matrix:
[]

sage: I = K.factor(13)[0][0]; I
Fractional ideal (-2*i + 3)
sage: I.residue_class_degree()
1
sage: quotient_char_p(I, 13)[0]
Vector space quotient V/W of dimension 1 over Finite Field of size 13 where
V: Vector space of dimension 2 over Finite Field of size 13
W: Vector space of degree 2 and dimension 1 over Finite Field of size 13
Basis matrix:
[1 8]
>>> from sage.all import *
>>> from sage.rings.number_field.number_field_ideal import quotient_char_p

>>> x = polygen(ZZ)
>>> K = NumberField(x**Integer(2) + Integer(1), names=('i',)); (i,) = K._first_ngens(1); O = K.maximal_order(); I = K.fractional_ideal(Integer(15))
>>> quotient_char_p(I, Integer(5))[Integer(0)]
Vector space quotient V/W of dimension 2 over Finite Field of size 5 where
V: Vector space of dimension 2 over Finite Field of size 5
W: Vector space of degree 2 and dimension 0 over Finite Field of size 5
Basis matrix:
[]
>>> quotient_char_p(I, Integer(3))[Integer(0)]
Vector space quotient V/W of dimension 2 over Finite Field of size 3 where
V: Vector space of dimension 2 over Finite Field of size 3
W: Vector space of degree 2 and dimension 0 over Finite Field of size 3
Basis matrix:
[]

>>> I = K.factor(Integer(13))[Integer(0)][Integer(0)]; I
Fractional ideal (-2*i + 3)
>>> I.residue_class_degree()
1
>>> quotient_char_p(I, Integer(13))[Integer(0)]
Vector space quotient V/W of dimension 1 over Finite Field of size 13 where
V: Vector space of dimension 2 over Finite Field of size 13
W: Vector space of degree 2 and dimension 1 over Finite Field of size 13
Basis matrix:
[1 8]
from sage.rings.number_field.number_field_ideal import quotient_char_p
x = polygen(ZZ)
K.<i> = NumberField(x^2 + 1); O = K.maximal_order(); I = K.fractional_ideal(15)
quotient_char_p(I, 5)[0]
quotient_char_p(I, 3)[0]
I = K.factor(13)[0][0]; I
I.residue_class_degree()
quotient_char_p(I, 13)[0]