Spaces of valuations¶
This module provides spaces of exponential pseudo-valuations on integral domains. It currently only provides support for such valuations if they are discrete, i.e., their image is a discrete additive subgroup of the rational numbers extended by \(\infty\).
AUTHORS:
- Julian Rüth (2016-10-14): initial version 
EXAMPLES:
sage: QQ.valuation(2).parent()
Discrete pseudo-valuations on Rational Field
>>> from sage.all import *
>>> QQ.valuation(Integer(2)).parent()
Discrete pseudo-valuations on Rational Field
Note
Note that many tests not only in this module do not create instances of valuations directly since this gives the wrong inheritance structure on the resulting objects:
sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace
sage: from sage.rings.valuation.trivial_valuation import TrivialDiscretePseudoValuation
sage: H = DiscretePseudoValuationSpace(QQ)
sage: v = TrivialDiscretePseudoValuation(H)
sage: v._test_category()
Traceback (most recent call last):
...
AssertionError: False is not true
>>> from sage.all import *
>>> from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace
>>> from sage.rings.valuation.trivial_valuation import TrivialDiscretePseudoValuation
>>> H = DiscretePseudoValuationSpace(QQ)
>>> v = TrivialDiscretePseudoValuation(H)
>>> v._test_category()
Traceback (most recent call last):
...
AssertionError: False is not true
Instead, the valuations need to be created through the
__make_element_class__ of the containing space:
sage: from sage.rings.valuation.trivial_valuation import TrivialDiscretePseudoValuation
sage: v = H.__make_element_class__(TrivialDiscretePseudoValuation)(H)
sage: v._test_category()
>>> from sage.all import *
>>> from sage.rings.valuation.trivial_valuation import TrivialDiscretePseudoValuation
>>> v = H.__make_element_class__(TrivialDiscretePseudoValuation)(H)
>>> v._test_category()
The factories such as TrivialPseudoValuation provide the right
inheritance structure:
sage: v = valuations.TrivialPseudoValuation(QQ)
sage: v._test_category()
>>> from sage.all import *
>>> v = valuations.TrivialPseudoValuation(QQ)
>>> v._test_category()
- class sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace(domain)[source]¶
- Bases: - UniqueRepresentation,- Homset- The space of discrete pseudo-valuations on - domain.- EXAMPLES: - sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: H = DiscretePseudoValuationSpace(QQ) sage: QQ.valuation(2) in H True - >>> from sage.all import * >>> from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace >>> H = DiscretePseudoValuationSpace(QQ) >>> QQ.valuation(Integer(2)) in H True - Note - We do not distinguish between the space of discrete valuations and the space of discrete pseudo-valuations. This is entirely for practical reasons: We would like to model the fact that every discrete valuation is also a discrete pseudo-valuation. At first, it seems to be sufficient to make sure that the - inoperator works which can essentially be achieved by overriding- _element_constructor_of the space of discrete pseudo-valuations to accept discrete valuations by just returning them. Currently, however, if one does not change the parent of an element in- _element_constructor_to- self, then one cannot register that conversion as a coercion. Consequently, the operators- <=and- >=cannot be made to work between discrete valuations and discrete pseudo-valuations on the same domain (because the implementation only calls- _richcmpif both operands have the same parent.) Of course, we could override- __ge__and- __le__but then we would likely run into other surprises. So in the end, we went for a single homspace for all discrete valuations (pseudo or not) as this makes the implementation much easier.- Todo - The comparison problem might be fixed by Issue #22029 or similar. - class ElementMethods[source]¶
- Bases: - object- Provides methods for discrete pseudo-valuations that are added automatically to valuations in this space. - EXAMPLES: - Here is an example of a method that is automagically added to a discrete valuation: - sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: H = DiscretePseudoValuationSpace(QQ) sage: QQ.valuation(2).is_discrete_pseudo_valuation() # indirect doctest True - >>> from sage.all import * >>> from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace >>> H = DiscretePseudoValuationSpace(QQ) >>> QQ.valuation(Integer(2)).is_discrete_pseudo_valuation() # indirect doctest True - The methods will be provided even if the concrete type is not created with - __make_element_class__:- sage: from sage.rings.valuation.valuation import DiscretePseudoValuation sage: m = DiscretePseudoValuation(H) sage: m.parent() is H True sage: m.is_discrete_pseudo_valuation() True - >>> from sage.all import * >>> from sage.rings.valuation.valuation import DiscretePseudoValuation >>> m = DiscretePseudoValuation(H) >>> m.parent() is H True >>> m.is_discrete_pseudo_valuation() True - However, the category framework advises you to use inheritance: - sage: m._test_category() Traceback (most recent call last): ... AssertionError: False is not true - >>> from sage.all import * >>> m._test_category() Traceback (most recent call last): ... AssertionError: False is not true - Using - __make_element_class__, makes your concrete valuation inherit from this class:- sage: m = H.__make_element_class__(DiscretePseudoValuation)(H) sage: m._test_category() - >>> from sage.all import * >>> m = H.__make_element_class__(DiscretePseudoValuation)(H) >>> m._test_category() - change_domain(ring)[source]¶
- Return this valuation over - ring.- Unlike - extension()or- restriction(), this might not be completely sane mathematically. It is essentially a conversion of this valuation into another space of valuations.- EXAMPLES: - sage: v = QQ.valuation(3) sage: v.change_domain(ZZ) 3-adic valuation - >>> from sage.all import * >>> v = QQ.valuation(Integer(3)) >>> v.change_domain(ZZ) 3-adic valuation 
 - element_with_valuation(s)[source]¶
- Return an element in the domain of this valuation with valuation - s.- EXAMPLES: - sage: v = ZZ.valuation(2) sage: v.element_with_valuation(10) 1024 - >>> from sage.all import * >>> v = ZZ.valuation(Integer(2)) >>> v.element_with_valuation(Integer(10)) 1024 
 - extension(ring)[source]¶
- Return the unique extension of this valuation to - ring.- EXAMPLES: - sage: v = ZZ.valuation(2) sage: w = v.extension(QQ) sage: w.domain() Rational Field - >>> from sage.all import * >>> v = ZZ.valuation(Integer(2)) >>> w = v.extension(QQ) >>> w.domain() Rational Field 
 - extensions(ring)[source]¶
- Return the extensions of this valuation to - ring.- EXAMPLES: - sage: v = ZZ.valuation(2) sage: v.extensions(QQ) [2-adic valuation] - >>> from sage.all import * >>> v = ZZ.valuation(Integer(2)) >>> v.extensions(QQ) [2-adic valuation] 
 - inverse(x, precision)[source]¶
- 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 - >>> from sage.all import * >>> v = ZZ.valuation(Integer(2)) >>> x = Integer(3) >>> y = v.inverse(Integer(3), Integer(2)); y 3 >>> x*y - Integer(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 - >>> from sage.all import * >>> v.inverse(Integer(2), Integer(2)) Traceback (most recent call last): ... ValueError: element has no approximate inverse in this ring - Of course this always works over fields: - sage: v = QQ.valuation(2) sage: v.inverse(2, 2) 1/2 - >>> from sage.all import * >>> v = QQ.valuation(Integer(2)) >>> v.inverse(Integer(2), Integer(2)) 1/2 
 - is_discrete_pseudo_valuation()[source]¶
- Return whether this valuation is a discrete pseudo-valuation. - EXAMPLES: - sage: QQ.valuation(2).is_discrete_pseudo_valuation() True - >>> from sage.all import * >>> QQ.valuation(Integer(2)).is_discrete_pseudo_valuation() True 
 - is_discrete_valuation()[source]¶
- Return whether this valuation is a discrete valuation, i.e., whether it is a - discrete pseudo valuationthat only sends zero to \(\infty\).- EXAMPLES: - sage: QQ.valuation(2).is_discrete_valuation() True - >>> from sage.all import * >>> QQ.valuation(Integer(2)).is_discrete_valuation() True 
 - is_negative_pseudo_valuation()[source]¶
- Return whether this valuation is a discrete pseudo-valuation that does attain \(-\infty\), i.e., it is non-trivial and its domain contains an element with valuation \(\infty\) that has an inverse. - EXAMPLES: - sage: QQ.valuation(2).is_negative_pseudo_valuation() False - >>> from sage.all import * >>> QQ.valuation(Integer(2)).is_negative_pseudo_valuation() False 
 - is_trivial()[source]¶
- Return whether this valuation is trivial, i.e., whether it is constant \(\infty\) or constant zero for everything but the zero element. - Subclasses need to override this method if they do not implement - uniformizer().- EXAMPLES: - sage: QQ.valuation(7).is_trivial() False - >>> from sage.all import * >>> QQ.valuation(Integer(7)).is_trivial() False 
 - lift(X)[source]¶
- Return a lift of - Xin the domain which reduces down to- Xagain via- reduce().- EXAMPLES: - sage: v = QQ.valuation(2) sage: v.lift(v.residue_ring().one()) 1 - >>> from sage.all import * >>> v = QQ.valuation(Integer(2)) >>> v.lift(v.residue_ring().one()) 1 
 - lower_bound(x)[source]¶
- Return a lower bound of this valuation at - x.- Use this method to get an approximation of the valuation of - xwhen speed is more important than accuracy.- EXAMPLES: - sage: v = ZZ.valuation(2) sage: v.lower_bound(2^10) 10 - >>> from sage.all import * >>> v = ZZ.valuation(Integer(2)) >>> v.lower_bound(Integer(2)**Integer(10)) 10 
 - reduce(x)[source]¶
- Return the image of - xin the- residue_ring()of this valuation.- EXAMPLES: - sage: v = QQ.valuation(2) sage: v.reduce(2) 0 sage: v.reduce(1) 1 sage: v.reduce(1/3) 1 sage: v.reduce(1/2) Traceback (most recent call last): ... ValueError: reduction is only defined for elements of nonnegative valuation - >>> from sage.all import * >>> v = QQ.valuation(Integer(2)) >>> v.reduce(Integer(2)) 0 >>> v.reduce(Integer(1)) 1 >>> v.reduce(Integer(1)/Integer(3)) 1 >>> v.reduce(Integer(1)/Integer(2)) Traceback (most recent call last): ... ValueError: reduction is only defined for elements of nonnegative valuation 
 - residue_field()[source]¶
- Return the residue field of this valuation, i.e., the field of fractions of the - residue_ring(), the elements of nonnegative valuation modulo the elements of positive valuation.- EXAMPLES: - sage: QQ.valuation(2).residue_field() Finite Field of size 2 sage: valuations.TrivialValuation(QQ).residue_field() Rational Field sage: valuations.TrivialValuation(ZZ).residue_field() Rational Field sage: GaussValuation(ZZ['x'], ZZ.valuation(2)).residue_field() Rational function field in x over Finite Field of size 2 - >>> from sage.all import * >>> QQ.valuation(Integer(2)).residue_field() Finite Field of size 2 >>> valuations.TrivialValuation(QQ).residue_field() Rational Field >>> valuations.TrivialValuation(ZZ).residue_field() Rational Field >>> GaussValuation(ZZ['x'], ZZ.valuation(Integer(2))).residue_field() Rational function field in x over Finite Field of size 2 
 - residue_ring()[source]¶
- Return the residue ring of this valuation, i.e., the elements of nonnegative valuation modulo the elements of positive valuation. EXAMPLES: - sage: QQ.valuation(2).residue_ring() Finite Field of size 2 sage: valuations.TrivialValuation(QQ).residue_ring() Rational Field - >>> from sage.all import * >>> QQ.valuation(Integer(2)).residue_ring() Finite Field of size 2 >>> valuations.TrivialValuation(QQ).residue_ring() Rational Field - Note that a residue ring always exists, even when a residue field may not: - sage: valuations.TrivialPseudoValuation(QQ).residue_ring() Quotient of Rational Field by the ideal (1) sage: valuations.TrivialValuation(ZZ).residue_ring() Integer Ring sage: GaussValuation(ZZ['x'], ZZ.valuation(2)).residue_ring() Univariate Polynomial Ring in x over Finite Field of size 2... - >>> from sage.all import * >>> valuations.TrivialPseudoValuation(QQ).residue_ring() Quotient of Rational Field by the ideal (1) >>> valuations.TrivialValuation(ZZ).residue_ring() Integer Ring >>> GaussValuation(ZZ['x'], ZZ.valuation(Integer(2))).residue_ring() Univariate Polynomial Ring in x over Finite Field of size 2... 
 - restriction(ring)[source]¶
- Return the restriction of this valuation to - ring.- EXAMPLES: - sage: v = QQ.valuation(2) sage: w = v.restriction(ZZ) sage: w.domain() Integer Ring - >>> from sage.all import * >>> v = QQ.valuation(Integer(2)) >>> w = v.restriction(ZZ) >>> w.domain() Integer Ring 
 - scale(scalar)[source]¶
- Return this valuation scaled by - scalar.- INPUT: - scalar– a nonnegative rational number or infinity
 - EXAMPLES: - sage: v = ZZ.valuation(3) sage: w = v.scale(3) sage: w(3) 3 - >>> from sage.all import * >>> v = ZZ.valuation(Integer(3)) >>> w = v.scale(Integer(3)) >>> w(Integer(3)) 3 - Scaling can also be done through multiplication with a scalar: - sage: w/3 == v True - >>> from sage.all import * >>> w/Integer(3) == v True - Multiplication by zero produces the trivial discrete valuation: - sage: w = 0*v sage: w(3) 0 sage: w(0) +Infinity - >>> from sage.all import * >>> w = Integer(0)*v >>> w(Integer(3)) 0 >>> w(Integer(0)) +Infinity - Multiplication by infinity produces the trivial discrete pseudo-valuation: - sage: w = infinity*v sage: w(3) +Infinity sage: w(0) +Infinity - >>> from sage.all import * >>> w = infinity*v >>> w(Integer(3)) +Infinity >>> w(Integer(0)) +Infinity 
 - separating_element(others)[source]¶
- Return an element in the domain of this valuation which has positive valuation with respect to this valuation but negative valuation with respect to the valuations in - others.- EXAMPLES: - sage: v2 = QQ.valuation(2) sage: v3 = QQ.valuation(3) sage: v5 = QQ.valuation(5) sage: v2.separating_element([v3,v5]) 4/15 - >>> from sage.all import * >>> v2 = QQ.valuation(Integer(2)) >>> v3 = QQ.valuation(Integer(3)) >>> v5 = QQ.valuation(Integer(5)) >>> v2.separating_element([v3,v5]) 4/15 
 - shift(x, s)[source]¶
- Shift - xin its expansion with respect to- uniformizer()by- s“digits”.- For nonnegative - s, this just returns- xmultiplied 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 expansion which have negative valuation.- EXAMPLES: - sage: v = ZZ.valuation(2) sage: v.shift(1, 10) 1024 sage: v.shift(11, -1) 5 - >>> from sage.all import * >>> v = ZZ.valuation(Integer(2)) >>> v.shift(Integer(1), Integer(10)) 1024 >>> v.shift(Integer(11), -Integer(1)) 5 - For some rings, there is no clear \(\pi\)-adic expansion. In this case, this method performs negative shifts by iterated division by the uniformizer and substraction of a lift of the reduction: - sage: R.<x> = ZZ[] sage: v = ZZ.valuation(2) sage: w = GaussValuation(R, v) sage: w.shift(x, 1) 2*x sage: w.shift(2*x, -1) x sage: w.shift(x + 2*x^2, -1) x^2 - >>> from sage.all import * >>> R = ZZ['x']; (x,) = R._first_ngens(1) >>> v = ZZ.valuation(Integer(2)) >>> w = GaussValuation(R, v) >>> w.shift(x, Integer(1)) 2*x >>> w.shift(Integer(2)*x, -Integer(1)) x >>> w.shift(x + Integer(2)*x**Integer(2), -Integer(1)) x^2 
 - simplify(x, error=None, force=False)[source]¶
- Return a simplified version of - x.- Produce an element which differs from - xby an element of valuation strictly greater than the valuation of- x(or strictly greater than- errorif set.)- If - forceis not set, then expensive simplifications may be avoided.- EXAMPLES: - sage: v = ZZ.valuation(2) sage: v.simplify(6, force=True) 2 sage: v.simplify(6, error=0, force=True) 0 - >>> from sage.all import * >>> v = ZZ.valuation(Integer(2)) >>> v.simplify(Integer(6), force=True) 2 >>> v.simplify(Integer(6), error=Integer(0), force=True) 0 
 - uniformizer()[source]¶
- Return an element in the domain which has positive valuation and generates the value group of this valuation. - EXAMPLES: - sage: QQ.valuation(11).uniformizer() 11 - >>> from sage.all import * >>> QQ.valuation(Integer(11)).uniformizer() 11 - Trivial valuations have no uniformizer: - sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: v = DiscretePseudoValuationSpace(QQ).an_element() sage: v.is_trivial() True sage: v.uniformizer() Traceback (most recent call last): ... ValueError: Trivial valuations do not define a uniformizing element - >>> from sage.all import * >>> from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace >>> v = DiscretePseudoValuationSpace(QQ).an_element() >>> v.is_trivial() True >>> v.uniformizer() Traceback (most recent call last): ... ValueError: Trivial valuations do not define a uniformizing element 
 - upper_bound(x)[source]¶
- Return an upper bound of this valuation at - x.- Use this method to get an approximation of the valuation of - xwhen speed is more important than accuracy.- EXAMPLES: - sage: v = ZZ.valuation(2) sage: v.upper_bound(2^10) 10 - >>> from sage.all import * >>> v = ZZ.valuation(Integer(2)) >>> v.upper_bound(Integer(2)**Integer(10)) 10 
 - value_group()[source]¶
- Return the value group of this discrete pseudo-valuation, the discrete additive subgroup of the rational numbers which is generated by the valuation of the - uniformizer().- EXAMPLES: - sage: QQ.valuation(2).value_group() Additive Abelian Group generated by 1 - >>> from sage.all import * >>> QQ.valuation(Integer(2)).value_group() Additive Abelian Group generated by 1 - A pseudo-valuation that is \(\infty\) everywhere, does not have a value group: - sage: from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace sage: v = DiscretePseudoValuationSpace(QQ).an_element() sage: v.value_group() Traceback (most recent call last): ... ValueError: The trivial pseudo-valuation that is infinity everywhere does not have a value group. - >>> from sage.all import * >>> from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace >>> v = DiscretePseudoValuationSpace(QQ).an_element() >>> v.value_group() Traceback (most recent call last): ... ValueError: The trivial pseudo-valuation that is infinity everywhere does not have a value group. 
 - value_semigroup()[source]¶
- Return the value semigroup of this discrete pseudo-valuation, the additive subsemigroup of the rational numbers which is generated by the valuations of the elements in the domain. - EXAMPLES: - Most commonly, in particular over fields, the semigroup is the group generated by the valuation of the uniformizer: - sage: G = QQ.valuation(2).value_semigroup(); G Additive Abelian Semigroup generated by -1, 1 sage: G in AdditiveMagmas().AdditiveAssociative().AdditiveUnital().AdditiveInverse() True - >>> from sage.all import * >>> G = QQ.valuation(Integer(2)).value_semigroup(); G Additive Abelian Semigroup generated by -1, 1 >>> G in AdditiveMagmas().AdditiveAssociative().AdditiveUnital().AdditiveInverse() True - If the domain is a discrete valuation ring, then the semigroup consists of the positive elements of the - value_group():- sage: Zp(2).valuation().value_semigroup() Additive Abelian Semigroup generated by 1 - >>> from sage.all import * >>> Zp(Integer(2)).valuation().value_semigroup() Additive Abelian Semigroup generated by 1 - The semigroup can have a more complicated structure when the uniformizer is not in the domain: - sage: v = ZZ.valuation(2) sage: R.<x> = ZZ[] sage: w = GaussValuation(R, v) sage: u = w.augmentation(x, 5/3) sage: u.value_semigroup() Additive Abelian Semigroup generated by 1, 5/3 - >>> from sage.all import * >>> v = ZZ.valuation(Integer(2)) >>> R = ZZ['x']; (x,) = R._first_ngens(1) >>> w = GaussValuation(R, v) >>> u = w.augmentation(x, Integer(5)/Integer(3)) >>> u.value_semigroup() Additive Abelian Semigroup generated by 1, 5/3 
 
 
- class sage.rings.valuation.valuation_space.ScaleAction[source]¶
- Bases: - Action- Action of integers, rationals and the infinity ring on valuations by scaling it. - EXAMPLES: - sage: v = QQ.valuation(5) sage: from operator import mul sage: v.parent().get_action(ZZ, mul, self_on_left=False) Left action by Integer Ring on Discrete pseudo-valuations on Rational Field - >>> from sage.all import * >>> v = QQ.valuation(Integer(5)) >>> from operator import mul >>> v.parent().get_action(ZZ, mul, self_on_left=False) Left action by Integer Ring on Discrete pseudo-valuations on Rational Field