From db72c88f069ee4be18546c93342fbee5803acd43 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Wed, 11 Sep 2019 08:48:31 +0200 Subject: Rename Eigen3 as Eigen (sphinx warning) --- src/python/doc/installation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/python/doc') diff --git a/src/python/doc/installation.rst b/src/python/doc/installation.rst index d8b6f861..5a6ad9f4 100644 --- a/src/python/doc/installation.rst +++ b/src/python/doc/installation.rst @@ -138,7 +138,7 @@ Documentation To build the documentation, `sphinx-doc `_ and `sphinxcontrib-bibtex `_ are -required. As the documentation is auto-tested, `CGAL`_, `Eigen3`_, +required. As the documentation is auto-tested, `CGAL`_, `Eigen`_, `Matplotlib`_, `NumPy`_ and `SciPy`_ are also mandatory to build the documentation. -- cgit v1.2.3 From 89d678a78dd2bf05ef3d00e889fe0d9c51fb3b32 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Fri, 20 Sep 2019 17:36:57 +0200 Subject: c++14 in installation documentation --- src/common/doc/installation.h | 2 +- src/python/doc/installation.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/python/doc') diff --git a/src/common/doc/installation.h b/src/common/doc/installation.h index 54f86573..2e64bef8 100644 --- a/src/common/doc/installation.h +++ b/src/common/doc/installation.h @@ -5,7 +5,7 @@ * Examples of GUDHI headers inclusion can be found in \ref utilities. * * \section compiling Compiling - * The library uses c++11 and requires Boost ≥ 1.56.0 + * The library uses c++14 and requires Boost ≥ 1.56.0 * and CMake ≥ 3.1. * It is a multi-platform library and compiles on Linux, Mac OSX and Visual Studio 2015. * diff --git a/src/python/doc/installation.rst b/src/python/doc/installation.rst index 5a6ad9f4..77d9e8b3 100644 --- a/src/python/doc/installation.rst +++ b/src/python/doc/installation.rst @@ -12,7 +12,7 @@ The easiest way to install the Python version of GUDHI is using Compiling ********* -The library uses c++11 and requires `Boost `_ ≥ 1.56.0, +The library uses c++14 and requires `Boost `_ ≥ 1.56.0, `CMake `_ ≥ 3.1 to generate makefiles, `NumPy `_ and `Cython `_ to compile the GUDHI Python module. -- cgit v1.2.3 From 1b007fc59f08bd01e1521eb1c0773b598bdf158b Mon Sep 17 00:00:00 2001 From: tlacombe Date: Mon, 23 Sep 2019 11:14:24 +0200 Subject: wasserstein distance added on fork --- src/python/doc/wasserstein_distance_sum.inc | 14 ++++++ src/python/doc/wasserstein_distance_user.rst | 39 +++++++++++++++ src/python/gudhi/wasserstein.py | 75 ++++++++++++++++++++++++++++ src/python/test/test_wasserstein_distance.py | 22 ++++++++ 4 files changed, 150 insertions(+) create mode 100644 src/python/doc/wasserstein_distance_sum.inc create mode 100644 src/python/doc/wasserstein_distance_user.rst create mode 100644 src/python/gudhi/wasserstein.py create mode 100755 src/python/test/test_wasserstein_distance.py (limited to 'src/python/doc') diff --git a/src/python/doc/wasserstein_distance_sum.inc b/src/python/doc/wasserstein_distance_sum.inc new file mode 100644 index 00000000..0263f80f --- /dev/null +++ b/src/python/doc/wasserstein_distance_sum.inc @@ -0,0 +1,14 @@ +.. table:: + :widths: 30 50 20 + + +-----------------------------------------------------------------+----------------------------------------------------------------------+------------------------------------------------------------------+ + | .. figure:: | The p-Wasserstein distance measures the similarity between two | :Author: Theo Lacombe | + | ../../doc/Bottleneck_distance/perturb_pd.png | persistence diagrams. It's the minimum value c that can be achieve by| | + | :figclass: align-center | a perfect matching between the points of the two diagrams (+ all the | :Introduced in: GUDHI 2.0.0 | + | | diagonal points), where the value of a matching is defined as the | | + | Wasserstein distance is the p-th root of the sum of the | p-th root of the sum of all edges lengths to the power p. Edges | :Copyright: MIT (`GPL v3 `_) | + | edges lengths to the power p. | lengths are measured in norm q, for $1 \leq q \leq \infty$. | | + | | | :Requires: `Python Optimal Transport (POT)` | + +-----------------------------------------------------------------+----------------------------------------------------------------------+------------------------------------------------------------------+ + | * :doc:`wasserstein_distance_user` | | + +-----------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/src/python/doc/wasserstein_distance_user.rst b/src/python/doc/wasserstein_distance_user.rst new file mode 100644 index 00000000..a51cfb71 --- /dev/null +++ b/src/python/doc/wasserstein_distance_user.rst @@ -0,0 +1,39 @@ +:orphan: + +.. To get rid of WARNING: document isn't included in any toctree + +Wasserstein distance user manual +=============================== +Definition +---------- + +.. include:: wasserstein_distance_sum.inc + +This implementation is based on ideas from "Large Scale Computation of Means and Cluster for Persistence Diagrams via Optimal Transport". + +Function +-------- +.. autofunction:: gudhi.wasserstein_distance + + +Basic example +------------- + +This example computes the 1-Wasserstein distance from 2 persistence diagrams with euclidean ground metric. +Note that persistence diagrams must be submitted as (n x 2) numpy arrays and must not contain inf values. + +.. testcode:: + + import gudhi + + diag1 = np.array([[2.7, 3.7],[9.6, 14.],[34.2, 34.974]]) + diag2 = np.array([[2.8, 4.45],[9.5, 14.1]]) + + message = "Wasserstein distance value = " + '%.2f' % gudhi.wasserstein_distance(diag1, diag2, q=2., p=1.) + print(message) + +The output is: + +.. testoutput:: + + Wasserstein distance value = 1.45 diff --git a/src/python/gudhi/wasserstein.py b/src/python/gudhi/wasserstein.py new file mode 100644 index 00000000..cc527ed8 --- /dev/null +++ b/src/python/gudhi/wasserstein.py @@ -0,0 +1,75 @@ +import numpy as np +import scipy.spatial.distance as sc +try: + import ot +except ImportError: + print("POT (Python Optimal Transport) package is not installed. Try to run $ pip install POT") + +""" 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): Theo Lacombe + + Copyright (C) 2016 Inria + + Modification(s): + - YYYY/MM Author: Description of the modification +""" + +def proj_on_diag(X): + ''' + param X: (n x 2) array encoding the points of a persistent diagram. + return: (n x 2) arary encoding the (respective orthogonal) projections of the points onto the diagonal + ''' + Z = (X[:,0] + X[:,1]) / 2. + return np.array([Z , Z]).T + + +def build_dist_matrix(X, Y, p=2., q=2.): + ''' + param X: (n x 2) np.array encoding the (points of the) first diagram. + param Y: (m x 2) np.array encoding the second diagram. + param q: Ground metric (i.e. norm l_q). + param p: exponent for the Wasserstein metric. + return: (n+1) x (m+1) np.array encoding the cost matrix C. + For 1 <= i <= n, 1 <= j <= m, C[i,j] encodes the distance between X[i] and Y[j], while C[i, m+1] (resp. C[n+1, j]) encodes the distance (to the p) between X[i] (resp Y[j]) and its orthogonal proj onto the diagonal. + note also that C[n+1, m+1] = 0 (it costs nothing to move from the diagonal to the diagonal). + ''' + Xdiag = proj_on_diag(X) + Ydiag = proj_on_diag(Y) + if np.isinf(p): + C = sc.cdist(X,Y, metric='chebyshev', p=q)**p + Cxd = np.linalg.norm(X - Xdiag, ord=q, axis=1)**p + Cdy = np.linalg.norm(Y - Ydiag, ord=q, axis=1)**p + else: + C = sc.cdist(X,Y, metric='minkowski', p=q)**p + Cxd = np.linalg.norm(X - Xdiag, ord=q, axis=1)**p + Cdy = np.linalg.norm(Y - Ydiag, ord=q, axis=1)**p + Cf = np.hstack((C, Cxd[:,None])) + Cdy = np.append(Cdy, 0) + + Cf = np.vstack((Cf, Cdy[None,:])) + + return Cf + + +def wasserstein_distance(X, Y, p=2., q=2.): + ''' + param X, Y: (n x 2) and (m x 2) numpy array (points of persistence diagrams) + param q: Ground metric (i.e. norm l_q); Default value is 2 (euclidean norm). + param p: exponent for Wasserstein; Default value is 2. + return: float, the p-Wasserstein distance (1 <= p < infty) with respect to the q-norm as ground metric. + ''' + M = build_dist_matrix(X, Y, p=p, q=q) + n = len(X) + m = len(Y) + a = 1.0 / (n + m) * np.ones(n) # weight vector of the input diagram. Uniform here. + hat_a = np.append(a, m/(n+m)) # so that we have a probability measure, required by POT + b = 1.0 / (n + m) * np.ones(m) # weight vector of the input diagram. Uniform here. + hat_b = np.append(b, n/(m+n)) # so that we have a probability measure, required by POT + + # Comptuation of the otcost using the ot.emd2 library. + # Note: it is the squared Wasserstein distance. + ot_cost = (n+m) * ot.emd2(hat_a, hat_b, M) + + return np.power(ot_cost, 1./p) + diff --git a/src/python/test/test_wasserstein_distance.py b/src/python/test/test_wasserstein_distance.py new file mode 100755 index 00000000..a5f7cf77 --- /dev/null +++ b/src/python/test/test_wasserstein_distance.py @@ -0,0 +1,22 @@ +import gudhi + +""" 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): Theo Lacombe + + Copyright (C) 2016 Inria + + Modification(s): + - YYYY/MM Author: Description of the modification +""" + +__author__ = "Theo Lacombe" +__copyright__ = "Copyright (C) 2016 Inria" +__license__ = "MIT" + + +def test_basic_bottleneck(): + diag1 = np.array([[2.7, 3.7], [9.6, 14.0], [34.2, 34.974]]) + diag2 = np.array([[2.8, 4.45], [9.5, 14.1]]) + + assert gudhi.wasserstein_distance(diag1, diag2) == 1.4453593023967701 -- cgit v1.2.3 From 36dfb09493f56f666367df39e5d1a170e49a1a23 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Mon, 23 Sep 2019 18:10:14 +0200 Subject: updated doc for sphinx compilation --- src/python/doc/wasserstein_distance_user.rst | 1 + 1 file changed, 1 insertion(+) (limited to 'src/python/doc') diff --git a/src/python/doc/wasserstein_distance_user.rst b/src/python/doc/wasserstein_distance_user.rst index a51cfb71..bcb7f19d 100644 --- a/src/python/doc/wasserstein_distance_user.rst +++ b/src/python/doc/wasserstein_distance_user.rst @@ -25,6 +25,7 @@ Note that persistence diagrams must be submitted as (n x 2) numpy arrays and mus .. testcode:: import gudhi + import numpy as np diag1 = np.array([[2.7, 3.7],[9.6, 14.],[34.2, 34.974]]) diag2 = np.array([[2.8, 4.45],[9.5, 14.1]]) -- cgit v1.2.3 From f9ec015c1bdd01068771d0d04ff55e0436ffc879 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Thu, 17 Oct 2019 11:55:22 +0200 Subject: updated index.rst to include Wasserstein distance --- src/python/doc/index.rst | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/python/doc') diff --git a/src/python/doc/index.rst b/src/python/doc/index.rst index e379bc23..16d918bc 100644 --- a/src/python/doc/index.rst +++ b/src/python/doc/index.rst @@ -73,6 +73,11 @@ Bottleneck distance .. include:: bottleneck_distance_sum.inc +Wasserstein distance +=================== + +.. include:: wasserstein_distance_sum.inc + Persistence graphical tools =========================== -- cgit v1.2.3 From 91632989f92b89752dd4e59836dff80b43f349f1 Mon Sep 17 00:00:00 2001 From: tlacombe Date: Thu, 17 Oct 2019 11:56:20 +0200 Subject: updated wasserstein doc to be sphinx-compatible + correction of typo in the .rst --- src/python/doc/wasserstein_distance_sum.inc | 4 ++-- src/python/gudhi/wasserstein.py | 32 +++++++++++++++-------------- 2 files changed, 19 insertions(+), 17 deletions(-) (limited to 'src/python/doc') diff --git a/src/python/doc/wasserstein_distance_sum.inc b/src/python/doc/wasserstein_distance_sum.inc index 0263f80f..3b0b9025 100644 --- a/src/python/doc/wasserstein_distance_sum.inc +++ b/src/python/doc/wasserstein_distance_sum.inc @@ -7,8 +7,8 @@ | :figclass: align-center | a perfect matching between the points of the two diagrams (+ all the | :Introduced in: GUDHI 2.0.0 | | | diagonal points), where the value of a matching is defined as the | | | Wasserstein distance is the p-th root of the sum of the | p-th root of the sum of all edges lengths to the power p. Edges | :Copyright: MIT (`GPL v3 `_) | - | edges lengths to the power p. | lengths are measured in norm q, for $1 \leq q \leq \infty$. | | - | | | :Requires: `Python Optimal Transport (POT)` | + | edges lengths to the power p. | lengths are measured in norm q, for :math:`1 \leq q \leq \infty`. | | + | | | :Requires: Python Optimal Transport (POT) :math:`\geq` 0.5.1 | +-----------------------------------------------------------------+----------------------------------------------------------------------+------------------------------------------------------------------+ | * :doc:`wasserstein_distance_user` | | +-----------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/src/python/gudhi/wasserstein.py b/src/python/gudhi/wasserstein.py index ae5f75a5..0b2fe79a 100644 --- a/src/python/gudhi/wasserstein.py +++ b/src/python/gudhi/wasserstein.py @@ -17,8 +17,8 @@ except ImportError: def _proj_on_diag(X): ''' - param X: (n x 2) array encoding the points of a persistent diagram. - return: (n x 2) arary encoding the (respective orthogonal) projections of the points onto the diagonal + :param X: (n x 2) array encoding the points of a persistent diagram. + :returns: (n x 2) arary encoding the (respective orthogonal) projections of the points onto the diagonal ''' Z = (X[:,0] + X[:,1]) / 2. return np.array([Z , Z]).T @@ -26,11 +26,11 @@ def _proj_on_diag(X): def _build_dist_matrix(X, Y, p=2., q=2.): ''' - param X: (n x 2) np.array encoding the (points of the) first diagram. - param Y: (m x 2) np.array encoding the second diagram. - param q: Ground metric (i.e. norm l_q). - param p: exponent for the Wasserstein metric. - return: (n+1) x (m+1) np.array encoding the cost matrix C. + :param X: (n x 2) np.array encoding the (points of the) first diagram. + :param Y: (m x 2) np.array encoding the second diagram. + :param q: Ground metric (i.e. norm l_q). + :param p: exponent for the Wasserstein metric. + :returns: (n+1) x (m+1) np.array encoding the cost matrix C. For 1 <= i <= n, 1 <= j <= m, C[i,j] encodes the distance between X[i] and Y[j], while C[i, m+1] (resp. C[n+1, j]) encodes the distance (to the p) between X[i] (resp Y[j]) and its orthogonal proj onto the diagonal. note also that C[n+1, m+1] = 0 (it costs nothing to move from the diagonal to the diagonal). ''' @@ -54,10 +54,10 @@ def _build_dist_matrix(X, Y, p=2., q=2.): def _perstot(X, p, q): ''' - param X: (n x 2) numpy array (points of a given diagram) - param q: Ground metric on the (upper-half) plane (i.e. norm l_q in R^2); Default value is 2 (euclidean norm). - param p: exponent for Wasserstein; Default value is 2. - return: float, the total persistence of the diagram (that is, its distance to the empty diagram). + :param X: (n x 2) numpy array (points of a given diagram) + :param q: Ground metric on the (upper-half) plane (i.e. norm l_q in R^2); Default value is 2 (euclidean norm). + :param p: exponent for Wasserstein; Default value is 2. + :returns: float, the total persistence of the diagram (that is, its distance to the empty diagram). ''' Xdiag = _proj_on_diag(X) return (np.sum(np.linalg.norm(X - Xdiag, ord=q, axis=1)**p))**(1/p) @@ -65,10 +65,12 @@ def _perstot(X, p, q): def wasserstein_distance(X, Y, p=2., q=2.): ''' - param X, Y: (n x 2) and (m x 2) numpy array (points of persistence diagrams) - param q: Ground metric on the (upper-half) plane (i.e. norm l_q in R^2); Default value is 2 (euclidean norm). - param p: exponent for Wasserstein; Default value is 2. - return: float, the p-Wasserstein distance (1 <= p < infty) with respect to the q-norm as ground metric. + :param X: (n x 2) np.array encoding the (points of the) first diagram. + :param Y: (m x 2) np.array encoding the second diagram. + :param q: Ground metric on the (upper-half) plane (i.e. norm l_q in R^2); Default value is 2 (euclidean norm). + :param p: exponent for Wasserstein; Default value is 2. + :returns: the p-Wasserstein distance (1 <= p < infty) with respect to the q-norm as ground metric. + :rtype: float ''' n = len(X) m = len(Y) -- cgit v1.2.3 From 7ea7dfe83e93dc3d33d8d50917f718c05f32ca7f Mon Sep 17 00:00:00 2001 From: tlacombe Date: Thu, 17 Oct 2019 23:54:39 +0200 Subject: removed GPL license, updated expected gudhi release (set at 3.1.0 for now) --- src/python/doc/wasserstein_distance_sum.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/python/doc') diff --git a/src/python/doc/wasserstein_distance_sum.inc b/src/python/doc/wasserstein_distance_sum.inc index 3b0b9025..24b72c0e 100644 --- a/src/python/doc/wasserstein_distance_sum.inc +++ b/src/python/doc/wasserstein_distance_sum.inc @@ -4,9 +4,9 @@ +-----------------------------------------------------------------+----------------------------------------------------------------------+------------------------------------------------------------------+ | .. figure:: | The p-Wasserstein distance measures the similarity between two | :Author: Theo Lacombe | | ../../doc/Bottleneck_distance/perturb_pd.png | persistence diagrams. It's the minimum value c that can be achieve by| | - | :figclass: align-center | a perfect matching between the points of the two diagrams (+ all the | :Introduced in: GUDHI 2.0.0 | + | :figclass: align-center | a perfect matching between the points of the two diagrams (+ all the | :Introduced in: GUDHI 3.1.0 | | | diagonal points), where the value of a matching is defined as the | | - | Wasserstein distance is the p-th root of the sum of the | p-th root of the sum of all edges lengths to the power p. Edges | :Copyright: MIT (`GPL v3 `_) | + | Wasserstein distance is the p-th root of the sum of the | p-th root of the sum of all edges lengths to the power p. Edges | :Copyright: MIT | | edges lengths to the power p. | lengths are measured in norm q, for :math:`1 \leq q \leq \infty`. | | | | | :Requires: Python Optimal Transport (POT) :math:`\geq` 0.5.1 | +-----------------------------------------------------------------+----------------------------------------------------------------------+------------------------------------------------------------------+ -- cgit v1.2.3 From 12f62eca36952053169a71f70169a0e15fa481fc Mon Sep 17 00:00:00 2001 From: tlacombe Date: Fri, 18 Oct 2019 22:30:07 +0200 Subject: correction edges lengths ==> edge lengths --- src/python/doc/wasserstein_distance_sum.inc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/python/doc') diff --git a/src/python/doc/wasserstein_distance_sum.inc b/src/python/doc/wasserstein_distance_sum.inc index 24b72c0e..ffd4d312 100644 --- a/src/python/doc/wasserstein_distance_sum.inc +++ b/src/python/doc/wasserstein_distance_sum.inc @@ -3,11 +3,11 @@ +-----------------------------------------------------------------+----------------------------------------------------------------------+------------------------------------------------------------------+ | .. figure:: | The p-Wasserstein distance measures the similarity between two | :Author: Theo Lacombe | - | ../../doc/Bottleneck_distance/perturb_pd.png | persistence diagrams. It's the minimum value c that can be achieve by| | - | :figclass: align-center | a perfect matching between the points of the two diagrams (+ all the | :Introduced in: GUDHI 3.1.0 | + | ../../doc/Bottleneck_distance/perturb_pd.png | persistence diagrams. It's the minimum value c that can be achieved | | + | :figclass: align-center | by a perfect matching between the points of the two diagrams (+ all | :Introduced in: GUDHI 3.1.0 | | | diagonal points), where the value of a matching is defined as the | | - | Wasserstein distance is the p-th root of the sum of the | p-th root of the sum of all edges lengths to the power p. Edges | :Copyright: MIT | - | edges lengths to the power p. | lengths are measured in norm q, for :math:`1 \leq q \leq \infty`. | | + | Wasserstein distance is the p-th root of the sum of the | p-th root of the sum of all edge lengths to the power p. Edge lengths| :Copyright: MIT | + | edge lengths to the power p. | are measured in norm q, for :math:`1 \leq q \leq \infty`. | | | | | :Requires: Python Optimal Transport (POT) :math:`\geq` 0.5.1 | +-----------------------------------------------------------------+----------------------------------------------------------------------+------------------------------------------------------------------+ | * :doc:`wasserstein_distance_user` | | -- cgit v1.2.3 From d02296df9ca6ebea31345a89a6070258c0ed91a9 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Sun, 27 Oct 2019 12:59:55 +0100 Subject: Mention POT in installation instructions --- src/python/doc/installation.rst | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/python/doc') diff --git a/src/python/doc/installation.rst b/src/python/doc/installation.rst index 5a6ad9f4..4778b3d9 100644 --- a/src/python/doc/installation.rst +++ b/src/python/doc/installation.rst @@ -215,6 +215,13 @@ The following examples require the `Matplotlib `_: * :download:`euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py <../example/euclidean_strong_witness_complex_diagram_persistence_from_off_file_example.py>` * :download:`euclidean_witness_complex_diagram_persistence_from_off_file_example.py <../example/euclidean_witness_complex_diagram_persistence_from_off_file_example.py>` +Python Optimal Transport +======================== + +The :doc:`Wasserstein distance ` +module requires `POT `_, a library that provides +several solvers for optimization problems related to Optimal Transport. + SciPy ===== -- cgit v1.2.3 From 3c76f73a530daacd48d476cd96bd946e4ab6d78a Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Sun, 27 Oct 2019 13:40:23 +0100 Subject: Wasserstein also uses SciPy --- src/python/doc/installation.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/python/doc') diff --git a/src/python/doc/installation.rst b/src/python/doc/installation.rst index 4778b3d9..3711ca8e 100644 --- a/src/python/doc/installation.rst +++ b/src/python/doc/installation.rst @@ -225,9 +225,10 @@ several solvers for optimization problems related to Optimal Transport. SciPy ===== -The :doc:`persistence graphical tools ` -module requires `SciPy `_, a Python-based ecosystem of -open-source software for mathematics, science, and engineering. +The :doc:`persistence graphical tools ` and +:doc:`Wasserstein distance ` modules require `SciPy +`_, a Python-based ecosystem of open-source software for +mathematics, science, and engineering. Threading Building Blocks ========================= -- cgit v1.2.3 From 1e42426b292f4bdc40044eedda59bbb51e2ca851 Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 31 Oct 2019 15:52:05 +0100 Subject: Fix #98 : set conda link to the correct one (not licensing link) --- src/python/doc/installation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/python/doc') diff --git a/src/python/doc/installation.rst b/src/python/doc/installation.rst index 77d9e8b3..5369efb0 100644 --- a/src/python/doc/installation.rst +++ b/src/python/doc/installation.rst @@ -8,7 +8,7 @@ Installation Conda ***** The easiest way to install the Python version of GUDHI is using -`conda `_. +`conda `_. Compiling ********* -- cgit v1.2.3 From b6174ec368be398e5f4bb647120f5e5905b933e6 Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Tue, 5 Nov 2019 22:30:13 +0100 Subject: Fix size of underlines for sphinx --- src/python/doc/index.rst | 4 ++-- src/python/doc/wasserstein_distance_user.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/python/doc') diff --git a/src/python/doc/index.rst b/src/python/doc/index.rst index 16d918bc..8f27da0d 100644 --- a/src/python/doc/index.rst +++ b/src/python/doc/index.rst @@ -23,7 +23,7 @@ Alpha complex .. include:: alpha_complex_sum.inc Rips complex -------------- +------------ .. include:: rips_complex_sum.inc @@ -74,7 +74,7 @@ Bottleneck distance .. include:: bottleneck_distance_sum.inc Wasserstein distance -=================== +==================== .. include:: wasserstein_distance_sum.inc diff --git a/src/python/doc/wasserstein_distance_user.rst b/src/python/doc/wasserstein_distance_user.rst index bcb7f19d..9ec64e93 100644 --- a/src/python/doc/wasserstein_distance_user.rst +++ b/src/python/doc/wasserstein_distance_user.rst @@ -3,7 +3,7 @@ .. To get rid of WARNING: document isn't included in any toctree Wasserstein distance user manual -=============================== +================================ Definition ---------- -- cgit v1.2.3 From 94391b1cc232c5f66ae3cdadf865554c57f1308a Mon Sep 17 00:00:00 2001 From: Marc Glisse Date: Tue, 5 Nov 2019 23:01:31 +0100 Subject: Create GUDHI_PYTHON_MODULES_EXTRA without auto-import Put Wasserstein in it. --- src/python/CMakeLists.txt | 3 ++- src/python/doc/wasserstein_distance_user.rst | 6 ++--- src/python/gudhi/__init__.py.in | 4 +-- src/python/test/test_wasserstein_distance.py | 38 +++++++++++++--------------- 4 files changed, 25 insertions(+), 26 deletions(-) (limited to 'src/python/doc') diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index 1b1684e1..dbef7183 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -49,7 +49,8 @@ if(PYTHONINTERP_FOUND) set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'alpha_complex', ") set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'euclidean_witness_complex', ") set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'euclidean_strong_witness_complex', ") - set(GUDHI_PYTHON_MODULES "${GUDHI_PYTHON_MODULES}'wasserstein', ") + # Modules that should not be auto-imported in __init__.py + set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'wasserstein', ") add_gudhi_debug_info("Python version ${PYTHON_VERSION_STRING}") add_gudhi_debug_info("Cython version ${CYTHON_VERSION}") diff --git a/src/python/doc/wasserstein_distance_user.rst b/src/python/doc/wasserstein_distance_user.rst index bcb7f19d..fc7bd82c 100644 --- a/src/python/doc/wasserstein_distance_user.rst +++ b/src/python/doc/wasserstein_distance_user.rst @@ -13,7 +13,7 @@ This implementation is based on ideas from "Large Scale Computation of Means and Function -------- -.. autofunction:: gudhi.wasserstein_distance +.. autofunction:: gudhi.wasserstein.wasserstein_distance Basic example @@ -24,13 +24,13 @@ Note that persistence diagrams must be submitted as (n x 2) numpy arrays and mus .. testcode:: - import gudhi + import gudhi.wasserstein import numpy as np diag1 = np.array([[2.7, 3.7],[9.6, 14.],[34.2, 34.974]]) diag2 = np.array([[2.8, 4.45],[9.5, 14.1]]) - message = "Wasserstein distance value = " + '%.2f' % gudhi.wasserstein_distance(diag1, diag2, q=2., p=1.) + message = "Wasserstein distance value = " + '%.2f' % gudhi.wasserstein.wasserstein_distance(diag1, diag2, q=2., p=1.) print(message) The output is: diff --git a/src/python/gudhi/__init__.py.in b/src/python/gudhi/__init__.py.in index 28bab0e1..4039c08f 100644 --- a/src/python/gudhi/__init__.py.in +++ b/src/python/gudhi/__init__.py.in @@ -21,13 +21,13 @@ __debug_info__ = @GUDHI_PYTHON_DEBUG_INFO@ from sys import exc_info from importlib import import_module -__all__ = [@GUDHI_PYTHON_MODULES@] +__all__ = [@GUDHI_PYTHON_MODULES@ @GUDHI_PYTHON_MODULES_EXTRA@] __available_modules = '' __missing_modules = '' # try to import * from gudhi.__module_name -for __module_name in __all__: +for __module_name in [@GUDHI_PYTHON_MODULES@]: try: __module = import_module('gudhi.' + __module_name) try: diff --git a/src/python/test/test_wasserstein_distance.py b/src/python/test/test_wasserstein_distance.py index c1b568e2..a6bf9901 100755 --- a/src/python/test/test_wasserstein_distance.py +++ b/src/python/test/test_wasserstein_distance.py @@ -1,4 +1,4 @@ -import gudhi +from gudhi.wasserstein import wasserstein_distance import numpy as np """ This file is part of the Gudhi Library - https://gudhi.inria.fr/ - which is released under MIT. @@ -23,28 +23,26 @@ def test_basic_wasserstein(): diag4 = np.array([[0, 3], [4, 8]]) emptydiag = np.array([[]]) - assert gudhi.wasserstein_distance(emptydiag, emptydiag, q=2., p=1.) == 0. - assert gudhi.wasserstein_distance(emptydiag, emptydiag, q=np.inf, p=1.) == 0. - assert gudhi.wasserstein_distance(emptydiag, emptydiag, q=np.inf, p=2.) == 0. - assert gudhi.wasserstein_distance(emptydiag, emptydiag, q=2., p=2.) == 0. + assert wasserstein_distance(emptydiag, emptydiag, q=2., p=1.) == 0. + assert wasserstein_distance(emptydiag, emptydiag, q=np.inf, p=1.) == 0. + assert wasserstein_distance(emptydiag, emptydiag, q=np.inf, p=2.) == 0. + assert wasserstein_distance(emptydiag, emptydiag, q=2., p=2.) == 0. - assert gudhi.wasserstein_distance(diag3, emptydiag, q=np.inf, p=1.) == 2. - assert gudhi.wasserstein_distance(diag3, emptydiag, q=1., p=1.) == 4. + assert wasserstein_distance(diag3, emptydiag, q=np.inf, p=1.) == 2. + assert wasserstein_distance(diag3, emptydiag, q=1., p=1.) == 4. - assert gudhi.wasserstein_distance(diag4, emptydiag, q=1., p=2.) == 5. # thank you Pythagorician triplets - assert gudhi.wasserstein_distance(diag4, emptydiag, q=np.inf, p=2.) == 2.5 - assert gudhi.wasserstein_distance(diag4, emptydiag, q=2., p=2.) == 3.5355339059327378 + assert wasserstein_distance(diag4, emptydiag, q=1., p=2.) == 5. # thank you Pythagorician triplets + assert wasserstein_distance(diag4, emptydiag, q=np.inf, p=2.) == 2.5 + assert wasserstein_distance(diag4, emptydiag, q=2., p=2.) == 3.5355339059327378 - assert gudhi.wasserstein_distance(diag1, diag2, q=2., p=1.) == 1.4453593023967701 - assert gudhi.wasserstein_distance(diag1, diag2, q=2.35, p=1.74) == 0.9772734057168739 + assert wasserstein_distance(diag1, diag2, q=2., p=1.) == 1.4453593023967701 + assert wasserstein_distance(diag1, diag2, q=2.35, p=1.74) == 0.9772734057168739 - assert gudhi.wasserstein_distance(diag1, emptydiag, q=2.35, p=1.7863) == 3.141592214572228 + assert wasserstein_distance(diag1, emptydiag, q=2.35, p=1.7863) == 3.141592214572228 - assert gudhi.wasserstein_distance(diag3, diag4, q=1., p=1.) == 3. - assert gudhi.wasserstein_distance(diag3, diag4, q=np.inf, p=1.) == 3. # no diag matching here - assert gudhi.wasserstein_distance(diag3, diag4, q=np.inf, p=2.) == np.sqrt(5) - assert gudhi.wasserstein_distance(diag3, diag4, q=1., p=2.) == np.sqrt(5) - assert gudhi.wasserstein_distance(diag3, diag4, q=4.5, p=2.) == np.sqrt(5) - - + assert wasserstein_distance(diag3, diag4, q=1., p=1.) == 3. + assert wasserstein_distance(diag3, diag4, q=np.inf, p=1.) == 3. # no diag matching here + assert wasserstein_distance(diag3, diag4, q=np.inf, p=2.) == np.sqrt(5) + assert wasserstein_distance(diag3, diag4, q=1., p=2.) == np.sqrt(5) + assert wasserstein_distance(diag3, diag4, q=4.5, p=2.) == np.sqrt(5) -- cgit v1.2.3