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 -*- Valuations which are defined as limits of valuations.
The discrete valuation of a complete field extends uniquely to a finite field extension. This is not the case anymore for fields which are not complete with respect to their discrete valuation. In this case, the extensions essentially correspond to the factors of the defining polynomial of the extension over the completion. However, these factors only exist over the completion and this makes it difficult to write down such valuations with a representation of finite length.
More specifically, let `v` be a discrete valuation on `K` and let `L=K[x]/(G)` a finite extension thereof. An extension of `v` to `L` can be represented as a discrete pseudo-valuation `w'` on `K[x]` which sends `G` to infinity. However, such `w'` might not be described by an :mod:`augmented valuation <sage.rings.valuation.augmented_valuation>` over a :mod:`Gauss valuation <sage.rings.valuation.gauss_valuation>` anymore. Instead, we may need to write is as a limit of augmented valuations.
The classes in this module provide the means of writing down such limits and resulting valuations on quotients.
AUTHORS:
- Julian Rüth (2016-10-19): initial version
EXAMPLES:
In this function field, the unique place of ``K`` which corresponds to the zero point has two extensions to ``L``. The valuations corresponding to these extensions can only be approximated::
sage: K.<x> = FunctionField(QQ) sage: R.<y> = K[] sage: L.<y> = K.extension(y^2 - x)
sage: v = K.valuation(1) sage: w = v.extensions(L); w [[ (x - 1)-adic valuation, v(y + 1) = 1 ]-adic valuation, [ (x - 1)-adic valuation, v(y - 1) = 1 ]-adic valuation]
The same phenomenon can be observed for valuations on number fields::
sage: K = QQ sage: R.<t> = K[] sage: L.<t> = K.extension(t^2 + 1) sage: v = QQ.valuation(5) sage: w = v.extensions(L); w [[ 5-adic valuation, v(t + 2) = 1 ]-adic valuation, [ 5-adic valuation, v(t + 3) = 1 ]-adic valuation]
.. NOTE::
We often rely on approximations of valuations even if we could represent the valuation without using a limit. This is done to improve performance as many computations already can be done correctly with an approximation::
sage: K.<x> = FunctionField(QQ) sage: R.<y> = K[] sage: L.<y> = K.extension(y^2 - x)
sage: v = K.valuation(1/x) sage: w = v.extension(L); w Valuation at the infinite place sage: w._base_valuation._base_valuation._improve_approximation() sage: w._base_valuation._base_valuation._approximation [ Gauss valuation induced by Valuation at the infinite place, v(y) = 1/2, v(y^2 - 1/x) = +Infinity ]
REFERENCES:
Limits of inductive valuations are discussed in [Mac1936I]_ and [Mac1936II]_. An overview can also be found in Section 4.6 of [Rüt2014]_.
""" #***************************************************************************** # Copyright (C) 2016-2017 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""" Return a limit valuation which sends the polynomial ``G`` to infinity and is greater than or equal than ``base_valuation``.
INPUT:
- ``base_valuation`` -- a discrete (pseudo-)valuation on a polynomial ring which is a discrete valuation on the coefficient ring which can be unqiuely augmented (possibly only in the limit) to a pseudo-valuation that sends ``G`` to infinity.
- ``G`` -- a squarefree polynomial in the domain of ``base_valuation``.
EXAMPLES::
sage: R.<x> = QQ[] sage: v = GaussValuation(R, QQ.valuation(2)) sage: w = valuations.LimitValuation(v, x) sage: w(x) +Infinity
""" r""" Create a key from the parameters of this valuation.
EXAMPLES:
Note that this does not normalize ``base_valuation`` in any way. It is easily possible to create the same limit in two different ways::
sage: R.<x> = QQ[] sage: v = GaussValuation(R, QQ.valuation(2)) sage: w = valuations.LimitValuation(v, x) # indirect doctest sage: v = v.augmentation(x, infinity) sage: u = valuations.LimitValuation(v, x) sage: u == w False
The point here is that this is not meant to be invoked from user code. But mostly from other factories which have made sure that the parameters are normalized already.
""" raise ValueError("base_valuation must be discrete on the coefficient ring.")
r""" Create an object from ``key``.
EXAMPLES::
sage: R.<x> = QQ[] sage: v = GaussValuation(R, QQ.valuation(2)) sage: w = valuations.LimitValuation(v, x^2 + 1) # indirect doctest
"""
r""" Base class for limit valuations.
A limit valuation is realized as an approximation of a valuation and means to improve that approximation when necessary.
EXAMPLES::
sage: K.<x> = FunctionField(QQ) sage: R.<y> = K[] sage: L.<y> = K.extension(y^2 - x)
sage: v = K.valuation(0) sage: w = v.extension(L) sage: w._base_valuation [ Gauss valuation induced by (x)-adic valuation, v(y) = 1/2 , … ]
The currently used approximation can be found in the ``_approximation`` field::
sage: w._base_valuation._approximation [ Gauss valuation induced by (x)-adic valuation, v(y) = 1/2 ]
TESTS::
sage: from sage.rings.valuation.limit_valuation import LimitValuation_generic sage: isinstance(w._base_valuation, LimitValuation_generic) True sage: TestSuite(w._base_valuation).run() # long time
""" r""" TESTS::
sage: R.<x> = QQ[] sage: K.<i> = QQ.extension(x^2 + 1) sage: v = K.valuation(2) sage: from sage.rings.valuation.limit_valuation import LimitValuation_generic sage: isinstance(v._base_valuation, LimitValuation_generic) True
"""
r""" Return the reduction of ``f`` as an element of the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_ring`.
INPUT:
- ``f`` -- an element in the domain of this valuation of non-negative valuation
- ``check`` -- whether or not to check that ``f`` has non-negative valuation (default: ``True``)
EXAMPLES::
sage: K.<x> = FunctionField(QQ) sage: R.<y> = K[] sage: L.<y> = K.extension(y^2 - (x - 1))
sage: v = K.valuation(0) sage: w = v.extension(L) sage: w.reduce(y) # indirect doctest u1
"""
r""" Return the valuation of ``f``.
EXAMPLES::
sage: K.<x> = FunctionField(QQ) sage: R.<y> = K[] sage: L.<y> = K.extension(y^2 - x)
sage: v = K.valuation(0) sage: w = v.extension(L) sage: w(y) # indirect doctest 1/2
""" self._improve_approximation_for_call(f) return self._approximation(f)
def _improve_approximation_for_reduce(self, f): r""" Replace our approximation with a sufficiently precise approximation to correctly compute the reduction of ``f``.
EXAMPLES::
sage: K.<x> = FunctionField(QQ) sage: R.<y> = K[] sage: L.<y> = K.extension(y^2 - (x - 1337))
For the unique extension over the place at 1337, the initial approximation is sufficient to compute the reduction of ``y``::
sage: v = K.valuation(1337) sage: w = v.extension(L) sage: u = w._base_valuation sage: u._approximation [ Gauss valuation induced by (x - 1337)-adic valuation, v(y) = 1/2 ] sage: w.reduce(y) 0 sage: u._approximation [ Gauss valuation induced by (x - 1337)-adic valuation, v(y) = 1/2 ]
However, at a place over 1341, the initial approximation is not sufficient for some values (note that 1341-1337 is a square)::
sage: v = K.valuation(1341) sage: w = v.extensions(L)[1] sage: u = w._base_valuation sage: u._approximation [ Gauss valuation induced by (x - 1341)-adic valuation, v(y - 2) = 1 ] sage: w.reduce((y - 2) / (x - 1341)) # indirect doctest 1/4 sage: u._approximation [ Gauss valuation induced by (x - 1341)-adic valuation, v(y - 1/4*x + 1333/4) = 2 ] sage: w.reduce((y - 1/4*x + 1333/4) / (x - 1341)^2) # indirect doctest -1/64 sage: u._approximation [ Gauss valuation induced by (x - 1341)-adic valuation, v(y + 1/64*x^2 - 1349/32*x + 1819609/64) = 3 ]
"""
def _improve_approximation_for_call(self, f): r""" Replace our approximation with a sufficiently precise approximation to correctly compute the valuation of ``f``.
EXAMPLES::
sage: K.<x> = FunctionField(QQ) sage: R.<y> = K[] sage: L.<y> = K.extension(y^2 - (x - 23))
For the unique extension over the place at 23, the initial approximation is sufficient to compute all valuations::
sage: v = K.valuation(23) sage: w = v.extension(L) sage: u = w._base_valuation sage: u._approximation [ Gauss valuation induced by (x - 23)-adic valuation, v(y) = 1/2 ] sage: w(x - 23) 1 sage: u._approximation [ Gauss valuation induced by (x - 23)-adic valuation, v(y) = 1/2 ]
However, due to performance reasons, sometimes we improve the approximation though it would not have been necessary (performing the improvement step is faster in this case than checking whether the approximation is sufficient)::
sage: w(y) # indirect doctest 1/2 sage: u._approximation [ Gauss valuation induced by (x - 23)-adic valuation, v(y) = 1/2, v(y^2 - x + 23) = +Infinity ]
"""
r""" Return a printable representation of this valuation.
EXAMPLES::
sage: K = QQ sage: R.<t> = K[] sage: L.<t> = K.extension(t^2 + 1) sage: v = QQ.valuation(2) sage: w = v.extension(L) sage: w._base_valuation # indirect doctest [ Gauss valuation induced by 2-adic valuation, v(t + 1) = 1/2 , … ]
""" return repr(self._initial_approximation)
r""" A limit valuation that is a pseudo-valuation on polynomial ring `K[x]` which sends a square-free polynomial `G` to infinity.
This uses the MacLane algorithm to compute the next element in the limit.
It starts from a first valuation ``approximation`` which has a unique augmentation that sends `G` to infinity and whose uniformizer must be a uniformizer of the limit and whose residue field must contain the residue field of the limit.
EXAMPLES::
sage: R.<x> = QQ[] sage: K.<i> = QQ.extension(x^2 + 1)
sage: v = K.valuation(2) sage: u = v._base_valuation; u [ Gauss valuation induced by 2-adic valuation, v(x + 1) = 1/2 , … ]
""" r""" TESTS::
sage: R.<x> = QQ[] sage: K.<i> = QQ.extension(x^2 + 1) sage: v = K.valuation(2) sage: u = v._base_valuation sage: from sage.rings.valuation.limit_valuation import MacLaneLimitValuation sage: isinstance(u, MacLaneLimitValuation) True
"""
r""" Return the extensions of this valuation to ``ring``.
EXAMPLES::
sage: v = GaussianIntegers().valuation(2) sage: u = v._base_valuation sage: u.extensions(QQ['x']) [[ Gauss valuation induced by 2-adic valuation, v(x + 1) = 1/2 , … ]]
""" from sage.rings.polynomial.polynomial_ring import is_PolynomialRing if is_PolynomialRing(ring) and self.domain().base_ring().is_subring(ring.base_ring()): if self.domain().base_ring().fraction_field() is ring.base_ring(): return [LimitValuation(self._initial_approximation.change_domain(ring), self._G.change_ring(ring.base_ring()))] else: # we need to recompute the mac lane approximants over this base # ring because it could split differently pass return super(MacLaneLimitValuation, self).extensions(ring)
r""" Return a lift of ``F`` from the :meth:`~sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace.ElementMethods.residue_ring` to the domain of this valuatiion.
EXAMPLES::
sage: K.<x> = FunctionField(QQ) sage: R.<y> = K[] sage: L.<y> = K.extension(y^4 - x^2 - 2*x - 1)
sage: v = K.valuation(1) sage: w = v.extensions(L)[1]; w [ (x - 1)-adic valuation, v(y^2 - 2) = 1 ]-adic valuation sage: s = w.reduce(y); s u1 sage: w.lift(s) # indirect doctest y
"""
r""" Return a uniformizing element for this valuation.
EXAMPLES::
sage: K.<x> = FunctionField(QQ) sage: R.<y> = K[] sage: L.<y> = K.extension(y^2 - x)
sage: v = K.valuation(0) sage: w = v.extension(L) sage: w.uniformizer() # indirect doctest y
"""
r""" Return the valuation of ``f``.
EXAMPLES::
sage: K = QQ sage: R.<x> = K[] sage: vK = K.valuation(2) sage: f = (x^2 + 7) * (x^2 + 9) sage: V = vK.mac_lane_approximants(f, require_incomparability=True)
sage: w = valuations.LimitValuation(V[0], f) sage: w((x^2 + 7) * (x + 3)) 3/2
sage: w = valuations.LimitValuation(V[1], f) sage: w((x^2 + 7) * (x + 3)) +Infinity
sage: w = valuations.LimitValuation(V[2], f) sage: w((x^2 + 7) * (x + 3)) +Infinity
"""
r""" Perform one step of the Mac Lane algorithm to improve our approximation.
EXAMPLES::
sage: K = QQ sage: R.<t> = K[] sage: L.<t> = K.extension(t^2 + 1) sage: v = QQ.valuation(2) sage: w = v.extension(L) sage: u = w._base_valuation sage: u._approximation [ Gauss valuation induced by 2-adic valuation, v(t + 1) = 1/2 ] sage: u._improve_approximation() sage: u._approximation [ Gauss valuation induced by 2-adic valuation, v(t + 1) = 1/2, v(t^2 + 1) = +Infinity ]
This method has no effect, if the approximation is already an infinite valuation::
sage: u._improve_approximation() sage: u._approximation [ Gauss valuation induced by 2-adic valuation, v(t + 1) = 1/2, v(t^2 + 1) = +Infinity ]
""" # an infinite valuation can not be improved further
assume_squarefree=True, assume_equivalence_irreducible=True, check=False, principal_part_bound=1 if self._approximation.E()*self._approximation.F() == self._approximation.phi().degree() else None, report_degree_bounds_and_caches=True)
r""" Replace our approximation with a sufficiently precise approximation to correctly compute the valuation of ``f``.
EXAMPLES:
In this examples, the approximation is increased unnecessarily. The first approximation would have been precise enough to compute the valuation of ``t + 2``. However, it is faster to improve the approximation (perform one step of the Mac Lane algorithm) than to check for this::
sage: K = QQ sage: R.<t> = K[] sage: L.<t> = K.extension(t^2 + 1) sage: v = QQ.valuation(5) sage: w = v.extensions(L)[0] sage: u = w._base_valuation sage: u._approximation [ Gauss valuation induced by 5-adic valuation, v(t + 2) = 1 ] sage: w(t + 2) # indirect doctest 1 sage: u._approximation [ Gauss valuation induced by 5-adic valuation, v(t + 7) = 2 ]
ALGORITHM:
Write `L=K[x]/(G)` and consider `g` a representative of the class of ``f`` in `K[x]` (of minimal degree.) Write `v` for ``self._approximation` and `\phi` for the last key polynomial of `v`. With repeated quotient and remainder `g` has a unique expansion as `g=\sum a_i\phi^i`. Suppose that `g` is an equivalence-unit with respect to ``self._approximation``, i.e., `v(a_0) < v(a_i\phi^i)` for all `i\ne 0`. If we denote the limit valuation as `w`, then `v(a_i\phi^i)=w(a_i\phi^i)` since the valuation of key polynomials does not change during augmentations (Theorem 6.4 in [Mac1936II]_.) By the strict triangle inequality, `w(g)=v(g)`. Note that any `g` which is coprime to `G` is an equivalence-unit after finitely many steps of the Mac Lane algorithm. Indeed, otherwise the valuation of `g` would be infinite (follows from Theorem 5.1 in [Mac1936II]_) since the valuation of the key polynomials increases. When `f` is not coprime to `G`, consider `s=gcd(f,G)` and write `G=st`. Since `G` is squarefree, either `s` or `t` have finite valuation. With the above algorithm, this can be decided in finitely many steps. From this we can deduce the valuation of `s` (and in fact replace `G` with the factor with infinite valuation for all future computations.)
""" # an infinite valuation can not be improved further
# zero always has infinite valuation (actually, this might # not be desirable for inexact zero elements with leading # zero coefficients.)
# TODO: I doubt that this really works over inexact fields else:
# t has infinite valuation self._G = t return self._improve_approximation_for_call(f // s) # s has infinite valuation
self._improve_approximation()
r""" Replace our approximation with a sufficiently precise approximation to correctly compute the reduction of ``f``.
EXAMPLES::
sage: K = QQ sage: R.<t> = K[] sage: L.<t> = K.extension(t^2 + 1) sage: v = QQ.valuation(13) sage: w = v.extensions(L)[0] sage: u = w._base_valuation sage: u._approximation [ Gauss valuation induced by 13-adic valuation, v(t + 5) = 1 ] sage: w.reduce((t + 5) / 13) # indirect doctest 8 sage: u._approximation [ Gauss valuation induced by 13-adic valuation, v(t + 70) = 2 ]
ALGORITHM:
The reduction produced by the approximation is correct for an equivalence-unit, see :meth:`_improve_approximation_for_call`.
"""
r""" Return the residue ring of this valuation, which is always a field.
EXAMPLES::
sage: K = QQ sage: R.<t> = K[] sage: L.<t> = K.extension(t^2 + 1) sage: v = QQ.valuation(2) sage: w = v.extension(L) sage: w.residue_ring() Finite Field of size 2
""" # the approximation ends in v(phi)=infty else:
r""" Return whether this valuation is greater or equal than ``other`` everywhere.
EXAMPLES::
sage: R.<x> = QQ[] sage: F = (x^2 + 7) * (x^2 + 9) sage: G = (x^2 + 7) sage: V = QQ.valuation(2).mac_lane_approximants(F, require_incomparability=True) sage: valuations.LimitValuation(V[0], F) >= valuations.LimitValuation(V[1], F) False sage: valuations.LimitValuation(V[1], F) >= valuations.LimitValuation(V[1], G) True sage: valuations.LimitValuation(V[2], F) >= valuations.LimitValuation(V[2], G) True
""" return other.is_discrete_valuation() # Two MacLane limit valuations v,w over the same constant # valuation are either equal or incomparable; neither v>w nor # v<w can hold everywhere. # They are equal iff they approximate the same factor of their # defining G. Note that they can be equal even if the defining # G is different, so we need to make sure that this can not be # the case. assert self._G.gcd(other._G).is_one() return False
# If the valuations are comparable, they must approximate the # same factor of G (see the documentation of LimitValuation: # the approximation must *uniquely* single out a valuation.) or self._initial_approximation <= other._initial_approximation)
return super(MacLaneLimitValuation, self)._ge_(other)
r""" Return the restriction of this valuation to ``ring``.
EXAMPLES::
sage: K = QQ sage: R.<t> = K[] sage: L.<t> = K.extension(t^2 + 1) sage: v = QQ.valuation(2) sage: w = v.extension(L) sage: w._base_valuation.restriction(K) 2-adic valuation
""" return super(MacLaneLimitValuation, self).restriction(ring)
r""" Return an element in the domain of this valuation which has positive valuation with respect to this valuation and higher valuation with respect to this valuation than with respect to ``other``.
EXAMPLES::
sage: K = QQ sage: R.<t> = K[] sage: L.<t> = K.extension(t^2 + 1) sage: v = QQ.valuation(2) sage: w = v.extension(L) sage: v = QQ.valuation(5) sage: u,uu = v.extensions(L) sage: w._base_valuation._weakly_separating_element(u._base_valuation) # long time 2 sage: u._base_valuation._weakly_separating_element(uu._base_valuation) # long time t + 2
sage: K.<x> = FunctionField(QQ) sage: v = K.valuation(1/x) sage: R.<y> = K[] sage: L.<y> = K.extension(y^2 - 1/(x^2 + 1)) sage: u,uu = v.extensions(L) sage: v = K.valuation(x) sage: w,ww = v.extensions(L) sage: v = K.valuation(1) sage: v = v.extension(L) sage: u.separating_element([uu,ww,w,v]) # long time, random output ((8*x^4 + 12*x^2 + 4)/(x^2 - x))*y + (8*x^4 + 8*x^2 + 1)/(x^3 - x^2)
The underlying algorithm is quite naive and might not terminate in reasonable time. In particular, the order of the arguments sometimes has a huge impact on the runtime::
sage: u.separating_element([ww,w,v,uu]) # not tested, takes forever
""" v = v._base_valuation u = u._base_valuation
# phi of the initial approximant must be good enough to separate it # from any other approximant of an extension else: # if the valuations are sane, it should be possible to separate # them with constants
r""" Return the value semigroup of this valuation.
TESTS::
sage: K = QQ sage: R.<t> = K[] sage: L.<t> = K.extension(t^2 + 1) sage: v = QQ.valuation(5) sage: u,uu = v.extensions(L) sage: u.value_semigroup() Additive Abelian Semigroup generated by -1, 1
""" return self._initial_approximation.value_semigroup()
r""" Return an element with valuation ``s``.
TESTS::
sage: K = QQ sage: R.<t> = K[] sage: L.<t> = K.extension(t^2 + 1) sage: v = QQ.valuation(2) sage: u = v.extension(L) sage: u.element_with_valuation(1/2) t + 1
""" return self._initial_approximation.element_with_valuation(s)
r""" Return an estimate on the coefficient size of ``f``.
The number returned is an estimate on the factor between the number of bits used by ``f`` and the minimal number of bits used by an element congruent to ``f``.
This is used by :meth:`simplify` to decide whether simplification of coefficients is going to lead to a significant shrinking of the coefficients of ``f``.
EXAMPLES::
sage: K = QQ sage: R.<t> = K[] sage: L.<t> = K.extension(t^2 + 1) sage: v = QQ.valuation(2) sage: u = v.extension(L) sage: u._relative_size(1024*t + 1024) 6
"""
r""" Return a simplified version of ``f``.
Produce an element which differs from ``f`` by an element of valuation strictly greater than the valuation of ``f`` (or strictly greater than ``error`` if set.)
EXAMPLES::
sage: K = QQ sage: R.<t> = K[] sage: L.<t> = K.extension(t^2 + 1) sage: v = QQ.valuation(2) sage: u = v.extension(L) sage: u.simplify(t + 1024, force=True) t
"""
# now _approximation is sufficiently precise to compute a valid # simplification of f
error = self.upper_bound(f)
r""" Return a lower bound of this valuation at ``x``.
Use this method to get an approximation of the valuation of ``x`` when speed is more important than accuracy.
EXAMPLES::
sage: K = QQ sage: R.<t> = K[] sage: L.<t> = K.extension(t^2 + 1) sage: v = QQ.valuation(2) sage: u = v.extension(L) sage: u.lower_bound(1024*t + 1024) 10 sage: u(1024*t + 1024) 21/2
"""
r""" Return an upper bound of this valuation at ``x``.
Use this method to get an approximation of the valuation of ``x`` when speed is more important than accuracy.
EXAMPLES::
sage: K = QQ sage: R.<t> = K[] sage: L.<t> = K.extension(t^2 + 1) sage: v = QQ.valuation(2) sage: u = v.extension(L) sage: u.upper_bound(1024*t + 1024) 21/2 sage: u(1024*t + 1024) 21/2
"""
r""" Return whether this valuation attains `-\infty`.
EXAMPLES:
For a Mac Lane limit valuation, this is never the case, so this method always returns ``False``::
sage: K = QQ sage: R.<t> = K[] sage: L.<t> = K.extension(t^2 + 1) sage: v = QQ.valuation(2) sage: u = v.extension(L) sage: u.is_negative_pseudo_valuation() False
""" return False |