pub struct HyperbolicPoint { /* private fields */ }Expand description
A point in the Poincaré disk model of hyperbolic space.
The Poincaré disk model represents hyperbolic space within a unit disk, where geodesics are represented by arcs of circles orthogonal to the boundary, and hyperbolic distance is distorted in a way that makes the model ideal for representing hierarchical tree structures.
Implementations§
Source§impl HyperbolicPoint
impl HyperbolicPoint
Sourcepub fn new(coords: FixedVector) -> Self
pub fn new(coords: FixedVector) -> Self
Create a new point in the Poincaré disk with the given coordinates.
Coordinates are automatically projected into the disk if they’re outside.
Sourcepub fn from_f32_slice(values: &[f32]) -> Self
pub fn from_f32_slice(values: &[f32]) -> Self
Create a new point from a slice of f32 values (user-facing boundary API).
Sourcepub fn from_slice(values: &[FixedPoint]) -> Self
pub fn from_slice(values: &[FixedPoint]) -> Self
Create a point from exact fixed-point coordinates — the lossless entry point, and the one the public API uses.
Sourcepub fn coords(&self) -> &FixedVector
pub fn coords(&self) -> &FixedVector
Get a reference to the underlying coordinates.
Sourcepub fn coords_mut(&mut self) -> &mut FixedVector
pub fn coords_mut(&mut self) -> &mut FixedVector
Get a mutable reference to the underlying coordinates.
Sourcepub fn euclidean_norm(&self) -> FixedPoint
pub fn euclidean_norm(&self) -> FixedPoint
Calculate the Euclidean norm of the point.
Sourcepub fn hyperbolic_distance(&self, other: &Self) -> FixedPoint
pub fn hyperbolic_distance(&self, other: &Self) -> FixedPoint
Calculate the hyperbolic distance between this point and another.
The hyperbolic distance in the Poincaré disk model is given by: d(p, q) = 2 * atanh(|p-q| / |1-p̄q|) where p̄ is the complex conjugate of p and |x| is the Euclidean norm.
Computed in squared space (one-sqrt form): r = √(|p−q|² / |1−p̄q|²) with
|p−q|² = |p|² + |q|² − 2⟨p,q⟩, so the kernel pays one sqrt
instead of the previous four (|p−q|, |p|, |q|, and the denominator —
two of which were norms immediately squared back). Measured: the
four-sqrt form cost ~78 µs/pair; fixed-point sqrt is ~15 µs each.
Same guards, same clamps, same saturation semantics; outputs may
differ from the old form in the last ULPs (different-but-still-
deterministic rounding sequence).
Sourcepub fn hyperbolic_ratio(&self, other: &Self) -> FixedPoint
pub fn hyperbolic_ratio(&self, other: &Self) -> FixedPoint
Compute the Möbius ratio |p-q| / |1-p̄q| without the atanh transcendental.
Since atanh is strictly monotonic on [0,1), comparing ratios is equivalent to comparing hyperbolic distances: d(p,q) < d(p,r) ⟺ ratio(p,q) < ratio(p,r)
Computed in squared space with a single sqrt (one-sqrt form):
r = √( (|p|² + |q|² − 2⟨p,q⟩) / (1 − 2⟨p,q⟩ + |p|²·|q|²) ) — one
dot product, two squared norms (no norm→square round-trips), one
division, one sqrt. The algebra now matches the proxy scorer
(metric_tree::HyperbolicMetric::proxy is exactly the pre-sqrt
value), so proxy and exact orderings share one computation path.
Guards are the squared-space equivalents of the previous ones:
origin when |p|² < small_epsilon², degenerate when den² < epsilon².
Sourcepub fn mobius_transform(&self, a: &Self, b: &Self) -> Self
pub fn mobius_transform(&self, a: &Self, b: &Self) -> Self
Apply the disk isometry that sends a to b (through the origin) to
this point.
Concretely this composes two gyro-translations:
T(z) = b ⊕ ((−a) ⊕ z)
The first factor maps a to the origin, the second maps the origin to
b; each is a Poincaré-disk isometry, so their composition is one too,
in any dimension. In particular T(a) = b and distances are
preserved: d(T(x), T(y)) = d(x, y).
This replaces an earlier real-scalar formula (z − a)/(1 − z·a) that
only reduced to a valid Möbius map when the disk was treated as the 1-D
complex plane; for d ≥ 2 it distorted distances. Prefer mobius_add,
reflect_to_origin, and reflect_from_origin directly when you
need just one of these factors.
Sourcepub fn mobius_add(a: &Self, z: &Self) -> Self
pub fn mobius_add(a: &Self, z: &Self) -> Self
Möbius addition in the Poincaré ball model: a ⊕ z.
The correct d-dimensional formula (Ungar’s gyroaddition): a ⊕ z = ((1 + 2⟨a,z⟩ + ‖z‖²)·a + (1 − ‖a‖²)·z) / (1 + 2⟨a,z⟩ + ‖a‖²·‖z‖²)
Key properties:
- Left identity: 0 ⊕ z = z
- Right identity: a ⊕ 0 = a
- Left inverse: (−a) ⊕ a = 0
- Left cancellation: (−a) ⊕ (a ⊕ b) = b
- Isometry: d(a⊕x, a⊕y) = d(x, y)
Sourcepub fn reflect_to_origin(&self, center: &Self) -> Self
pub fn reflect_to_origin(&self, center: &Self) -> Self
Reflect a point to the origin frame via Möbius addition: (−center) ⊕ self. Maps center to the origin while preserving hyperbolic distances.
Sourcepub fn reflect_from_origin(&self, center: &Self) -> Self
pub fn reflect_from_origin(&self, center: &Self) -> Self
Reflect a point from the origin frame to center’s frame: center ⊕ self. Maps the origin to center’s position while preserving hyperbolic distances.
Sourcepub fn hyperbolic_midpoint(&self, other: &Self) -> Self
pub fn hyperbolic_midpoint(&self, other: &Self) -> Self
Calculate the hyperbolic midpoint between this point and another.
Sourcepub fn point_at_distance(
&self,
direction: &FixedVector,
distance: FixedPoint,
) -> Self
pub fn point_at_distance( &self, direction: &FixedVector, distance: FixedPoint, ) -> Self
Create a point at a specified distance and direction from this point.
The direction is specified as a Euclidean vector that gets normalized.
Trait Implementations§
Source§impl Clone for HyperbolicPoint
impl Clone for HyperbolicPoint
Source§fn clone(&self) -> HyperbolicPoint
fn clone(&self) -> HyperbolicPoint
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more