Poincare Ball model

Poincare ball model is a compact representation of hyperbolic space. To have a nice introduction into this model we should start from simple concepts, putting them all together to build a more complete picture.

Hyperbolic spaces

Hyperbolic space is a constant negative curvature Riemannian manifold. A very simple example of Riemannian manifold with constant, but positive curvature is sphere.

An (N+1)-dimensional hyperboloid spans the manifold that can be embedded into N-dimensional space via projections.

Originally, the distance between points on the hyperboloid is defined as

\[d(x, y) = \operatorname{arccosh}(x, y)\]

It is difficult to work in (N+1)-dimensional space and there is a range of useful embeddings exist in literature

Klein Model

Poincare Model

Here we go.

First of all we note, that Poincare ball is embedded in a Sphere of radius \(r=1/\sqrt{c}\), where c is negative curvature. We also note, as \(c\) goes to \(0\), we recover infinite radius ball. We should expect this limiting behaviour recovers Euclidean geometry.

To connect Euclidean space with its embedded manifold we need to get \(g_x\). It is done via conformal factor \(\lambda^c_x\).

geoopt.manifolds.poincare.math.lambda_x(x, *, c=1.0, keepdim=False, dim=-1)[source]

Compute the conformal factor \(\lambda^c_x\) for a point on the ball.

\[\lambda^c_x = \frac{1}{1 - c \|x\|_2^2}\]
Parameters:
  • x (tensor) – point on the Poincare ball
  • c (float|tensor) – ball negative curvature
  • keepdim (bool) – retain the last dim? (default: false)
  • dim (int) – reduction dimension
Returns:

conformal factor

Return type:

tensor

\(\lambda^c_x\) connects Euclidean inner product with Riemannian one

geoopt.manifolds.poincare.math.inner(x, u, v, *, c=1.0, keepdim=False, dim=-1)[source]

Compute inner product for two vectors on the tangent space w.r.t Riemannian metric on the Poincare ball.

\[\langle u, v\rangle_x = (\lambda^c_x)^2 \langle u, v \rangle\]
Parameters:
  • x (tensor) – point on the Poincare ball
  • u (tensor) – tangent vector to \(x\) on Poincare ball
  • v (tensor) – tangent vector to \(x\) on Poincare ball
  • c (float|tensor) – ball negative curvature
  • keepdim (bool) – retain the last dim? (default: false)
  • dim (int) – reduction dimension
Returns:

inner product

Return type:

tensor

geoopt.manifolds.poincare.math.norm(x, u, *, c=1.0, keepdim=False, dim=-1)[source]

Compute vector norm on the tangent space w.r.t Riemannian metric on the Poincare ball.

\[\|u\|_x = \lambda^c_x \|u\|_2\]
Parameters:
  • x (tensor) – point on the Poincare ball
  • u (tensor) – tangent vector to \(x\) on Poincare ball
  • c (float|tensor) – ball negative curvature
  • keepdim (bool) – retain the last dim? (default: false)
  • dim (int) – reduction dimension
Returns:

norm of vector

Return type:

tensor

geoopt.manifolds.poincare.math.egrad2rgrad(x, grad, *, c=1.0, dim=-1)[source]

Translate Euclidean gradient to Riemannian gradient on tangent space of \(x\).

\[\nabla_x = \nabla^E_x / (\lambda_x^c)^2\]
Parameters:
  • x (tensor) – point on the Poincare ball
  • grad (tensor) – Euclidean gradient for \(x\)
  • c (float|tensor) – ball negative curvature
  • dim (int) – reduction dimension for operations
Returns:

Riemannian gradient \(u\in T_x\mathbb{D}_c^n\)

Return type:

tensor

Math

The good thing about Poincare ball is that it forms a Gyrogroup. Minimal definition of a Gyrogroup assumes a binary operation \(*\) defined that satisfies a set of properties.

Left identity
For every element \(a\in G\) there exist \(e\in G\) such that \(e * a = a\).
Left Inverse
For every element \(a\in G\) there exist \(b\in G\) such that \(b * a = e\)
Gyroassociativity
For any \(a,b,c\in G\) there exist \(gyr[a, b]c\in G\) such that \(a * (b * c)=(a * b) * gyr[a, b]c\)
Gyroautomorphism
\(gyr[a, b]\) is a magma automorphism in G
Left loop
\(gyr[a, b] = gyr[a * b, b]\)

As mentioned above, hyperbolic space forms a Gyrogroup equipped with

geoopt.manifolds.poincare.math.mobius_add(x, y, *, c=1.0, dim=-1)[source]

Compute Mobius addition is a special operation in a hyperbolic space.

\[x \oplus_c y = \frac{ (1 + 2 c \langle x, y\rangle + c \|y\|^2_2) x + (1 - c \|x\|_2^2) y }{ 1 + 2 c \langle x, y\rangle + c^2 \|x\|^2_2 \|y\|^2_2 }\]

(Source code, png, hires.png, pdf)

../_images/mobius_add.png

In general this operation is not commutative:

\[x \oplus_c y \ne y \oplus_c x\]

But in some cases this property holds:

  • zero vector case
\[\mathbf{0} \oplus_c x = x \oplus_c \mathbf{0}\]
  • zero negative curvature case that is same as Euclidean addition
\[x \oplus_0 y = y \oplus_0 x\]

Another useful property is so called left-cancellation law:

\[(-x) \oplus_c (x \oplus_c y) = y\]
Parameters:
  • x (tensor) – point on the Poincare ball
  • y (tensor) – point on the Poincare ball
  • c (float|tensor) – ball negative curvature
  • dim (int) – reduction dimension for operations
Returns:

the result of mobius addition

Return type:

tensor

geoopt.manifolds.poincare.math.gyration(a, b, u, *, c=1.0, dim=-1)[source]

Apply gyration \(\operatorname{gyr}[u, v]w\).

Guration is a special operation in hyperbolic geometry. Addition operation \(\oplus_c\) is not associative (as mentioned in mobius_add()), but gyroassociative which means

\[u \oplus_c (v \oplus_c w) = (u\oplus_c v) \oplus_c \operatorname{gyr}[u, v]w,\]

where

\[\operatorname{gyr}[u, v]w = \ominus (u \oplus_c v) \oplus (u \oplus_c (v \oplus_c w))\]

We can simplify this equation using explicit formula for Mobius addition [1]. Recall

\[ \begin{align}\begin{aligned}\begin{split}A = - c^2 \langle u, w\rangle \langle v, v\rangle + c \langle v, w\rangle + 2 c^2 \langle u, v\rangle \langle v, w\rangle\\ B = - c^2 \langle v, w\rangle \langle u, u\rangle - c \langle u, w\rangle\\ D = 1 + 2 c \langle u, v\rangle + c^2 \langle u, u\rangle \langle v, v\rangle\\\end{split}\\\operatorname{gyr}[u, v]w = w + 2 \frac{A u + B v}{D}\end{aligned}\end{align} \]
Parameters:
  • a (tensor) – first point on Poincare ball
  • b (tensor) – second point on Poincare ball
  • u (tensor) – vector field for operation
  • c (float|tensor) – ball negative curvature
  • dim (int) – reduction dimension for operations
Returns:

the result of automorphism

Return type:

tensor

References

[1] A. A. Ungar (2009), A Gyrovector Space Approach to Hyperbolic Geometry

Using this math, it is possible to define another useful operations

geoopt.manifolds.poincare.math.mobius_sub(x, y, *, c=1.0, dim=-1)[source]

Compute Mobius substraction.

Mobius substraction can be represented via Mobius addition as follows:

\[x \ominus_c y = x \oplus_c (-y)\]
Parameters:
  • x (tensor) – point on Poincare ball
  • y (tensor) – point on Poincare ball
  • c (float|tensor) – ball negative curvature
  • dim (int) – reduction dimension for operations
Returns:

the result of mobius substraction

Return type:

tensor

geoopt.manifolds.poincare.math.mobius_scalar_mul(r, x, *, c=1.0, dim=-1)[source]

Compute left scalar multiplication on the Poincare ball.

\[r \otimes_c x = (1/\sqrt{c}) \tanh(r\tanh^{-1}(\sqrt{c}\|x\|_2))\frac{x}{\|x\|_2}\]

This operation has properties similar to Euclidean

  • n-addition property
\[r \otimes_c x = x \oplus_c \dots \oplus_c x\]
  • Distributive property
\[(r_1 + r_2) \otimes_c x = r_1 \otimes_c x \oplus r_2 \otimes_c x\]
  • Scalar associativity
\[(r_1 r_2) \otimes_c x = r_1 \otimes_c (r_2 \otimes_c x)\]
  • Scaling property
\[|r| \otimes_c x / \|r \otimes_c x\|_2 = x/\|x\|_2\]
Parameters:
  • r (float|tensor) – scalar for multiplication
  • x (tensor) – point on Poincare ball
  • c (float|tensor) – ball negative curvature
  • dim (int) – reduction dimension for operations
Returns:

the result of mobius scalar multiplication

Return type:

tensor

geoopt.manifolds.poincare.math.mobius_pointwise_mul(w, x, *, c=1.0, dim=-1)[source]

Compute a generalization for point-wise multiplication to hyperbolic space.

Mobius pointwise multiplication is defined as follows

\[\operatorname{diag}(w) \otimes_c x = (1/\sqrt{c}) \tanh\left( \frac{\|\operatorname{diag}(w)x\|_2}{x}\tanh^{-1}(\sqrt{c}\|x\|_2) \right)\frac{\|\operatorname{diag}(w)x\|_2}{\|x\|_2}\]
Parameters:
  • w (tensor) – weights for multiplication (should be broadcastable to x)
  • x (tensor) – point on Poincare ball
  • c (float|tensor) – negative ball curvature
  • dim (int) – reduction dimension for operations
Returns:

Mobius point-wise mul result

Return type:

tensor

geoopt.manifolds.poincare.math.mobius_matvec(m, x, *, c=1.0, dim=-1)[source]

Compute a generalization for matrix-vector multiplication to hyperbolic space.

Mobius matrix vector operation is defined as follows:

\[M \otimes_c x = (1/\sqrt{c}) \tanh\left( \frac{\|Mx\|_2}{\|x\|_2}\tanh^{-1}(\sqrt{c}\|x\|_2) \right)\frac{Mx}{\|Mx\|_2}\]

(Source code, png, hires.png, pdf)

../_images/mobius_matvec.png
Parameters:
  • m (tensor) – matrix for multiplication. Batched matmul is performed if m.dim() > 2, but only last dim reduction is supported
  • x (tensor) – point on Poincare ball
  • c (float|tensor) – negative ball curvature
  • dim (int) – reduction dimension for operations
Returns:

Mobius matvec result

Return type:

tensor

geoopt.manifolds.poincare.math.mobius_fn_apply(fn, x, *args, c=1.0, dim=-1, **kwargs)[source]

Compute a generalization for function application in hyperbolic space.

First, hyperbolic vector is mapped to a Euclidean space via \(\operatorname{Log}^c_0\) and nonlinear function is applied in this tangent space. The resulting vector is then mapped back with \(\operatorname{Exp}^c_0\)

\[f^{\otimes_c}(x) = \operatorname{Exp}^c_0(f(\operatorname{Log}^c_0(y)))\]

(Source code, png, hires.png, pdf)

../_images/mobius_sigmoid_apply.png
Parameters:
  • x (tensor) – point on Poincare ball
  • fn (callable) – function to apply
  • c (float|tensor) – ball negative curvature
  • dim (int) – reduction dimension for operations
Returns:

Result of function in hyperbolic space

Return type:

tensor

geoopt.manifolds.poincare.math.mobius_fn_apply_chain(x, *fns, c=1.0, dim=-1)[source]

Compute a generalization for sequential function application in hyperbolic space.

First, hyperbolic vector is mapped to a Euclidean space via \(\operatorname{Log}^c_0\) and nonlinear function is applied in this tangent space. The resulting vector is then mapped back with \(\operatorname{Exp}^c_0\)

\[f^{\otimes_c}(x) = \operatorname{Exp}^c_0(f(\operatorname{Log}^c_0(y)))\]

The definition of mobius function application allows chaining as

\[y = \operatorname{Exp}^c_0(\operatorname{Log}^c_0(y))\]

Resulting in

\[(f \circ g)^{\otimes_c}(x) = \operatorname{Exp}^c_0((f \circ g) (\operatorname{Log}^c_0(y)))\]
Parameters:
  • x (tensor) – point on Poincare ball
  • fns (callable[]) – functions to apply
  • c (float|tensor) – ball negative curvature
  • dim (int) – reduction dimension for operations
Returns:

Apply chain result

Return type:

tensor

Manifold

Now we are ready to proceed with studying distances, geodesics, exponential maps and more

geoopt.manifolds.poincare.math.dist(x, y, *, c=1.0, keepdim=False, dim=-1)[source]

Compute geodesic distance on the Poincare ball.

\[d_c(x, y) = \frac{2}{\sqrt{c}}\tanh^{-1}(\sqrt{c}\|(-x)\oplus_c y\|_2)\]

(Source code, png, hires.png, pdf)

../_images/distance.png
Parameters:
  • x (tensor) – point on Poincare ball
  • y (tensor) – point on Poincare ball
  • c (float|tensor) – ball negative curvature
  • keepdim (bool) – retain the last dim? (default: false)
  • dim (int) – reduction dimension
Returns:

geodesic distance between \(x\) and \(y\)

Return type:

tensor

geoopt.manifolds.poincare.math.dist2plane(x, p, a, *, c=1.0, keepdim=False, signed=False, dim=-1)[source]

Compute geodesic distance from \(x\) to a hyperbolic hyperplane in Poincare ball.

The distance is computed to a plane that is orthogonal to \(a\) and contains \(p\).

(Source code, png, hires.png, pdf)

../_images/distance2plane.png

To form an intuition what is a hyperbolic hyperplane, let’s first consider Euclidean hyperplane

\[H_{a, b} = \left\{ x \in \mathbb{R}^n\;:\;\langle x, a\rangle - b = 0 \right\},\]

where \(a\in \mathbb{R}^n\backslash \{\mathbf{0}\}\) and \(b\in \mathbb{R}^n\).

This formulation of a hyperplane is hard to generalize, therefore we can rewrite \(\langle x, a\rangle - b\) utilizing orthogonal completion. Setting any \(p\) s.t. \(b=\langle a, p\rangle\) we have

\[\begin{split}H_{a, b} = \left\{ x \in \mathbb{R}^n\;:\;\langle x, a\rangle - b = 0 \right\}\\ =H_{a, \langle a, p\rangle} = \tilde{H}_{a, p}\\ = \left\{ x \in \mathbb{R}^n\;:\;\langle x, a\rangle - \langle a, p\rangle = 0 \right\}\\ =\left\{ x \in \mathbb{R}^n\;:\;\langle -p + x, a\rangle = 0 \right\}\\ = p + \{a\}^\perp\end{split}\]

Naturally we have a set \(\{a\}^\perp\) with applied \(+\) operator to each element. Generalizing a notion of summation to the hyperbolic space we replace \(+\) with \(\oplus_c\).

Next, we should figure out what is \(\{a\}^\perp\) in the Poincare ball.

First thing that we should acknowledge is that notion of orthogonality is defined for vectors in tangent spaces. Let’s consider now \(p\in \mathbb{D}_c^n\) and \(a\in T_p\mathbb{D}_c^n\backslash \{\mathbf{0}\}\).

Slightly deviating from traditional notation let’s write \(\{a\}_p^\perp\) highlighting the tight relationship of \(a\in T_p\mathbb{D}_c^n\backslash \{\mathbf{0}\}\) with \(p \in \mathbb{D}_c^n\). We then define

\[\{a\}_p^\perp := \left\{ z\in T_p\mathbb{D}_c^n \;:\; \langle z, a\rangle_p = 0 \right\}\]

Recalling that a tangent vector \(z\) for point \(p\) yields \(x = \operatorname{Exp}^c_p(z)\) we rewrite the above equation as

\[\{a\}_p^\perp := \left\{ x\in \mathbb{D}_c^n \;:\; \langle \operatorname{Log}_p^c(x), a\rangle_p = 0 \right\}\]

This formulation is something more pleasant to work with. Putting all together

\[\begin{split}\tilde{H}_{a, p}^c = p + \{a\}^\perp_p\\ = \left\{ x \in \mathbb{D}_c^n\;:\;\langle\operatorname{Log}^c_p(x), a\rangle_p = 0 \right\} \\ = \left\{ x \in \mathbb{D}_c^n\;:\;\langle -p \oplus_c x, a\rangle = 0 \right\}\end{split}\]

To compute the distance \(d_c(x, \tilde{H}_{a, p}^c)\) we find

\[\begin{split}d_c(x, \tilde{H}_{a, p}^c) = \inf_{w\in \tilde{H}_{a, p}^c} d_c(x, w)\\ = \frac{1}{\sqrt{c}} \sinh^{-1}\left\{ \frac{ 2\sqrt{c} |\langle(-p)\oplus_c x, a\rangle| }{ (1-c\|(-p)\oplus_c x\|^2_2)\|a\|_2 } \right\}\end{split}\]
Parameters:
  • x (tensor) – point on Poincare ball
  • a (tensor) – vector on tangent space of \(p\)
  • p (tensor) – point on Poincare ball lying on the hyperplane
  • c (float|tensor) – ball negative curvature
  • keepdim (bool) – retain the last dim? (default: false)
  • signed (bool) – return signed distance
  • dim (int) – reduction dimension for operations
Returns:

distance to the hyperplane

Return type:

tensor

geoopt.manifolds.poincare.math.parallel_transport(x, y, v, *, c=1.0, dim=-1)[source]

Perform parallel transport on the Poincare ball.

Parallel transport is essential for adaptive algorithms in Riemannian manifolds. For Hyperbolic spaces parallel transport is expressed via gyration.

(Source code, png, hires.png, pdf)

../_images/gyrovector_parallel_transport.png

To recover parallel transport we first need to study isomorphism between gyrovectors and vectors. The reason is that originally, parallel transport is well defined for gyrovectors as

\[P_{x\to y}(z) = \operatorname{gyr}[y, -x]z,\]

where \(x,\:y,\:z \in \mathbb{D}_c^n\) and \(\operatorname{gyr}[a, b]c = \ominus (a \oplus_c b) \oplus_c (a \oplus_c (b \oplus_c c))\)

But we want to obtain parallel transport for vectors, not for gyrovectors. The blessing is isomorphism mentioned above. This mapping is given by

\[U^c_p \: : \: T_p\mathbb{D}_c^n \to \mathbb{G} = v \mapsto \lambda^c_p v\]

Finally, having points \(x,\:y \in \mathbb{D}_c^n\) and a tangent vector \(u\in T_x\mathbb{D}_c^n\) we obtain

\[\begin{split}P^c_{x\to y}(v) = (U^c_y)^{-1}\left(\operatorname{gyr}[y, -x] U^c_x(v)\right)\\ = \operatorname{gyr}[y, -x] v \lambda^c_x / \lambda^c_y\end{split}\]

(Source code, png, hires.png, pdf)

../_images/parallel_transport.png
Parameters:
  • x (tensor) – starting point
  • y (tensor) – end point
  • v (tensor) – tangent vector to be transported
  • c (float|tensor) – ball negative curvature
  • dim (int) – reduction dimension for operations
Returns:

transported vector

Return type:

tensor

geoopt.manifolds.poincare.math.geodesic(t, x, y, *, c=1.0, dim=-1)[source]

Compute geodesic at the time point \(t\).

Geodesic (the shortest) path connecting \(x\) and \(y\). The path can be treated as and extension of a line segment between points but in a Riemannian manifold. In Poincare ball model, the path is expressed using Mobius addition and scalar multiplication:

\[\gamma_{x\to y}(t) = x \oplus_c r \otimes_c ((-x) \oplus_c y)\]

The required properties of this path are the following:

\[\begin{split}\gamma_{x\to y}(0) = x\\ \gamma_{x\to y}(1) = y\\ \dot\gamma_{x\to y}(t) = v\end{split}\]

Moreover, as geodesic path is not only the shortest path connecting points and Poincare ball. This definition also requires local distance minimization and thus another property appears:

\[d_c(\gamma_{x\to y}(t_1), \gamma_{x\to y}(t_2)) = v|t_1-t_2|\]

“Natural parametrization” of the curve ensures unit speed geodesics which yields the above formula with \(v=1\). However, for Poincare ball we can always compute the constant speed \(v\) from the points that particular path connects:

\[v = d_c(\gamma_{x\to y}(0), \gamma_{x\to y}(1)) = d_c(x, y)\]
Parameters:
  • t (float|tensor) – travelling time
  • x (tensor) – starting point on Poincare ball
  • y (tensor) – target point on Poincare ball
  • c (float|tensor) – ball negative curvature
  • dim (int) – reduction dimension for operations
Returns:

point on the Poincare ball

Return type:

tensor

geoopt.manifolds.poincare.math.geodesic_unit(t, x, u, *, c=1.0, dim=-1)[source]

Compute unit speed geodesic at time \(t\) starting from \(x\) with direction \(u/\|u\|_x\).

\[\gamma_{x,u}(t) = x\oplus_c \tanh(t\sqrt{c}/2) \frac{u}{\sqrt{c}\|u\|_2}\]
Parameters:
  • t (tensor) – travelling time
  • x (tensor) – initial point
  • u (tensor) – direction
  • c (float|tensor) – ball negative curvature
  • dim (int) – reduction dimension for operations
Returns:

the point on geodesic line

Return type:

tensor

geoopt.manifolds.poincare.math.expmap(x, u, *, c=1.0, dim=-1)[source]

Compute exponential map on the Poincare ball.

Exponential map for Poincare ball model. This is tightly related with geodesic(). Intuitively Exponential map is a smooth constant travelling from starting point \(x\) with speed \(u\).

A bit more formally this is travelling along curve \(\gamma_{x, u}(t)\) such that

\[\begin{split}\gamma_{x, u}(0) = x\\ \dot\gamma_{x, u}(0) = u\\ \|\dot\gamma_{x, u}(t)\|_{\gamma_{x, u}(t)} = \|u\|_x\end{split}\]

The existence of this curve relies on uniqueness of differential equation solution, that is local. For the Poincare ball model the solution is well defined globally and we have.

\[\begin{split}\operatorname{Exp}^c_x(u) = \gamma_{x, u}(1) = \\ x\oplus_c \tanh(\sqrt{c}/2 \|u\|_x) \frac{u}{\sqrt{c}\|u\|_2}\end{split}\]
Parameters:
  • x (tensor) – starting point on Poincare ball
  • u (tensor) – speed vector on Poincare ball
  • c (float|tensor) – ball negative curvature
  • dim (int) – reduction dimension for operations
Returns:

\(\gamma_{x, u}(1)\) end point

Return type:

tensor

geoopt.manifolds.poincare.math.expmap0(u, *, c=1.0, dim=-1)[source]

Compute exponential map for Poincare ball model from \(0\).

\[\operatorname{Exp}^c_0(u) = \tanh(\sqrt{c}/2 \|u\|_2) \frac{u}{\sqrt{c}\|u\|_2}\]
Parameters:
  • u (tensor) – speed vector on Poincare ball
  • c (float|tensor) – ball negative curvature
  • dim (int) – reduction dimension for operations
Returns:

\(\gamma_{0, u}(1)\) end point

Return type:

tensor

geoopt.manifolds.poincare.math.logmap(x, y, *, c=1.0, dim=-1)[source]

Compute logarithmic map for two points \(x\) and \(y\) on the manifold.

\[\operatorname{Log}^c_x(y) = \frac{2}{\sqrt{c}\lambda_x^c} \tanh^{-1}( \sqrt{c} \|(-x)\oplus_c y\|_2 ) * \frac{(-x)\oplus_c y}{\|(-x)\oplus_c y\|_2}\]

The result of Logarithmic map is a vector such that

\[y = \operatorname{Exp}^c_x(\operatorname{Log}^c_x(y))\]
Parameters:
  • x (tensor) – starting point on Poincare ball
  • y (tensor) – target point on Poincare ball
  • c (float|tensor) – ball negative curvature
  • dim (int) – reduction dimension for operations
Returns:

tangent vector that transports \(x\) to \(y\)

Return type:

tensor

geoopt.manifolds.poincare.math.logmap0(y, *, c=1.0, dim=-1)[source]

Compute logarithmic map for \(y\) from \(0\) on the manifold.

\[\operatorname{Log}^c_0(y) = \tanh^{-1}(\sqrt{c}\|y\|_2) \frac{y}{\|y\|_2}\]

The result is such that

\[y = \operatorname{Exp}^c_0(\operatorname{Log}^c_0(y))\]
Parameters:
  • y (tensor) – target point on Poincare ball
  • c (float|tensor) – ball negative curvature
  • dim (int) – reduction dimension for operations
Returns:

tangent vector that transports \(0\) to \(y\)

Return type:

tensor

Stability

Numerical stability is a pain in this model. It is strongly recommended to work in float64, so expect adventures in float32 (but this is not certain).

geoopt.manifolds.poincare.math.project(x, *, c=1.0, dim=-1, eps=None)[source]

Safe projection on the manifold for numerical stability.

Parameters:
  • x (tensor) – point on the Poincare ball
  • c (float|tensor) – ball negative curvature
  • dim (int) – reduction dimension to compute norm
  • eps (float) – stability parameter, uses default for dtype if not provided
Returns:

projected vector on the manifold

Return type:

tensor