# 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


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


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()


The factories such as TrivialPseudoValuation provide the right inheritance structure:

sage: v = valuations.TrivialPseudoValuation(QQ)
sage: v._test_category()

class sage.rings.valuation.valuation_space.DiscretePseudoValuationSpace(domain)#

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


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 in operator 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 _richcmp if 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 trac ticket #22029 or similar.

class ElementMethods#

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


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


However, the category framework advises you to use inheritance:

sage: 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()

change_domain(ring)#

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)

element_with_valuation(s)#

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

extension(ring)#

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

extensions(ring)#

Return the extensions of this valuation to ring.

EXAMPLES:

sage: v = ZZ.valuation(2)
sage: v.extensions(QQ)

inverse(x, precision)#

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


Of course this always works over fields:

sage: v = QQ.valuation(2)
sage: v.inverse(2, 2)
1/2

is_discrete_pseudo_valuation()#

Return whether this valuation is a discrete pseudo-valuation.

EXAMPLES:

sage: QQ.valuation(2).is_discrete_pseudo_valuation()
True

is_discrete_valuation()#

Return whether this valuation is a discrete valuation, i.e., whether it is a discrete pseudo valuation that only sends zero to $$\infty$$.

EXAMPLES:

sage: QQ.valuation(2).is_discrete_valuation()
True

is_negative_pseudo_valuation()#

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

is_trivial()#

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

lift(X)#

Return a lift of X in the domain which reduces down to X again via reduce().

EXAMPLES:

sage: v = QQ.valuation(2)
sage: v.lift(v.residue_ring().one())
1

lower_bound(x)#

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: v = ZZ.valuation(2)
sage: v.lower_bound(2^10)
10

reduce(x)#

Return the image of x in 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 non-negative valuation

residue_field()#

Return the residue field of this valuation, i.e., the field of fractions of the residue_ring(), the elements of non-negative 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

residue_ring()#

Return the residue ring of this valuation, i.e., the elements of non-negative 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


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 (using ...)

restriction(ring)#

Return the restriction of this valuation to ring.

EXAMPLES:

sage: v = QQ.valuation(2)
sage: w = v.restriction(ZZ)
sage: w.domain()
Integer Ring

scale(scalar)#

Return this valuation scaled by scalar.

INPUT:

• scalar – a non-negative rational number or infinity

EXAMPLES:

sage: v = ZZ.valuation(3)
sage: w = v.scale(3)
sage: w(3)
3


Scaling can also be done through multiplication with a scalar:

sage: w/3 == v
True


Multiplication by zero produces the trivial discrete valuation:

sage: w = 0*v
sage: w(3)
0
sage: w(0)
+Infinity


Multiplication by infinity produces the trivial discrete pseudo-valuation:

sage: w = infinity*v
sage: w(3)
+Infinity
sage: w(0)
+Infinity

separating_element(others)#

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

shift(x, s)#

Shift x in its expansion with respect to 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 expansion which have negative valuation.

EXAMPLES:

sage: v = ZZ.valuation(2)
sage: v.shift(1, 10)
1024
sage: v.shift(11, -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

simplify(x, error=None, force=False)#

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.)

If force is 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

uniformizer()#

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


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

upper_bound(x)#

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: v = ZZ.valuation(2)
sage: v.upper_bound(2^10)
10

value_group()#

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


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.

value_semigroup()#

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
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


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

class sage.rings.valuation.valuation_space.ScaleAction#

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