Piecewise-linear maps

class plmaps.plmap.PLMap(domain, range)[source]

Let \(I\) and \(J\) be closed intervals. We define \(\operatorname{PL}_{S, G}(I, J)\) to be the set of functions \(\alpha \colon I \to J\) with the following properties.

  • \(\alpha\) is an orientation-preserving bijection.
  • \(\alpha\) is piecewise-linear, with finitely many linear segments.
  • The coordinates of each breakpoint of \(\alpha\) belong to \(S\).
  • The gradients of each linear section of \(\alpha\) belong to \(G\).

We do not require that the endpoints of \(I\) or \(J\) belong to \(S\).

This class represents functions of this form where \(S = \mathbb{Q}\) and \(G = \mathbb{Q}_{>0}\).

Variables:
__init__(domain, range)[source]

Create a new PLMap given the breakpoints’ coordinates. Breakpoint lists are normalised in memory: redudant breakpoints (where the the gradient does not change) are removed. Coordinates are provided via two lists domain and range of Fraction s.

Raises:
  • ValueError – if len(domain) != len(range).
  • ValueError – if len(domain) < 2.
  • ValueError – if domain or range are not increasing sequences.
  • ValueError – if domain or range contain invalid breakpoints. This requirement does not apply the first or last element of each list.
  • ValueError – if domain or range describe linear segments with invalid gradients.
>>> PLMap([0, 1], [0, Fraction(1, 2), 1])
Traceback (most recent call last):
...
ValueError: Domain and range lengths differ
>>> PLMap([], [])
Traceback (most recent call last):
...
ValueError: Domain must be defined by at least two points
>>> PLMap([0, 0], [1, 0])
Traceback (most recent call last):
...
ValueError: domain is not an increasing sequence
>>> PLMap([0, 1], [1, 0])
Traceback (most recent call last):
...
ValueError: range is not an increasing sequence
domain
range
gradients
classmethod identity(t0, t1)[source]
__iter__()[source]

Iterating over a PLMap yields its breakpoints.

classmethod from_aut(aut)[source]

Creates a new PLMap using a Homomorphism.

classmethod from_stream(stream)[source]
save_to_file(filename)[source]
__mul__(other)[source]

Postcompose on the right.

image(x)[source]

Where does the current PLMap send the point \(x\)?

Raises:ValueError – if \(x\) is not in the current map’s domain.
inverse_image(y)[source]

Where is mapped by the current PLMap to the point \(y\)?

Raises:ValueError – if \(y\) is not in the current map’s range.
rgradient_at(x)[source]
is_identity()[source]
dump(short=True)[source]
format_pl_segments(**kwargs)[source]
tikz_path()[source]
commutes(other)[source]
centralise_in_F()[source]
restriction(t0, t1)[source]

Produce a copy of the current PLMap restricted to the interval \([t_0, t_1]\).

Parameters:

target (iterable) – A sequence of at least two integers. The first and last entries are the start and end of the interval onto which we restrict.

Raises:
  • ValueError – if t0 >= t1.
  • ValueError – if t0 and t1 do not describe a subinterval of self.domain.
restriction_of_range(t0, t1, raw=False)[source]

Produce a copy of the current PLMap restricted to the interval \([t_0, t_1]\).

Parameters:

target (iterable) – A sequence of at least two integers. The first and last entries are the start and end of the interval onto which we restrict.

Raises:
  • ValueError – if t0 >= t1.
  • ValueError – if t0 and t1 do not describe a subinterval of self.domain.
is_permutation()[source]
fixed_points(raw=False)[source]
fixed_point_boundary()[source]
is_one_bump()[source]
one_bump_test_conjugate_with(other, initial_gradient, verbose=False)[source]
one_bump_linearity_boxes(other, initial_gradient)[source]
class plmaps.plmap.PL2(domain, range)[source]

\(\operatorname{PL}_2\) is shorthand for the set of PLMap s with \(S = \mathbb{Z}[1/2]\) and \(G = 2^{\mathbb Z}\). As noted above <plmaps.plmaps.PLMap>, we don’t insist that the endpoints of the domain and range lie in S: we’re working with what my thesis calls \(\operatorname{PL}_2^\text{rest}\) rather than \(\operatorname{PL}_2^\text{flat}\).

>>> PL2([0, Fraction(1, 3)], [1, Fraction(5, 3)])
<PL2: [0, 1/3] -> [1, 5/3]>
>>> PL2([0, Fraction(1, 2), 1], [1, Fraction(5, 3), 2])
Traceback (most recent call last):
...
ValueError: range contains an invalid breakpoint
>>> PL2([0, 1], [0, 3])
Traceback (most recent call last):
...
ValueError: Invalid gradient
one_bump_test_conjugate(other)[source]
one_bump_cent_gen(verbose=False)[source]

If the current PLMap is a one-bump function \(D o D\), produce an element which generates its centraliser in \(\operatorname{PL}(D)\). The generator’s initial gradient will be above 1 if and only if the the current PLMap’s initial gradient is above 1.

Raises:ValueError – if the current PLMap is not a one-bump function.