Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Relative Number Field Ideals
AUTHORS:
- Steven Sivek (2005-05-16)
- William Stein (2007-09-06)
- Nick Alexander (2009-01)
EXAMPLES::
sage: K.<a,b> = NumberField([x^2 + 1, x^2 + 2]) sage: A = K.absolute_field('z') sage: I = A.factor(7)[0][0] sage: from_A, to_A = A.structure() sage: G = [from_A(z) for z in I.gens()]; G [7, -2*b*a - 1] sage: K.fractional_ideal(G) Fractional ideal (2*b*a + 1) sage: K.fractional_ideal(G).absolute_norm().factor() 7^2 """ from __future__ import absolute_import
#***************************************************************************** # Copyright (C) 2007 William Stein <wstein@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # http://www.gnu.org/licenses/ #*****************************************************************************
from .number_field_ideal import NumberFieldFractionalIdeal from sage.structure.factorization import Factorization from sage.structure.proof.proof import get_flag from sage.structure.richcmp import richcmp
import sage.rings.rational_field as rational_field import sage.rings.integer_ring as integer_ring QQ = rational_field.RationalField() ZZ = integer_ring.IntegerRing()
class NumberFieldFractionalIdeal_rel(NumberFieldFractionalIdeal): """ An ideal of a relative number field.
EXAMPLES::
sage: K.<a> = NumberField([x^2 + 1, x^2 + 2]); K Number Field in a0 with defining polynomial x^2 + 1 over its base field sage: i = K.ideal(38); i Fractional ideal (38)
sage: K.<a0, a1> = NumberField([x^2 + 1, x^2 + 2]); K Number Field in a0 with defining polynomial x^2 + 1 over its base field sage: i = K.ideal([a0+1]); i # random Fractional ideal (-a1*a0) sage: (g, ) = i.gens_reduced(); g # random -a1*a0 sage: (g / (a0 + 1)).is_integral() True sage: ((a0 + 1) / g).is_integral() True
TESTS:
One test fails, because ideals aren't fully integrated into the categories framework yet::
sage: TestSuite(i).run() Failure in _test_category: ... The following tests failed: _test_category """ def _richcmp_(self, other, op): """ Compare an ideal of a relative number field to something else.
EXAMPLES::
sage: K.<a, b> = NumberField([x^2 + 23, x^2 - 7]) sage: I = K.ideal(2, (a + 2*b + 3)/2) sage: J = K.ideal(2, a - b) sage: I == J False """
def _contains_(self, x): """ Return True if x is an element of this ideal.
This function is called (indirectly) when the ``in`` operator is used.
EXAMPLES::
sage: K.<a, b> = NumberField([x^2 + 23, x^2 - 7]) sage: I = K.ideal(2, (a + 2*b + 3)/2) sage: [z in I for z in [a, b, 2, a + b]] # indirect doctest [False, False, True, True] """
def pari_rhnf(self): """ Return PARI's representation of this relative ideal in Hermite normal form.
EXAMPLES::
sage: K.<a, b> = NumberField([x^2 + 23, x^2 - 7]) sage: I = K.ideal(2, (a + 2*b + 3)/2) sage: I.pari_rhnf() [[1, -2; 0, 1], [[2, 1; 0, 1], 1/2]] """
def absolute_ideal(self, names = 'a'): r""" If this is an ideal in the extension `L/K`, return the ideal with the same generators in the absolute field `L/\QQ`.
INPUT:
- ``names`` (optional) -- string; name of generator of the absolute field
EXAMPLES::
sage: x = ZZ['x'].0 sage: K.<b> = NumberField(x^2 - 2) sage: L.<c> = K.extension(x^2 - b) sage: F.<m> = L.absolute_field()
An example of an inert ideal::
sage: P = F.factor(13)[0][0]; P Fractional ideal (13) sage: J = L.ideal(13) sage: J.absolute_ideal() Fractional ideal (13)
Now a non-trivial ideal in `L` that is principal in the subfield `K`. Since the optional 'names' argument is not passed, the generators of the absolute ideal J are returned in terms of the default field generator 'a'. This does not agree with the generator 'm' of the absolute field F defined above::
sage: J = L.ideal(b); J Fractional ideal (b) sage: J.absolute_ideal() Fractional ideal (a^2) sage: J.relative_norm() Fractional ideal (2) sage: J.absolute_norm() 4 sage: J.absolute_ideal().norm() 4
Now pass 'm' as the name for the generator of the absolute field:
sage: J.absolute_ideal('m') Fractional ideal (m^2)
Now an ideal not generated by an element of `K`::
sage: J = L.ideal(c); J Fractional ideal (c) sage: J.absolute_ideal() Fractional ideal (a) sage: J.absolute_norm() 2 sage: J.ideal_below() Fractional ideal (b) sage: J.ideal_below().norm() 2 """
def _from_absolute_ideal(self, id): r""" Convert the absolute ideal id to a relative number field ideal.
Assumes id.number_field() == self.absolute_field('a').
WARNING: This is an internal helper function.
TESTS::
sage: L.<a, b> = QQ.extension([x^2 + 71, x^3 + 2*x + 1]) sage: (2*a + b).norm() 22584817 sage: J = L.ideal(2*a + b) sage: 2*a + b in J True sage: J.absolute_norm() 22584817 sage: J.absolute_ideal() Fractional ideal (22584817, -1473/812911*a^5 + 8695/4877466*a^4 - 1308209/4877466*a^3 + 117415/443406*a^2 - 22963264/2438733*a - 13721081784272/2438733) sage: J.absolute_ideal().norm() 22584817
sage: J._from_absolute_ideal(J.absolute_ideal()) == J True """
def free_module(self): r""" Return this ideal as a `\ZZ`-submodule of the `\QQ`-vector space corresponding to the ambient number field.
EXAMPLES::
sage: K.<a, b> = NumberField([x^3 - x + 1, x^2 + 23]) sage: I = K.ideal(a*b - 1) sage: I.free_module() Free module of degree 6 and rank 6 over Integer Ring User basis matrix: ... sage: I.free_module().is_submodule(K.maximal_order().free_module()) True
"""
def gens_reduced(self): r""" Return a small set of generators for this ideal. This will always return a single generator if one exists (i.e. if the ideal is principal), and otherwise two generators.
EXAMPLES::
sage: K.<a, b> = NumberField([x^2 + 1, x^2 - 2]) sage: I = K.ideal((a + 1)*b/2 + 1) sage: I.gens_reduced() (1/2*b*a + 1/2*b + 1,)
TESTS:
Number fields defined by non-monic and non-integral polynomials are supported (:trac:`252`)::
sage: K.<a> = NumberField(2*x^2 - 1/3) sage: L.<b> = K.extension(5*x^2 + 1) sage: P = L.primes_above(2)[0] sage: P.gens_reduced() (2, 15*a*b + 3*a + 1) """ ## Compute the single generator, if it exists
# PARI always returns two elements, even if only one is needed! gens = gens[:1] gens = gens[1:]
def __invert__(self): """ Return the multiplicative inverse of self. Call with ~self.
EXAMPLES::
sage: K.<a,b> = NumberField([x^2 + 1, x^2 + 2]) sage: I = K.fractional_ideal(4) sage: I^(-1) Fractional ideal (1/4) sage: I * I^(-1) Fractional ideal (1) """ raise ZeroDivisionError
def is_principal(self, proof=None): """ Return True if this ideal is principal. If so, set self.__reduced_generators, with length one.
EXAMPLES::
sage: K.<a, b> = NumberField([x^2 - 23, x^2 + 1]) sage: I = K.ideal([7, (-1/2*b - 3/2)*a + 3/2*b + 9/2]) sage: I.is_principal() True sage: I # random Fractional ideal ((1/2*b + 1/2)*a - 3/2*b - 3/2) """
def is_zero(self): r""" Return True if this is the zero ideal.
EXAMPLES::
sage: K.<a, b> = NumberField([x^2 + 3, x^3 + 4]) sage: K.ideal(17).is_zero() False sage: K.ideal(0).is_zero() True """
def absolute_norm(self): """ Compute the absolute norm of this fractional ideal in a relative number field, returning a positive integer.
EXAMPLES::
sage: L.<a, b, c> = QQ.extension([x^2 - 23, x^2 - 5, x^2 - 7]) sage: I = L.ideal(a + b) sage: I.absolute_norm() 104976 sage: I.relative_norm().relative_norm().relative_norm() 104976 """
def relative_norm(self): """ Compute the relative norm of this fractional ideal in a relative number field, returning an ideal in the base field.
EXAMPLES::
sage: R.<x> = QQ[] sage: K.<a> = NumberField(x^2+6) sage: L.<b> = K.extension(K['x'].gen()^4 + a) sage: N = L.ideal(b).relative_norm(); N Fractional ideal (-a) sage: N.parent() Monoid of ideals of Number Field in a with defining polynomial x^2 + 6 sage: N.ring() Number Field in a with defining polynomial x^2 + 6 sage: PQ.<X> = QQ[] sage: F.<a, b> = NumberField([X^2 - 2, X^2 - 3]) sage: PF.<Y> = F[] sage: K.<c> = F.extension(Y^2 - (1 + a)*(a + b)*a*b) sage: K.ideal(1).relative_norm() Fractional ideal (1) sage: K.ideal(13).relative_norm().relative_norm() Fractional ideal (28561) sage: K.ideal(13).relative_norm().relative_norm().relative_norm() 815730721 sage: K.ideal(13).absolute_norm() 815730721
Number fields defined by non-monic and non-integral polynomials are supported (:trac:`252`)::
sage: K.<a> = NumberField(2*x^2 - 1/3) sage: L.<b> = K.extension(5*x^2 + 1) sage: P = L.primes_above(2)[0] sage: P.relative_norm() Fractional ideal (-6*a + 2) """
def norm(self): """ The norm of a fractional ideal in a relative number field is deliberately unimplemented, so that a user cannot mistake the absolute norm for the relative norm, or vice versa.
EXAMPLES::
sage: K.<a, b> = NumberField([x^2 + 1, x^2 - 2]) sage: K.ideal(2).norm() Traceback (most recent call last): ... NotImplementedError: For a fractional ideal in a relative number field you must use relative_norm or absolute_norm as appropriate """
def ideal_below(self): r""" Compute the ideal of `K` below this ideal of `L`.
EXAMPLES::
sage: R.<x> = QQ[] sage: K.<a> = NumberField(x^2+6) sage: L.<b> = K.extension(K['x'].gen()^4 + a) sage: N = L.ideal(b) sage: M = N.ideal_below(); M == K.ideal([-a]) True sage: Np = L.ideal( [ L(t) for t in M.gens() ]) sage: Np.ideal_below() == M True sage: M.parent() Monoid of ideals of Number Field in a with defining polynomial x^2 + 6 sage: M.ring() Number Field in a with defining polynomial x^2 + 6 sage: M.ring() is K True
This example concerns an inert ideal::
sage: K = NumberField(x^4 + 6*x^2 + 24, 'a') sage: K.factor(7) Fractional ideal (7) sage: K0, K0_into_K, _ = K.subfields(2)[0] sage: K0 Number Field in a0 with defining polynomial x^2 - 6*x + 24 sage: L = K.relativize(K0_into_K, 'c'); L Number Field in c with defining polynomial x^2 + a0 over its base field sage: L.base_field() is K0 True sage: L.ideal(7) Fractional ideal (7) sage: L.ideal(7).ideal_below() Fractional ideal (7) sage: L.ideal(7).ideal_below().number_field() is K0 True
This example concerns an ideal that splits in the quadratic field but each factor ideal remains inert in the extension::
sage: len(K.factor(19)) 2 sage: K0 = L.base_field(); a0 = K0.gen() sage: len(K0.factor(19)) 2 sage: w1 = -a0 + 1; P1 = K0.ideal([w1]) sage: P1.norm().factor(), P1.is_prime() (19, True) sage: L_into_K, K_into_L = L.structure() sage: L.ideal(K_into_L(K0_into_K(w1))).ideal_below() == P1 True
The choice of embedding of quadratic field into quartic field matters::
sage: rho, tau = K0.embeddings(K) sage: L1 = K.relativize(rho, 'b') sage: L2 = K.relativize(tau, 'b') sage: L1_into_K, K_into_L1 = L1.structure() sage: L2_into_K, K_into_L2 = L2.structure() sage: a = K.gen() sage: P = K.ideal([a^2 + 5]) sage: K_into_L1(P).ideal_below() == K0.ideal([-a0 + 1]) True sage: K_into_L2(P).ideal_below() == K0.ideal([-a0 + 5]) True sage: K0.ideal([-a0 + 1]) == K0.ideal([-a0 + 5]) False
It works when the base_field is itself a relative number field::
sage: PQ.<X> = QQ[] sage: F.<a, b> = NumberFieldTower([X^2 - 2, X^2 - 3]) sage: PF.<Y> = F[] sage: K.<c> = F.extension(Y^2 - (1 + a)*(a + b)*a*b) sage: I = K.ideal(3, c) sage: J = I.ideal_below(); J Fractional ideal (-b) sage: J.number_field() == F True
Number fields defined by non-monic and non-integral polynomials are supported (:trac:`252`)::
sage: K.<a> = NumberField(2*x^2 - 1/3) sage: L.<b> = K.extension(5*x^2 + 1) sage: P = L.primes_above(2)[0] sage: P.ideal_below() Fractional ideal (-6*a + 2) """
def factor(self): """ Factor the ideal by factoring the corresponding ideal in the absolute number field.
EXAMPLES::
sage: K.<a, b> = QQ.extension([x^2 + 11, x^2 - 5]) sage: K.factor(5) (Fractional ideal (5, (-1/4*b - 1/4)*a + 1/4*b - 3/4))^2 * (Fractional ideal (5, (-1/4*b - 1/4)*a + 1/4*b - 7/4))^2 sage: K.ideal(5).factor() (Fractional ideal (5, (-1/4*b - 1/4)*a + 1/4*b - 3/4))^2 * (Fractional ideal (5, (-1/4*b - 1/4)*a + 1/4*b - 7/4))^2 sage: K.ideal(5).prime_factors() [Fractional ideal (5, (-1/4*b - 1/4)*a + 1/4*b - 3/4), Fractional ideal (5, (-1/4*b - 1/4)*a + 1/4*b - 7/4)]
sage: PQ.<X> = QQ[] sage: F.<a, b> = NumberFieldTower([X^2 - 2, X^2 - 3]) sage: PF.<Y> = F[] sage: K.<c> = F.extension(Y^2 - (1 + a)*(a + b)*a*b) sage: I = K.ideal(c) sage: P = K.ideal((b*a - b - 1)*c/2 + a - 1) sage: Q = K.ideal((b*a - b - 1)*c/2) sage: list(I.factor()) == [(P, 2), (Q, 1)] True sage: I == P^2*Q True sage: [p.is_prime() for p in [P, Q]] [True, True] """ # sorting and simplification will already have been done
def integral_basis(self): r""" Return a basis for self as a `\ZZ`-module.
EXAMPLES::
sage: K.<a,b> = NumberField([x^2 + 1, x^2 - 3]) sage: I = K.ideal(17*b - 3*a) sage: x = I.integral_basis(); x # random [438, -b*a + 309, 219*a - 219*b, 156*a - 154*b]
The exact results are somewhat unpredictable, hence the ``# random`` flag, but we can test that they are indeed a basis::
sage: V, _, phi = K.absolute_vector_space() sage: V.span([phi(u) for u in x], ZZ) == I.free_module() True """
def integral_split(self): r""" 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: K.<a, b> = NumberFieldTower([x^2 - 23, x^2 + 1]) sage: I = K.ideal([a + b/3]) sage: J, d = I.integral_split() sage: J.is_integral() True sage: J == d*I True """
def is_prime(self): """ Return True if this ideal of a relative number field is prime.
EXAMPLES::
sage: K.<a, b> = NumberField([x^2 - 17, x^3 - 2]) sage: K.ideal(a + b).is_prime() True sage: K.ideal(13).is_prime() False """
def is_integral(self): """ Return True if this ideal is integral.
EXAMPLES::
sage: K.<a, b> = QQ.extension([x^2 + 11, x^2 - 5]) sage: I = K.ideal(7).prime_factors()[0] sage: I.is_integral() True sage: (I/2).is_integral() False """
def absolute_ramification_index(self): """ Return the absolute ramification index of this fractional ideal, assuming it is prime. Otherwise, raise a ValueError.
The absolute ramification index is the power of this prime appearing in the factorization of the rational prime that this prime lies over.
Use relative_ramification_index to obtain the power of this prime occurring in the factorization of the prime ideal of the base field that this prime lies over.
EXAMPLES::
sage: PQ.<X> = QQ[] sage: F.<a, b> = NumberFieldTower([X^2 - 2, X^2 - 3]) sage: PF.<Y> = F[] sage: K.<c> = F.extension(Y^2 - (1 + a)*(a + b)*a*b) sage: I = K.ideal(3, c) sage: I.absolute_ramification_index() 4 sage: I.smallest_integer() 3 sage: K.ideal(3) == I^4 True """ raise ValueError("the fractional ideal (= %s) is not prime"%self)
def relative_ramification_index(self): """ Return the relative ramification index of this fractional ideal, assuming it is prime. Otherwise, raise a ValueError.
The relative ramification index is the power of this prime appearing in the factorization of the prime ideal of the base field that this prime lies over.
Use absolute_ramification_index to obtain the power of this prime occurring in the factorization of the rational prime that this prime lies over.
EXAMPLES::
sage: PQ.<X> = QQ[] sage: F.<a, b> = NumberFieldTower([X^2 - 2, X^2 - 3]) sage: PF.<Y> = F[] sage: K.<c> = F.extension(Y^2 - (1 + a)*(a + b)*a*b) sage: I = K.ideal(3, c) sage: I.relative_ramification_index() 2 sage: I.ideal_below() # random sign Fractional ideal (b) sage: I.ideal_below() == K.ideal(b) True sage: K.ideal(b) == I^2 True """ raise ValueError("the fractional ideal (= %s) is not prime"%self)
def ramification_index(self): r""" For ideals in relative number fields, ``ramification_index`` is deliberately not implemented in order to avoid ambiguity. Either :meth:`~relative_ramification_index` or :meth:`~absolute_ramification_index` should be used instead.
EXAMPLES::
sage: K.<a, b> = NumberField([x^2 + 1, x^2 - 2]) sage: K.ideal(2).ramification_index() Traceback (most recent call last): ... NotImplementedError: For an ideal in a relative number field you must use relative_ramification_index or absolute_ramification_index as appropriate """
def residue_class_degree(self): r""" Return the residue class degree of this prime.
EXAMPLES::
sage: PQ.<X> = QQ[] sage: F.<a, b> = NumberFieldTower([X^2 - 2, X^2 - 3]) sage: PF.<Y> = F[] sage: K.<c> = F.extension(Y^2 - (1 + a)*(a + b)*a*b) sage: [I.residue_class_degree() for I in K.ideal(c).prime_factors()] [1, 2] """ raise ValueError("the ideal (= %s) is not prime"%self)
def residues(self): """ Returns a iterator through a complete list of residues modulo this integral ideal.
An error is raised if this fractional ideal is not integral.
EXAMPLES::
sage: K.<a, w> = NumberFieldTower([x^2 - 3, x^2 + x + 1]) sage: I = K.ideal(6, -w*a - w + 4) sage: list(I.residues())[:5] [(25/3*w - 1/3)*a + 22*w + 1, (16/3*w - 1/3)*a + 13*w, (7/3*w - 1/3)*a + 4*w - 1, (-2/3*w - 1/3)*a - 5*w - 2, (-11/3*w - 1/3)*a - 14*w - 3] """
def element_1_mod(self, other): r""" Returns 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.
EXAMPLES::
sage: K.<a, b> = NumberFieldTower([x^2 - 23, x^2 + 1]) sage: I = Ideal(2, (a - 3*b + 2)/2) sage: J = K.ideal(a) sage: z = I.element_1_mod(J) sage: z in I True sage: 1 - z in J True """ # Catch invalid inputs by making sure that we can make an ideal out of other. raise TypeError("%s is not an integral ideal"%self)
raise TypeError("%s is not an integral ideal"%other)
raise TypeError("%s and %s are not coprime ideals"%(self, other))
def smallest_integer(self): r""" Return the smallest non-negative integer in `I \cap \ZZ`, where `I` is this ideal. If `I = 0`, returns `0`.
EXAMPLES::
sage: K.<a, b> = NumberFieldTower([x^2 - 23, x^2 + 1]) sage: I = K.ideal([a + b]) sage: I.smallest_integer() 12 sage: [m for m in range(13) if m in I] [0, 12] """
def valuation(self, p): r""" Return the valuation of this fractional ideal at ``p``.
INPUT:
- ``p`` -- a prime ideal `\mathfrak{p}` of this relative 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: K.<a, b> = NumberField([x^2 - 17, x^3 - 2]) sage: A = K.ideal(a + b) sage: A.is_prime() True sage: (A*K.ideal(3)).valuation(A) 1 sage: K.ideal(25).valuation(5) Traceback (most recent call last): ... ValueError: p (= Fractional ideal (5)) must be a prime """ raise ValueError("p (= %s) must be nonzero"%p) raise ValueError("p (= %s) must be an ideal in %s"%self.number_field())
def is_NumberFieldFractionalIdeal_rel(x): """ Return True if x is a fractional ideal of a relative number field.
EXAMPLES::
sage: from sage.rings.number_field.number_field_ideal_rel import is_NumberFieldFractionalIdeal_rel sage: from sage.rings.number_field.number_field_ideal import is_NumberFieldFractionalIdeal sage: is_NumberFieldFractionalIdeal_rel(2/3) False sage: is_NumberFieldFractionalIdeal_rel(ideal(5)) False sage: k.<a> = NumberField(x^2 + 2) sage: I = k.ideal([a + 1]); I Fractional ideal (a + 1) sage: is_NumberFieldFractionalIdeal_rel(I) False sage: R.<x> = QQ[] sage: K.<a> = NumberField(x^2+6) sage: L.<b> = K.extension(K['x'].gen()^4 + a) sage: I = L.ideal(b); I Fractional ideal (6, b) sage: is_NumberFieldFractionalIdeal_rel(I) True sage: N = I.relative_norm(); N Fractional ideal (-a) sage: is_NumberFieldFractionalIdeal_rel(N) False sage: is_NumberFieldFractionalIdeal(N) True """
|