Geometry Package

Module containing a class representation of geodesic on hyperbolic space. In particular the class abstracts the translation procedure between the upper halfplane and Poincare disc models and facilitates a homogeneous interface for geometric operations and visualization.

Authors:

  • Tobias Weich

  • Philipp Schuette

  • Sebastian Albrecht

class pyzeta.geometry.geodesic.Geodesic(z1, z2, model='H')[source]

Utility class representing a geodesic in the Upper Halfplane \(\mathbb{H}\) or in the Poincare Disk \(\mathbb{D}\) through two given points of the respective model.

__init__(z1, z2, model='H')[source]

Create a hyperbolic geodesic through two points z1 and z2.

The geodesic can be created in the Upper Halfplane \(\mathbb{H}\) or in the Poincare Disk \(\mathbb{D}\). The model can be specified when a geodesic is newly created, and the behaviour of any class method adopts to this choice. Nevertheless, any class method supports the keyword argument model to allow for one-time changes of the model.

Parameters:
  • z1 (Union[float, complex]) – Point in the chosen model

  • z2 (Union[float, complex]) – Point in the chosen model

  • model (str) – Model for hyperbolic space (‘H’ or ‘D’), defaults to ‘H’ (default: 'H')

Raises:
  • InvalidDiskPoint – Raised if outside Poincare disc

  • InvalidHalfplanePoint – Raised if outside upper halfplane

  • InvalidModelException – Raised if model is neither ‘H’ nor ‘D’

  • InvalidGeodesicException – Raised if both points are identical

getReflecAxis(other)[source]

Calculate the reflection axis between a hyperbolic geodesic on the Upper Halfplane \(\mathbb{H}\) and another non-intersecting one.

Reflection at the axis transforms the two geodesics into one another. The reflection axis is itself a geodesic.

Parameters:

other (Geodesic) – Geodesic which does not intersect the first one

Raises:

NotImplementedError – Raised if any of the two geodesics extends to \(\infty\).

Returns:

Geodesic – Reflection axis

intersect(other)[source]

Calculate the intersection point of a hyperbolic geodesics with another one.

The model for hyperbolic space is inferred from the model of the geodesic self.

Parameters:

other (Geodesic) – Other geodesic intersecting given one in a single point.

Raises:

ValueError – Raised if the two geodesics are identical.

Returns:

Optional[Tuple[float, float]] – Coordinates of the intersection point

property model: str

Getter method for the model attribute of a Geodesic instance.

plot(*, inftyMax=5.0, ax=None, **kwargs)[source]

Plot a hyperbolic geodesic.

Parameters:
  • inftyMax (float) – Value at which the imaginary axis is cropped if (default: 5.0) the geodesic extends to \(\infty\), defaults to 5

  • ax (Optional[Any]) – Matplotlib axes object in which the plot should be drawn. If (default: None) None is passed, a new figure and axes are created, defaults to None

  • **kwargs (object) – Valid keyword arguments include ‘color’, ‘linestyle’, ‘linewidth’, ‘marker’ and ‘markersize’. Further matplotlib.lines.Line2D properties and matplotlib.patch properties work (but may not be reliable).

Returns:

Tuple[Any, Any] – Matplotlib figure and matplotlib axes object in which the plot is drawn

Module containing a class implementation of \(\mathrm{SL}(2, \mathbb{R})\) matrices acting on the upper half plane \(\mathbb{H}\) via Moebius transformations.

Authors:n - Tobias Weichn - Philipp Schuetten - Sebastiant Albrechtn

class pyzeta.geometry.sl2r.SL2R(A)[source]

Utility class representing symmetries of the Upper Halfplane \(\mathbb{H}\), i.e. elements of \(\mathrm{SL}(2, \mathbb{R})\).

__call__(z)[source]

Calculate action of an element of \(\mathrm{SL}(2, \mathbb{R})\) on a point, vector or geodesic in the Upper Halfplane \(\mathbb{H}\).

Elements \(g = \begin{pmatrix} a & b \\ c & d \end{pmatrix} \in\mathrm{SL}(2, \mathbb{R})\) act on the Upper Halfplane \(\mathbb{H}\) via Moebius trafos:

\[\mathbb{H}\ni z\mapsto g\cdot z = \frac{az + b}{cz + d}\in \mathbb{H}.\]
Parameters:

z (Union[Geodesic, float, complex, ndarray[Any, dtype[complex128]]]) – Point or vector or hyperbolic geodesic in the Upper Halfplane \(\mathbb{H}\)

Raises:

InvalidHalfplanePoint – Raised for points outside Upper Halfplane.

Returns:

Union[Geodesic, float, complex, ndarray[Any, dtype[complex128]]] – Transformed input

__init__(A)[source]

Create an element of \(\mathrm{SL}(2, \mathbb{R})\).

The class can represent both orientation-preserving and orientation- reversing transformations. True elements of \(\mathrm{SL}(2, \mathbb{R})\) are orientation-preserving. However, it is useful for other parts of the hypgeo module that this class can represent matrices both with determinant +1 and -1.

Parameters:

A (ndarray[Any, dtype[complex128]]) – Matrix representation of an element of \(\mathrm{SL}(2, \mathbb{R})\). Be aware that an input matrix with non-unit determinant will be normalised to unit determinant up to sign.

Raises:

InvalidMatrixException – Raised if A has zero determinant.

__len__()[source]

Calculate displacement length of a hyperbolic element of \(\mathrm{SL}(2, \mathbb{R})\).

Raises:

ValueError – Raised if the element is not hyperbolic.

Returns:

float – Displacement length

__mul__(other)[source]

Calculate matrix product of two elements of \(\mathrm{SL}(2, \mathbb{R})\).

Parameters:

other (SL2R) – Element of \(\mathrm{SL}(2, \mathbb{R})\)

Returns:

SL2R – Matrix product of the two elements

__pow__(power)[source]

Calculate matrix power of an element of \(\mathrm{SL}(2, \mathbb{R})\).

Parameters:

power (int) – Power to which the element is raised

Returns:

SL2R – Matrix power of the element

__repr__()[source]

Return string representation of an element of \(\mathrm{SL}(2, \mathbb{R})\).

This method works identically as the __str__ method. It is necessary for a human readable string representation of lists of SL2R elements.

Returns:

str – String representation of an element of \(\mathrm{SL}(2, \mathbb{R})\)

getFixPt()[source]

Calculate fixed point(s) of an element of \(\mathrm{SL}(2, \mathbb{R})\).

Uses Dal’Bo p.16. Only fixed point(s) inside \(\mathbb{H}\) are returned. Fixed points outside \(\mathbb{H}\) are discarded.

Raises:
  • ValueError – Raised if the element is the unit element.

  • NotImplementedError – Raised if the element has negative determinant.

Returns:

Optional[Tuple[Union[float, complex], ...]] – Fixed point(s)

getIsoCirc()[source]

TODO: What does this method do? Rename once we are sure, what it does!

Return type:

Geodesic

getTransAx()[source]

Calculate translation axis of a hyperbolic element of \(\mathrm{SL}(2, \mathbb{R})\).

The axis of translation of a hyperbolic element of \(\mathrm{SL}(2, \mathbb{R})\) is the unique geodesic between the two fixed points. It is preserved under the action of the hyperbolic element.

Raises:

ValueError – Raised if the element is not hyperbolic.

Returns:

Geodesic – Translation axis

inverse()[source]

Calculate inverse of an element of \(\mathrm{SL}(2, \mathbb{R})\).

The same as SL2R.__pow__(-1).

Returns:

SL2R – Inverse of the element

plotFixPt(*, ax=None, **kwargs)[source]

Calculate and plot fixed point(s) of an element of \(\mathrm{SL}(2, \mathbb{R})\).

Parameters:
  • ax (Optional[Any]) – Matplotlib axes object in which the plot should be drawn. If (default: None) None is passed, a new figure and axes are created, defaults to None

  • **kwargs (object) – Keyword arguments are passed to matplotlib.pyplot.scatter().

Raises:

ValueError – Raised if the element has no fixed points in \(\mathbb{H}\).

Returns:

Tuple[Any, Any] – Matplotlib figure and matplotlib axes object in which the plot is drawn

Module containing a class implementation of \(\mathrm{SU}(1, 1)\) matrices acting on the Poincare disc \(\mathbb{D}\) via Moebius transformations.

Authors:n - Tobias Weichn - Philipp Schuetten - Sebastian Albrechtn

class pyzeta.geometry.su11.SU11(A)[source]

Utility class representing symmetries of the Poincare disc, i.e. elements of \(\mathrm{SU}(1, 1)\).

__call__(z)[source]

Calculate action of an element of \(\mathrm{SU}(1,1)\) on a point, vector or geodesic in the Poincare Disk \(\mathbb{D}\).

Elements \(g = \begin{pmatrix} a & b \\ b^* & a^* \end{pmatrix} \in\mathrm{SU}(1,1)\) act on the Poincare Disk \(\mathbb{D}\) via Moebius trafos:

\[\mathbb{D}\ni z\mapsto g\cdot z = \frac{az + b}{b^*z + a^*}\in \mathbb{D}.\]
Parameters:

z (Union[Geodesic, float, complex, ndarray[Any, dtype[complex128]]]) – Point or vector or hyperbolic geodesic in the Poincare Disk \(\mathbb{D}\)

Raises:

InvalidDiskPoint – Raised for points outside Poincare Disk.

Returns:

Union[Geodesic, float, complex, ndarray[Any, dtype[complex128]]] – Transformed input

__init__(A)[source]

Create an element of \(\mathrm{SU}(1,1)\).

The class can represent both orientation-preserving and orientation- reversing transformations. True elements of \(\mathrm{SU}(1,1)\) are orientation-preserving. However, it is useful for other parts of the hypgeo module that this class can represent matrices both with determinant +1 and -1.

Parameters:

A (ndarray[Any, dtype[complex128]]) – Matrix representation of an element of \(\mathrm{SU}(1,1)\). Be aware that an input matrix with non-unit determinant will be normalised to unit determinant up to sign.

Raises:

InvalidMatrixException – Raised if A has zero determinant or if it does not satisfy other defining properties of \(\mathrm{SU}(1,1)\).

__len__()[source]

Calculate displacement length of a hyperbolic element of \(\mathrm{SU}(1,1)\).

Raises:

ValueError – Raised if the element is not hyperbolic.

Returns:

float – Displacement length

__mul__(other)[source]

Calculate matrix product of two elements of \(\mathrm{SU}(1,1)\).

Parameters:

other (SU11) – Element of \(\mathrm{SU}(1,1)\).

Returns:

SU11 – Matrix product of the two elements

__pow__(power)[source]

Calculate matrix power of an element of \(\mathrm{SU}(1,1)\).

Parameters:

power (int) – Power to which the element is raised

Returns:

SU11 – Matrix power of the element

__repr__()[source]

Return string representation of an element of \(\mathrm{SU}(1,1)\).

This method works identically as the __str__ method. It is necessary for a human readable string representation of lists of SU11 elements.

Returns:

str – String representation of an element of \(\mathrm{SU}(1,1)\)

getFixPt()[source]

Calculate fixed point(s) of an element of \(\mathrm{SU}(1,1)\).

Only fixed point(s) inside \(\mathbb{D}\) are returned. Fixed points outside \(\mathbb{D}\) are discarded.

Raises:
  • ValueError – Raised if the element is the unit element.

  • NotImplementedError – Raised if the element has negative determinant.

Returns:

Tuple[Union[float, complex], ...] – Fixed point(s) inside (the closure of) \(\mathbb{D}\)

getIsoCirc()[source]

TODO: What does this method do? Rename once we are sure what it does!

Return type:

Geodesic

getTransAx()[source]

Calculate translation axis of a hyperbolic element of \(\mathrm{SU}(1,1)\).

The axis of translation of a hyperbolic element of \(\mathrm{SU}(1,1)\) is the unique geodesic between the two fixed points. It is preserved under the action of the hyperbolic element.

Raises:

ValueError – Raised if the element is not hyperbolic.

Returns:

Geodesic – Translation axis

inverse()[source]

Calculate inverse of an element of \(\mathrm{SU}(1,1)\).

The same as SU11.__pow__(-1).

Returns:

SU11 – Inverse of the element

plotFixPt(*, ax=None, **kwargs)[source]

Calculate and plot fixed point(s) of an element of \(\mathrm{SU}(1, 1)\).

Parameters:
  • ax (Optional[Any]) – Matplotlib axes object in which the plot should be drawn. If (default: None) None is passed, a new figure and axes are created, defaults to None

  • **kwargs (object) – Keyword arguments for matplotlib.pyplot.scatter().

Raises:

ValueError – Raised if not fixed points in \(\mathbb{D}\).

Returns:

Tuple[Any, Any] – Matplotlib figure and axes object with the new plot inside

TODO.

Authors:

  • Sebastian Albrecht

  • Philipp Schuette

pyzeta.geometry.helpers.DtoH(z)[source]

Map point from the Poincare Disk to the Upper Halfplane.

The inverse Cayley transformation \(C = \begin{pmatrix} 1 & -1 \\ i & i \end{pmatrix}\) maps the poincare disc \(\mathbb{D}\) onto the upper halfplane \(\mathbb{H}\).

Parameters:

z (Union[float, complex]) – Point on the Poincare Disk

Returns:

complex – Point on the Upper Halfplane

pyzeta.geometry.helpers.HtoD(z)[source]

Map point from the Upper Halfplane to the Poincare Disk.

The Cayley transformation \(C = \begin{pmatrix} -1 & i \\ 1 & i \end{pmatrix}\) maps the upper halfplane \(\mathbb{H}\) onto the poincare disc \(\mathbb{D}\).

Parameters:

z (Union[float, complex]) – Point on the Upper Halfplane

Returns:

complex – Point on the Poincare Disk

pyzeta.geometry.helpers.checkConsistencyAndConvert(z1, z2, model)[source]

Check consistency of a given pair of points in the given model and map the points to the upper halfplane if necessary.

TODO.

Return type:

Tuple[Union[float, complex], Union[float, complex]]

pyzeta.geometry.helpers.stabilize(z, model='H', tol=1e-09)[source]

Stabilize computations in the module by taking care of small numerical errors that push boundary points out of the respective model.

From the mathematical theory it is usually clear that results of computations in this module are points that lie inside the hyperbolic plane \(\mathbb{H}\) or the Poincare disc \(\mathbb{D}\) (or on their respective boundaries). In some cases, numerical computations produce very small errors (< 10^-9) that lie outside the respective boundary (i.e. points with very small negative imaginary part, in the case of \(\mathbb{H}\), or with absolute value very small above 1, in the case of \(\mathbb{D}\)).

Parameters:
  • z (Union[float, complex, ndarray[Any, dtype[complex128]]]) – Point or vector in the chosen model

  • model (str) – Model for hyperbolic space (‘H’ or ‘D’), defaults to ‘H’ (default: 'H')

  • tol (float) – Absolute tolerance, defaults to 1e-9 (default: 1e-09)

Raises:

InvalidModelException – Raised if model is neither ‘H’ nor ‘D’.

Returns:

Union[float, complex, ndarray[Any, dtype[complex128]]] – Point or vector with errors within tolerance removed.

pyzeta.geometry.helpers.styleHyperbolicPlanePlot(model, ax, xLimits, yLimits)[source]

Style a plot of the upper halfplane of Poincare disc models of hyperbolic space within given limits. Limits are only applied in the upper halfplane model because the closed unit disc is compact.

Parameters:
  • model (str) – the model to use for styling

  • ax (Any) – given matplotlib axes to style

  • xLimits (Tuple[float, float]) – the x-axis limits to apply

  • yLimits (Tuple[float, float]) – the y-axis limits to apply

Return type:

None

TODO.

Authors:

  • Philipp Schuette

  • Tobias Weich

  • Sebastian Albrecht

pyzeta.geometry.visuals.SLtoSU(g)[source]

Transform element g of \(\mathrm{SL}(2, \mathbb{R})\) into element of \(\mathrm{SU}(1, 1)\).

The Cayley transformation \(C = \begin{pmatrix} -1 & i \\ 1 & i \end{pmatrix}\) maps the Upper Halfplane \(\mathbb{H}\) onto the Poincare Disk \(\mathbb{D}\). Given an isometry g of the Upper Halfplane, the related isometry of the Poincare Disk is given by \(g^{\prime} = C g C^{-1}\).

Parameters:

g (SL2R) – Element in \(\mathrm{SL}(2, \mathbb{R})\)

Returns:

SU11 – Conjugated element in \(\mathrm{SU}(1,1)\)

pyzeta.geometry.visuals.SUtoSL(g)[source]

Transform element of \(\mathrm{SU}(1, 1)\) into element of \(\mathrm{SL}(2, \mathbb{R})\).

The Cayley transformation \(C = \begin{pmatrix} -1 & i \\ 1 & i \end{pmatrix}\) maps the Upper Halfplane \(\mathbb{H}\) onto the Poincare Disk \(\mathbb{D}\). Given an isometry g of the Poincare Disk, the related isometry of the Upper Halfplane is given by \(g^{\prime} = C^{-1} g C\).

Parameters:

g (SU11) – Element in \(\mathrm{SU}(1,1)\)

Returns:

SL2R – Conjugated element in \(\mathrm{SL}(2, \mathbb{R})\)

pyzeta.geometry.visuals.getFundDom(*generators, z0=1j)[source]

Compute the fundamental domain of a Schottky group of arbitrary rank.

A Schottky group of rank k is generated by k hyperbolic isometries. The generators are the only arguments passed to this function. Note that only the k generators (not in addition their inverses) should be passed. Generators may be of type SL2R or of type SU11. The model (upper halfplane or Poincare disc) is inferred from the type of the generators.

The fundamental domain computed here is a Dirichlet domain (cf. Dal’Bo p.21) centered at z0.

Parameters:
  • *generators (Union[SL2R, SU11]) – Generators of the Schottky group

  • z0 (Union[float, complex]) – center of the Dirichlet domain, defaults to i (or 0) (default: 1j) on the Upper Halfplane (or on the Poincare Disk, respectively)

Raises:
  • InvalidMatrixException – Raised if the generators are neither of type SL2R nor of type SU11

  • TypeError – Raised if not all generators are of the same type

Returns:

List[Tuple[float, float]] – List of tuple of float, the tuples contain the endpoints of geodesics bounding the fundamental domain; there are two tuples per generator, on the Upper Halfplane the endpoints lie on the real axis and are thus determined by their real part, on the Poincare Disk the endpoints lie on the unit circle and are determined by their angle

pyzeta.geometry.visuals.getMiddlePt(z1, z2, model='H')[source]

Compute the middle point of the hyperbolic segment [z1, z2].

The middle point lies on the hyperbolic segment and is equidistant from the endpoints of the segment measured w.r.t. hyperbolic distance.

Parameters:
  • z1 (Union[float, complex]) – Point in the chosen model

  • z2 (Union[float, complex]) – Point in the chosen model

  • model (str) – Model for hyperbolic space (‘H’ or ‘D’), defaults to ‘H’ (default: 'H')

Raises:
  • InvalidDiskPoint – Raised for points outside Poincare Disk.

  • InvalidHalfplanePoint – Raised for points outside Upper Halfplane.

  • InvalidModelException – Raised if model is neither ‘H’ nor ‘D’.

Returns:

Union[float, complex] – Middle point

pyzeta.geometry.visuals.getPerpGeo(z1, z2, model='H')[source]

Compute the perpendicular bisector of the hyperbolic segment [z1, z2].

The perpendicular bisector of a hyperbolic segment is the unique geodesic through the middle point of the segment and perpendicular to the segment.

Parameters:
  • z1 (Union[float, complex]) – Point in the chosen model

  • z2 (Union[float, complex]) – Point in the chosen model

  • model (str) – Model for hyperbolic space (‘H’ or ‘D’), defaults to ‘H’ (default: 'H')

Raises:
  • InvalidDiskPoint – Raised for points outside Poincare Disk.

  • InvalidHalfplanePoint – Raised for points outside Upper Halfplane.

  • InvalidModelException – Raised if model is neither ‘H’ nor ‘D’.

  • InvalidGeodesicsException – Raised if both points are identical.

  • ValueError – Raised it the middle point of the hyperbolic segment lies on the boundary of the model. This happens if exactly one endpoint of the segment lies on the boundary.

Returns:

Geodesic – Perpendicular bisector

pyzeta.geometry.visuals.getReflecTrafo(geo)[source]

Compute the transformation matrix corresponding to a reflection at the geodesic.

Parameters:

geo (Geodesic) – Geodesic at which the reflection takes place

Returns:

Union[SL2R, SU11] – Matrix representing the reflection transformation

pyzeta.geometry.visuals.horoDist(z, xi, model='H')[source]

Compute the horocyclic distance between two points z and xi.

Parameters:
  • z (ndarray[Any, dtype[complex128]]) – Array of points in the chosen model

  • xi (Union[float, complex]) – Point in the chosen model

  • model (str) – Model for hyperbolic space (‘H’ or ‘D’), defaults to ‘H’ (default: 'H')

Raises:
  • ValueError – Raised if xi is not a boundary point.

  • InvalidModelException – Raised if model is neither ‘H’ nor ‘D’.

Returns:

ndarray[Any, dtype[float64]] – Horocyclic distance between a point z of hyperbolic space and a point xi on the boundary of hyperbolic space

pyzeta.geometry.visuals.hypDist(z1, z2, model='H')[source]

Compute the hyperbolic distance between two points z1 and z2.

Parameters:
  • z1 (complex) – Point in the chosen model

  • z2 (complex) – Point in the chosen model

  • model (str) – Model for hyperbolic space (‘H’ or ‘D’), defaults to ‘H’ (default: 'H')

Raises:
  • InvalidDiskPoint – Raised for points outside Poincare Disk.

  • InvalidHalfplanePoint – Raised for points outside Upper Halfplane.

  • InvalidModelException – Raised if model is neither ‘H’ nor ‘D’.

Returns:

float – Hyperbolic distance \(\mathrm{d}_{\mathbb{H}}(z1, z2)\) or \(\mathrm{d}_{\mathbb{D}}(z1, z2)\)

pyzeta.geometry.visuals.hypPlaneWave(realArr, imagArr, xi, k, model='H')[source]

TODO.

Return type:

ndarray[Any, dtype[complex128]]

pyzeta.geometry.visuals.plotFundDom(*generators, z0=1j, transAx=True, center=True, ax=None, **kwargs)[source]

Plot the fundamental domain of a Schottky group of arbitrary rank.

The generators must be passed as arguments to this function. Note that only the generators (not in addition their inverses) should be passed. Generators may be of type SL2R or of type SU11. The model (Upper Halfplane or Poincare Disk) is infered from the type of the generators.

The fundamental domain plotted here is a Dirichlet domain (cf. Dal’Bo p.21) centered at z0.

Parameters:
  • *generators (Union[SL2R, SU11]) – Generators of the Schottky group

  • z0 (Union[float, complex]) – center of the Dirichlet domain, defaults to i (or 0) (default: 1j) on the Upper Halfplane (or on the Poincare Disk, respectively)

  • transAx (bool) – specifies whether the translation axis is plotted for each (default: True) generator, defaults to true

  • center (bool) – specifies whether the center of the domain is plotted, (default: True) defaults to True

  • ax (Optional[Any]) – Matplotlib axes object in which the plot should be drawn. If (default: None) None is passed, a new figure and axes are created, defaults to None

  • **kwargs (object) – Further keyword arguments are passed to hypgeo.Geodesic.plot

Raises:

InvalidMatrixException – Raised if the generators are neither of type SL2R nor of type SU11

Returns:

Tuple[Any, Any] – Matplotlib figure and axes objects with the new plot inside

pyzeta.geometry.visuals.styleFundamentalDomain(generators, z0, model, ax, boundaryPts, transAx, center, **kwargs)[source]

TODO.

Return type:

None