Hyperbolic Points¶
This module implements points in hyperbolic space of arbitrary dimension. It also contains the implementations for specific models of hyperbolic geometry.
This module also implements ideal points in hyperbolic space of arbitrary dimension. It also contains the implementations for specific models of hyperbolic geometry.
Note that not all models of hyperbolic space are bounded, meaning that the ideal boundary is not the topological boundary of the set underlying tho model. For example, the unit disk model is bounded with boundary given by the unit sphere. The hyperboloid model is not bounded.
AUTHORS:
Greg Laun (2013): initial version
EXAMPLES:
We can construct points in the upper half plane model, abbreviated UHP for convenience:
sage: UHP = HyperbolicPlane().UHP()
sage: UHP.get_point(2 + I)
Point in UHP I + 2
sage: g = UHP.get_point(3 + I)
sage: g.dist(UHP.get_point(I))
arccosh(11/2)
>>> from sage.all import *
>>> UHP = HyperbolicPlane().UHP()
>>> UHP.get_point(Integer(2) + I)
Point in UHP I + 2
>>> g = UHP.get_point(Integer(3) + I)
>>> g.dist(UHP.get_point(I))
arccosh(11/2)
UHP = HyperbolicPlane().UHP() UHP.get_point(2 + I) g = UHP.get_point(3 + I) g.dist(UHP.get_point(I))
We can also construct boundary points in the upper half plane model:
sage: UHP.get_point(3)
Boundary point in UHP 3
>>> from sage.all import *
>>> UHP.get_point(Integer(3))
Boundary point in UHP 3
UHP.get_point(3)
Some more examples:
sage: HyperbolicPlane().UHP().get_point(0)
Boundary point in UHP 0
sage: HyperbolicPlane().PD().get_point(I/2)
Point in PD 1/2*I
sage: HyperbolicPlane().KM().get_point((0,1))
Boundary point in KM (0, 1)
sage: HyperbolicPlane().HM().get_point((0,0,1))
Point in HM (0, 0, 1)
>>> from sage.all import *
>>> HyperbolicPlane().UHP().get_point(Integer(0))
Boundary point in UHP 0
>>> HyperbolicPlane().PD().get_point(I/Integer(2))
Point in PD 1/2*I
>>> HyperbolicPlane().KM().get_point((Integer(0),Integer(1)))
Boundary point in KM (0, 1)
>>> HyperbolicPlane().HM().get_point((Integer(0),Integer(0),Integer(1)))
Point in HM (0, 0, 1)
HyperbolicPlane().UHP().get_point(0) HyperbolicPlane().PD().get_point(I/2) HyperbolicPlane().KM().get_point((0,1)) HyperbolicPlane().HM().get_point((0,0,1))
- class sage.geometry.hyperbolic_space.hyperbolic_point.HyperbolicPoint(model, coordinates, is_boundary, check=True, **graphics_options)[source]¶
Bases:
Element
Abstract base class for hyperbolic points. This class should never be instantiated.
INPUT:
model
– the model of the hyperbolic spacecoordinates
– the coordinates of a hyperbolic point in the appropriate modelis_boundary
– whether the point is a boundary pointcheck
– boolean (default:True
); ifTrue
, then check to make sure the coordinates give a valid point in the model
EXAMPLES:
Comparison between different models is performed via coercion:
sage: UHP = HyperbolicPlane().UHP() sage: p = UHP.get_point(.2 + .3*I); p Point in UHP 0.200000000000000 + 0.300000000000000*I sage: PD = HyperbolicPlane().PD() sage: q = PD.get_point(0.2 + 0.3*I); q Point in PD 0.200000000000000 + 0.300000000000000*I sage: p == q False sage: PD(p) Point in PD 0.231213872832370 - 0.502890173410405*I sage: bool(p.coordinates() == q.coordinates()) True
>>> from sage.all import * >>> UHP = HyperbolicPlane().UHP() >>> p = UHP.get_point(RealNumber('.2') + RealNumber('.3')*I); p Point in UHP 0.200000000000000 + 0.300000000000000*I >>> PD = HyperbolicPlane().PD() >>> q = PD.get_point(RealNumber('0.2') + RealNumber('0.3')*I); q Point in PD 0.200000000000000 + 0.300000000000000*I >>> p == q False >>> PD(p) Point in PD 0.231213872832370 - 0.502890173410405*I >>> bool(p.coordinates() == q.coordinates()) True
UHP = HyperbolicPlane().UHP() p = UHP.get_point(.2 + .3*I); p PD = HyperbolicPlane().PD() q = PD.get_point(0.2 + 0.3*I); q p == q PD(p) bool(p.coordinates() == q.coordinates())
Similarly for boundary points:
sage: p = UHP.get_point(-1); p Boundary point in UHP -1 sage: q = PD.get_point(-1); q Boundary point in PD -1 sage: p == q True sage: PD(p) Boundary point in PD -1
>>> from sage.all import * >>> p = UHP.get_point(-Integer(1)); p Boundary point in UHP -1 >>> q = PD.get_point(-Integer(1)); q Boundary point in PD -1 >>> p == q True >>> PD(p) Boundary point in PD -1
p = UHP.get_point(-1); p q = PD.get_point(-1); q p == q PD(p)
It is an error to specify a point that does not lie in the appropriate model:
sage: HyperbolicPlane().UHP().get_point(0.2 - 0.3*I) Traceback (most recent call last): ... ValueError: 0.200000000000000 - 0.300000000000000*I is not a valid point in the UHP model sage: HyperbolicPlane().PD().get_point(1.2) Traceback (most recent call last): ... ValueError: 1.20000000000000 is not a valid point in the PD model sage: HyperbolicPlane().KM().get_point((1,1)) Traceback (most recent call last): ... ValueError: (1, 1) is not a valid point in the KM model sage: HyperbolicPlane().HM().get_point((1, 1, 1)) Traceback (most recent call last): ... ValueError: (1, 1, 1) is not a valid point in the HM model
>>> from sage.all import * >>> HyperbolicPlane().UHP().get_point(RealNumber('0.2') - RealNumber('0.3')*I) Traceback (most recent call last): ... ValueError: 0.200000000000000 - 0.300000000000000*I is not a valid point in the UHP model >>> HyperbolicPlane().PD().get_point(RealNumber('1.2')) Traceback (most recent call last): ... ValueError: 1.20000000000000 is not a valid point in the PD model >>> HyperbolicPlane().KM().get_point((Integer(1),Integer(1))) Traceback (most recent call last): ... ValueError: (1, 1) is not a valid point in the KM model >>> HyperbolicPlane().HM().get_point((Integer(1), Integer(1), Integer(1))) Traceback (most recent call last): ... ValueError: (1, 1, 1) is not a valid point in the HM model
HyperbolicPlane().UHP().get_point(0.2 - 0.3*I) HyperbolicPlane().PD().get_point(1.2) HyperbolicPlane().KM().get_point((1,1)) HyperbolicPlane().HM().get_point((1, 1, 1))
It is an error to specify an interior point of hyperbolic space as a boundary point:
sage: HyperbolicPlane().UHP().get_point(0.2 + 0.3*I, is_boundary=True) Traceback (most recent call last): ... ValueError: 0.200000000000000 + 0.300000000000000*I is not a valid boundary point in the UHP model
>>> from sage.all import * >>> HyperbolicPlane().UHP().get_point(RealNumber('0.2') + RealNumber('0.3')*I, is_boundary=True) Traceback (most recent call last): ... ValueError: 0.200000000000000 + 0.300000000000000*I is not a valid boundary point in the UHP model
HyperbolicPlane().UHP().get_point(0.2 + 0.3*I, is_boundary=True)
- coordinates()[source]¶
Return the coordinates of the point.
EXAMPLES:
sage: HyperbolicPlane().UHP().get_point(2 + I).coordinates() I + 2 sage: HyperbolicPlane().PD().get_point(1/2 + 1/2*I).coordinates() 1/2*I + 1/2 sage: HyperbolicPlane().KM().get_point((1/3, 1/4)).coordinates() (1/3, 1/4) sage: HyperbolicPlane().HM().get_point((0,0,1)).coordinates() (0, 0, 1)
>>> from sage.all import * >>> HyperbolicPlane().UHP().get_point(Integer(2) + I).coordinates() I + 2 >>> HyperbolicPlane().PD().get_point(Integer(1)/Integer(2) + Integer(1)/Integer(2)*I).coordinates() 1/2*I + 1/2 >>> HyperbolicPlane().KM().get_point((Integer(1)/Integer(3), Integer(1)/Integer(4))).coordinates() (1/3, 1/4) >>> HyperbolicPlane().HM().get_point((Integer(0),Integer(0),Integer(1))).coordinates() (0, 0, 1)
HyperbolicPlane().UHP().get_point(2 + I).coordinates() HyperbolicPlane().PD().get_point(1/2 + 1/2*I).coordinates() HyperbolicPlane().KM().get_point((1/3, 1/4)).coordinates() HyperbolicPlane().HM().get_point((0,0,1)).coordinates()
- graphics_options()[source]¶
Return the graphics options of the current point.
EXAMPLES:
sage: p = HyperbolicPlane().UHP().get_point(2 + I, color='red') sage: p.graphics_options() {'color': 'red'}
>>> from sage.all import * >>> p = HyperbolicPlane().UHP().get_point(Integer(2) + I, color='red') >>> p.graphics_options() {'color': 'red'}
p = HyperbolicPlane().UHP().get_point(2 + I, color='red') p.graphics_options()
- is_boundary()[source]¶
Return
True
ifself
is a boundary point.EXAMPLES:
sage: PD = HyperbolicPlane().PD() sage: p = PD.get_point(0.5+.2*I) sage: p.is_boundary() False sage: p = PD.get_point(I) sage: p.is_boundary() True
>>> from sage.all import * >>> PD = HyperbolicPlane().PD() >>> p = PD.get_point(RealNumber('0.5')+RealNumber('.2')*I) >>> p.is_boundary() False >>> p = PD.get_point(I) >>> p.is_boundary() True
PD = HyperbolicPlane().PD() p = PD.get_point(0.5+.2*I) p.is_boundary() p = PD.get_point(I) p.is_boundary()
- model()[source]¶
Return the model to which the
HyperbolicPoint
belongs.EXAMPLES:
sage: HyperbolicPlane().UHP().get_point(I).model() Hyperbolic plane in the Upper Half Plane Model sage: HyperbolicPlane().PD().get_point(0).model() Hyperbolic plane in the Poincare Disk Model sage: HyperbolicPlane().KM().get_point((0,0)).model() Hyperbolic plane in the Klein Disk Model sage: HyperbolicPlane().HM().get_point((0,0,1)).model() Hyperbolic plane in the Hyperboloid Model
>>> from sage.all import * >>> HyperbolicPlane().UHP().get_point(I).model() Hyperbolic plane in the Upper Half Plane Model >>> HyperbolicPlane().PD().get_point(Integer(0)).model() Hyperbolic plane in the Poincare Disk Model >>> HyperbolicPlane().KM().get_point((Integer(0),Integer(0))).model() Hyperbolic plane in the Klein Disk Model >>> HyperbolicPlane().HM().get_point((Integer(0),Integer(0),Integer(1))).model() Hyperbolic plane in the Hyperboloid Model
HyperbolicPlane().UHP().get_point(I).model() HyperbolicPlane().PD().get_point(0).model() HyperbolicPlane().KM().get_point((0,0)).model() HyperbolicPlane().HM().get_point((0,0,1)).model()
- show(boundary=True, **options)[source]¶
Plot
self
.EXAMPLES:
sage: HyperbolicPlane().PD().get_point(0).show() # needs sage.plot Graphics object consisting of 2 graphics primitives sage: HyperbolicPlane().KM().get_point((0,0)).show() # needs sage.plot Graphics object consisting of 2 graphics primitives sage: HyperbolicPlane().HM().get_point((0,0,1)).show() # needs sage.plot Graphics3d Object
>>> from sage.all import * >>> HyperbolicPlane().PD().get_point(Integer(0)).show() # needs sage.plot Graphics object consisting of 2 graphics primitives >>> HyperbolicPlane().KM().get_point((Integer(0),Integer(0))).show() # needs sage.plot Graphics object consisting of 2 graphics primitives >>> HyperbolicPlane().HM().get_point((Integer(0),Integer(0),Integer(1))).show() # needs sage.plot Graphics3d Object
HyperbolicPlane().PD().get_point(0).show() # needs sage.plot HyperbolicPlane().KM().get_point((0,0)).show() # needs sage.plot HyperbolicPlane().HM().get_point((0,0,1)).show() # needs sage.plot
- symmetry_involution()[source]¶
Return the involutory isometry fixing the given point.
EXAMPLES:
sage: z = HyperbolicPlane().UHP().get_point(3 + 2*I) sage: z.symmetry_involution() Isometry in UHP [ 3/2 -13/2] [ 1/2 -3/2] sage: HyperbolicPlane().UHP().get_point(I).symmetry_involution() Isometry in UHP [ 0 -1] [ 1 0] sage: HyperbolicPlane().PD().get_point(0).symmetry_involution() Isometry in PD [-I 0] [ 0 I] sage: HyperbolicPlane().KM().get_point((0, 0)).symmetry_involution() Isometry in KM [-1 0 0] [ 0 -1 0] [ 0 0 1] sage: HyperbolicPlane().HM().get_point((0,0,1)).symmetry_involution() Isometry in HM [-1 0 0] [ 0 -1 0] [ 0 0 1] sage: p = HyperbolicPlane().UHP().random_element() sage: A = p.symmetry_involution() sage: p.dist(A*p) # abs tol 1e-10 0 sage: A.preserves_orientation() True sage: A*A == HyperbolicPlane().UHP().get_isometry(identity_matrix(2)) # needs scipy True
>>> from sage.all import * >>> z = HyperbolicPlane().UHP().get_point(Integer(3) + Integer(2)*I) >>> z.symmetry_involution() Isometry in UHP [ 3/2 -13/2] [ 1/2 -3/2] >>> HyperbolicPlane().UHP().get_point(I).symmetry_involution() Isometry in UHP [ 0 -1] [ 1 0] >>> HyperbolicPlane().PD().get_point(Integer(0)).symmetry_involution() Isometry in PD [-I 0] [ 0 I] >>> HyperbolicPlane().KM().get_point((Integer(0), Integer(0))).symmetry_involution() Isometry in KM [-1 0 0] [ 0 -1 0] [ 0 0 1] >>> HyperbolicPlane().HM().get_point((Integer(0),Integer(0),Integer(1))).symmetry_involution() Isometry in HM [-1 0 0] [ 0 -1 0] [ 0 0 1] >>> p = HyperbolicPlane().UHP().random_element() >>> A = p.symmetry_involution() >>> p.dist(A*p) # abs tol 1e-10 0 >>> A.preserves_orientation() True >>> A*A == HyperbolicPlane().UHP().get_isometry(identity_matrix(Integer(2))) # needs scipy True
z = HyperbolicPlane().UHP().get_point(3 + 2*I) z.symmetry_involution() HyperbolicPlane().UHP().get_point(I).symmetry_involution() HyperbolicPlane().PD().get_point(0).symmetry_involution() HyperbolicPlane().KM().get_point((0, 0)).symmetry_involution() HyperbolicPlane().HM().get_point((0,0,1)).symmetry_involution() p = HyperbolicPlane().UHP().random_element() A = p.symmetry_involution() p.dist(A*p) # abs tol 1e-10 A.preserves_orientation() A*A == HyperbolicPlane().UHP().get_isometry(identity_matrix(2)) # needs scipy
- to_model(model)[source]¶
Convert
self
to themodel
.INPUT:
other
– (a string representing) the image model
EXAMPLES:
sage: UHP = HyperbolicPlane().UHP() sage: PD = HyperbolicPlane().PD() sage: PD.get_point(1/2+I/2).to_model(UHP) Point in UHP I + 2 sage: PD.get_point(1/2+I/2).to_model('UHP') Point in UHP I + 2
>>> from sage.all import * >>> UHP = HyperbolicPlane().UHP() >>> PD = HyperbolicPlane().PD() >>> PD.get_point(Integer(1)/Integer(2)+I/Integer(2)).to_model(UHP) Point in UHP I + 2 >>> PD.get_point(Integer(1)/Integer(2)+I/Integer(2)).to_model('UHP') Point in UHP I + 2
UHP = HyperbolicPlane().UHP() PD = HyperbolicPlane().PD() PD.get_point(1/2+I/2).to_model(UHP) PD.get_point(1/2+I/2).to_model('UHP')
- update_graphics(update=False, **options)[source]¶
Update the graphics options of a
HyperbolicPoint
. Ifupdate
isTrue
, update rather than overwrite.EXAMPLES:
sage: p = HyperbolicPlane().UHP().get_point(I); p.graphics_options() {} sage: p.update_graphics(color = "red"); p.graphics_options() {'color': 'red'} sage: p.update_graphics(color = "blue"); p.graphics_options() {'color': 'blue'} sage: p.update_graphics(True, size = 20); p.graphics_options() {'color': 'blue', 'size': 20}
>>> from sage.all import * >>> p = HyperbolicPlane().UHP().get_point(I); p.graphics_options() {} >>> p.update_graphics(color = "red"); p.graphics_options() {'color': 'red'} >>> p.update_graphics(color = "blue"); p.graphics_options() {'color': 'blue'} >>> p.update_graphics(True, size = Integer(20)); p.graphics_options() {'color': 'blue', 'size': 20}
p = HyperbolicPlane().UHP().get_point(I); p.graphics_options() p.update_graphics(color = "red"); p.graphics_options() p.update_graphics(color = "blue"); p.graphics_options() p.update_graphics(True, size = 20); p.graphics_options()
- class sage.geometry.hyperbolic_space.hyperbolic_point.HyperbolicPointUHP(model, coordinates, is_boundary, check=True, **graphics_options)[source]¶
Bases:
HyperbolicPoint
A point in the UHP model.
INPUT:
the coordinates of a point in the unit disk in the complex plane \(\CC\)
EXAMPLES:
sage: HyperbolicPlane().UHP().get_point(2*I) Point in UHP 2*I sage: HyperbolicPlane().UHP().get_point(1) Boundary point in UHP 1
>>> from sage.all import * >>> HyperbolicPlane().UHP().get_point(Integer(2)*I) Point in UHP 2*I >>> HyperbolicPlane().UHP().get_point(Integer(1)) Boundary point in UHP 1
HyperbolicPlane().UHP().get_point(2*I) HyperbolicPlane().UHP().get_point(1)
- show(boundary=True, **options)[source]¶
Plot
self
.EXAMPLES:
sage: HyperbolicPlane().UHP().get_point(I).show() Graphics object consisting of 2 graphics primitives sage: HyperbolicPlane().UHP().get_point(0).show() # needs sage.plot Graphics object consisting of 2 graphics primitives sage: HyperbolicPlane().UHP().get_point(infinity).show() Traceback (most recent call last): ... NotImplementedError: can...t draw the point infinity
>>> from sage.all import * >>> HyperbolicPlane().UHP().get_point(I).show() Graphics object consisting of 2 graphics primitives >>> HyperbolicPlane().UHP().get_point(Integer(0)).show() # needs sage.plot Graphics object consisting of 2 graphics primitives >>> HyperbolicPlane().UHP().get_point(infinity).show() Traceback (most recent call last): ... NotImplementedError: can...t draw the point infinity
HyperbolicPlane().UHP().get_point(I).show() HyperbolicPlane().UHP().get_point(0).show() # needs sage.plot HyperbolicPlane().UHP().get_point(infinity).show()
- symmetry_involution()[source]¶
Return the involutory isometry fixing the given point.
EXAMPLES:
sage: HyperbolicPlane().UHP().get_point(3 + 2*I).symmetry_involution() Isometry in UHP [ 3/2 -13/2] [ 1/2 -3/2]
>>> from sage.all import * >>> HyperbolicPlane().UHP().get_point(Integer(3) + Integer(2)*I).symmetry_involution() Isometry in UHP [ 3/2 -13/2] [ 1/2 -3/2]
HyperbolicPlane().UHP().get_point(3 + 2*I).symmetry_involution()