Source code for gudhi.hera
# This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT.
# See file LICENSE or go to https://gudhi.inria.fr/licensing/ for full license details.
# Author(s): Hannah Schreiber
#
# Copyright (C) 2025 Inria
#
# Modification(s):
# - YYYY/MM Author: Description of the modification
__license__ = "BSD 3-Clause"
import numpy as np
from numpy.typing import ArrayLike
import warnings
from gudhi import _hera_ext as t
def _diagram_as_numpy_array(diagram: ArrayLike) -> np.ndarray:
dgm = np.asarray(diagram, dtype=np.double)
# to allow empty diagrams (invalid shapes will be deled with by nanobind later)
if dgm.size == 0 and dgm.ndim == 1:
dgm = np.empty((0, 2))
return dgm
[docs]
def bottleneck_distance(X: ArrayLike, Y: ArrayLike, delta: float = 0.01) -> float:
"""Compute the Bottleneck distance between two diagrams.
Points at infinity are supported.
.. note::
Points on the diagonal are not supported and must be filtered out before calling this function.
Parameters:
X (n x 2 numpy array): First diagram
Y (n x 2 numpy array): Second diagram
delta (float): Relative error 1+delta
Returns:
float: (approximate) bottleneck distance d_B(X,Y)
"""
return t._bottleneck_distance(
_diagram_as_numpy_array(X), _diagram_as_numpy_array(Y), delta
)
[docs]
def wasserstein_distance(
X: ArrayLike,
Y: ArrayLike,
order: float = 1,
internal_p: float = float("Inf"),
delta: float = 0.01,
matching: bool = False,
):
"""Compute the Wasserstein distance between two diagrams.
Points at infinity are supported.
Parameters:
X (n x 2 numpy array): First diagram
Y (n x 2 numpy array): Second diagram
order (float): Wasserstein exponent W_q
internal_p (float): Internal Minkowski norm L^p in R^2
delta (float): Relative error 1+delta
matching (bool): if ``True``, computes and returns the optimal matching between X and Y, encoded as a
(n x 2) np.array [...[i,j]...], meaning the i-th point in X is matched to the j-th point in Y, with the
convention that (-1) represents the diagonal. If the distance between two diagrams is +inf (which happens
if the cardinalities of essential parts differ) and the matching is requested, it will be set to ``None``
(any matching is optimal).
.. warning::
For matching request, please consider using :func:`~gudhi.wasserstein.wasserstein_distance` (POT
version) instead. This version with ``matching=True`` is known to have bugs.
Returns:
float|Tuple[float,numpy.array|None]: Approximate Wasserstein distance W_q(X,Y), and optionally the
corresponding matching
"""
if matching:
warnings.warn(
"""
There is known bug (https://github.com/GUDHI/gudhi-devel/issues/1158) when `matching` is set to `True` with
the Hera backend. For the moment, we recommend using `gudhi.wasserstein.wasserstein_distance` instead.
""", UserWarning)
return t._wasserstein_distance(
_diagram_as_numpy_array(X),
_diagram_as_numpy_array(Y),
order,
internal_p,
delta,
matching,
)