Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- coding: utf-8 -*- Coercion Maps Between Hyperbolic Plane Models
This module implements the coercion maps between different hyperbolic plane models.
AUTHORS:
- Travis Scrimshaw (2014): initial version """
#*********************************************************************** # Copyright (C) 2014 Travis Scrimshaw <tscrim at ucdavis.edu> # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # http://www.gnu.org/licenses/ #***********************************************************************
""" Abstract base class for morphisms between the hyperbolic models. """ """ Return the type of morphism.
EXAMPLES::
sage: UHP = HyperbolicPlane().UHP() sage: PD = HyperbolicPlane().PD() sage: phi = UHP.coerce_map_from(PD) sage: phi._repr_type() 'Coercion Isometry' """
""" Return the image of ``x`` under ``self``.
EXAMPLES::
sage: UHP = HyperbolicPlane().UHP() sage: PD = HyperbolicPlane().PD() sage: HM = HyperbolicPlane().HM() sage: phi = UHP.coerce_map_from(PD) sage: phi(PD.get_point(0.5+0.5*I)) Point in UHP 2.00000000000000 + 1.00000000000000*I sage: psi = HM.coerce_map_from(UHP) sage: psi(UHP.get_point(I)) Point in HM (0, 0, 1)
It is an error to try to convert a boundary point to a model that doesn't support boundary points::
sage: psi(UHP.get_point(infinity)) Traceback (most recent call last): ... NotImplementedError: boundary points are not implemented for the Hyperboloid Model
It is an error to try to convert a boundary point to a model that doesn't support boundary points::
sage: psi(UHP(infinity)) Traceback (most recent call last): ... NotImplementedError: boundary points are not implemented for the Hyperboloid Model """
else:
""" Convert the geodesic ``x`` of the domain into a geodesic of the codomain.
EXAMPLES::
sage: UHP = HyperbolicPlane().UHP() sage: PD = HyperbolicPlane().PD() sage: phi = UHP.coerce_map_from(PD) sage: phi.convert_geodesic(PD.get_geodesic(0.5+0.5*I, -I)) Geodesic in UHP from 2.00000000000000 + 1.00000000000000*I to 0 """ **x.graphics_options())
""" Convert the hyperbolic isometry ``x`` of the domain into an isometry of the codomain.
EXAMPLES::
sage: UHP = HyperbolicPlane().UHP() sage: HM = HyperbolicPlane().HM() sage: phi = HM.coerce_map_from(UHP) sage: I2 = UHP.get_isometry(identity_matrix(2)) sage: phi.convert_isometry(I2) Isometry in HM [1 0 0] [0 1 0] [0 0 1] """
""" Return the inverse coercion of ``self``.
EXAMPLES::
sage: UHP = HyperbolicPlane().UHP() sage: PD = HyperbolicPlane().PD() sage: phi = UHP.coerce_map_from(PD) sage: ~phi Coercion Isometry morphism: From: Hyperbolic plane in the Upper Half Plane Model To: Hyperbolic plane in the Poincare Disk Model """
############ # From UHP # ############
""" Coercion from the UHP to PD model. """ """ Return the image of the coordinates of the hyperbolic point ``x`` under ``self``.
EXAMPLES::
sage: UHP = HyperbolicPlane().UHP() sage: PD = HyperbolicPlane().PD() sage: phi = PD.coerce_map_from(UHP) sage: phi.image_coordinates(I) 0 """
""" Return the image of the matrix of the hyperbolic isometry ``x`` under ``self``.
EXAMPLES::
sage: UHP = HyperbolicPlane().UHP() sage: PD = HyperbolicPlane().PD() sage: phi = PD.coerce_map_from(UHP) sage: phi.image_isometry_matrix(identity_matrix(2)) [1 0] [0 1] """ # x = I * x
""" Coercion from the UHP to KM model. """ """ Return the image of the coordinates of the hyperbolic point ``x`` under ``self``.
EXAMPLES::
sage: UHP = HyperbolicPlane().UHP() sage: KM = HyperbolicPlane().KM() sage: phi = KM.coerce_map_from(UHP) sage: phi.image_coordinates(3 + I) (6/11, 9/11) """ (real(x)**2 + imag(x)**2 - 1)/(real(x)**2 + imag(x)**2 + 1))
""" Return the image of the matrix of the hyperbolic isometry ``x`` under ``self``.
EXAMPLES::
sage: UHP = HyperbolicPlane().UHP() sage: KM = HyperbolicPlane().KM() sage: phi = KM.coerce_map_from(UHP) sage: phi.image_isometry_matrix(identity_matrix(2)) [1 0 0] [0 1 0] [0 0 1] """
""" Coercion from the UHP to HM model. """ """ Return the image of the coordinates of the hyperbolic point ``x`` under ``self``.
EXAMPLES::
sage: UHP = HyperbolicPlane().UHP() sage: HM = HyperbolicPlane().HM() sage: phi = HM.coerce_map_from(UHP) sage: phi.image_coordinates(3 + I) (3, 9/2, 11/2) """ (real(x)**2 + imag(x)**2 - 1)/(2*imag(x)), (real(x)**2 + imag(x)**2 + 1)/(2*imag(x))))
""" Return the image of the matrix of the hyperbolic isometry ``x`` under ``self``.
EXAMPLES::
sage: UHP = HyperbolicPlane().UHP() sage: HM = HyperbolicPlane().HM() sage: phi = HM.coerce_map_from(UHP) sage: phi.image_isometry_matrix(identity_matrix(2)) [1 0 0] [0 1 0] [0 0 1] """
########### # From PD # ###########
""" Coercion from the PD to UHP model. """ """ Return the image of the coordinates of the hyperbolic point ``x`` under ``self``.
EXAMPLES::
sage: PD = HyperbolicPlane().PD() sage: UHP = HyperbolicPlane().UHP() sage: phi = UHP.coerce_map_from(PD) sage: phi.image_coordinates(0.5+0.5*I) 2.00000000000000 + 1.00000000000000*I sage: phi.image_coordinates(0) I sage: phi.image_coordinates(I) +Infinity sage: phi.image_coordinates(-I) 0 """
""" Return the image of the matrix of the hyperbolic isometry ``x`` under ``self``.
EXAMPLES:
We check that orientation-reversing isometries behave as they should::
sage: PD = HyperbolicPlane().PD() sage: UHP = HyperbolicPlane().UHP() sage: phi = UHP.coerce_map_from(PD) sage: phi.image_isometry_matrix(matrix([[0,I],[I,0]])) [-1 0] [ 0 -1] """
""" Coercion from the PD to KM model. """ """ Return the image of the coordinates of the hyperbolic point ``x`` under ``self``.
EXAMPLES::
sage: PD = HyperbolicPlane().PD() sage: KM = HyperbolicPlane().KM() sage: phi = KM.coerce_map_from(PD) sage: phi.image_coordinates(0.5+0.5*I) (0.666666666666667, 0.666666666666667) """ 2*imag(x)/(Integer(1) + real(x)**2 + imag(x)**2))
""" Return the image of the matrix of the hyperbolic isometry ``x`` under ``self``.
EXAMPLES::
sage: PD = HyperbolicPlane().PD() sage: KM = HyperbolicPlane().KM() sage: phi = KM.coerce_map_from(PD) sage: phi.image_isometry_matrix(matrix([[0,I],[I,0]])) [-1 0 0] [ 0 1 0] [ 0 0 -1] """ matrix(2, [1, -I, -I, 1]) / Integer(2))
""" Coercion from the PD to HM model. """ """ Return the image of the coordinates of the hyperbolic point ``x`` under ``self``.
EXAMPLES::
sage: PD = HyperbolicPlane().PD() sage: HM = HyperbolicPlane().HM() sage: phi = HM.coerce_map_from(PD) sage: phi.image_coordinates(0.5+0.5*I) (2.00000000000000, 2.00000000000000, 3.00000000000000) """ 2*imag(x)/(1 - real(x)**2 - imag(x)**2), (real(x)**2 + imag(x)**2 + 1) / (1 - real(x)**2 - imag(x)**2)))
""" Return the image of the matrix of the hyperbolic isometry ``x`` under ``self``.
EXAMPLES::
sage: PD = HyperbolicPlane().PD() sage: HM = HyperbolicPlane().HM() sage: phi = HM.coerce_map_from(PD) sage: phi.image_isometry_matrix(matrix([[0,I],[I,0]])) [-1 0 0] [ 0 1 0] [ 0 0 -1] """ matrix(2, [1, -I, -I, 1]) / Integer(2))
########### # From KM # ###########
""" Coercion from the KM to UHP model. """ """ Return the image of the coordinates of the hyperbolic point ``x`` under ``self``.
EXAMPLES::
sage: KM = HyperbolicPlane().KM() sage: UHP = HyperbolicPlane().UHP() sage: phi = UHP.coerce_map_from(KM) sage: phi.image_coordinates((0, 0)) I sage: phi.image_coordinates((0, 1)) +Infinity """ + I*(-(sqrt(-x[0]**2 - x[1]**2 + 1) - x[0]**2 - x[1]**2 + 1) / ((x[1] - 1)*sqrt(-x[0]**2 - x[1]**2 + 1) + x[1] - 1)))
""" Return the image of the matrix of the hyperbolic isometry ``x`` under ``self``.
EXAMPLES::
sage: KM = HyperbolicPlane().KM() sage: UHP = HyperbolicPlane().UHP() sage: phi = UHP.coerce_map_from(KM) sage: m = matrix([[5/3,0,4/3], [0,1,0], [4/3,0,5/3]]) sage: phi.image_isometry_matrix(m) [2*sqrt(1/3) sqrt(1/3)] [ sqrt(1/3) 2*sqrt(1/3)] """
""" Coercion from the KM to PD model. """ """ Return the image of the coordinates of the hyperbolic point ``x`` under ``self``.
EXAMPLES::
sage: KM = HyperbolicPlane().KM() sage: PD = HyperbolicPlane().PD() sage: phi = PD.coerce_map_from(KM) sage: phi.image_coordinates((0, 0)) 0 """ + I*x[1]/(1 + (1 - x[0]**2 - x[1]**2).sqrt()))
""" Return the image of the matrix of the hyperbolic isometry ``x`` under ``self``.
EXAMPLES::
sage: KM = HyperbolicPlane().KM() sage: PD = HyperbolicPlane().PD() sage: phi = PD.coerce_map_from(KM) sage: m = matrix([[5/3,0,4/3], [0,1,0], [4/3,0,5/3]]) sage: phi.image_isometry_matrix(m) [2*sqrt(1/3) sqrt(1/3)] [ sqrt(1/3) 2*sqrt(1/3)] """ matrix(2,[1,I,I,1])/Integer(2))
""" Coercion from the KM to HM model. """ """ Return the image of the coordinates of the hyperbolic point ``x`` under ``self``.
EXAMPLES::
sage: KM = HyperbolicPlane().KM() sage: HM = HyperbolicPlane().HM() sage: phi = HM.coerce_map_from(KM) sage: phi.image_coordinates((0, 0)) (0, 0, 1) """ / (1 - x[0]**2 - x[1]**2))
""" Return the image of the matrix of the hyperbolic isometry ``x`` under ``self``.
EXAMPLES::
sage: KM = HyperbolicPlane().KM() sage: HM = HyperbolicPlane().HM() sage: phi = HM.coerce_map_from(KM) sage: m = matrix([[5/3,0,4/3], [0,1,0], [4/3,0,5/3]]) sage: phi.image_isometry_matrix(m) [5/3 0 4/3] [ 0 1 0] [4/3 0 5/3] """
########### # From HM # ###########
""" Coercion from the HM to UHP model. """ """ Return the image of the coordinates of the hyperbolic point ``x`` under ``self``.
EXAMPLES::
sage: HM = HyperbolicPlane().HM() sage: UHP = HyperbolicPlane().UHP() sage: phi = UHP.coerce_map_from(HM) sage: phi.image_coordinates( vector((0,0,1)) ) I """ - x[0]**2 - x[1]**2 + x[1] - 1)
""" Return the image of the matrix of the hyperbolic isometry ``x`` under ``self``.
EXAMPLES::
sage: HM = HyperbolicPlane().HM() sage: UHP = HyperbolicPlane().UHP() sage: phi = UHP.coerce_map_from(HM) sage: phi.image_isometry_matrix(identity_matrix(3)) [1 0] [0 1] """
""" Coercion from the HM to PD model. """ """ Return the image of the coordinates of the hyperbolic point ``x`` under ``self``.
EXAMPLES::
sage: HM = HyperbolicPlane().HM() sage: PD = HyperbolicPlane().PD() sage: phi = PD.coerce_map_from(HM) sage: phi.image_coordinates( vector((0,0,1)) ) 0 """
""" Return the image of the matrix of the hyperbolic isometry ``x`` under ``self``.
EXAMPLES::
sage: HM = HyperbolicPlane().HM() sage: PD = HyperbolicPlane().PD() sage: phi = PD.coerce_map_from(HM) sage: phi.image_isometry_matrix(identity_matrix(3)) [1 0] [0 1] """ matrix(2,[1,I,I,1])/Integer(2))
""" Coercion from the HM to KM model. """ """ Return the image of the coordinates of the hyperbolic point ``x`` under ``self``.
EXAMPLES::
sage: HM = HyperbolicPlane().HM() sage: KM = HyperbolicPlane().KM() sage: phi = KM.coerce_map_from(HM) sage: phi.image_coordinates( vector((0,0,1)) ) (0, 0) """
""" Return the image of the matrix of the hyperbolic isometry ``x`` under ``self``.
EXAMPLES::
sage: HM = HyperbolicPlane().HM() sage: KM = HyperbolicPlane().KM() sage: phi = KM.coerce_map_from(HM) sage: phi.image_isometry_matrix(identity_matrix(3)) [1 0 0] [0 1 0] [0 0 1] """
##################################################################### ## Helper functions
r""" Given a matrix in `SL(2, \RR)` return its irreducible representation in `O(2,1)`.
Note that this is not the only homomorphism, but it is the only one that works in the context of the implemented 2D hyperbolic geometry models.
EXAMPLES::
sage: from sage.geometry.hyperbolic_space.hyperbolic_coercion import SL2R_to_SO21 sage: A = SL2R_to_SO21(identity_matrix(2)) sage: J = matrix([[1,0,0],[0,1,0],[0,0,-1]]) #Lorentzian Gram matrix sage: norm(A.transpose()*J*A - J) < 10**-4 True """
# Kill ~0 imaginary parts [a*d + b*c, a*c - b*d, a*c + b*d, a*b - c*d, Integer(1)/Integer(2)*a**2 - Integer(1)/Integer(2)*b**2 - Integer(1)/Integer(2)*c**2 + Integer(1)/Integer(2)*d**2, Integer(1)/Integer(2)*a**2 + Integer(1)/Integer(2)*b**2 - Integer(1)/Integer(2)*c**2 - Integer(1)/Integer(2)*d**2, a*b + c*d, Integer(1)/Integer(2)*a**2 - Integer(1)/Integer(2)*b**2 + Integer(1)/Integer(2)*c**2 - Integer(1)/Integer(2)*d**2, Integer(1)/Integer(2)*a**2 + Integer(1)/Integer(2)*b**2 + Integer(1)/Integer(2)*c**2 + Integer(1)/Integer(2)*d**2]))
#B = B.apply_map(attrcall('real')) else: # Orientation-reversing isometries swap the nappes of # the lightcone. This fixes that issue.
r""" A homomorphism from `SO(2, 1)` to `SL(2, \RR)`.
Note that this is not the only homomorphism, but it is the only one that works in the context of the implemented 2D hyperbolic geometry models.
EXAMPLES::
sage: from sage.geometry.hyperbolic_space.hyperbolic_coercion import SO21_to_SL2R sage: (SO21_to_SL2R(identity_matrix(3)) - identity_matrix(2)).norm() < 10**-4 True """ #################################################################### # SL(2,R) is the double cover of SO (2,1)^+, so we need to choose # # a lift. I have formulas for the absolute values of each entry # # a,b ,c,d of the lift matrix(2,[a,b,c,d]), but we need to choose # # one entry to be positive. I choose d for no particular reason, # # unless d = 0, then we choose c > 0. The basic strategy for this # # function is to find the linear map induced by the SO(2,1) # # element on the Lie algebra sl(2, R). This corresponds to the # # Adjoint action by a matrix A or -A in SL(2,R). To find which # # matrix let X,Y,Z be a basis for sl(2,R) and look at the images # # of X,Y,Z as well as the second and third standard basis vectors # # for 2x2 matrices (these are traceless, so are in the Lie # # algebra). These corresponds to AXA^-1 etc and give formulas # # for the entries of A. # #################################################################### Integer(1)/Integer(2)*m_8 + Integer(1)/Integer(2)*m_9) else: # d is 0, so we make c > 0 Integer(1)/Integer(2)*m_8 + Integer(1)/Integer(2)*m_9) # d = 0, so ad - bc = -bc = pm 1. |