Hyperbolic Models - Hyperbolic Geometry

Skip to content
Back to top
View this page
Edit this page

# Hyperbolic Models

In this module, a hyperbolic model is a collection of data that allow the user to implement new models of hyperbolic space with minimal effort. The data include facts about the underlying set (such as whether the model is bounded), facts about the metric (such as whether the model is conformal), facts about the isometry group (such as whether it is a linear or projective group), and more. Generally speaking, any data or method that pertains to the model itself – rather than the points, geodesics, or isometries of the model – is implemented in this module.

Abstractly, a model of hyperbolic space is a connected, simply connected manifold equipped with a complete Riemannian metric of constant curvature \(-1\). This module records information sufficient to enable computations in hyperbolic space without explicitly specifying the underlying set or its Riemannian metric. Although, see the SageManifolds project if you would like to take this approach.

This module implements the abstract base class for a model of hyperbolic space of arbitrary dimension. It also contains the implementations of specific models of hyperbolic geometry.

AUTHORS:

- Greg Laun (2013): Initial version.

EXAMPLES:

We illustrate how the classes in this module encode data by comparing the upper half plane (UHP), Poincaré disk (PD) and hyperboloid (HM) models. First we create:

Sage

    sage: U = HyperbolicPlane().UHP()
    sage: P = HyperbolicPlane().PD()
    sage: H = HyperbolicPlane().HM()

Python

    >>> from sage.all import *
    >>> U = HyperbolicPlane().UHP()
    >>> P = HyperbolicPlane().PD()
    >>> H = HyperbolicPlane().HM()

We note that the UHP and PD models are bounded while the HM model is not:

Sage

    sage: U.is_bounded() and P.is_bounded()
    True
    sage: H.is_bounded()
    False

[Python]

    >>> from sage.all import *
    >>> U.is_bounded() and P.is_bounded()
    True
    >>> H.is_bounded()
    False

The isometry groups of UHP and PD are projective, while that of HM is linear:

Sage

    sage: U.is_isometry_group_projective()
    True
    sage: H.is_isometry_group_projective()
    False

Python

    >>> from sage.all import *
    >>> U.is_isometry_group_projective()
    True
    >>> H.is_isometry_group_projective()
    False

The models are responsible for determining if the coordinates of points and the matrix of linear maps are appropriate for constructing points and isometries in hyperbolic space:

Sage

    sage: U.point_in_model(2 + I)
    True
    sage: U.point_in_model(2 - I)
    False
    sage: U.point_in_model(2)
    False
    sage: U.boundary_point_in_model(2)
    True

[Python]

    >>> from sage.all import *
    >>> U.point_in_model(Integer(2) + I)
    True
    >>> U.point_in_model(Integer(2) - I)
    False
    >>> U.point_in_model(Integer(2))
    False
    >>> U.boundary_point_in_model(Integer(2))
    True

class sage.geometry.hyperbolic_space.hyperbolic_model.HyperbolicModel(space, name, short_name, bounded, conformal, dimension, isometry_group, isometry_group_is_projective)

  Bases: `Parent`, `UniqueRepresentation`, `BindableClass`

  Abstract base class for hyperbolic models.

  Element

    alias of `HyperbolicPoint`

  bdry_point_test(p)

    Test whether a point is in the model. If the point is in the model, do nothing; otherwise raise a `ValueError`.

    EXAMPLES:

    Sage

        sage: HyperbolicPlane().UHP().bdry_point_test(2)
        sage: HyperbolicPlane().UHP().bdry_point_test(1 + I)
        Traceback (most recent call last):
        ...
        ValueError: I + 1 is not a valid boundary point in the UHP model

    Python

        >>> from sage.all import *
        >>> HyperbolicPlane().UHP().bdry_point_test(Integer(2))
        >>> HyperbolicPlane().UHP().bdry_point_test(Integer(1) + I)
        Traceback (most recent call last):
        ...
        ValueError: I + 1 is not a valid boundary point in the UHP model

  boundary_point_in_model(p)

    Return `True` if the point is on the ideal boundary of hyperbolic space and `False` otherwise.

    INPUT:

    - any object that can converted into a complex number

    OUTPUT: boolean

    EXAMPLES:

    Sage

        sage: HyperbolicPlane().UHP().boundary_point_in_model(I)
        False

    Python

        >>> from sage.all import *
        >>> HyperbolicPlane().UHP().boundary_point_in_model(I)
        False

  dist(a, b)

    Calculate the hyperbolic distance between `a` and `b`.

    INPUT:

    - `a`, `b` – a point or geodesic

    OUTPUT: the hyperbolic distance

    EXAMPLES:

    Sage

        sage: UHP = HyperbolicPlane().UHP()
        sage: p1 = UHP.get_point(5 + 7*I)
        sage: p2 = UHP.get_point(1.0 + I)
        sage: UHP.dist(p1, p2)
        2.23230104635820

        sage: PD = HyperbolicPlane().PD()
        sage: p1 = PD.get_point(0)
        sage: p2 = PD.get_point(I/2)
        sage: PD.dist(p1, p2)
        arccosh(5/3)

        sage: UHP(p1).dist(UHP(p2))
        arccosh(5/3)

        sage: KM = HyperbolicPlane().KM()
        sage: p1 = KM.get_point((0, 0))
        sage: p2 = KM.get_point((1/2, 1/2))
        sage: numerical_approx(KM.dist(p1, p2))
        0.881373587019543

        sage: HM = HyperbolicPlane().HM()
        sage: p1 = HM.get_point((0,0,1))
        sage: p2 = HM.get_point((1,0,sqrt(2)))
        sage: numerical_approx(HM.dist(p1, p2))
        0.881373587019543

    Python

        >>> from sage.all import *
        >>> UHP = HyperbolicPlane().UHP()
        >>> p1 = UHP.get_point(Integer(5) + Integer(7)*I)
        >>> p2 = UHP.get_point(RealNumber('1.0') + I)
        >>> UHP.dist(p1, p2)
        2.23230104635820

        >>> PD = HyperbolicPlane().PD()
        >>> p1 = PD.get_point(Integer(0))
        >>> p2 = PD.get_point(I/Integer(2))
        >>> PD.dist(p1, p2)
        arccosh(5/3)

        >>> UHP(p1).dist(UHP(p2))
        arccosh(5/3)

        >>> KM = HyperbolicPlane().KM()
        >>> p1 = KM.get_point((Integer(0), Integer(0)))
        >>> p2 = KM.get_point((Integer(1)/Integer(2), Integer(1)/Integer(2)))
        >>> numerical_approx(KM.dist(p1, p2))
        0.881373587019543

        >>> HM = HyperbolicPlane().HM()
        >>> p1 = HM.get_point((Integer(0),Integer(0),Integer(1)))
        >>> p2 = HM.get_point((Integer(1),Integer(0),sqrt(Integer(2))))
        >>> numerical_approx(HM.dist(p1, p2))
        0.881373587019543

    Distance between a point and itself is 0:

    Sage

        sage: p = UHP.get_point(47 + I)
        sage: UHP.dist(p, p)
        0

    [Python]

        >>> from sage.all import *
        >>> p = UHP.get_point(Integer(47) + I)
        >>> UHP.dist(p, p)
        0

    Points on the boundary are infinitely far from interior points:

    Sage

        sage: UHP.get_point(3).dist(UHP.get_point(I))
        +Infinity

    Python

        >>> from sage.all import *
        >>> UHP.get_point(Integer(3)).dist(UHP.get_point(I))
        +Infinity

  get_geodesic(start, end=None, **graphics_options)

    Return a geodesic in the appropriate model.

    EXAMPLES:

    Sage

        sage: HyperbolicPlane().UHP().get_geodesic(I, 2*I)
        Geodesic in UHP from I to 2*I

        sage: HyperbolicPlane().PD().get_geodesic(0, I/2)
        Geodesic in PD from 0 to 1/2*I

        sage: HyperbolicPlane().KM().get_geodesic((1/2, 1/2), (0,0))
        Geodesic in KM from (1/2, 1/2) to (0, 0)

        sage: HyperbolicPlane().HM().get_geodesic((0,0,1), (1,0, sqrt(2)))
        Geodesic in HM from (0, 0, 1) to (1, 0, sqrt(2))

    Python

        >>> from sage.all import *
        >>> HyperbolicPlane().UHP().get_geodesic(I, Integer(2)*I)
        Geodesic in UHP from I to 2*I

        >>> HyperbolicPlane().PD().get_geodesic(Integer(0), I/Integer(2))
        Geodesic in PD from 0 to 1/2*I

        >>> HyperbolicPlane().KM().get_geodesic((Integer(1)/Integer(2), Integer(1)/Integer(2)), (Integer(0),Integer(0)))
        Geodesic in KM from (1/2, 1/2) to (0, 0)

        >>> HyperbolicPlane().HM().get_geodesic((Integer(0),Integer(0),Integer(1)), (Integer(1),Integer(0), sqrt(Integer(2))))
        Geodesic in HM from (0, 0, 1) to (1, 0, sqrt(2))

  get_isometry(A)

    Return an isometry in `self` from the matrix `A` in the isometry group of `self`.

    EXAMPLES:

    Sage

        sage: HyperbolicPlane().UHP().get_isometry(identity_matrix(2))
        Isometry in UHP
        [1 0]
        [0 1]

        sage: HyperbolicPlane().PD().get_isometry(identity_matrix(2))
        Isometry in PD
        [1 0]
        [0 1]

        sage: HyperbolicPlane().KM().get_isometry(identity_matrix(3))               # needs scipy
        Isometry in KM
        [1 0 0]
        [0 1 0]
        [0 0 1]

        sage: HyperbolicPlane().HM().get_isometry(identity_matrix(3))               # needs scipy
        Isometry in HM
        [1 0 0]
        [0 1 0]
        [0 0 1]

    Python

        >>> from sage.all import *
        >>> HyperbolicPlane().UHP().get_isometry(identity_matrix(Integer(2)))
        Isometry in UHP
        [1 0]
        [0 1]

        >>> HyperbolicPlane().PD().get_isometry(identity_matrix(Integer(2)))
        Isometry in PD
        [1 0]
        [0 1]

        >>> HyperbolicPlane().KM().get_isometry(identity_matrix(Integer(3)))               # needs scipy
        Isometry in KM
        [1 0 0]
        [0 1 0]
        [0 0 1]

        >>> HyperbolicPlane().HM().get_isometry(identity_matrix(Integer(3)))               # needs scipy
        Isometry in HM
        [1 0 0]
        [0 1 0]
        [0 0 1]

  get_point(coordinates, is_boundary=None, **graphics_options)

    Return a point in `self`.

    Automatically determine the type of point to return given either:

    1. the coordinates of a point in the interior or ideal boundary of hyperbolic space, or

    2. a `HyperbolicPoint` object.

    INPUT:

    - a point in hyperbolic space or on the ideal boundary

    OUTPUT: a `HyperbolicPoint`

    EXAMPLES:

    We can create an interior point via the coordinates:

    Sage

        sage: HyperbolicPlane().UHP().get_point(2*I)
        Point in UHP 2*I

    Python

        >>> from sage.all import *
        >>> HyperbolicPlane().UHP().get_point(Integer(2)*I)
        Point in UHP 2*I

    Or we can create a boundary point via the coordinates:

    Sage

        sage: HyperbolicPlane().UHP().get_point(23)
        Boundary point in UHP 23

    [Python]

        >>> from sage.all import *
        >>> HyperbolicPlane().UHP().get_point(Integer(23))
        Boundary point in UHP 23

    However we cannot create points outside of our model:

    Sage

        sage: HyperbolicPlane().UHP().get_point(12 - I)
        Traceback (most recent call last):
        ...
        ValueError: -I + 12 is not a valid point in the UHP model

    Python

        >>> from sage.all import *
        >>> HyperbolicPlane().UHP().get_point(Integer(12) - I)
        Traceback (most recent call last):
        ...
        ValueError: -I + 12 is not a valid point in the UHP model

    Sage

        sage: HyperbolicPlane().UHP().get_point(2 + 3*I)
        Point in UHP 3*I + 2

        sage: HyperbolicPlane().PD().get_point(0)
        Point in PD 0

        sage: HyperbolicPlane().KM().get_point((0,0))
        Point in KM (0, 0)

        sage: HyperbolicPlane().HM().get_point((0,0,1))
        Point in HM (0, 0, 1)

        sage: p = HyperbolicPlane().UHP().get_point(I, color='red')
        sage: p.graphics_options()
        {'color': 'red'}

    [Python]

        >>> from sage.all import *
        >>> HyperbolicPlane().UHP().get_point(Integer(2) + Integer(3)*I)
        Point in UHP 3*I + 2

        >>> HyperbolicPlane().PD().get_point(Integer(0))
        Point in PD 0

        >>> HyperbolicPlane().KM().get_point((Integer(0),Integer(0)))
        Point in KM (0, 0)

        >>> HyperbolicPlane().HM().get_point((Integer(0),Integer(0),Integer(1)))
        Point in HM (0, 0, 1)

        >>> p = HyperbolicPlane().UHP().get_point(I, color='red')
        >>> p.graphics_options()
        {'color': 'red'}

    Sage

        sage: HyperbolicPlane().UHP().get_point(12)
        Boundary point in UHP 12

        sage: HyperbolicPlane().UHP().get_point(infinity)
        Boundary point in UHP +Infinity

        sage: HyperbolicPlane().PD().get_point(I)
        Boundary point in PD I

        sage: HyperbolicPlane().KM().get_point((0,-1))
        Boundary point in KM (0, -1)

    Python

        >>> from sage.all import *
        >>> HyperbolicPlane().UHP().get_point(Integer(12))
        Boundary point in UHP 12

        >>> HyperbolicPlane().UHP().get_point(infinity)
        Boundary point in UHP +Infinity

        >>> HyperbolicPlane().PD().get_point(I)
        Boundary point in PD I

        >>> HyperbolicPlane().KM().get_point((Integer(0),-Integer(1)))
        Boundary point in KM (0, -1)

  is_bounded()

    Return `True` if `self` is a bounded model.

    EXAMPLES:

    Sage

        sage: HyperbolicPlane().UHP().is_bounded()
        True
        sage: HyperbolicPlane().PD().is_bounded()
        True
        sage: HyperbolicPlane().KM().is_bounded()
        True
        sage: HyperbolicPlane().HM().is_bounded()
        False

    Python

        >>> from sage.all import *
        >>> HyperbolicPlane().UHP().is_bounded()
        True
        >>> HyperbolicPlane().PD().is_bounded()
        True
        >>> HyperbolicPlane().KM().is_bounded()
        True
        >>> HyperbolicPlane().HM().is_bounded()
        False

  is_conformal()

    Return `True` if `self` is a conformal model.

    EXAMPLES:

    Sage

        sage: UHP = HyperbolicPlane().UHP()
        sage: UHP.is_conformal()
        True

    Python

        >>> from sage.all import *
        >>> UHP = HyperbolicPlane().UHP()
        >>> UHP.is_conformal()
        True

  is_isometry_group_projective()

    Return `True` if the isometry group of `self` is projective.

    EXAMPLES:

    Sage

        sage: UHP = HyperbolicPlane().UHP()
        sage: UHP.is_isometry_group_projective()
        True

    Python

        >>> from sage.all import *
        >>> UHP = HyperbolicPlane().UHP()
        >>> UHP.is_isometry_group_projective()
        True

  isometry_from_fixed_points(repel, attract)

    Given two fixed points `repel` and `attract` as hyperbolic points return a hyperbolic isometry with `repel` as repelling fixed point and `attract` as attracting fixed point.

    EXAMPLES:

    Sage

        sage: UHP = HyperbolicPlane().UHP()
        sage: PD = HyperbolicPlane().PD()
        sage: PD.isometry_from_fixed_points(-i, i)
        Isometry in PD
        [   3/4  1/4*I]
        [-1/4*I    3/4]

    Python

        >>> from sage.all import *
        >>> UHP = HyperbolicPlane().UHP()
        >>> PD = HyperbolicPlane().PD()
        >>> PD.isometry_from_fixed_points(-i, i)
        Isometry in PD
        [   3/4  1/4*I]
        [-1/4*I    3/4]

    Sage

        sage: p, q = PD.get_point(1/2 + I/2), PD.get_point(6/13 + 9/13*I)
        sage: PD.isometry_from_fixed_points(p, q)
        Traceback (most recent call last):
        ...
        ValueError: fixed points of hyperbolic elements must be ideal

        sage: p, q = PD.get_point(4/5 + 3/5*I), PD.get_point(-I)
        sage: PD.isometry_from_fixed_points(p, q)
        Isometry in PD
        [ 1/6*I - 2/3 -1/3*I - 1/6]
        [ 1/3*I - 1/6 -1/6*I - 2/3]

    [Python]

        >>> from sage.all import *
        >>> p, q = PD.get_point(Integer(1)/Integer(2) + I/Integer(2)), PD.get_point(Integer(6)/Integer(13) + Integer(9)/Integer(13)*I)
        >>> PD.isometry_from_fixed_points(p, q)
        Traceback (most recent call last):
        ...
        ValueError: fixed points of hyperbolic elements must be ideal

        >>> p, q = PD.get_point(Integer(4)/Integer(5) + Integer(3)/Integer(5)*I), PD.get_point(-I)
        >>> PD.isometry_from_fixed_points(p, q)
        Isometry in PD
        [ 1/6*I - 2/3 -1/3*I - 1/6]
        [ 1/3*I - 1/6 -1/6*I - 2/3]

  isometry_in_model(A)

    Return `True` if the input matrix represents an isometry of the given model and `False` otherwise.

    INPUT:

    - `A` – a matrix that represents an isometry in the appropriate model

    OUTPUT: boolean

    EXAMPLES:

    Sage

        sage: HyperbolicPlane().UHP().isometry_in_model(identity_matrix(2))
        True

        sage: HyperbolicPlane().UHP().isometry_in_model(identity_matrix(3))
        False

    Python

        >>> from sage.all import *
        >>> HyperbolicPlane().UHP().isometry_in_model(identity_matrix(Integer(2)))
        True

        >>> HyperbolicPlane().UHP().isometry_in_model(identity_matrix(Integer(3)))
        False

  isometry_test(A)

    Test whether an isometry `A` is in the model.

    If the isometry is in the model, do nothing. Otherwise, raise a `ValueError`.

    EXAMPLES:

    Sage

        sage: HyperbolicPlane().UHP().isometry_test(identity_matrix(2))
        sage: HyperbolicPlane().UHP().isometry_test(matrix(2, [I,1,2,1]))
        Traceback (most recent call last):
        ...
        ValueError:
        [I 1]
        [2 1] is not a valid isometry in the UHP model

    Python

        >>> from sage.all import *
        >>> HyperbolicPlane().UHP().isometry_test(identity_matrix(Integer(2)))
        >>> HyperbolicPlane().UHP().isometry_test(matrix(Integer(2), [I,Integer(1),Integer(2),Integer(1)]))
        Traceback (most recent call last):
        ...
        ValueError:
        [I 1]
        [2 1] is not a valid isometry in the UHP model

  name()

    Return the name of this model.

    EXAMPLES:

    Sage

        sage: UHP = HyperbolicPlane().UHP()
        sage: UHP.name()
        'Upper Half Plane Model'

    Python

        >>> from sage.all import *
        >>> UHP = HyperbolicPlane().UHP()
        >>> UHP.name()
        'Upper Half Plane Model'

  point_in_model(p)

    Return `True` if the point `p` is in the interior of the given model and `False` otherwise.

    INPUT:

    - any object that can converted into a complex number

    OUTPUT: boolean

    EXAMPLES:

    Sage

        sage: HyperbolicPlane().UHP().point_in_model(I)
        True
        sage: HyperbolicPlane().UHP().point_in_model(-I)
        False

    Python

        >>> from sage.all import *
        >>> HyperbolicPlane().UHP().point_in_model(I)
        True
        >>> HyperbolicPlane().UHP().point_in_model(-I)
        False

  point_test(p)

    Test whether a point is in the model. If the point is in the model, do nothing. Otherwise, raise a `ValueError`.

    EXAMPLES:

    Sage

        sage: from sage.geometry.hyperbolic_space.hyperbolic_model import HyperbolicModelUHP
        sage: HyperbolicPlane().UHP().point_test(2 + I)
        sage: HyperbolicPlane().UHP().point_test(2 - I)
        Traceback (most recent call last):
        ...
        ValueError: -I + 2 is not a valid point in the UHP model

    Python

        >>> from sage.all import *
        >>> from sage.geometry.hyperbolic_space.hyperbolic_model import HyperbolicModelUHP
        >>> HyperbolicPlane().UHP().point_test(Integer(2) + I)
        >>> HyperbolicPlane().UHP().point_test(Integer(2) - I)
        Traceback (most recent call last):
        ...
        ValueError: -I + 2 is not a valid point in the UHP model

  random_element(**kwargs)

    Return a random point in `self`.

    The points are uniformly distributed over the rectangle \([-10, 10] \times [0, 10 i]\) in the upper half plane model.

    EXAMPLES:

    Sage

        sage: p = HyperbolicPlane().UHP().random_element()
        sage: bool((p.coordinates().imag()) > 0)
        True

        sage: p = HyperbolicPlane().PD().random_element()
        sage: HyperbolicPlane().PD().point_in_model(p.coordinates())
        True

        sage: p = HyperbolicPlane().KM().random_element()
        sage: HyperbolicPlane().KM().point_in_model(p.coordinates())
        True

        sage: p = HyperbolicPlane().HM().random_element().coordinates()
        sage: bool((p[0]**2 + p[1]**2 - p[2]**2 - 1) < 10**-8)
        True

    Python

        >>> from sage.all import *
        >>> p = HyperbolicPlane().UHP().random_element()
        >>> bool((p.coordinates().imag()) > Integer(0))
        True

        >>> p = HyperbolicPlane().PD().random_element()
        >>> HyperbolicPlane().PD().point_in_model(p.coordinates())
        True

        >>> p = HyperbolicPlane().KM().random_element()
        >>> HyperbolicPlane().KM().point_in_model(p.coordinates())
        True

        >>> p = HyperbolicPlane().HM().random_element().coordinates()
        >>> bool((p[Integer(0)]**Integer(2) + p[Integer(1)]**Integer(2) - p[Integer(2)]**Integer(2) - Integer(1)) < Integer(10)**-Integer(8))
        True

  random_geodesic(**kwargs)

    Return a random hyperbolic geodesic.

    Return the geodesic between two random points.

    EXAMPLES:

    Sage

        sage: h = HyperbolicPlane().PD().random_geodesic()
        sage: all( e.coordinates().abs() <= 1 for e in h.endpoints() )
        True

    Python

        >>> from sage.all import *
        >>> h = HyperbolicPlane().PD().random_geodesic()
        >>> all( e.coordinates().abs() <= Integer(1) for e in h.endpoints() )
        True

  random_isometry(preserve_orientation=True, **kwargs)

    Return a random isometry in the model of `self`.

    INPUT:

    - `preserve_orientation` – if `True` return an orientation-preserving isometry

    OUTPUT: a hyperbolic isometry

    EXAMPLES:

    Sage

        sage: # needs scipy
        sage: A = HyperbolicPlane().PD().random_isometry()
        sage: A.preserves_orientation()
        True
        sage: B = HyperbolicPlane().PD().random_isometry(preserve_orientation=False)
        sage: B.preserves_orientation()
        False

    Python

        >>> from sage.all import *
        >>> # needs scipy
        >>> A = HyperbolicPlane().PD().random_isometry()
        >>> A.preserves_orientation()
        True
        >>> B = HyperbolicPlane().PD().random_isometry(preserve_orientation=False)
        >>> B.preserves_orientation()
        False

  random_point(**kwargs)

    Return a random point of `self`.

    The points are uniformly distributed over the rectangle \([-10, 10] \times [0, 10 i]\) in the upper half plane model.

    EXAMPLES:

    Sage

        sage: p = HyperbolicPlane().UHP().random_point()
        sage: bool((p.coordinates().imag()) > 0)
        True

        sage: PD = HyperbolicPlane().PD()
        sage: p = PD.random_point()
        sage: PD.point_in_model(p.coordinates())
        True

    Python

        >>> from sage.all import *
        >>> p = HyperbolicPlane().UHP().random_point()
        >>> bool((p.coordinates().imag()) > Integer(0))
        True

        >>> PD = HyperbolicPlane().PD()
        >>> p = PD.random_point()
        >>> PD.point_in_model(p.coordinates())
        True

  short_name()

    Return the short name of this model.

    EXAMPLES:

    Sage

        sage: UHP = HyperbolicPlane().UHP()
        sage: UHP.short_name()
        'UHP'

    Python

        >>> from sage.all import *
        >>> UHP = HyperbolicPlane().UHP()
        >>> UHP.short_name()
        'UHP'

class sage.geometry.hyperbolic_space.hyperbolic_model.HyperbolicModelHM(space)

  Bases: `HyperbolicModel`

  Hyperboloid Model.

  boundary_point_in_model(p)

    Return `False` since the Hyperboloid model has no boundary points.

    EXAMPLES:

    Sage

        sage: HM = HyperbolicPlane().HM()
        sage: HM.boundary_point_in_model((0,0,1))
        False
        sage: HM.boundary_point_in_model((1,0,sqrt(2)))
        False
        sage: HM.boundary_point_in_model((1,2,1))
        False

    Python

        >>> from sage.all import *
        >>> HM = HyperbolicPlane().HM()
        >>> HM.boundary_point_in_model((Integer(0),Integer(0),Integer(1)))
        False
        >>> HM.boundary_point_in_model((Integer(1),Integer(0),sqrt(Integer(2))))
        False
        >>> HM.boundary_point_in_model((Integer(1),Integer(2),Integer(1)))
        False

  get_background_graphic(**bdry_options)

    Return a graphic object that makes the model easier to visualize. For the hyperboloid model, the background object is the hyperboloid itself.

    EXAMPLES:

    Sage

        sage: H = HyperbolicPlane().HM().get_background_graphic()                   # needs sage.plot

    Python

        >>> from sage.all import *
        >>> H = HyperbolicPlane().HM().get_background_graphic()                   # needs sage.plot

  isometry_in_model(A)

    Test that the matrix `A` is in the group \(SO(2,1)^+\).

    EXAMPLES:

    Sage

        sage: A = diagonal_matrix([1,1,-1])
        sage: HyperbolicPlane().HM().isometry_in_model(A)                            # needs scipy
        True

    Python

        >>> from sage.all import *
        >>> A = diagonal_matrix([Integer(1),Integer(1),-Integer(1)])
        >>> HyperbolicPlane().HM().isometry_in_model(A)                            # needs scipy
        True

  point_in_model(p)

    Check whether a complex number lies in the hyperboloid.

    EXAMPLES:

    Sage

        sage: HM = HyperbolicPlane().HM()
        sage: HM.point_in_model((0,0,1))
        True
        sage: HM.point_in_model((1,0,sqrt(2)))
        True
        sage: HM.point_in_model((1,2,1))
        False

    Python

        >>> from sage.all import *
        >>> HM = HyperbolicPlane().HM()
        >>> HM.point_in_model((Integer(0),Integer(0),Integer(1)))
        True
        >>> HM.point_in_model((Integer(1),Integer(0),sqrt(Integer(2))))
        True
        >>> HM.point_in_model((Integer(1),Integer(2),Integer(1)))
        False

class sage.geometry.hyperbolic_space.hyperbolic_model.HyperbolicModelKM(space)

  Bases: `HyperbolicModel`

  Klein Model.

  boundary_point_in_model(p)

    Check whether a point lies in the unit circle, which corresponds to the ideal boundary of the hyperbolic plane in the Klein model.

    EXAMPLES:

    Sage

        sage: KM = HyperbolicPlane().KM()
        sage: KM.boundary_point_in_model((1, 0))
        True
        sage: KM.boundary_point_in_model((1/2, 1/2))
        False
        sage: KM.boundary_point_in_model((1, .2))
        False

    Python

        >>> from sage.all import *
        >>> KM = HyperbolicPlane().KM()
        >>> KM.boundary_point_in_model((Integer(1), Integer(0)))
        True
        >>> KM.boundary_point_in_model((Integer(1)/Integer(2), Integer(1)/Integer(2)))
        False
        >>> KM.boundary_point_in_model((Integer(1), RealNumber('.2')))
        False

  get_background_graphic(**bdry_options)

    Return a graphic object that makes the model easier to visualize.

    For the Klein model, the background object is the ideal boundary.

    EXAMPLES:

    Sage

        sage: circ = HyperbolicPlane().KM().get_background_graphic()                # needs sage.plot

    Python

        >>> from sage.all import *
        >>> circ = HyperbolicPlane().KM().get_background_graphic()                # needs sage.plot

  isometry_in_model(A)

    Check if the given matrix `A` is in the group \(SO(2,1)\).

    EXAMPLES:

    Sage

        sage: A = matrix(3, [[1, 0, 0], [0, 17/8, 15/8], [0, 15/8, 17/8]])
        sage: HyperbolicPlane().KM().isometry_in_model(A)                           # needs scipy
        True

    Python

        >>> from sage.all import *
        >>> A = matrix(Integer(3), [[Integer(1), Integer(0), Integer(0)], [Integer(0), Integer(17)/Integer(8), Integer(15)/Integer(8)], [Integer(0), Integer(15)/Integer(8), Integer(17)/Integer(8)]])
        >>> HyperbolicPlane().KM().isometry_in_model(A)                           # needs scipy
        True

  point_in_model(p)

    Check whether a point lies in the open unit disk.

    EXAMPLES:

    Sage

        sage: KM = HyperbolicPlane().KM()
        sage: KM.point_in_model((1, 0))
        False
        sage: KM.point_in_model((1/2, 1/2))
        True
        sage: KM.point_in_model((1, .2))
        False

    Python

        >>> from sage.all import *
        >>> KM = HyperbolicPlane().KM()
        >>> KM.point_in_model((Integer(1), Integer(0)))
        False
        >>> KM.point_in_model((Integer(1)/Integer(2), Integer(1)/Integer(2)))
        True
        >>> KM.point_in_model((Integer(1), RealNumber('.2')))
        False

class sage.geometry.hyperbolic_space.hyperbolic_model.HyperbolicModelPD(space)

  Bases: `HyperbolicModel`

  Poincaré Disk Model.

  boundary_point_in_model(p)

    Check whether a complex number lies in the open unit disk.

    EXAMPLES:

    Sage

        sage: PD = HyperbolicPlane().PD()
        sage: PD.boundary_point_in_model(1.00)
        True
        sage: PD.boundary_point_in_model(1/2 + I/2)
        False
        sage: PD.boundary_point_in_model(1 + .2*I)
        False

    Python

        >>> from sage.all import *
        >>> PD = HyperbolicPlane().PD()
        >>> PD.boundary_point_in_model(RealNumber('1.00'))
        True
        >>> PD.boundary_point_in_model(Integer(1)/Integer(2) + I/Integer(2))
        False
        >>> PD.boundary_point_in_model(Integer(1) + RealNumber('.2')*I)
        False

  get_background_graphic(**bdry_options)

    Return a graphic object that makes the model easier to visualize.

    For the Poincaré disk, the background object is the ideal boundary.

    EXAMPLES:

    Sage

        sage: circ = HyperbolicPlane().PD().get_background_graphic()                # needs sage.plot

    Python

        >>> from sage.all import *
        >>> circ = HyperbolicPlane().PD().get_background_graphic()                # needs sage.plot

  isometry_in_model(A)

    Check if the given matrix `A` is in the group \(U(1,1)\).

    EXAMPLES:

    Sage

        sage: z = [CC.random_element() for k in range(2)]; z.sort(key=abs)
        sage: A = matrix(2,[z[1], z[0],z[0].conjugate(),z[1].conjugate()])
        sage: HyperbolicPlane().PD().isometry_in_model(A)
        True

    Python

        >>> from sage.all import *
        >>> z = [CC.random_element() for k in range(Integer(2))]; z.sort(key=abs)
        >>> A = matrix(Integer(2),[z[Integer(1)], z[Integer(0)],z[Integer(0)].conjugate(),z[Integer(1)].conjugate()])
        >>> HyperbolicPlane().PD().isometry_in_model(A)
        True

  point_in_model(p)

    Check whether a complex number lies in the open unit disk.

    EXAMPLES:

    Sage

        sage: PD = HyperbolicPlane().PD()
        sage: PD.point_in_model(1.00)
        False
        sage: PD.point_in_model(1/2 + I/2)
        True
        sage: PD.point_in_model(1 + .2*I)
        False

    Python

        >>> from sage.all import *
        >>> PD = HyperbolicPlane().PD()
        >>> PD.point_in_model(RealNumber('1.00'))
        False
        >>> PD.point_in_model(Integer(1)/Integer(2) + I/Integer(2))
        True
        >>> PD.point_in_model(Integer(1) + RealNumber('.2')*I)
        False

class sage.geometry.hyperbolic_space.hyperbolic_model.HyperbolicModelUHP(space)

  Bases: `HyperbolicModel`

  Upper Half Plane model.

  Element

    alias of `HyperbolicPointUHP`

  boundary_point_in_model(p)

    Check whether a complex number is a real number or `\infty`. In the `UHP.model_name_name`, this is the ideal boundary of hyperbolic space.

    EXAMPLES:

    Sage

        sage: UHP = HyperbolicPlane().UHP()
        sage: UHP.boundary_point_in_model(1 + I)
        False
        sage: UHP.boundary_point_in_model(infinity)
        True
        sage: UHP.boundary_point_in_model(CC(infinity))
        True
        sage: UHP.boundary_point_in_model(RR(infinity))
        True
        sage: UHP.boundary_point_in_model(1)
        True
        sage: UHP.boundary_point_in_model(12)
        True
        sage: UHP.boundary_point_in_model(1 - I)
        False
        sage: UHP.boundary_point_in_model(-2*I)
        False
        sage: UHP.boundary_point_in_model(0)
        True
        sage: UHP.boundary_point_in_model(I)
        False

    Python

        >>> from sage.all import *
        >>> UHP = HyperbolicPlane().UHP()
        >>> UHP.boundary_point_in_model(Integer(1) + I)
        False
        >>> UHP.boundary_point_in_model(infinity)
        True
        >>> UHP.boundary_point_in_model(CC(infinity))
        True
        >>> UHP.boundary_point_in_model(RR(infinity))
        True
        >>> UHP.boundary_point_in_model(Integer(1))
        True
        >>> UHP.boundary_point_in_model(Integer(12))
        True
        >>> UHP.boundary_point_in_model(Integer(1) - I)
        False
        >>> UHP.boundary_point_in_model(-Integer(2)*I)
        False
        >>> UHP.boundary_point_in_model(Integer(0))
        True
        >>> UHP.boundary_point_in_model(I)
        False

  get_background_graphic(**bdry_options)

    Return a graphic object that makes the model easier to visualize. For the upper half space, the background object is the ideal boundary.

    EXAMPLES:

    Sage

        sage: hp = HyperbolicPlane().UHP().get_background_graphic()                 # needs sage.plot

    Python

        >>> from sage.all import *
        >>> hp = HyperbolicPlane().UHP().get_background_graphic()                 # needs sage.plot

  isometry_from_fixed_points(repel, attract)

    Given two fixed points `repel` and `attract` as complex numbers return a hyperbolic isometry with `repel` as repelling fixed point and `attract` as attracting fixed point.

    EXAMPLES:

    Sage

        sage: UHP = HyperbolicPlane().UHP()
        sage: UHP.isometry_from_fixed_points(2 + I, 3 + I)
        Traceback (most recent call last):
        ...
        ValueError: fixed points of hyperbolic elements must be ideal

        sage: UHP.isometry_from_fixed_points(2, 0)
        Isometry in UHP
        [  -1    0]
        [-1/3 -1/3]

    Python

        >>> from sage.all import *
        >>> UHP = HyperbolicPlane().UHP()
        >>> UHP.isometry_from_fixed_points(Integer(2) + I, Integer(3) + I)
        Traceback (most recent call last):
        ...
        ValueError: fixed points of hyperbolic elements must be ideal

        >>> UHP.isometry_from_fixed_points(Integer(2), Integer(0))
        Isometry in UHP
        [  -1    0]
        [-1/3 -1/3]

  isometry_in_model(A)

    Check that `A` acts as an isometry on the upper half plane. That is, `A` must be an invertible \(2 \times 2\) matrix with real entries.

    EXAMPLES:

    Sage

        sage: UHP = HyperbolicPlane().UHP()
        sage: A = matrix(2,[1,2,3,4])
        sage: UHP.isometry_in_model(A)
        True
        sage: B = matrix(2,[I,2,4,1])
        sage: UHP.isometry_in_model(B)
        False

    Python

        >>> from sage.all import *
        >>> UHP = HyperbolicPlane().UHP()
        >>> A = matrix(Integer(2),[Integer(1),Integer(2),Integer(3),Integer(4)])
        >>> UHP.isometry_in_model(A)
        True
        >>> B = matrix(Integer(2),[I,Integer(2),Integer(4),Integer(1)])
        >>> UHP.isometry_in_model(B)
        False

    An example of a matrix \(A\) such that \(\det(A) \neq 1\), but the \(A\) acts isometrically:

    Sage

        sage: C = matrix(2,[10,0,0,10])
        sage: UHP.isometry_in_model(C)
        True

    [Python]

        >>> from sage.all import *
        >>> C = matrix(Integer(2),[Integer(10),Integer(0),Integer(0),Integer(10)])
        >>> UHP.isometry_in_model(C)
        True

  point_in_model(p)

    Check whether a complex number lies in the open upper half plane.

    EXAMPLES:

    Sage

        sage: UHP = HyperbolicPlane().UHP()
        sage: UHP.point_in_model(1 + I)
        True
        sage: UHP.point_in_model(infinity)
        False
        sage: UHP.point_in_model(CC(infinity))
        False
        sage: UHP.point_in_model(RR(infinity))
        False
        sage: UHP.point_in_model(1)
        False
        sage: UHP.point_in_model(12)
        False
        sage: UHP.point_in_model(1 - I)
        False
        sage: UHP.point_in_model(-2*I)
        False
        sage: UHP.point_in_model(I)
        True
        sage: UHP.point_in_model(0) # Not interior point
        False

    Python

        >>> from sage.all import *
        >>> UHP = HyperbolicPlane().UHP()
        >>> UHP.point_in_model(Integer(1) + I)
        True
        >>> UHP.point_in_model(infinity)
        False
        >>> UHP.point_in_model(CC(infinity))
        False
        >>> UHP.point_in_model(RR(infinity))
        False
        >>> UHP.point_in_model(Integer(1))
        False
        >>> UHP.point_in_model(Integer(12))
        False
        >>> UHP.point_in_model(Integer(1) - I)
        False
        >>> UHP.point_in_model(-Integer(2)*I)
        False
        >>> UHP.point_in_model(I)
        True
        >>> UHP.point_in_model(Integer(0)) # Not interior point
        False

  random_isometry(preserve_orientation=True, **kwargs)

    Return a random isometry in the Upper Half Plane model.

    INPUT:

    - `preserve_orientation` – if `True` return an orientation-preserving isometry

    OUTPUT: a hyperbolic isometry

    EXAMPLES:

    Sage

        sage: A = HyperbolicPlane().UHP().random_isometry()                         # needs scipy
        sage: B = HyperbolicPlane().UHP().random_isometry(preserve_orientation=False)           # needs scipy
        sage: B.preserves_orientation()                                             # needs scipy
        False

    Python

        >>> from sage.all import *
        >>> A = HyperbolicPlane().UHP().random_isometry()                         # needs scipy
        >>> B = HyperbolicPlane().UHP().random_isometry(preserve_orientation=False)           # needs scipy
        >>> B.preserves_orientation()                                             # needs scipy
        False

  random_point(**kwargs)

    Return a random point in the upper half plane. The points are uniformly distributed over the rectangle \([-10, 10] \times [0, 10i]\).

    EXAMPLES:

    Sage

        sage: p = HyperbolicPlane().UHP().random_point().coordinates()
        sage: bool((p.imag()) > 0)
        True

    Python

        >>> from sage.all import *
        >>> p = HyperbolicPlane().UHP().random_point().coordinates()
        >>> bool((p.imag()) > Integer(0))
        True