Hyperbolic space

The hyperbolic space can be represented in three different models.

In the following the common functions are collected.

A function in this general section uses vectors interpreted as if in the hyperboloid model, and other representations usually just convert to this representation to use these general functions.

Manifolds.HyperbolicType
Hyperbolic{T} <: AbstractDecoratorManifold{ℝ}

The hyperbolic space $\mathcal H^n$ represented by $n+1$-Tuples, i.e. embedded in the Lorentzian manifold equipped with the MinkowskiMetric $⟨⋅,⋅⟩_{\mathrm{M}}$. The space is defined as

\[\mathcal H^n = \Bigl\{p ∈ ℝ^{n+1}\ \Big|\ ⟨p,p⟩_{\mathrm{M}}= -p_{n+1}^2 + \displaystyle\sum_{k=1}^n p_k^2 = -1, p_{n+1} > 0\Bigr\},.\]

The tangent space $T_p \mathcal H^n$ is given by

\[T_p \mathcal H^n := \bigl\{ X ∈ ℝ^{n+1} : ⟨p,X⟩_{\mathrm{M}} = 0 \bigr\}.\]

Note that while the MinkowskiMetric renders the Lorentz manifold (only) pseudo-Riemannian, on the tangent bundle of the Hyperbolic space it induces a Riemannian metric. The corresponding sectional curvature is $-1$.

If p and X are Vectors of length n+1 they are assumed to be a HyperboloidPoint and a HyperboloidTVector, respectively

Other models are the Poincaré ball model, see PoincareBallPoint and PoincareBallTVector, respectively and the Poincaré half space model, see PoincareHalfSpacePoint and PoincareHalfSpaceTVector, respectively.

Constructor

Hyperbolic(n::Int; parameter::Symbol=:type)

Generate the Hyperbolic manifold of dimension n.

source
Manifolds.HyperboloidPointType
HyperboloidPoint <: AbstractManifoldPoint

In the Hyperboloid model of the Hyperbolic $\mathcal H^n$ points are represented as vectors in $ℝ^{n+1}$ with MinkowskiMetric equal to $-1$.

This representation is the default, i.e. AbstractVectors are assumed to have this representation.

source
Manifolds.HyperboloidTVectorType
HyperboloidTVector <: TVector

In the Hyperboloid model of the Hyperbolic $\mathcal H^n$ tangent vctors are represented as vectors in $ℝ^{n+1}$ with MinkowskiMetric $⟨p,X⟩_{\mathrm{M}}=0$ to their base point $p$.

This representation is the default, i.e. vectors are assumed to have this representation.

source
Base.expMethod
exp(M::Hyperbolic, p, X)

Compute the exponential map on the Hyperbolic space $\mathcal H^n$ emanating from p towards X. The formula reads

\[\exp_p X = \cosh(\sqrt{⟨X,X⟩_{\mathrm{M}}})p + \sinh(\sqrt{⟨X,X⟩_{\mathrm{M}}})\frac{X}{\sqrt{⟨X,X⟩_{\mathrm{M}}}},\]

where $⟨⋅,⋅⟩_{\mathrm{M}}$ denotes the MinkowskiMetric on the embedding, the Lorentzian manifold.

source
Base.logMethod
log(M::Hyperbolic, p, q)

Compute the logarithmic map on the Hyperbolic space $\mathcal H^n$, the tangent vector representing the geodesic starting from p reaches q after time 1. The formula reads for $p ≠ q$

\[\log_p q = d_{\mathcal H^n}(p,q) \frac{q-⟨p,q⟩_{\mathrm{M}} p}{\lVert q-⟨p,q⟩_{\mathrm{M}} p \rVert_2},\]

where $⟨⋅,⋅⟩_{\mathrm{M}}$ denotes the MinkowskiMetric on the embedding, the Lorentzian manifold. For $p=q$ the logarithmic map is equal to the zero vector.

source
Manifolds.manifold_volumeMethod
manifold_dimension(M::Hyperbolic)

Return the volume of the hyperbolic space manifold $\mathcal H^n$, i.e. infinity.

source
ManifoldsBase.check_pointMethod
check_point(M::Hyperbolic, p; kwargs...)

Check whether p is a valid point on the Hyperbolic M.

For the HyperboloidPoint or plain vectors this means that, p is a vector of length $n+1$ with inner product in the embedding of -1, see MinkowskiMetric. The tolerance for the last test can be set using the kwargs....

For the PoincareBallPoint a valid point is a vector $p ∈ ℝ^n$ with a norm strictly less than 1.

For the PoincareHalfSpacePoint a valid point is a vector from $p ∈ ℝ^n$ with a positive last entry, i.e. $p_n>0$

source
ManifoldsBase.check_vectorMethod
check_vector(M::Hyperbolic, p, X; kwargs... )

Check whether X is a tangent vector to p on the Hyperbolic M, i.e. after check_point(M,p), X has to be of the same dimension as p. The tolerance for the last test can be set using the kwargs....

For a the hyperboloid model or vectors, X has to be orthogonal to p with respect to the inner product from the embedding, see MinkowskiMetric.

For a the Poincaré ball as well as the Poincaré half plane model, X has to be a vector from $ℝ^{n}$.

source
ManifoldsBase.parallel_transport_toMethod
parallel_transport_to(M::Hyperbolic, p, X, q)

Compute the parallel transport of the X from the tangent space at p on the Hyperbolic space $\mathcal H^n$ to the tangent at q along the geodesic connecting p and q. The formula reads

\[\mathcal P_{q←p}X = X - \frac{⟨\log_p q,X⟩_p}{d^2_{\mathcal H^n}(p,q)} \bigl(\log_p q + \log_qp \bigr),\]

where $⟨⋅,⋅⟩_p$ denotes the inner product in the tangent space at p.

source
ManifoldsBase.projectMethod
project(M::Hyperbolic, p, X)

Perform an orthogonal projection with respect to the Minkowski inner product of X onto the tangent space at p of the Hyperbolic space M.

The formula reads

\[Y = X + ⟨p,X⟩_{\mathrm{M}} p,\]

where $⟨⋅, ⋅⟩_{\mathrm{M}}$ denotes the MinkowskiMetric on the embedding, the Lorentzian manifold.

Note

Projection is only available for the (default) HyperboloidTVector representation, the others don't have such an embedding

source
ManifoldsBase.riemann_tensorMethod
riemann_tensor(M::Hyperbolic{n}, p, X, Y, Z)

Compute the Riemann tensor $R(X,Y)Z$ at point p on Hyperbolic M. The formula reads (see e.g., [Lee19] Proposition 8.36)

\[R(X,Y)Z = - (\langle Z, Y \rangle X - \langle Z, X \rangle Y)\]

source

hyperboloid model

Base.convertMethod
convert(::Type{HyperboloidPoint}, p::PoincareBallPoint)
convert(::Type{AbstractVector}, p::PoincareBallPoint)

convert a point PoincareBallPoint x (from $ℝ^n$) from the Poincaré ball model of the Hyperbolic manifold $\mathcal H^n$ to a HyperboloidPoint $π(p) ∈ ℝ^{n+1}$. The isometry is defined by

\[π(p) = \frac{1}{1-\lVert p \rVert^2} \begin{pmatrix}2p_1\\⋮\\2p_n\\1+\lVert p \rVert^2\end{pmatrix}\]

Note that this is also used, when the type to convert to is a vector.

source
Base.convertMethod
convert(::Type{HyperboloidPoint}, p::PoincareHalfSpacePoint)
convert(::Type{AbstractVector}, p::PoincareHalfSpacePoint)

convert a point PoincareHalfSpacePoint p (from $ℝ^n$) from the Poincaré half plane model of the Hyperbolic manifold $\mathcal H^n$ to a HyperboloidPoint $π(p) ∈ ℝ^{n+1}$.

This is done in two steps, namely transforming it to a Poincare ball point and from there further on to a Hyperboloid point.

source
Base.convertMethod
convert(::Type{HyperboloidTVector}, p::PoincareBallPoint, X::PoincareBallTVector)
convert(::Type{AbstractVector}, p::PoincareBallPoint, X::PoincareBallTVector)

Convert the PoincareBallTVector X from the tangent space at p to a HyperboloidTVector by computing the push forward of the isometric map, cf. convert(::Type{HyperboloidPoint}, p::PoincareBallPoint).

The push forward $π_*(p)$ maps from $ℝ^n$ to a subspace of $ℝ^{n+1}$, the formula reads

\[π_*(p)[X] = \begin{pmatrix} \frac{2X_1}{1-\lVert p \rVert^2} + \frac{4}{(1-\lVert p \rVert^2)^2}⟨X,p⟩p_1\\ ⋮\\ \frac{2X_n}{1-\lVert p \rVert^2} + \frac{4}{(1-\lVert p \rVert^2)^2}⟨X,p⟩p_n\\ \frac{4}{(1-\lVert p \rVert^2)^2}⟨X,p⟩ \end{pmatrix}.\]

source
Base.convertMethod
convert(::Type{HyperboloidTVector}, p::PoincareHalfSpacePoint, X::PoincareHalfSpaceTVector)
convert(::Type{AbstractVector}, p::PoincareHalfSpacePoint, X::PoincareHalfSpaceTVector)

convert a point PoincareHalfSpaceTVector X (from $ℝ^n$) at p from the Poincaré half plane model of the Hyperbolic manifold $\mathcal H^n$ to a HyperboloidTVector $π(p) ∈ ℝ^{n+1}$.

This is done in two steps, namely transforming it to a Poincare ball point and from there further on to a Hyperboloid point.

source
Base.convertMethod
convert(
    ::Type{Tuple{HyperboloidPoint,HyperboloidTVector}}.
    (p,X)::Tuple{PoincareBallPoint,PoincareBallTVector}
)
convert(
    ::Type{Tuple{P,T}},
    (p, X)::Tuple{PoincareBallPoint,PoincareBallTVector},
) where {P<:AbstractVector, T <: AbstractVector}

Convert a PoincareBallPoint p and a PoincareBallTVector X to a HyperboloidPoint and a HyperboloidTVector simultaneously, see convert(::Type{HyperboloidPoint}, ::PoincareBallPoint) and convert(::Type{HyperboloidTVector}, ::PoincareBallPoint, ::PoincareBallTVector) for the formulae.

source
Base.convertMethod
convert(
    ::Type{Tuple{HyperboloidPoint,HyperboloidTVector},
    (p,X)::Tuple{PoincareHalfSpacePoint, PoincareHalfSpaceTVector}
)
convert(
    ::Type{Tuple{T,T},
    (p,X)::Tuple{PoincareHalfSpacePoint, PoincareHalfSpaceTVector}
) where {T<:AbstractVector}

convert a point PoincareHalfSpaceTVector X (from $ℝ^n$) at p from the Poincaré half plane model of the Hyperbolic manifold $\mathcal H^n$ to a tuple of a HyperboloidPoint and a HyperboloidTVector $π(p) ∈ ℝ^{n+1}$ simultaneously.

This is done in two steps, namely transforming it to the Poincare ball model and from there further on to a Hyperboloid.

source
ManifoldDiff.riemannian_HessianMethod
Y = riemannian_Hessian(M::Hyperbolic, p, G, H, X)
riemannian_Hessian!(M::Hyperbolic, Y, p, G, H, X)

Compute the Riemannian Hessian $\operatorname{Hess} f(p)[X]$ given the Euclidean gradient $∇ f(\tilde p)$ in G and the Euclidean Hessian $∇^2 f(\tilde p)[\tilde X]$ in H, where $\tilde p, \tilde X$ are the representations of $p,X$ in the embedding,.

Let $\mathbf{g} = \mathbf{g}^{-1} = \operatorname{diag}(1,...,1,-1)$. Then using Remark 4.1 [Ngu23] the formula reads

\[\operatorname{Hess}f(p)[X] = \operatorname{proj}_{T_p\mathcal M}\bigl( \mathbf{g}^{-1}\nabla^2f(p)[X] + X⟨p,\mathbf{g}^{-1}∇f(p)⟩_p \bigr).\]

source
Manifolds.volume_densityMethod
volume_density(M::Hyperbolic, p, X)

Compute volume density function of the hyperbolic manifold. The formula reads $(\sinh(\lVert X\rVert)/\lVert X\rVert)^(n-1)$ where n is the dimension of M. It is derived from Eq. (4.1) in[CLLD22].

source
ManifoldsBase.change_representerMethod
change_representer(M::Hyperbolic, ::EuclideanMetric, p, X)

Change the Eucliden representer X of a cotangent vector at point p. We only have to correct for the metric, which means that the sign of the last entry changes, since for the result $Y$ we are looking for a tangent vector such that

\[ g_p(Y,Z) = -y_{n+1}z_{n+1} + \sum_{i=1}^n y_iz_i = \sum_{i=1}^{n+1} z_ix_i\]

holds, which directly yields $y_i=x_i$ for $i=1,\ldots,n$ and $y_{n+1}=-x_{n+1}$.

source
ManifoldsBase.distanceMethod
distance(M::Hyperbolic, p, q)
distance(M::Hyperbolic, p::HyperboloidPoint, q::HyperboloidPoint)

Compute the distance on the Hyperbolic M, which reads

\[d_{\mathcal H^n}(p,q) = \operatorname{acosh}( - ⟨p, q⟩_{\mathrm{M}}),\]

where $⟨⋅,⋅⟩_{\mathrm{M}}$ denotes the MinkowskiMetric on the embedding, the Lorentzian manifold.

source
ManifoldsBase.get_coordinatesMethod
get_coordinates(M::Hyperbolic, p, X, ::DefaultOrthonormalBasis)

Compute the coordinates of the vector X with respect to the orthogonalized version of the unit vectors from $ℝ^n$, where $n$ is the manifold dimension of the Hyperbolic M, utting them intop the tangent space at p and orthonormalizing them.

source
ManifoldsBase.get_vectorMethod
get_vector(M::Hyperbolic, p, c, ::DefaultOrthonormalBasis)

Compute the vector from the coordinates with respect to the orthogonalized version of the unit vectors from $ℝ^n$, where $n$ is the manifold dimension of the Hyperbolic M, utting them intop the tangent space at p and orthonormalizing them.

source
ManifoldsBase.innerMethod
inner(M::Hyperbolic, p, X, Y)
inner(M::Hyperbolic, p::HyperboloidPoint, X::HyperboloidTVector, Y::HyperboloidTVector)

Cmpute the inner product in the Hyperboloid model, i.e. the minkowski_metric in the embedding. The formula reads

\[g_p(X,Y) = ⟨X,Y⟩_{\mathrm{M}} = -X_{n}Y_{n} + \displaystyle\sum_{k=1}^{n-1} X_kY_k.\]

This employs the metric of the embedding, see Lorentz space.

source

Visualization of the Hyperboloid

For the case of Hyperbolic(2) there is plotting available based on a PlottingRecipe. You can easily plot points, connecting geodesics as well as tangent vectors.

Note

The recipes are only loaded if Plots.jl or RecipesBase.jl is loaded.

If we consider a set of points, we can first plot these and their connecting geodesics using the geodesic_interpolation for the points. This variable specifies with how many points a geodesic between two successive points is sampled (per default it's -1, which deactivates geodesics) and the line style is set to be a path.

In general you can plot the surface of the hyperboloid either as wireframe (wireframe=true) additionally specifying wires (or wires_x and wires_y) to change the density of wires and a wireframe_color. The same holds for the plot as a surface (which is false by default) and its surface_resolution (or surface_resolution_x or surface_resolution_y) and a surface_color.

using Manifolds, Plots
M = Hyperbolic(2)
pts =  [ [0.85*cos(φ), 0.85*sin(φ), sqrt(0.85^2+1)] for φ ∈ range(0,2π,length=11) ]
scene = plot(M, pts; geodesic_interpolation=100)
Example block output

To just plot the points atop, we can just omit the geodesic_interpolation parameter to obtain a scatter plot. Note that we avoid redrawing the wireframe in the following plot! calls.

plot!(scene, M, pts; wireframe=false)
Example block output

We can further generate tangent vectors in these spaces and use a plot for there. Keep in mind that a tangent vector in plotting always requires its base point.

pts2 = [ [0.45 .*cos(φ + 6π/11), 0.45 .*sin(φ + 6π/11), sqrt(0.45^2+1) ] for φ ∈ range(0,2π,length=11)]
vecs = log.(Ref(M),pts,pts2)
plot!(scene, M, pts, vecs; wireframe=false)
Example block output

Just to illustrate, for the first point the tangent vector is pointing along the following geodesic

plot!(scene, M, [pts[1], pts2[1]]; geodesic_interpolation=100, wireframe=false)
Example block output

Internal functions

The following functions are available for internal use to construct points in the hyperboloid model

Manifolds._hyperbolizeMethod
_hyperbolize(M, p, Y)

Given the Hyperbolic(n) manifold using the hyperboloid model and a point p thereon, we can put a vector $Y\in ℝ^n$ into the tangent space by computing its last component such that for the resulting p we have that its minkowski_metric is $⟨p,X⟩_{\mathrm{M}} = 0$, i.e. $X_{n+1} = \frac{⟨\tilde p, Y⟩}{p_{n+1}}$, where $\tilde p = (p_1,\ldots,p_n)$.

source
Manifolds._hyperbolizeMethod
_hyperbolize(M, q)

Given the Hyperbolic(n) manifold using the hyperboloid model, a point from the $q\in ℝ^n$ can be set onto the manifold by computing its last component such that for the resulting p we have that its minkowski_metric is $⟨p,p⟩_{\mathrm{M}} = - 1$, i.e. $p_{n+1} = \sqrt{\lVert q \rVert^2 - 1}$

source

Poincaré ball model

Base.convertMethod
convert(::Type{PoincareBallPoint}, p::HyperboloidPoint)
convert(::Type{PoincareBallPoint}, p::T) where {T<:AbstractVector}

convert a HyperboloidPoint $p∈ℝ^{n+1}$ from the hyperboloid model of the Hyperbolic manifold $\mathcal H^n$ to a PoincareBallPoint $π(p)∈ℝ^{n}$ in the Poincaré ball model. The isometry is defined by

\[π(p) = \frac{1}{1+p_{n+1}} \begin{pmatrix}p_1\\⋮\\p_n\end{pmatrix}\]

Note that this is also used, when x is a vector.

source
Base.convertMethod
convert(::Type{PoincareBallPoint}, p::PoincareHalfSpacePoint)

convert a point PoincareHalfSpacePoint p (from $ℝ^n$) from the Poincaré half plane model of the Hyperbolic manifold $\mathcal H^n$ to a PoincareBallPoint $π(p) ∈ ℝ^n$. Denote by $\tilde p = (p_1,\ldots,p_{d-1})^{\mathrm{T}}$. Then the isometry is defined by

\[π(p) = \frac{1}{\lVert \tilde p \rVert^2 + (p_n+1)^2} \begin{pmatrix}2p_1\\⋮\\2p_{n-1}\\\lVert p\rVert^2 - 1\end{pmatrix}.\]

source
Base.convertMethod
convert(::Type{PoincareBallTVector}, p::HyperboloidPoint, X::HyperboloidTVector)
convert(::Type{PoincareBallTVector}, p::P, X::T) where {P<:AbstractVector, T<:AbstractVector}

convert a HyperboloidTVector X at p to a PoincareBallTVector on the Hyperbolic manifold $\mathcal H^n$ by computing the push forward $π_*(p)[X]$ of the isometry $π$ that maps from the Hyperboloid to the Poincaré ball, cf. convert(::Type{PoincareBallPoint}, ::HyperboloidPoint).

The formula reads

\[π_*(p)[X] = \frac{1}{p_{n+1}+1}\Bigl(\tilde X - \frac{X_{n+1}}{p_{n+1}+1}\tilde p \Bigl),\]

where $\tilde X = \begin{pmatrix}X_1\\⋮\\X_n\end{pmatrix}$ and $\tilde p = \begin{pmatrix}p_1\\⋮\\p_n\end{pmatrix}$.

source
Base.convertMethod
convert(
    ::Type{PoincareBallTVector},
    p::PoincareHalfSpacePoint,
    X::PoincareHalfSpaceTVector
)

convert a PoincareHalfSpaceTVector X at p to a PoincareBallTVector on the Hyperbolic manifold $\mathcal H^n$ by computing the push forward $π_*(p)[X]$ of the isometry $π$ that maps from the Poincaré half space to the Poincaré ball, cf. convert(::Type{PoincareBallPoint}, ::PoincareHalfSpacePoint).

The formula reads

\[π_*(p)[X] = \frac{1}{\lVert \tilde p\rVert^2 + (1+p_n)^2} \begin{pmatrix} 2X_1\\ ⋮\\ 2X_{n-1}\\ 2⟨X,p⟩ \end{pmatrix} - \frac{2}{(\lVert \tilde p\rVert^2 + (1+p_n)^2)^2} \begin{pmatrix} 2p_1(⟨X,p⟩+X_n)\\ ⋮\\ 2p_{n-1}(⟨X,p⟩+X_n)\\ (\lVert p \rVert^2-1)(⟨X,p⟩+X_n) \end{pmatrix}\]

where $\tilde p = \begin{pmatrix}p_1\\⋮\\p_{n-1}\end{pmatrix}$.

source
Base.convertMethod
convert(
    ::Type{Tuple{PoincareBallPoint,PoincareBallTVector}},
    (p,X)::Tuple{HyperboloidPoint,HyperboloidTVector}
)
convert(
    ::Type{Tuple{PoincareBallPoint,PoincareBallTVector}},
    (p, X)::Tuple{P,T},
) where {P<:AbstractVector, T <: AbstractVector}

Convert a HyperboloidPoint p and a HyperboloidTVector X to a PoincareBallPoint and a PoincareBallTVector simultaneously, see convert(::Type{PoincareBallPoint}, ::HyperboloidPoint) and convert(::Type{PoincareBallTVector}, ::HyperboloidPoint, ::HyperboloidTVector) for the formulae.

source
Base.convertMethod
convert(
    ::Type{Tuple{PoincareBallPoint,PoincareBallTVector}},
    (p,X)::Tuple{HyperboloidPoint,HyperboloidTVector}
)
convert(
    ::Type{Tuple{PoincareBallPoint,PoincareBallTVector}},
    (p, X)::Tuple{T,T},
) where {T <: AbstractVector}

Convert a PoincareHalfSpacePoint p and a PoincareHalfSpaceTVector X to a PoincareBallPoint and a PoincareBallTVector simultaneously, see convert(::Type{PoincareBallPoint}, ::PoincareHalfSpacePoint) and convert(::Type{PoincareBallTVector}, ::PoincareHalfSpacePoint, ::PoincareHalfSpaceTVector) for the formulae.

source
ManifoldsBase.change_metricMethod
change_metric(M::Hyperbolic, ::EuclideanMetric, p::PoincareBallPoint, X::PoincareBallTVector)

Since in the metric we always have the term $α = \frac{2}{1-\sum_{i=1}^n p_i^2}$ per element, the correction for the metric reads $Z = \frac{1}{α}X$.

source
ManifoldsBase.change_representerMethod
change_representer(M::Hyperbolic, ::EuclideanMetric, p::PoincareBallPoint, X::PoincareBallTVector)

Since in the metric we have the term $α = \frac{2}{1-\sum_{i=1}^n p_i^2}$ per element, the correction for the gradient reads $Y = \frac{1}{α^2}X$.

source
ManifoldsBase.distanceMethod
distance(::Hyperbolic, p::PoincareBallPoint, q::PoincareBallPoint)

Compute the distance on the Hyperbolic manifold $\mathcal H^n$ represented in the Poincaré ball model. The formula reads

\[d_{\mathcal H^n}(p,q) = \operatorname{acosh}\Bigl( 1 + \frac{2\lVert p - q \rVert^2}{(1-\lVert p\rVert^2)(1-\lVert q\rVert^2)} \Bigr)\]

source
ManifoldsBase.innerMethod
inner(::Hyperbolic, p::PoincareBallPoint, X::PoincareBallTVector, Y::PoincareBallTVector)

Compute the inner product in the Poincaré ball model. The formula reads

\[g_p(X,Y) = \frac{4}{(1-\lVert p \rVert^2)^2} ⟨X, Y⟩ .\]

source
ManifoldsBase.projectMethod
project(::Hyperbolic, ::PoincareBallPoint, ::PoincareBallTVector)

projection of tangent vectors in the Poincaré ball model is just the identity, since the tangent space consists of all $ℝ^n$.

source

Visualization of the Poincaré ball

For the case of Hyperbolic(2) there is a plotting available based on a PlottingRecipe you can easily plot points, connecting geodesics as well as tangent vectors.

Note

The recipes are only loaded if Plots.jl or RecipesBase.jl is loaded.

If we consider a set of points, we can first plot these and their connecting geodesics using the geodesic_interpolation For the points. This variable specifies with how many points a geodesic between two successive points is sampled (per default it's -1, which deactivates geodesics) and the line style is set to be a path. Another keyword argument added is the border of the Poincaré disc, namely circle_points = 720 resolution of the drawn boundary (every hlaf angle) as well as its color, hyperbolic_border_color = RGBA(0.0, 0.0, 0.0, 1.0).

using Manifolds, Plots
M = Hyperbolic(2)
pts = PoincareBallPoint.( [0.85 .* [cos(φ), sin(φ)] for φ ∈ range(0,2π,length=11)])
scene = plot(M, pts, geodesic_interpolation = 100)
Example block output

To just plot the points atop, we can just omit the geodesic_interpolation parameter to obtain a scatter plot

plot!(scene, M, pts)
Example block output

We can further generate tangent vectors in these spaces and use a plot for there. Keep in mind, that a tangent vector in plotting always requires its base point

pts2 = PoincareBallPoint.( [0.45 .* [cos(φ + 6π/11), sin(φ + 6π/11)] for φ ∈ range(0,2π,length=11)])
vecs = log.(Ref(M),pts,pts2)
plot!(scene, M, pts,vecs)
Example block output

Just to illustrate, for the first point the tangent vector is pointing along the following geodesic

plot!(scene, M, [pts[1], pts2[1]], geodesic_interpolation=100)
Example block output

Poincaré half space model

Base.convertMethod
convert(::Type{PoincareHalfSpacePoint}, p::Hyperboloid)
convert(::Type{PoincareHalfSpacePoint}, p)

convert a HyperboloidPoint or Vectorp (from $ℝ^{n+1}$) from the Hyperboloid model of the Hyperbolic manifold $\mathcal H^n$ to a PoincareHalfSpacePoint $π(x) ∈ ℝ^{n}$.

This is done in two steps, namely transforming it to a Poincare ball point and from there further on to a PoincareHalfSpacePoint point.

source
Base.convertMethod
convert(::Type{PoincareHalfSpacePoint}, p::PoincareBallPoint)

convert a point PoincareBallPoint p (from $ℝ^n$) from the Poincaré ball model of the Hyperbolic manifold $\mathcal H^n$ to a PoincareHalfSpacePoint $π(p) ∈ ℝ^n$. Denote by $\tilde p = (p_1,\ldots,p_{n-1})$. Then the isometry is defined by

\[π(p) = \frac{1}{\lVert \tilde p \rVert^2 - (p_n-1)^2} \begin{pmatrix}2p_1\\⋮\\2p_{n-1}\\1-\lVert p\rVert^2\end{pmatrix}.\]

source
Base.convertMethod
convert(::Type{PoincareHalfSpaceTVector}, p::HyperboloidPoint, ::HyperboloidTVector)
convert(::Type{PoincareHalfSpaceTVector}, p::P, X::T) where {P<:AbstractVector, T<:AbstractVector}

convert a HyperboloidTVector X at p to a PoincareHalfSpaceTVector on the Hyperbolic manifold $\mathcal H^n$ by computing the push forward $π_*(p)[X]$ of the isometry $π$ that maps from the Hyperboloid to the Poincaré half space, cf. convert(::Type{PoincareHalfSpacePoint}, ::HyperboloidPoint).

This is done similarly to the approach there, i.e. by using the Poincaré ball model as an intermediate step.

source
Base.convertMethod
convert(::Type{PoincareHalfSpaceTVector}, p::PoincareBallPoint, X::PoincareBallTVector)

convert a PoincareBallTVector X at p to a PoincareHalfSpacePoint on the Hyperbolic manifold $\mathcal H^n$ by computing the push forward $π_*(p)[X]$ of the isometry $π$ that maps from the Poincaré ball to the Poincaré half space, cf. convert(::Type{PoincareHalfSpacePoint}, ::PoincareBallPoint).

The formula reads

\[π_*(p)[X] = \frac{1}{\lVert \tilde p\rVert^2 + (1-p_n)^2} \begin{pmatrix} 2X_1\\ ⋮\\ 2X_{n-1}\\ -2⟨X,p⟩ \end{pmatrix} - \frac{2}{(\lVert \tilde p\rVert^2 + (1-p_n)^2)^2} \begin{pmatrix} 2p_1(⟨X,p⟩-X_n)\\ ⋮\\ 2p_{n-1}(⟨X,p⟩-X_n)\\ (\lVert p \rVert^2-1)(⟨X,p⟩-X_n) \end{pmatrix}\]

where $\tilde p = \begin{pmatrix}p_1\\⋮\\p_{n-1}\end{pmatrix}$.

source
Base.convertMethod
convert(
    ::Type{Tuple{PoincareHalfSpacePoint,PoincareHalfSpaceTVector}},
    (p,X)::Tuple{HyperboloidPoint,HyperboloidTVector}
)
convert(
    ::Type{Tuple{PoincareHalfSpacePoint,PoincareHalfSpaceTVector}},
    (p, X)::Tuple{P,T},
) where {P<:AbstractVector, T <: AbstractVector}

Convert a HyperboloidPoint p and a HyperboloidTVector X to a PoincareHalfSpacePoint and a PoincareHalfSpaceTVector simultaneously, see convert(::Type{PoincareHalfSpacePoint}, ::HyperboloidPoint) and convert(::Type{PoincareHalfSpaceTVector}, ::Tuple{HyperboloidPoint,HyperboloidTVector}) for the formulae.

source
ManifoldsBase.distanceMethod
distance(::Hyperbolic, p::PoincareHalfSpacePoint, q::PoincareHalfSpacePoint)

Compute the distance on the Hyperbolic manifold $\mathcal H^n$ represented in the Poincaré half space model. The formula reads

\[d_{\mathcal H^n}(p,q) = \operatorname{acosh}\Bigl( 1 + \frac{\lVert p - q \rVert^2}{2 p_n q_n} \Bigr)\]

source
ManifoldsBase.innerMethod
inner(
    ::Hyperbolic,
    p::PoincareHalfSpacePoint,
    X::PoincareHalfSpaceTVector,
    Y::PoincareHalfSpaceTVector
)

Compute the inner product in the Poincaré half space model. The formula reads

\[g_p(X,Y) = \frac{⟨X,Y⟩}{p_n^2}.\]

source
ManifoldsBase.projectMethod
project(::Hyperbolic, ::PoincareHalfSpacePoint ::PoincareHalfSpaceTVector)

projection of tangent vectors in the Poincaré half space model is just the identity, since the tangent space consists of all $ℝ^n$.

source

Visualization on the Poincaré half plane

For the case of Hyperbolic(2) there is a plotting available based on a PlottingRecipe you can easily plot points, connecting geodesics as well as tangent vectors.

Note

The recipes are only loaded if Plots.jl or RecipesBase.jl is loaded.

We again have two different recipes, one for points, one for tangent vectors, where the first one again can be equipped with geodesics between the points. In the following example we generate 7 points on an ellipse in the Hyperboloid model.

using Manifolds, Plots
M = Hyperbolic(2)
pre_pts = [2.0 .* [5.0*cos(φ), sin(φ)] for φ ∈ range(0,2π,length=7)]
pts = convert.(
    Ref(PoincareHalfSpacePoint),
    Manifolds._hyperbolize.(Ref(M), pre_pts)
)
scene = plot(M, pts, geodesic_interpolation = 100)
Example block output

To just plot the points atop, we can just omit the geodesic_interpolation parameter to obtain a scatter plot

plot!(scene, M, pts)
Example block output

We can further generate tangent vectors in these spaces and use a plot for there. Keep in mind, that a tangent vector in plotting always requires its base point. Here we would like to look at the tangent vectors pointing to the origin

origin = PoincareHalfSpacePoint([0.0,1.0])
vecs = [log(M,p,origin) for p ∈ pts]
scene = plot!(scene, M, pts, vecs)
Example block output

And we can again look at the corresponding geodesics, for example

plot!(scene, M, [pts[1], origin], geodesic_interpolation=100)
plot!(scene, M, [pts[2], origin], geodesic_interpolation=100)
Example block output

Literature

[CLLD22]
E. Chevallier, D. Li, Y. Lu and D. B. Dunson. Exponential-wrapped distributions on symmetric spaces. ArXiv Preprint (2022).
[Lee19]
J. M. Lee. Introduction to Riemannian Manifolds (Springer Cham, 2019).
[Ngu23]
D. Nguyen. Operator-Valued Formulas for Riemannian Gradient and Hessian and Families of Tractable Metrics in Riemannian Optimization. Journal of Optimization Theory and Applications 198, 135–164 (2023), arXiv:2009.10159.