Piecewise affine functions on the Berkovich projective line

Let \(K\) be a field, \(v_K\) a discrete valuation on \(K\) and \(X=\mathbb{P}^1_K\) the Berkovich line over \(K\).

A continuous function

\[h: X \to \mathbb{R}\cup\{\pm\infty\}\]

is called piecewise affine if it factors over the retraction map

\[r_T: X \to T\]

onto a Berkovich subtree \(T\subset X\), and the restriction of \(h\) to the edges of \(T\) are affine (with respect to the natural affine structure of a path on a Berkovich line).

The most important examples of piecewise linear functions are valuative functions. For instance, to any nonzero rational function \(f \in F=K(x)\) we associate the function

\[h_f:X \to \mathbb{R}\cup\{\pm\infty\}, \xi \mapsto v_\xi(f).\]

A general valuative function on \(X\) is simply a rational multiple of a function of the form \(h_f\). Any such function \(h\) can be written uniquely in the form

\[h = a_0 + \sum_i a_i\cdot h_{f_i}\]

where the \(f_i\) are irreducible polynomials in the parameter \(x\), and the \(a_i\) are rational numbers, with \(a_i \neq 0\) for \(i > 0\).

Let \(h\) be a nonconstant piecewise affine function on \(X\). Then the subset

\[U := \{ \xi \in X \mid h(\xi) \geq 0 \}\]

is an affinoid subdomain (unless it is empty, or the full Berkovich line \(X\)). If \(h=h_f\) is the valuative function associated to a rational function \(f\), then \(U\) is actually a rational domain.

AUTHORS:

  • Stefan Wewers (2017-2019)

EXAMPLES:

sage: from mclf import *
sage: F.<x> = FunctionField(QQ)
sage: X = BerkovichLine(F, QQ.valuation(2))

We can define a valuative function by a rational function on \(X\):

sage: f = (x^2+2*x-2)/(2*x-1)
sage: h = valuative_function(X, f)

We check that the value of \(h\) is the valuation of \(f\), at several points:

sage: xi = X.gauss_point()
sage: h(xi), xi.v(f)
(0, 0)
sage: xi = X.infty()
sage: h(xi), xi.v(f)
(-Infinity, -Infinity)
sage: xi = X.point_from_discoid(x, 3)
sage: h(xi), xi.v(f)
(1, 1)

We can also define a valuative function by a pair \((L, a_0)\):

sage: L = [(x - 1, 2/3), (x + 1, 3/2)]
sage: a_0 = -3
sage: h = valuative_function(X, (L, a_0))
sage: xi = X.point_from_discoid(x + 1, 2)
sage: h(xi)
2/3

We can compute the affinoid domain given by the inequality \(h(\xi)\geq 0\):

sage: h.affinoid_domain()
Affinoid with 2 components:
Elementary affinoid defined by
v(x - 1) >= 9/4
Elementary affinoid defined by
v(x + 1) >= 14/9
class mclf.berkovich.piecewise_affine_functions.AffineFunction(gamma, a, b)

Bases: SageObject

An affine function on a closed annuloid or a closed discoid.

INPUT:

  • xi1, xi2 – points on the Berkovich line \(X\) such that \(\xi_1<=\xi_2\)
  • a, b – rational numbers

OUTPUT:

the affine function \(h\) on the domain \(D\) of the path \(\gamma = [\xi_1,\xi_2]\) defined by \(a\) and \(b\). If \(t:D \to \mathbb{R}\) is the standard parametrization, then

\[h(\xi) := a\cdot t(\xi) + b.\]
berkovich_line()

Return the Berkovich line underlying this affine function.

domain()

Return the domain of definition of this affine function.

find_point_with_value(c)

Return a point where this affine function takes a given value.

OUTPUT:

a point \(\xi\) on the interior of the underlying path such that the function is nonconstant in \(\xi\) and takes the value \(c\).

If no such point exists, None is returned.

Note: do I really want only the points in the interior?

initial_point()

Return the initial point of the path underlying this affine function.

initial_value()

Return the initial value of this affine function.

is_constant()

Return whether this affine function is constant.

is_in_domain(xi)

Return whether a point is in the domain of definition of this affine function.

is_increasing()

Return whether this affine function is strictly increasing.

path()

Return the path underlying this affine function.

terminal_point()

Return the terminal point of the path underlying this affine function.

terminal_value()

Return the terminal value of this affine function.

class mclf.berkovich.piecewise_affine_functions.DirectedPath(xi1, xi2)

Bases: SageObject

A directed path on the Berkovic path.

INPUT:

  • xi1, xi2 – two points on the Berkovich line such that \(\xi1\leq \xi_2\)

OUTPUT:

the directed path \(\gamma = [\xi_1,\xi_2]\).

EXAMPLES:

sage: from mclf import *
sage: F.<x> = FunctionField(QQ)
sage: X = BerkovichLine(F, QQ.valuation(2))

We can define a path by specifying the initial and the terminal point:

sage: xi1 = X.point_from_discoid(x, 1)
sage: xi2 = X.point_from_discoid(x^2 + 4, 5)
sage: gamma = DirectedPath(xi1, xi2)
sage: gamma
path from Point of type II on Berkovich line, corresponding to v(x) >= 1 to Point of type II on Berkovich line, corresponding to v(x^2 + 4) >= 5

We use the standard parametrization for a path; it depends on the discoid representation of the terminal point:

sage: gamma.point(3)
Point of type II on Berkovich line, corresponding to v(x + 2) >= 3/2

Given a path \(\gamma=[\xi_1,\xi_2]\), we define its tube \(D\) as follows. If \(\xi_2\) is of type II, then \(D\) is the open annuloid with boundary point points \(\xi_1\) and \(\xi_2\). If \(\xi_1\) is of type I, then \(D:=D_{\xi_1}\) is the discoid with boundary point \(\xi_1\).:

sage: gamma.tube()
domain defined by
v(x + 2) > 1
v(1/(x^2 + 4)) > -5

sage: gamma.is_in_tube(X.gauss_point())
False

sage: gamma.is_in_tube(xi2)
False
berkovich_line()

Return the Berkovich line on which this path lives.

initial_parameter()

Return the initial parameter of this path.

OUTPUT:

a rational number \(s_0\) such that \(\gamma(s_0)\) is the initial point of this path \(\gamma\).

initial_point()

Return the initial point of this path.

initial_slope()

Return the slope of this path at the initial point.

is_limit_path()

Return whether the terminal point of this path is a limit point.

point(t)

Return the point on the path with given parameter.

INPUT:

  • t – a rational number, or Infinity

OUTPUT:

the point \(\xi = \gamma(t)\) on this path, with respect to the standard parametrization.

terminal_parameter()

Return the terminal parameter of this path.

OUTPUT:

a rational number \(s_1\) (or \(\infty\))` such that \(\gamma(s_1)\) is the terminal point of this path \(\gamma\).

terminal_point()

Return the terminal point of this path.

tube()

Return the tube around this path.

Let \(\xi_1\) be the initial and \(\xi_2\) be the terminal point of this path. Then the tube is either the open annuloid with boundary points \(\xi_1\) and \(\xi2\) (if \(\xi_2\) is of type II) or the closed discoid with boundary point \(xi_1\) (if \(\xi_2\) is of type I).

class mclf.berkovich.piecewise_affine_functions.Discoid(xi0, xi1=None)

Bases: mclf.berkovich.piecewise_affine_functions.Domain

Return a closed discoid of the Berkovich line.

INPUT:

  • xi0 - a point on the Berkovich line \(X\)
  • xi1 (default: None) – another point on \(X\)

OUTPUT:

the closed discoid \(D\) consisting of all point on the Berkovich line which are greater or equal to \(\xi_0\). If \(\xi_1\) is given, then it is checked whether \(\xi1\) lies in \(D\).

If \(\xi_0\) is the Gauss point, then \(D\) is taken to be the closed discoid with minimal point \(\xi_0\), containing \(\xi_1\). If \(\xi_1\) is not given, then \(D\) is taken to be the closed unit disk.

EXAMPLES:

sage: from mclf import *
sage: F.<x> = FunctionField(QQ)
sage: X = BerkovichLine(F, QQ.valuation(2))
sage: Discoid(X.gauss_point())
the closed discoid defined by v(x) >= 0
minimal_point()

Return the minimal point of this closed discoid.

class mclf.berkovich.piecewise_affine_functions.Domain(X, inequalities, strict_inequalities)

Bases: SageObject

A domain in the Berkovich line, defined by inequalities.

Objects of this class are used as domains of definition of affine and piecewise affine functions. Although they may be affinoid domains, this class has no relation to the class AffinoidDomainOnBerkovichLine.

INPUT:

  • X – a Berkovich line
  • inequalities – a list of pairs \((f, a)\)
  • strict_inequalities – a list of pairs \((g, b)\)

OUTPUT: the domain of \(X\) which is the intersection of the domains defined by the inequalities

\[v(f) \leq a, \quad v(g) < b.\]

Here \(f, g\) are assumed to be nonconstant rational functions on \(X\), and \(a\), \(b\) rational numbers.

If the inequalities and strict_inequalities are both empty then the full Berkovich line is returned.

berkovich_line()

Return the Berkovich line underlying this domain.

contains_infty()

Return whether this domain contains the point at infinity.

inequalities()

Return the list of non-strict inequalities which are part of the definition of this domain.

is_full_berkovich_line()

Return whether this domain is the full Berkovich line.

minimal_point()

Return the minimal point of this domain.

Since an arbitrary domain has no minimal point, this method raises an error, unless this domain is the full Berkovich line.

strict_inequalities()

Return the list of strict inequalities which are part of the definition of this domain.

class mclf.berkovich.piecewise_affine_functions.PiecewiseAffineFunction(D, a0, restrictions)

Bases: SageObject

A piecewise affine function on a domain in the Berkovich line.

INPUT:

  • D – a domain in the Berkovich line
  • a0 – a rational number
  • restrictions – a list of pairs \((h_1,h_2)\)

OUTPUT:

a piecewise affine function \(h\) on \(D\).

We assume that \(D\) is either a closed discoid, or the full Berkovich line \(X\). Let \(\xi_0\) be the initial point of the function, which is either the boundary point of \(D\) or, if \(D=X\), the Gauss point on \(X\).

The restrictions are the restrictions of \(h\) to proper open subdiscoids \(D_1\) of \(D\). It is assumed that \(h\) is constant, with value \(a_0\), on the complement of these subdiscoids. The restriction of \(h\) to \(D_1\) is given by a pair \((h_1, h_2)\), where \(h_2\) is the restriction of \(h\) to a proper closed subdiscoid \(D_2\subset D_1\) and \(h_1\) is the restriction of \(h\) to the open annuloid \(D_1\backslash D_2\). It is assumed that \(h_1\) is an affine functions, whereas \(h_2\) is piecewise affine.

We allow \(D_2\) to be empty, in which case \(h_2\) is None and the domain of \(h_1\) is an open discoid.

EXAMPLES:

sage: from mclf import *
sage: F.<x> = FunctionField(QQ)
sage: X = BerkovichLine(F, QQ.valuation(2))

We can define the “valuative function” of a rational function:

sage: f = (x^2 - 2) / x
sage: h = valuative_function(X, f)
sage: h
piecewise affine function on the Berkovich line, with initial value 0

A piecewise affine function can be evaluated at any point.

sage: xi = X.point_from_discoid(x, 2)
sage: h(xi)
-1
sage: xi.v(f)
-1

A piecewise affine function defines an affininoid subdomain (the point where the function takes nonnegative values).

sage: h.affinoid_domain() Elementary affinoid defined by v(x) >= 0 v(1/x) >= -1 <BLANKLINE>
affinoid_domain()

Return the affinoid domain defined by this function.

OUTPUT:

the affinoid subdomain of the domain of this function \(h\), defind by the inequality

\[h(xi) \geq 0.\]

EXAMPLES:

sage: from mclf import *
sage: F.<x> = FunctionField(QQ)
sage: X = BerkovichLine(F, QQ.valuation(2))
sage: h1 = valuative_function(X, 2*x)
sage: h1.affinoid_domain()
Elementary affinoid defined by
v(x) >= -1
sage: h2 = valuative_function(X, x*(x-1)/2)
sage: h2.affinoid_domain()
Affinoid with 2 components:
Elementary affinoid defined by
v(x + 1) >= 1
Elementary affinoid defined by
v(x) >= 1
berkovich_line()

Return the Berkovich line on which this function is defined.

domain()

Return the domain of this function.

find_next_points_with_value(a, xi0=None)

Return the next points where this function takes a given value, after a given point.

INPUT:

  • a – a rational number
  • xi0 (default: None) – a point in the domain of this function

OUTPUT: The list of all points on the nerf of this function

  • at which this function takes the value \(a\),
  • which are strictly greater than \(\xi_0\), and
  • which are minimal with this property.

If xi0 is None then the second condition is ignored.

NOTE:

Note that the function may be constant on a path of the nerf. If
this constant value is equal to a, and xi0 lies on this path, then
there is no minimal point on this path with the required conditions.
Therefore, the search is continued on all strictly greater paths.

EXAMPLES:

sage: from mclf import *
sage: F.<x> = FunctionField(QQ)
sage: X = BerkovichLine(F, QQ.valuation(2))
sage: h = valuative_function(X, (x^2 + x + 2)/x)
sage: h.find_next_points_with_value(0)
[Point of type II on Berkovich line, corresponding to v(x) >= 0]

If the second parameter \(\xi_0\) is given, the output consists of points strictly less than \(\xi_0\). As the function \(h\) is constant on the path from the Gauss point to the point \(v(x)\geq 1\), no point on this path is minimal with the required properties.

sage: h.find_next_points_with_value(0, X.gauss_point())
[]
sage: h.find_next_points_with_value(1)
[Point of type II on Berkovich line, corresponding to v(x + 2) >= 2,
 Point of type II on Berkovich line, corresponding to v(x + 1) >= 1]
sage: points = h.find_next_points_with_value(-1)
sage: points
[Point of type II on Berkovich line, corresponding to v(x) >= 2,
 Point of type II on Berkovich line, corresponding to v(1/x) >= 1]
sage: h.find_next_points_with_value(-1, points[0])
[]

For the moment, the value \(a=\infty\) does not lead to a correct result.

sage: h.find_next_points_with_value(Infinity)
[]
find_next_zeroes(xi0=None)

Return the next zeroes of this function after a given point.

INPUT:

  • xi0 (default: None) – a point in the domain of this function

OUTPUT: The list of all points in the domain of this function which

  • are zeroes of this function,
  • are not in the constant locus of the function
  • are greater or equal to \(\xi_0\), and
  • are minimal with this property.

If xi0 is None then the third condition is ignored.

initial_point()

Return the initial point of this function.

This is the minimal point of the domain of this function.

initial_value()

Return the value of this function at the initial point.

is_constant()

Return whether this function is constant.

is_in_domain(xi)

Return whether a given point is in the domain of this function.

restrictions()

Return the restrictions of this piecewise affine functions.

OUTPUT:

a list of pairs \((h_1,h_2)\), where \(h_1\) is an affine function which is the restriction of this function \(h\) to an open subannuloid of the domain of \(h\), and \(h_2\) is the restriction of \(h\) to the closed discoid which the unique hole of the domain of \(h_1\).

If the domain of \(h_1\) is an open discoid (so there is no hole), then \(h_2\) is None.

Together with the initial value, these restrictions define \(h\), because \(h\) is constant on the complement of the domains of definitios of these restrictions.

mclf.berkovich.piecewise_affine_functions.open_annuloid(xi0, xi1)

Return an open annuloid.

INPUT:

  • xi0, xi1 – points of type II on the Berkovich line \(X\)

OUTPUT:

the open annuloid \(A\) with boundary points \(xi_0\) and \(\xi_1\). Note that \(\xi0\) and \(\xi_1\) are not contained in \(D\).

It is assumed that \(\xi_0 < \xi_1\). This means that \(A\) cannot contain the Gauss point.

EXAMPLES:

sage: from mclf import *
sage: F.<x> = FunctionField(QQ)
sage: X = BerkovichLine(F, QQ.valuation(2))
sage: xi0 = X.point_from_discoid(x-1, 1)
sage: xi1 = X.point_from_discoid(x+1, 2)
sage: open_annuloid(xi0, xi1)
domain defined by
v(x + 1) > 1
v(1/(x + 1)) > -2
mclf.berkovich.piecewise_affine_functions.open_discoid(xi0, xi1)

Return an open discoid.

INPUT:

  • xi0, xi1 – points on the Berkovich line \(X\)

OUTPUT:

the open discoid \(D\) with boundary point \(xi_0\) which contains \(\xi_1\). Note that \(\xi0\) is not contained in \(D\).

It is assumed that \(\xi_0 < \xi_1\). This means that \(D\) cannot contain the Gauss point.

EXAMPLES:

sage: from mclf import *
sage: F.<x> = FunctionField(QQ)
sage: X = BerkovichLine(F, QQ.valuation(2))
sage: xi0 = X.point_from_discoid(x-1, 1)
sage: xi1 = X.point_from_discoid(x+1, 2)
sage: open_discoid(xi0, xi1)
domain defined by
v(x + 1) > 1
mclf.berkovich.piecewise_affine_functions.valuative_function(D, f, T=None, is_factored=False)

A valuative function on a domain in the Berkovich line.

INPUT:

  • D – a domain in the Berkovich line, or the Berkovich line itself

  • f – a nonconstant rational function on \(X\), or

    a pair \((L, a_0)\), where \(L\) is a list of pairs \((g, a)\) consisting of

    • a polynomial \(g\) (element of the function field on \(X\))
    • a nonzero rational number \(a\)

    and where \(a_0\) is a rational number

  • T (default: None) – a Berkovich tree

  • is_factored – a boolean (default: False)

OUTPUT:

If \(f\) is a rational function, then we create the valuative function \(h\) on \(D\) defined as

\[h(\xi) := v_K(f(\xi))\]

If f is a pair \((L, a_0)\) as above, where \(L\) is a list of pairs \((f_i, a_i)\), then the corresponding valuative function is defined as

\[h(\xi) := a_0 + \sum_i a_i v(f(\xi)).\]

The domain \(D\) must be either a standard closed discoid, or the full Berkovich line.

If the Berkovich tree \(T\) is given, then it is assumed that \(T\) is the dendrite of the function \(h\) on \(D\). This means that the root of \(T\) is the minimal point of \(D\), and that the restriction of \(h\) to the edges of \(T\) are affine.

If is_factored is True then we assume that \(L\) is actually a list of triples \((f, a, [\xi])\), where the \(f\) are irreducible polynomials, and \([\xi]\) is the list of all points of type I which are zeroes of \(f\).