Bear Reference Manual

For Version 0.9.4

David Dumas (

7 June 2005


This manual is for Bear (version 0.9.4, 7 June 2005), a free software package that performs Bers slice computations and discreteness testing for punctured torus groups.

Like Bear itself, this reference manual is still under development. Users should also consult the files README, NEWS, and INSTALL included with the source code distribution for further information about building, installing, and using Bear.


Command-Line Parameters

Bear accepts the following command-line options, which are also documented on the manual page:

Run-time Modules


Bear interprets its input using Lua (, a procedural scripting language with a simple C-like syntax. What follows is a micro-introduction Lua as it is used to control Bear and a listing of the parameters and functions that Bear provides. The Lua documentation, which is available from the web page, provides much more detailed information.

A typical Bear script might calculate holonomy representations, test for discreteness, and write some of the resulting data to a file. This is accomplished by manipulating the values of certain parameters and then calling functions that perform the actual calculations and I/O operations.

The functionality of Bear is divided into several modules, which are like C structures or (instances of) C++ classes. Each module is a single data structure (a Lua table, actually) that contains both control parameters and functions that perform operations depending on those parameters.

Parameters can be assigned values using a C-like syntax:

modulename.parameter = value;

Note that the semicolon at the end of the line is optional. The parameter value can be a literal of the appropriate type, as in these examples:

module.numberparam = 867530.9;
module.stringparam1 = 'foo in single quotes';
module.stringparam2 = ``bar in double quotes'';

Values can also be constructed via more complicated expressions, possibly using other variables; for example, the following will give module.b the value 205.80:

m = 2; d = 5;
module.b = (m*100) + d + 80/100

For the construction of strings there is the concatenation operator ``..'':

firstword = 'foo'; secondword = 'bar';
module.foospacebar = firstword .. ' ' .. secondword;

The core functionality of Bear is provided by the functions of the various modules; such functions are called as follows:


Lua also has an extensive runtime library, providing many of the basic mathematical operations, string formatting functions, file input and output, and operating system interfaces common in other high-level languages. We will not detail these here, except for an example showing the usefulness of library functions for Bear computation scripts:

index = 15;               -- this is a comment, started by two hyphens
basefilename = 'output';
filename = basefilename .. string.format('\%03d',index) .. '.dat';
print(filename);          -- will print 'output015.dat'

bear - The global runtime options module


The bear module allows certain global options to be changed at runtime, and allows a script to query certain configuration parameters (e.g. the version number). When the value of a parameter in this module is changed, it takes effect immediately.


bers - The Bers Slice Module


The bers module computes holonomy groups of complex projective structures on a punctured torus. When combined with a discreteness test, this allows one to draw pictures of Bers slices of punctured tori, which is the main purpose of Bear.

The punctured torus is specified by means of its commensurable punctured sphere $ \hat{{\mathbb{C}}}$ - {0, 1,$ \lambda$,$ \infty$}; the holonomy group is then computed as the linear monodromy of the differential equation

u''(z) + $\displaystyle {\frac{{1}}{{2}}}$$\displaystyle \phi$(z)u(z) = 0

where the quadratic differential $ \phi$(z) is given by

$\displaystyle \phi$(z) = $\displaystyle {\frac{{1}}{{2 z^2}}}$ + $\displaystyle {\frac{{(\lambda - 1)^2}}{{2 (z -
\lambda^2) (z - 1)^2}}}$ + $\displaystyle {\frac{{c}}{{z(z - 1) (z - \lambda)}}}$.

Here c is a complex-valued parameter that specifies the complex projective structure. The module iterates through values of c in a square grid with a specified center and size.


The heart of the Bers module is an ordinary differential equation solver that is applied to the Schwarzian equation associated to a quadratic differential. All of the ODE solvers from the GNU Scientific Library (GSL) are available, including popular methods like Runge-Kutta (classical, and with higher-order error estimates) and the Bulirsch-Stoer implicit solver.

If a FORTRAN compiler is available when Bear is built, the LSODE solver is also included (since version 0.9.4), and its use is recommended for high performance in holonomy calculations of moderate complexity.

Both the bers and bers2 modules support a modular integration contour API (since version 0.9.3), allowing several types of integration contours (splines, piecewise linear, ellipses, etc.). The various integration contours have different speed/accuracy characteristics that become more apparent near the extremes of the moduli space of punctured tori.

Older versions of the bers module (before 0.9.3) supported an adaptive precision modification algorithm that attempted to improve the accuracy of the holonomy calculation in cases where the Schwarzian equation integrand is highly oscillatory. This feature has been removed because its implementation was never very successful. Different schemes for the improvement of ODE solver performance in the oscillatory regime may be considered for future development.


Obsoleted parameters

These parameters were available in previous versions of Bear, but have since been removed. It is not expected that they found widespread use.


bers2 - The New Bers Slice Module


The bers2 module performs the same function as the bers module (above).


The bers2 module is a rewrite of the bers module that allows the holonomy to be computed on a sparse grid and then inteprolated over a much finer mesh. When the Schwarzian equation can be solved accurately, the holonomy typically varies slowly enough that such interpolation gives nearly the same output with much less calculation. In cases where the Schwarzian equation is highly oscillatory, however, the bers module may be a better choice.

Both the bers and bers2 modules support a modular integration contour API (since version 0.9.3), allowing several types of integration contours (splines, piecewise linear, ellipses, etc.). The various integration contours have different speed/accuracy characteristics that become more apparent near the extremes of the moduli space of punctured tori.


Parameters unchanged from the bers module.

Parameters specific to the bers2 module.


linear - The Linear Slice Module


The linear module generates an array of Markov triples corresponding to a linear slice of the representation variety in which one trace is fixed and the other varies through a square grid of values in $ \mathbb {C}$.



anosov - The Anosov Slice Module

This module is experimental and may change substantially in future releases.


The anosov module computes Markov triples on the unstable manifold associated to a fixed point of a pseudo-anosov mapping class on the representation variety. It is also possible to search for fixed points and stable/unstable eigenvalues, though this Newton-type iteration is not very predictable for initial guesses far from a fixed point.



bowditch - The Bowditch Discreteness Algorithm Module


The bowditch module takes as input the Markov triples representing holonomy representations of a family of projective structures on punctured tori and attempts to determine which among these representations have discrete image. It does by searching for a finite attractor within the tree of generating triples for the holonomy group. Such an attractor is defined by the property that every edge of the tree points toward it, where each edge is given an orientation pointing toward the smaller trace. (Note that the endpoints of an edge correspond to triples that differ only in one generator.)

Bowditch has shown that if such an attractor exists, the set of all edges that satisfy a certain inequality is such an attractor; furthermore, this set is always connected. Thus the discreteness algorithm proceeds by searching for edges in the Bowditch subtree and declaring the representation discrete if the search terminates (within a certain time limit).

The inequality that defines the Bowditch locus involves a real parameter t > 0, and the corresponding subtree grows as t is increased.



holonomy - The Holonomy I/O Module


The holonomy module writes holonomy data (Markov triples) and associated metadata to HDF5 data files.



discreteness - The Discreteness Data I/O Module


The discreteness module writes discreteness data and associated metadata to HDF5 data files.



Mathematical Details

Parameterization of quadratic differentials

Bers slices for punctured tori are computed by numerically solving the Schwarzian differential equation

u" + $\displaystyle {\frac{{1}}{{2}}}$$\displaystyle \phi$u = 0

on the four-times punctured Riemann sphere that is commensurable with the punctured torus in question. The parameter $ \lambda$ specifies the punctured torus by means of the cross ratio of the four punctures of the commensurable punctured sphere.

In this way the space of holomorphic quadratic differentials on the punctured torus is identified with a complex affine subspace of the space of meromorphic quadratic differentials on the Riemann sphere. For the punctured torus with parameter $ \lambda$, the affine space consists of differentials with poles of order 2 at each of the four punctures that are symmetric under the Mo"bius transformations that preserve the set of punctures.

Such a meromorphic differential can be expressed in the form

$\displaystyle \phi$(z) = $\displaystyle {\frac{{1}}{{2 z^2}}}$ + $\displaystyle {\frac{{(\lambda - 1)^2}}{{2 (z -
\lambda^2) (z - 1)^2}}}$ + $\displaystyle {\frac{{c}}{{z(z - 1) (z - \lambda)}}}$

for some complex number C. Note that c = 0 does not correspond to the Fuchsian uniformization of the punctured torus; the value of C with this property is called the "accessory parameter", and is difficult to calculate in general.

Computation of monodromy

Bear uses the GNU Scientific Library to numerically integrate the Schwarzian differential equation. Starting with a modular parameter $ \lambda$ and a complex number c specifying a quadratic differential, Bear produces a "Markov triple" (x, y, z) of traces that define the holonomy group via the following steps:

  1. Compute contours.
    Ellipses encircling {0,$ \lambda$} and {1,$ \lambda$} are computed and then replaced with approximating periodic cubic splines (to avoid costly computation of trigonometric functions). Currently, the number of points used for the splines is fixed at compile-time, with a default of 16.

  2. Integrate ODE.
    The linear second-order holomorphic ODE is converted to a first-order four-dimensional real system, which is then integrated along the contours computed above. GSL uses one of several standard integration algorithms, and attempts to maintain an absolute error of at most $ \varepsilon$ by adjusting the step size. This produces a pair of monodromy transformations M1 and M2.

  3. Convert traces.
    The monodromy transformations correspond to the squares of generating holonomy elements because of the commensurability relationship between the punctured torus and the sphere. The traces of generators A, B, and AB are then computed from the matrix entries of M1 and M2 using the SL2(C) trace identities.

The discreteness algorithm

The discreteness algorithm used by Bear is based on the work of Brian Bowditch as described in his paper Markoff triples and quasifuchsian Groups (Preprint, University of Southampton). In this paper a certain class of representations of punctured torus groups into PSL2(C) is defined, and it is conjectured that this locus is exactly the set of quasifuchsian representations. It is also shown that the set of quasifuchsian representations is a connected component of this locus, and in particular that the boundary of the "Bowditch locus" contains the boundary of the quasifuchsian locus.

Bear proceeds as though the Bowditch conjecture holds, labeling a representation discrete (quasifuchsian) if it can be shown to lie in the Bowditch locus. On the other hand, the Jørgensen inequality is used as a sufficient condition for indiscreteness, so it is possible that some indiscrete representations belonging to the Bowditch locus are excluded. The table below summarizes the situation; unless limited by the number of computations allowed for a given representation, Bear reports the status of representations as follows:

  Bowditch Non-Bowditch
Jørgensen holds quasifuchsian uncertain
Jørgensen violated undefined indiscrete

while conjecturally the reality is as follows:

  Bowditch Non-Bowditch
Jørgensen holds quasifuchsian (nowhere dense set)
Jørgensen violated (never occurs) indiscrete

The Bowditch algorithm makes use of the infinite trivalent tree of Markov triples associated to the initial triple of traces (x, y, z) of generators A, B, and AB. In this tree, the three neighbors of a given triple are related as follows:

Triple Neighbors
(x,y,z) (x,xz-y,z)

Note that in each case, a triple differs from its neighbor by a single entry; the edges of the tree are then oriented so that the edge in which z is replaced by w, which we call the (z, w)-edge, is oriented toward whichever of the two has smaller absolute value. If | z| = | w| then the edge can be oriented arbitrarily with affecting the algorithm.

A representation lies in the Bowditch locus if it has a "finite attractor", that is, a finite connected subtree $ \Omega$ of markov triples such that every other edge in the tree points toward $ \Omega$. Bowditch shows that it is possible to determine whether or not a representation has this property using a simple algorithm; he defines a subtree $ \tau$($ \varepsilon$) where the (z, w)-edge belongs to $ \tau$($ \varepsilon$) if and only if the traces satisfy one of the following conditions:

1. | z| < 3 + $ \varepsilon$ and | w| < H(z)

2. | w| < 3 + $ \varepsilon$ and | z| < H(w)

Here H is a complicated function that has certain properties which imply that $ \tau$($ \varepsilon$) is always connected. Bowditch then shows that if a representation has a finite attractor, then for any positive $ \varepsilon$, $ \tau$($ \varepsilon$) is a finite attractor.

Thus the algorithm proceeds as follows:

  1. Check the Markov triple against the J/orgensen inequality, which states that each trace must have absolute value greater than or equal to one. As other Markov triples are generated, they are also checked, and if a violation is ever discovered, the representation is `indiscrete'.

  2. Follow oriented edges until a sink is found. (If no sink is found, then call the representation `undecided'.)

  3. Recursively search the tree starting from this sink, enumerating all edges that satisfy the Bowditch inequalities.

  4. If only finitely many edges are found, the representation is (conjecturally) `quasifuchsian'.

  5. If the search proceeds for too long (exceeds a set depth, numerical overflow, etc.), then the representation is `undecided'.

David Dumas <>