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
# -*- coding: utf-8 -*- `p`-adic valuations on number fields and their subrings and completions
EXAMPLES::
sage: ZZ.valuation(2) 2-adic valuation sage: QQ.valuation(3) 3-adic valuation sage: CyclotomicField(5).valuation(5) 5-adic valuation sage: GaussianIntegers().valuation(7) 7-adic valuation sage: Zp(11).valuation() 11-adic valuation
These valuations can then, e.g., be used to compute approximate factorizations in the completion of a ring::
sage: v = ZZ.valuation(2) sage: R.<x> = ZZ[] sage: f = x^5 + x^4 + x^3 + x^2 + x - 1 sage: v.montes_factorization(f, required_precision=20) (x + 676027) * (x^4 + 372550*x^3 + 464863*x^2 + 385052*x + 297869)
AUTHORS:
- Julian Rüth (2013-03-16): initial version
REFERENCES:
The theory used here was originally developed in [Mac1936I]_ and [Mac1936II]_. An overview can also be found in Chapter 4 of [Rüt2014]_.
""" #***************************************************************************** # Copyright (C) 2013-2016 Julian Rüth <julian.rueth@fsfe.org> # # 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/ #*****************************************************************************
r""" Create a ``prime``-adic valuation on ``R``.
INPUT:
- ``R`` -- a subring of a number field or a subring of a local field in characteristic zero
- ``prime`` -- a prime that does not split, a discrete (pseudo-)valuation, a fractional ideal, or ``None`` (default: ``None``)
EXAMPLES:
For integers and rational numbers, ``prime`` is just a prime of the integers::
sage: valuations.pAdicValuation(ZZ, 3) 3-adic valuation
sage: valuations.pAdicValuation(QQ, 3) 3-adic valuation
``prime`` may be ``None`` for local rings::
sage: valuations.pAdicValuation(Qp(2)) 2-adic valuation
sage: valuations.pAdicValuation(Zp(2)) 2-adic valuation
But it must be specified in all other cases::
sage: valuations.pAdicValuation(ZZ) Traceback (most recent call last): ... ValueError: prime must be specified for this ring
It can sometimes be beneficial to define a number field extension as a quotient of a polynomial ring (since number field extensions always compute an absolute polynomial defining the extension which can be very costly)::
sage: R.<x> = QQ[] sage: K.<a> = NumberField(x^2 + 1) sage: R.<x> = K[] sage: L.<b> = R.quo(x^2 + a) sage: valuations.pAdicValuation(L, 2) 2-adic valuation
.. SEEALSO::
:meth:`NumberField_generic.valuation() <sage.rings.number_field.number_field.NumberField_generic.valuation>`, :meth:`Order.valuation() <sage.rings.number_field.order.Order.valuation>`, :meth:`pAdicGeneric.valuation() <sage.rings.padics.padic_generic.pAdicGeneric.valuation>`, :meth:`RationalField.valuation() <sage.rings.rational_field.RationalField.valuation>`, :meth:`IntegerRing_class.valuation() <sage.rings.integer_ring.IntegerRing_class.valuation>`.
""" r""" Create a unique key identifying the valuation of ``R`` with respect to ``prime``.
EXAMPLES::
sage: QQ.valuation(2) # indirect doctest 2-adic valuation
"""
# We do not support equal characteristic yet raise ValueError("R must be a ring of characteristic zero.")
else: raise NotImplementedError("p-adic valuations not implemented for %r"%(R,))
r""" Create a unique key identifying the valuation of ``R`` with respect to ``prime``.
EXAMPLES::
sage: QQ.valuation(2) # indirect doctest 2-adic valuation
""" raise ValueError("prime must be a prime in the integers but %s is not"%(prime,))
r""" Create a unique key identifying the valuation of ``R`` with respect to ``prime``.
EXAMPLES::
sage: Qp(2).valuation() # indirect doctest 2-adic valuation
""" # We do not care much about the value of prime since there is only one # reasonable p-adic valuation here raise ValueError("prime must be an element of positive valuation")
r""" Create a unique key identifying the valuation of ``R`` with respect to ``prime``.
EXAMPLES::
sage: GaussianIntegers().valuation(2) # indirect doctest 2-adic valuation
"""
else: raise ValueError("prime must be a discrete pseudo-valuation, a prime in the base ring, or a fractional ideal")
r""" Create a unique key identifying the valuation of ``R`` with respect to ``v``.
.. NOTE::
``prime``, the original parameter that was passed to :meth:`create_key_and_extra_args`, is only used to provide more meaningful error messages
EXAMPLES::
sage: GaussianIntegers().valuation(ZZ.valuation(2)) # indirect doctest 2-adic valuation
TESTS:
We can extend to the field of fractions of a quotient ring::
sage: R.<x> = ZZ[] sage: S = R.quo(x^2 + 1) sage: v = valuations.pAdicValuation(S, 2) sage: R.<x> = QQ[] sage: S = R.quo(x^2 + 1) sage: v = valuations.pAdicValuation(S, v)
"""
# v is defined on a subring of K[x]. # We try to lift v to a pseudo-valuation on K[x]. # First, we lift valuations defined on subrings of K to # valuations on K[x]. # Then, we lift valuations defined on polynomial rings which are # subrings of K[x] to K[x] # v is defined on a ring whose field of fractions is L else: raise NotImplementedError("can not rewrite %r which is defined on %r as a pseudo-valuation on %r"%(v, v.domain(), G.parent()))
# To obtain uniqueness of p-adic valuations, we need a canonical # description of v. We consider all extensions of vK to L and select # the one approximated by v.
r""" Create a unique key identifying the valuation of ``R`` with respect to ``I``.
.. NOTE::
``prime``, the original parameter that was passed to :meth:`create_key_and_extra_args`, is only used to provide more meaningful error messages
EXAMPLES::
sage: GaussianIntegers().valuation(GaussianIntegers().ideal(2)) # indirect doctest 2-adic valuation
"""
# To obtain uniqueness of p-adic valuations, we need a canonical # description of v. We consider all extensions of vK to L and select # the one approximated by v. # Of course, this only works if I comes from a single prime downstairs. raise ValueError("%r does not lie over a single prime of %r"%(I, K))
raise ValueError("%s does not single out a unique extension of %s to %s"%(prime, vK, L)) else:
r""" Helper method which returns the defining data of the number field ``R``.
EXAMPLES::
sage: R.<x> = QQ[] sage: K = R.quo(x^2 + 1) sage: valuations.pAdicValuation._normalize_number_field_data(K) (Rational Field, Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1, x^2 + 1)
""" raise NotImplementedError("can not normalize quotients over %r"%(R.base_ring(),)) else: raise NotImplementedError("can not normalize %r"%(R,))
r""" Create a `p`-adic valuation from ``key``.
EXAMPLES::
sage: ZZ.valuation(5) # indirect doctest 5-adic valuation
""" else: else: raise NotImplementedError
r""" Abstract base class for `p`-adic valuations.
INPUT:
- ``ring`` -- an integral domain
- ``p`` -- a rational prime over which this valuation lies, not necessarily a uniformizer for the valuation
EXAMPLES::
sage: ZZ.valuation(3) 3-adic valuation
sage: QQ.valuation(5) 5-adic valuation
For `p`-adic rings, ``p`` has to match the `p` of the ring.
sage: v = valuations.pAdicValuation(Zp(3), 2); v Traceback (most recent call last): ... ValueError: prime must be an element of positive valuation
TESTS::
sage: TestSuite(ZZ.valuation(3)).run() # long time sage: TestSuite(QQ.valuation(5)).run() # long time sage: TestSuite(Zp(5).valuation()).run() # long time
""" r""" TESTS::
sage: from sage.rings.padics.padic_valuation import pAdicValuation_base sage: isinstance(ZZ.valuation(3), pAdicValuation_base) True
"""
r""" Return the `p` of this `p`-adic valuation.
EXAMPLES::
sage: GaussianIntegers().valuation(2).p() 2
"""
r""" Reduce ``x`` modulo the ideal of elements of positive valuation.
INPUT:
- ``x`` -- an element in the domain of this valuation
OUTPUT:
An element of the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_field`.
EXAMPLES::
sage: v = ZZ.valuation(3) sage: v.reduce(4) 1
"""
r""" Lift ``x`` from the residue field to the domain of this valuation.
INPUT:
- ``x`` -- an element of the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_field`
EXAMPLES::
sage: v = ZZ.valuation(3) sage: xbar = v.reduce(4) sage: v.lift(xbar) 1
"""
r""" Return whether ``G`` defines a single unramified extension of the completion of the domain of this valuation.
INPUT:
- ``G`` -- a monic squarefree polynomial over the domain of this valuation
- ``include_steps`` -- a boolean (default: ``False``); whether to include the approximate valuations that were used to determine the result in the return value.
- ``assume_squarefree`` -- a boolean (default: ``False``); whether to assume that ``G`` is square-free over the completion of the domain of this valuation. Setting this to ``True`` can significantly improve the performance.
EXAMPLES:
We consider an extension as unramified if its ramification index is 1. Hence, a trivial extension is unramified::
sage: R.<x> = QQ[] sage: v = QQ.valuation(2) sage: v.is_unramified(x) True
If ``G`` remains irreducible in reduction, then it defines an unramified extension::
sage: v.is_unramified(x^2 + x + 1) True
However, even if ``G`` factors, it might define an unramified extension::
sage: v.is_unramified(x^2 + 2*x + 4) True
"""
raise ValueError("G must be a monic univariate polynomial over the domain of this valuation") raise ValueError("G must be squarefree")
ret = False break
ret = False break
return ret, steps else:
r""" Return whether ``G`` defines a single totally ramified extension of the completion of the domain of this valuation.
INPUT:
- ``G`` -- a monic squarefree polynomial over the domain of this valuation
- ``include_steps`` -- a boolean (default: ``False``); where to include the valuations produced during the process of checking whether ``G`` is totally ramified in the return value
- ``assume_squarefree`` -- a boolean (default: ``False``); whether to assume that ``G`` is square-free over the completion of the domain of this valuation. Setting this to ``True`` can significantly improve the performance.
ALGORITHM:
This is a simplified version of :meth:`sage.rings.valuation.valuation.DiscreteValuation.mac_lane_approximants`.
EXAMPLES::
sage: k = Qp(5,4) sage: v = k.valuation() sage: R.<x> = k[] sage: G = x^2 + 1 sage: v.is_totally_ramified(G) False sage: G = x + 1 sage: v.is_totally_ramified(G) True sage: G = x^2 + 2 sage: v.is_totally_ramified(G) False sage: G = x^2 + 5 sage: v.is_totally_ramified(G) True sage: v.is_totally_ramified(G, include_steps=True) (True, [Gauss valuation induced by 5-adic valuation, [ Gauss valuation induced by 5-adic valuation, v((1 + O(5^4))*x) = 1/2 ]])
We consider an extension as totally ramified if its ramification index matches the degree. Hence, a trivial extension is totally ramified::
sage: R.<x> = QQ[] sage: v = QQ.valuation(2) sage: v.is_totally_ramified(x) True
TESTS:
An example that Sebastian Pauli used at Sage Days 87::
sage: R = ZpFM(3, 20) sage: S.<x> = R[] sage: f = x^9 + 9*x^2 + 3 sage: R.valuation().is_totally_ramified(f) True
"""
raise ValueError("G must be a monic univariate polynomial over the domain of this valuation") raise ValueError("G must be squarefree")
ret = False break
else:
r""" Change the domain of this valuation to ``ring`` if possible.
EXAMPLES::
sage: v = ZZ.valuation(2) sage: v.change_domain(QQ).domain() Rational Field
"""
r""" Return the extensions of this valuation to an integral quotient over the domain of this valuation.
EXAMPLES::
sage: R.<x> = QQ[] sage: QQ.valuation(2)._extensions_to_quotient(R.quo(x^2 + x + 1)) [2-adic valuation]
"""
r""" Return the extensions of this valuation to ``ring``.
EXAMPLES::
sage: v = ZZ.valuation(2) sage: v.extensions(GaussianIntegers()) [2-adic valuation]
TESTS::
sage: R.<a> = QQ[] sage: L.<a> = QQ.extension(x^3 - 2) sage: R.<b> = L[] sage: M.<b> = L.extension(b^2 + 2*b + a) sage: M.valuation(2) 2-adic valuation
Check that we can extend to a field written as a quotient::
sage: R.<x> = QQ[] sage: K.<a> = QQ.extension(x^2 + 1) sage: R.<y> = K[] sage: L.<b> = R.quo(x^2 + a) sage: QQ.valuation(2).extensions(L) [2-adic valuation]
A case where there was at some point an internal error in the approximants code::
sage: R.<x> = QQ[] sage: L.<a> = NumberField(x^4 + 2*x^3 + 2*x^2 + 8) sage: QQ.valuation(2).extensions(L) [[ 2-adic valuation, v(x + 2) = 3/2 ]-adic valuation, [ 2-adic valuation, v(x) = 1/2 ]-adic valuation]
A case where the extension was incorrect at some point::
sage: v = QQ.valuation(2) sage: L.<a> = NumberField(x^2 + 2) sage: M.<b> = L.extension(x^2 + 1) sage: w = v.extension(L).extension(M) sage: w(w.uniformizer()) 1/4
A case where the extensions could not be separated at some point::
sage: v = QQ.valuation(2) sage: R.<x> = QQ[] sage: F = x^48 + 120*x^45 + 56*x^42 + 108*x^36 + 32*x^33 + 40*x^30 + 48*x^27 + 80*x^24 + 112*x^21 + 96*x^18 + 96*x^15 + 24*x^12 + 96*x^9 + 16*x^6 + 96*x^3 + 68 sage: L.<a> = QQ.extension(F) sage: v.extensions(L) [[ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 10*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation, [ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 2*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation]
""" if self.domain().modulus() == ring.modulus(): base_extensions = self._base_valuation.extensions(self._base_valuation.domain().change_ring(self._base_valuation.domain().base_ring().fraction_field())) return [pAdicValuation(ring, base._initial_approximation) for base in base_extensions] if ring.base_ring() is not ring and self.domain().is_subring(ring.base_ring()): return sum([w.extensions(ring) for w in self.extensions(ring.base_ring())], []) return super(pAdicValuation_base, self).extensions(ring)
r""" Return the restriction of this valuation to ``ring``.
EXAMPLES::
sage: v = GaussianIntegers().valuation(2) sage: v.restriction(ZZ) 2-adic valuation
"""
raise ValueError("ring must be a subring of the domain of this valuation but %r is not a subring of %r"%(ring, self.domain()))
def value_semigroup(self): r""" Return the value semigroup of this valuation.
EXAMPLES::
sage: v = GaussianIntegers().valuation(2) sage: v.value_semigroup() Additive Abelian Semigroup generated by 1/2
""" else:
""" The `p`-adic valuation of a complete `p`-adic ring.
INPUT:
- ``R`` -- a `p`-adic ring
EXAMPLES::
sage: v = Qp(2).valuation(); v #indirect doctest 2-adic valuation
TESTS::
sage: TestSuite(v).run() # long time
""" """ TESTS::
sage: from sage.rings.padics.padic_valuation import pAdicValuation_padic sage: isinstance(Qp(2).valuation(), pAdicValuation_padic) True
"""
""" Reduce ``x`` modulo the ideal of elements of positive valuation.
INPUT:
- ``x`` -- an element of the domain of this valuation
OUTPUT:
An element of the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_field`.
EXAMPLES::
sage: R = Zp(3) sage: Zp(3).valuation().reduce(R(4)) 1
"""
""" Lift ``x`` from the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_field` to the domain of this valuation.
INPUT:
- ``x`` -- an element of the residue field of this valuation
EXAMPLES::
sage: R = Zp(3) sage: v = R.valuation() sage: xbar = v.reduce(R(4)) sage: v.lift(xbar) 1 + O(3^20)
"""
""" Return a uniformizer of this valuation.
EXAMPLES::
sage: v = Zp(3).valuation() sage: v.uniformizer() 3 + O(3^21)
"""
""" Return an element of valuation ``v``.
INPUT:
- ``v`` -- an element of the :meth:`pAdicValuation_base.value_semigroup` of this valuation
EXAMPLES::
sage: R = Zp(3) sage: v = R.valuation() sage: v.element_with_valuation(3) 3^3 + O(3^23)
sage: K = Qp(3) sage: R.<y> = K[] sage: L.<y> = K.extension(y^2 + 3*y + 3) sage: L.valuation().element_with_valuation(3/2) y^3 + O(y^43)
"""
""" Return a printable representation of this valuation.
EXAMPLES::
sage: ZZ.valuation(3)._repr_() '3-adic valuation'
"""
r""" Evaluate this valuation at ``x``.
EXAMPLES::
sage: K = Qp(3) sage: R.<y> = K[] sage: L.<y> = K.extension(y^2 - 3) sage: L.valuation()(3) 1
"""
r""" Return the residue field of this valuation.
EXAMPLES::
sage: Qq(9, names='a').valuation().residue_ring() Finite Field in a0 of size 3^2
"""
r""" Shift ``x`` in its expansion with respect to :meth:`uniformizer` by ``s`` "digits".
For non-negative ``s``, this just returns ``x`` multiplied by a power of the uniformizer `\pi`.
For negative ``s``, it does the same but when not over a field, it drops coefficients in the `\pi`-adic expension which have negative valuation.
EXAMPLES::
sage: R = ZpCA(2) sage: v = R.valuation() sage: v.shift(R.one(), 1) 2 + O(2^20) sage: v.shift(R.one(), -1) O(2^19)
sage: S.<y> = R[] sage: S.<y> = R.extension(y^3 - 2) sage: v = S.valuation() sage: v.shift(1, 5) y^5 + O(y^60)
"""
r""" Return a simplified version of ``x``.
Produce an element which differs from ``x`` by an element of valuation strictly greater than the valuation of ``x`` (or strictly greater than ``error`` if set.)
INPUT:
- ``x`` -- an element in the domain of this valuation
- ``error`` -- a rational, infinity, or ``None`` (default: ``None``), the error allowed to introduce through the simplification
- ``force`` -- ignored
EXAMPLES::
sage: R = Zp(2) sage: v = R.valuation() sage: v.simplify(6) 2 + O(2^21) sage: v.simplify(6, error=0) 0
"""
return x # we need to scale by the ramification index because p-adics use a # different normalization
r""" A `p`-adic valuation on the integers or the rationals.
EXAMPLES::
sage: v = ZZ.valuation(3); v 3-adic valuation
TESTS::
sage: TestSuite(v).run() # long time
""" """ Return a printable representation of this valuation.
EXAMPLES::
sage: ZZ.valuation(3)._repr_() '3-adic valuation'
"""
""" Evaluate this valuation at ``x``.
INPUT:
- ``x`` -- an element in the domain of this valuation
EXAMPLES::
sage: ZZ.valuation(3)(9) 2
""" # x.valuation() is a factor 10 slower when computing the valuation # of a rational zero than when computing the valuation of another # small rational. Special casing this is a factor 100 faster.
""" Return a uniformizer of this `p`-adic valuation, i.e., `p` as an element of the domain.
EXAMPLES::
sage: v = ZZ.valuation(3) sage: v.uniformizer() 3
"""
""" Return the residue field of this valuation.
EXAMPLES::
sage: v = ZZ.valuation(3) sage: v.residue_ring() Finite Field of size 3
"""
r""" Return whether this valuation is greater than or equal than ``other`` everywhere.
EXAMPLES::
sage: v = ZZ.valuation(2) sage: w = valuations.TrivialValuation(ZZ) sage: v >= w True
"""
r""" Return an estimate on the coefficient size of ``x``.
The number returned is an estimate on the factor between the number of bits used by ``x`` and the minimal number of bits used by an element congruent to ``x``.
This is used by :meth:`simplify` to decide whether simplification of coefficients is going to lead to a significant shrinking of the coefficients of ``x``.
EXAMPLES::
sage: v = ZZ.valuation(2) sage: v._relative_size(2) 1 sage: v._relative_size(2**20) 11
"""
r""" Return a simplified version of ``x``.
Produce an element which differs from ``x`` by an element of valuation strictly greater than the valuation of ``x`` (or strictly greater than ``error`` if set.)
INPUT:
- ``x`` -- an element in the domain of this valuation
- ``error`` -- a rational, infinity, or ``None`` (default: ``None``), the error allowed to introduce through the simplification
- ``force`` -- ignored
- ``size_heuristic_bound`` -- when ``force`` is not set, the expected factor by which the ``x`` need to shrink to perform an actual simplification (default: 32)
EXAMPLES::
sage: v = ZZ.valuation(2) sage: v.simplify(6, force=True) 2 sage: v.simplify(6, error=0, force=True) 0
"""
return x
# If there is not much relative precision left, it is better to # just go with the integer/rational lift. The rational # reconstruction is likely not smaller.
r""" Return an approximate inverse of ``x``.
The element returned is such that the product differs from 1 by an element of valuation at least ``precision``.
INPUT:
- ``x`` -- an element in the domain of this valuation
- ``precision`` -- a rational or infinity
EXAMPLES::
sage: v = ZZ.valuation(2) sage: x = 3 sage: y = v.inverse(3, 2); y 3 sage: x*y - 1 8
This might not be possible for elements of positive valuation::
sage: v.inverse(2, 2) Traceback (most recent call last): ... ValueError: element has no approximate inverse in this ring
Unless the precision is very small::
sage: v.inverse(2, 0) 1
"""
r""" A `p`-adic valuation on a number field or a subring thereof, i.e., a valuation that extends the `p`-adic valuation on the integers.
EXAMPLES::
sage: v = GaussianIntegers().valuation(3); v 3-adic valuation
TESTS::
sage: TestSuite(v).run(skip='_test_shift') # long time
The ``_test_shift`` test fails because the parent of the shift is incorrect, see :trac:`23971`::
sage: v.shift(1, -1).parent() Number Field in I with defining polynomial x^2 + 1
""" r""" TESTS::
sage: v = GaussianIntegers().valuation(3) sage: from sage.rings.padics.padic_valuation import pAdicFromLimitValuation sage: isinstance(v, pAdicFromLimitValuation) True
"""
r""" Return ``f``, an element of the underlying limit valuation, as an element of the domain of this valuation.
EXAMPLES::
sage: v = GaussianIntegers().valuation(3) sage: I = GaussianIntegers().fraction_field().gen() sage: v._to_base_domain(I) x
TESTS:
Check that this also works for relative extensions::
sage: v = QQ.valuation(2) sage: L.<a> = NumberField(x^2 + 2) sage: M.<b> = L.extension(x^2 + 1) sage: w = v.extension(L).extension(M) sage: w._to_base_domain(b) x
"""
r""" Return ``f``, an element of the domain of this valuation, as an element of the domain of the underlying limit valuation.
EXAMPLES::
sage: v = GaussianIntegers().valuation(3) sage: v._from_base_domain(v._base_valuation.domain().gen()) I
"""
r""" Return the extensions of this valuation to ``ring``.
EXAMPLES::
sage: v = GaussianIntegers().valuation(3) sage: v.extensions(v.domain().fraction_field()) [3-adic valuation]
"""
r""" Return a fraction field of ``ring``.
EXAMPLES:
This works around some annoyances with ``ring.fraction_field()``::
sage: R.<x> = ZZ[] sage: S = R.quo(x^2 + 1) sage: S.fraction_field() Fraction Field of Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1
sage: from sage.rings.padics.padic_valuation import _fraction_field sage: _fraction_field(S) Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1
"""
|