From 0c47b28201093851140ab499331017ef42312ce7 Mon Sep 17 00:00:00 2001 From: yuichi-ike Date: Thu, 21 May 2020 11:02:00 +0900 Subject: DTM Rips added (straightforward way) --- src/python/CMakeLists.txt | 10 ++++- src/python/doc/rips_complex_ref.rst | 13 ++++++ src/python/doc/rips_complex_sum.inc | 3 ++ src/python/doc/rips_complex_user.rst | 20 +++++++++ src/python/gudhi/dtm_rips_complex.py | 46 +++++++++++++++++++ src/python/test/test_dtm_rips_complex.py | 40 +++++++++++++++++ src/python/test/test_weighted_rips.py | 63 --------------------------- src/python/test/test_weighted_rips_complex.py | 63 +++++++++++++++++++++++++++ 8 files changed, 194 insertions(+), 64 deletions(-) create mode 100644 src/python/gudhi/dtm_rips_complex.py create mode 100644 src/python/test/test_dtm_rips_complex.py delete mode 100644 src/python/test/test_weighted_rips.py create mode 100644 src/python/test/test_weighted_rips_complex.py (limited to 'src/python') diff --git a/src/python/CMakeLists.txt b/src/python/CMakeLists.txt index ab08cd6d..96dd3f6f 100644 --- a/src/python/CMakeLists.txt +++ b/src/python/CMakeLists.txt @@ -58,6 +58,7 @@ if(PYTHONINTERP_FOUND) set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'wasserstein', ") set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'point_cloud', ") set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'weighted_rips_complex', ") + set(GUDHI_PYTHON_MODULES_EXTRA "${GUDHI_PYTHON_MODULES_EXTRA}'dtm_rips_complex', ") add_gudhi_debug_info("Python version ${PYTHON_VERSION_STRING}") add_gudhi_debug_info("Cython version ${CYTHON_VERSION}") @@ -234,6 +235,7 @@ if(PYTHONINTERP_FOUND) file(COPY "gudhi/wasserstein" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi") file(COPY "gudhi/point_cloud" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi") file(COPY "gudhi/weighted_rips_complex.py" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi") + file(COPY "gudhi/dtm_rips_complex.py" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gudhi") add_custom_command( OUTPUT gudhi.so @@ -492,9 +494,15 @@ if(PYTHONINTERP_FOUND) # Weighted Rips if(SCIPY_FOUND) - add_gudhi_py_test(test_weighted_rips) + add_gudhi_py_test(test_weighted_rips_complex) endif() + # DTM Rips + if(SCIPY_FOUND) + add_gudhi_py_test(test_dtm_rips_complex) + endif() + + # Set missing or not modules set(GUDHI_MODULES ${GUDHI_MODULES} "python" CACHE INTERNAL "GUDHI_MODULES") else(CYTHON_FOUND) diff --git a/src/python/doc/rips_complex_ref.rst b/src/python/doc/rips_complex_ref.rst index 5f3e46c1..f781fd92 100644 --- a/src/python/doc/rips_complex_ref.rst +++ b/src/python/doc/rips_complex_ref.rst @@ -25,3 +25,16 @@ Weighted Rips complex reference manual :show-inheritance: .. automethod:: gudhi.weighted_rips_complex.WeightedRipsComplex.__init__ + +.. _dtm-rips-complex-reference-manual: + +================================= +DTM Rips complex reference manual +================================= + +.. autoclass:: gudhi.dtm_rips_complex.DtmRipsComplex + :members: + :undoc-members: + :show-inheritance: + + .. automethod:: gudhi.dtm_rips_complex.DtmRipsComplex.__init__ \ No newline at end of file diff --git a/src/python/doc/rips_complex_sum.inc b/src/python/doc/rips_complex_sum.inc index f7580714..9cd8074b 100644 --- a/src/python/doc/rips_complex_sum.inc +++ b/src/python/doc/rips_complex_sum.inc @@ -14,6 +14,9 @@ | | | | | | Weighted Rips complex constructs a simplicial complex from a distance | | | | matrix and weights on vertices. | | + | | | | + | | DTM Rips complex builds a simplicial complex from a point set or | | + | | a distance matrix. | | +----------------------------------------------------------------+------------------------------------------------------------------------+----------------------------------------------------------------------+ | * :doc:`rips_complex_user` | * :doc:`rips_complex_ref` | +----------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/src/python/doc/rips_complex_user.rst b/src/python/doc/rips_complex_user.rst index 819568be..eb2657df 100644 --- a/src/python/doc/rips_complex_user.rst +++ b/src/python/doc/rips_complex_user.rst @@ -398,3 +398,23 @@ The output is: .. testoutput:: [(0, (3.1622776601683795, inf)), (0, (3.1622776601683795, 5.39834563766817)), (0, (3.1622776601683795, 5.39834563766817))] + +DTM Rips Complex +---------------- + +`DtmdRipsComplex `_ builds a simplicial complex from a point set or a full distence matrix (in the form of ndarray), as described in the above example. + +.. testcode:: + + import numpy as np + from dtm_rips_complex import DtmRipsComplex + pts = np.array([[2.0, 2.0], [0.0, 1.0], [3.0, 4.0]]) + dtm_rips = DtmRipsComplex(points=pts, k=2) + st = dtm_rips.create_simplex_tree(max_dimension=2) + print(st.persistence()) + +The output is: + +.. testoutput:: + + [(0, (3.1622776601683795, inf)), (0, (3.1622776601683795, 5.39834563766817)), (0, (3.1622776601683795, 5.39834563766817))] diff --git a/src/python/gudhi/dtm_rips_complex.py b/src/python/gudhi/dtm_rips_complex.py new file mode 100644 index 00000000..6d2f9f31 --- /dev/null +++ b/src/python/gudhi/dtm_rips_complex.py @@ -0,0 +1,46 @@ +# 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): Yuichi Ike, Raphaƫl Tinarrage +# +# Copyright (C) 2020 Inria, Copyright (C) 2020 FUjitsu Laboratories Ltd. +# +# Modification(s): +# - YYYY/MM Author: Description of the modification + + +from gudhi.weighted_rips_complex import WeightedRipsComplex +from gudhi.point_cloud.dtm import DistanceToMeasure +from scipy.spatial.distance import cdist + +class DtmRipsComplex(WeightedRipsComplex): + """ + Class to generate a DTM Rips complex from a distance matrix or a point set, + in the way described in :cite:`dtmfiltrations`. + Remark that all the filtration values are doubled compared to the definition in the paper + for the consistency with RipsComplex. + """ + def __init__(self, + points=None, + distance_matrix=None, + k=1, + q=2, + max_filtration=float('inf')): + """ + Args: + points (Sequence[Sequence[float]]): list of points. + distance_matrix (ndarray): full distance matrix. + k (int): number of neighbors for the computation of DTM. Defaults to 1, which is equivalent to the usual Rips complex. + q (float): order used to compute the distance to measure. Defaults to 2. + max_filtration (float): specifies the maximal filtration value to be considered. + """ + if distance_matrix is None: + if points is None: + # Empty Rips construction + points=[] + distance_matrix = cdist(points,points) + self.distance_matrix = distance_matrix + dtm = DistanceToMeasure(k, q=q, metric="precomputed") + # TODO: address the error when k is too large + self.weights = dtm.fit_transform(distance_matrix) + self.max_filtration = max_filtration + diff --git a/src/python/test/test_dtm_rips_complex.py b/src/python/test/test_dtm_rips_complex.py new file mode 100644 index 00000000..bc6e5a59 --- /dev/null +++ b/src/python/test/test_dtm_rips_complex.py @@ -0,0 +1,40 @@ +""" 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): Yuichi Ike + + Copyright (C) 2020 Inria, Copyright (C) 2020 FUjitsu Laboratories Ltd. + + Modification(s): + - YYYY/MM Author: Description of the modification +""" + +from gudhi.dtm_rips_complex import DtmRipsComplex +import numpy as np +from math import sqrt +import pytest + +def test_dtm_rips_complex(): + pts = np.array([[2.0, 2.0], [0.0, 1.0], [3.0, 4.0]]) + dtm_rips = DtmRipsComplex(points=pts, k=2) + st = dtm_rips.create_simplex_tree(max_dimension=2) + st.persistence() + persistence_intervals0 = st.persistence_intervals_in_dimension(0) + assert persistence_intervals0 == pytest.approx(np.array([[3.16227766, 5.39834564],[3.16227766, 5.39834564], [3.16227766, float("inf")]])) + +def test_compatibility_with_rips(): + distance_matrix = np.array([[0, 1, 1, sqrt(2)], [1, 0, sqrt(2), 1], [1, sqrt(2), 0, 1], [sqrt(2), 1, 1, 0]]) + dtm_rips = DtmRipsComplex(distance_matrix=distance_matrix, max_filtration=42) + st = dtm_rips.create_simplex_tree(max_dimension=1) + assert list(st.get_filtration()) == [ + ([0], 0.0), + ([1], 0.0), + ([2], 0.0), + ([3], 0.0), + ([0, 1], 1.0), + ([0, 2], 1.0), + ([1, 3], 1.0), + ([2, 3], 1.0), + ([1, 2], sqrt(2)), + ([0, 3], sqrt(2)), + ] + diff --git a/src/python/test/test_weighted_rips.py b/src/python/test/test_weighted_rips.py deleted file mode 100644 index 7ef48333..00000000 --- a/src/python/test/test_weighted_rips.py +++ /dev/null @@ -1,63 +0,0 @@ -""" 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): Yuichi Ike and Masatoshi Takenouchi - - Copyright (C) 2020 Inria - - Modification(s): - - YYYY/MM Author: Description of the modification -""" - -from gudhi.weighted_rips_complex import WeightedRipsComplex -from gudhi.point_cloud.dtm import DistanceToMeasure -import numpy as np -from math import sqrt -from scipy.spatial.distance import cdist -import pytest - -def test_non_dtm_rips_complex(): - dist = [[], [1]] - weights = [1, 100] - w_rips = WeightedRipsComplex(distance_matrix=dist, weights=weights) - st = w_rips.create_simplex_tree(max_dimension=2) - assert st.filtration([0,1]) == pytest.approx(200.0) - -def test_compatibility_with_rips(): - distance_matrix = [[0], [1, 0], [1, sqrt(2), 0], [sqrt(2), 1, 1, 0]] - w_rips = WeightedRipsComplex(distance_matrix=distance_matrix,max_filtration=42) - st = w_rips.create_simplex_tree(max_dimension=1) - assert list(st.get_filtration()) == [ - ([0], 0.0), - ([1], 0.0), - ([2], 0.0), - ([3], 0.0), - ([0, 1], 1.0), - ([0, 2], 1.0), - ([1, 3], 1.0), - ([2, 3], 1.0), - ([1, 2], sqrt(2)), - ([0, 3], sqrt(2)), - ] - -def test_compatibility_with_filtered_rips(): - distance_matrix = [[0], [1, 0], [1, sqrt(2), 0], [sqrt(2), 1, 1, 0]] - w_rips = WeightedRipsComplex(distance_matrix=distance_matrix,max_filtration=1.0) - st = w_rips.create_simplex_tree(max_dimension=1) - - assert st.__is_defined() == True - assert st.__is_persistence_defined() == False - - assert st.num_simplices() == 8 - assert st.num_vertices() == 4 - -def test_dtm_rips_complex(): - pts = np.array([[2.0, 2.0], [0.0, 1.0], [3.0, 4.0]]) - dist = cdist(pts,pts) - dtm = DistanceToMeasure(2, q=2, metric="precomputed") - r = dtm.fit_transform(dist) - w_rips = WeightedRipsComplex(distance_matrix=dist, weights=r) - st = w_rips.create_simplex_tree(max_dimension=2) - st.persistence() - persistence_intervals0 = st.persistence_intervals_in_dimension(0) - assert persistence_intervals0 == pytest.approx(np.array([[3.16227766, 5.39834564],[3.16227766, 5.39834564], [3.16227766, float("inf")]])) - diff --git a/src/python/test/test_weighted_rips_complex.py b/src/python/test/test_weighted_rips_complex.py new file mode 100644 index 00000000..7ef48333 --- /dev/null +++ b/src/python/test/test_weighted_rips_complex.py @@ -0,0 +1,63 @@ +""" 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): Yuichi Ike and Masatoshi Takenouchi + + Copyright (C) 2020 Inria + + Modification(s): + - YYYY/MM Author: Description of the modification +""" + +from gudhi.weighted_rips_complex import WeightedRipsComplex +from gudhi.point_cloud.dtm import DistanceToMeasure +import numpy as np +from math import sqrt +from scipy.spatial.distance import cdist +import pytest + +def test_non_dtm_rips_complex(): + dist = [[], [1]] + weights = [1, 100] + w_rips = WeightedRipsComplex(distance_matrix=dist, weights=weights) + st = w_rips.create_simplex_tree(max_dimension=2) + assert st.filtration([0,1]) == pytest.approx(200.0) + +def test_compatibility_with_rips(): + distance_matrix = [[0], [1, 0], [1, sqrt(2), 0], [sqrt(2), 1, 1, 0]] + w_rips = WeightedRipsComplex(distance_matrix=distance_matrix,max_filtration=42) + st = w_rips.create_simplex_tree(max_dimension=1) + assert list(st.get_filtration()) == [ + ([0], 0.0), + ([1], 0.0), + ([2], 0.0), + ([3], 0.0), + ([0, 1], 1.0), + ([0, 2], 1.0), + ([1, 3], 1.0), + ([2, 3], 1.0), + ([1, 2], sqrt(2)), + ([0, 3], sqrt(2)), + ] + +def test_compatibility_with_filtered_rips(): + distance_matrix = [[0], [1, 0], [1, sqrt(2), 0], [sqrt(2), 1, 1, 0]] + w_rips = WeightedRipsComplex(distance_matrix=distance_matrix,max_filtration=1.0) + st = w_rips.create_simplex_tree(max_dimension=1) + + assert st.__is_defined() == True + assert st.__is_persistence_defined() == False + + assert st.num_simplices() == 8 + assert st.num_vertices() == 4 + +def test_dtm_rips_complex(): + pts = np.array([[2.0, 2.0], [0.0, 1.0], [3.0, 4.0]]) + dist = cdist(pts,pts) + dtm = DistanceToMeasure(2, q=2, metric="precomputed") + r = dtm.fit_transform(dist) + w_rips = WeightedRipsComplex(distance_matrix=dist, weights=r) + st = w_rips.create_simplex_tree(max_dimension=2) + st.persistence() + persistence_intervals0 = st.persistence_intervals_in_dimension(0) + assert persistence_intervals0 == pytest.approx(np.array([[3.16227766, 5.39834564],[3.16227766, 5.39834564], [3.16227766, float("inf")]])) + -- cgit v1.2.3 From c4e93ba5f1d003c442e3d56d6a0b3e80651dd6ec Mon Sep 17 00:00:00 2001 From: yuichi-ike Date: Thu, 21 May 2020 11:28:51 +0900 Subject: bug fixed --- src/python/doc/rips_complex_user.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/doc/rips_complex_user.rst b/src/python/doc/rips_complex_user.rst index eb2657df..ac11a4b6 100644 --- a/src/python/doc/rips_complex_user.rst +++ b/src/python/doc/rips_complex_user.rst @@ -407,7 +407,7 @@ DTM Rips Complex .. testcode:: import numpy as np - from dtm_rips_complex import DtmRipsComplex + from gudhi.dtm_rips_complex import DtmRipsComplex pts = np.array([[2.0, 2.0], [0.0, 1.0], [3.0, 4.0]]) dtm_rips = DtmRipsComplex(points=pts, k=2) st = dtm_rips.create_simplex_tree(max_dimension=2) -- cgit v1.2.3 From 2ccc5ea97a5979f80fec93863da5549e4e6f2eea Mon Sep 17 00:00:00 2001 From: yuichi-ike Date: Fri, 22 May 2020 10:22:31 +0900 Subject: class name changed, documents modified --- src/python/doc/rips_complex_ref.rst | 4 ++-- src/python/doc/rips_complex_user.rst | 8 +++++--- src/python/gudhi/dtm_rips_complex.py | 12 ++++++++---- src/python/test/test_dtm_rips_complex.py | 6 +++--- 4 files changed, 18 insertions(+), 12 deletions(-) (limited to 'src/python') diff --git a/src/python/doc/rips_complex_ref.rst b/src/python/doc/rips_complex_ref.rst index f781fd92..2aa6b268 100644 --- a/src/python/doc/rips_complex_ref.rst +++ b/src/python/doc/rips_complex_ref.rst @@ -32,9 +32,9 @@ Weighted Rips complex reference manual DTM Rips complex reference manual ================================= -.. autoclass:: gudhi.dtm_rips_complex.DtmRipsComplex +.. autoclass:: gudhi.dtm_rips_complex.DTMRipsComplex :members: :undoc-members: :show-inheritance: - .. automethod:: gudhi.dtm_rips_complex.DtmRipsComplex.__init__ \ No newline at end of file + .. automethod:: gudhi.dtm_rips_complex.DTMRipsComplex.__init__ \ No newline at end of file diff --git a/src/python/doc/rips_complex_user.rst b/src/python/doc/rips_complex_user.rst index ac11a4b6..450e6c1a 100644 --- a/src/python/doc/rips_complex_user.rst +++ b/src/python/doc/rips_complex_user.rst @@ -378,6 +378,7 @@ Example from a point cloud combined with DistanceToMeasure ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Combining with DistanceToMeasure, one can compute the DTM-filtration of a point set, as in `this notebook `_. +Remark that DTMRipsComplex class provides exactly this function. .. testcode:: @@ -402,14 +403,15 @@ The output is: DTM Rips Complex ---------------- -`DtmdRipsComplex `_ builds a simplicial complex from a point set or a full distence matrix (in the form of ndarray), as described in the above example. +`DTMRipsComplex `_ builds a simplicial complex from a point set or a full distence matrix (in the form of ndarray), as described in the above example. +This class constructs a weighted Rips complex giving larger weights to outliers, which reduces their impact on the persistence diagram. See `this notebook `_ for some experiments. .. testcode:: import numpy as np - from gudhi.dtm_rips_complex import DtmRipsComplex + from gudhi.dtm_rips_complex import DTMRipsComplex pts = np.array([[2.0, 2.0], [0.0, 1.0], [3.0, 4.0]]) - dtm_rips = DtmRipsComplex(points=pts, k=2) + dtm_rips = DTMRipsComplex(points=pts, k=2) st = dtm_rips.create_simplex_tree(max_dimension=2) print(st.persistence()) diff --git a/src/python/gudhi/dtm_rips_complex.py b/src/python/gudhi/dtm_rips_complex.py index 6d2f9f31..70c8e5dd 100644 --- a/src/python/gudhi/dtm_rips_complex.py +++ b/src/python/gudhi/dtm_rips_complex.py @@ -12,7 +12,7 @@ from gudhi.weighted_rips_complex import WeightedRipsComplex from gudhi.point_cloud.dtm import DistanceToMeasure from scipy.spatial.distance import cdist -class DtmRipsComplex(WeightedRipsComplex): +class DTMRipsComplex(WeightedRipsComplex): """ Class to generate a DTM Rips complex from a distance matrix or a point set, in the way described in :cite:`dtmfiltrations`. @@ -28,7 +28,7 @@ class DtmRipsComplex(WeightedRipsComplex): """ Args: points (Sequence[Sequence[float]]): list of points. - distance_matrix (ndarray): full distance matrix. + distance_matrix (numpy.ndarray): full distance matrix. k (int): number of neighbors for the computation of DTM. Defaults to 1, which is equivalent to the usual Rips complex. q (float): order used to compute the distance to measure. Defaults to 2. max_filtration (float): specifies the maximal filtration value to be considered. @@ -39,8 +39,12 @@ class DtmRipsComplex(WeightedRipsComplex): points=[] distance_matrix = cdist(points,points) self.distance_matrix = distance_matrix - dtm = DistanceToMeasure(k, q=q, metric="precomputed") + # TODO: address the error when k is too large - self.weights = dtm.fit_transform(distance_matrix) + if k <= 1: + self.weights = [0] * len(distance_matrix) + else: + dtm = DistanceToMeasure(k, q=q, metric="precomputed") + self.weights = dtm.fit_transform(distance_matrix) self.max_filtration = max_filtration diff --git a/src/python/test/test_dtm_rips_complex.py b/src/python/test/test_dtm_rips_complex.py index bc6e5a59..7cd2ad90 100644 --- a/src/python/test/test_dtm_rips_complex.py +++ b/src/python/test/test_dtm_rips_complex.py @@ -8,14 +8,14 @@ - YYYY/MM Author: Description of the modification """ -from gudhi.dtm_rips_complex import DtmRipsComplex +from gudhi.dtm_rips_complex import DTMRipsComplex import numpy as np from math import sqrt import pytest def test_dtm_rips_complex(): pts = np.array([[2.0, 2.0], [0.0, 1.0], [3.0, 4.0]]) - dtm_rips = DtmRipsComplex(points=pts, k=2) + dtm_rips = DTMRipsComplex(points=pts, k=2) st = dtm_rips.create_simplex_tree(max_dimension=2) st.persistence() persistence_intervals0 = st.persistence_intervals_in_dimension(0) @@ -23,7 +23,7 @@ def test_dtm_rips_complex(): def test_compatibility_with_rips(): distance_matrix = np.array([[0, 1, 1, sqrt(2)], [1, 0, sqrt(2), 1], [1, sqrt(2), 0, 1], [sqrt(2), 1, 1, 0]]) - dtm_rips = DtmRipsComplex(distance_matrix=distance_matrix, max_filtration=42) + dtm_rips = DTMRipsComplex(distance_matrix=distance_matrix, max_filtration=42) st = dtm_rips.create_simplex_tree(max_dimension=1) assert list(st.get_filtration()) == [ ([0], 0.0), -- cgit v1.2.3 From 55316205b2c7c2e3d7e3fe3ea92e20f3f8b29b11 Mon Sep 17 00:00:00 2001 From: yuichi-ike Date: Tue, 26 May 2020 18:22:14 +0900 Subject: test fixed, documents modified --- src/python/doc/rips_complex_user.rst | 6 ++++-- src/python/gudhi/dtm_rips_complex.py | 1 + src/python/test/test_dtm_rips_complex.py | 16 ++++------------ 3 files changed, 9 insertions(+), 14 deletions(-) (limited to 'src/python') diff --git a/src/python/doc/rips_complex_user.rst b/src/python/doc/rips_complex_user.rst index 450e6c1a..dd2f2cc0 100644 --- a/src/python/doc/rips_complex_user.rst +++ b/src/python/doc/rips_complex_user.rst @@ -378,7 +378,7 @@ Example from a point cloud combined with DistanceToMeasure ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Combining with DistanceToMeasure, one can compute the DTM-filtration of a point set, as in `this notebook `_. -Remark that DTMRipsComplex class provides exactly this function. +Remark that `DTMRipsComplex `_ class provides exactly this function. .. testcode:: @@ -400,10 +400,12 @@ The output is: [(0, (3.1622776601683795, inf)), (0, (3.1622776601683795, 5.39834563766817)), (0, (3.1622776601683795, 5.39834563766817))] +.. _dtm-rips-complex: + DTM Rips Complex ---------------- -`DTMRipsComplex `_ builds a simplicial complex from a point set or a full distence matrix (in the form of ndarray), as described in the above example. +`DTMRipsComplex `_ builds a simplicial complex from a point set or a full distance matrix (in the form of ndarray), as described in the above example. This class constructs a weighted Rips complex giving larger weights to outliers, which reduces their impact on the persistence diagram. See `this notebook `_ for some experiments. .. testcode:: diff --git a/src/python/gudhi/dtm_rips_complex.py b/src/python/gudhi/dtm_rips_complex.py index 70c8e5dd..d77ad36e 100644 --- a/src/python/gudhi/dtm_rips_complex.py +++ b/src/python/gudhi/dtm_rips_complex.py @@ -18,6 +18,7 @@ class DTMRipsComplex(WeightedRipsComplex): in the way described in :cite:`dtmfiltrations`. Remark that all the filtration values are doubled compared to the definition in the paper for the consistency with RipsComplex. + :Requires: `SciPy `_ """ def __init__(self, points=None, diff --git a/src/python/test/test_dtm_rips_complex.py b/src/python/test/test_dtm_rips_complex.py index 7cd2ad90..e1c0ee44 100644 --- a/src/python/test/test_dtm_rips_complex.py +++ b/src/python/test/test_dtm_rips_complex.py @@ -9,6 +9,7 @@ """ from gudhi.dtm_rips_complex import DTMRipsComplex +from gudhi import RipsComplex import numpy as np from math import sqrt import pytest @@ -25,16 +26,7 @@ def test_compatibility_with_rips(): distance_matrix = np.array([[0, 1, 1, sqrt(2)], [1, 0, sqrt(2), 1], [1, sqrt(2), 0, 1], [sqrt(2), 1, 1, 0]]) dtm_rips = DTMRipsComplex(distance_matrix=distance_matrix, max_filtration=42) st = dtm_rips.create_simplex_tree(max_dimension=1) - assert list(st.get_filtration()) == [ - ([0], 0.0), - ([1], 0.0), - ([2], 0.0), - ([3], 0.0), - ([0, 1], 1.0), - ([0, 2], 1.0), - ([1, 3], 1.0), - ([2, 3], 1.0), - ([1, 2], sqrt(2)), - ([0, 3], sqrt(2)), - ] + rips_complex = RipsComplex(distance_matrix=distance_matrix, max_edge_length=42) + st_from_rips = rips_complex.create_simplex_tree(max_dimension=1) + assert list(st.get_filtration()) == list(st_from_rips.get_filtration()) -- cgit v1.2.3 From a9e1f9bbb4b39bca0d59857f57f5182701532820 Mon Sep 17 00:00:00 2001 From: yuichi-ike Date: Thu, 28 May 2020 09:19:55 +0900 Subject: comment modified --- src/python/gudhi/dtm_rips_complex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/gudhi/dtm_rips_complex.py b/src/python/gudhi/dtm_rips_complex.py index d77ad36e..63c9b138 100644 --- a/src/python/gudhi/dtm_rips_complex.py +++ b/src/python/gudhi/dtm_rips_complex.py @@ -28,7 +28,7 @@ class DTMRipsComplex(WeightedRipsComplex): max_filtration=float('inf')): """ Args: - points (Sequence[Sequence[float]]): list of points. + points (numpy.ndarray): array of points. distance_matrix (numpy.ndarray): full distance matrix. k (int): number of neighbors for the computation of DTM. Defaults to 1, which is equivalent to the usual Rips complex. q (float): order used to compute the distance to measure. Defaults to 2. -- cgit v1.2.3 From 851afaab00a47f1469cb5819b4a26ea52bad988b Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 28 May 2020 08:34:33 +0200 Subject: sphinx-build workaround differently --- src/python/doc/python3-sphinx-build.py | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100755 src/python/doc/python3-sphinx-build.py (limited to 'src/python') diff --git a/src/python/doc/python3-sphinx-build.py b/src/python/doc/python3-sphinx-build.py deleted file mode 100755 index 84d158cf..00000000 --- a/src/python/doc/python3-sphinx-build.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python3 - -""" -Emulate sphinx-build for python3 -""" - -from sys import exit, argv -from sphinx import main - -if __name__ == '__main__': - exit(main(argv)) -- cgit v1.2.3 From 194cacad8dabf69f41f105917b1afff62348b4ec Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 28 May 2020 21:45:31 +0200 Subject: Remove this test as it fails under windows --- src/python/doc/nerve_gic_complex_user.rst | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/python') diff --git a/src/python/doc/nerve_gic_complex_user.rst b/src/python/doc/nerve_gic_complex_user.rst index 0e67fc78..abb7bf7a 100644 --- a/src/python/doc/nerve_gic_complex_user.rst +++ b/src/python/doc/nerve_gic_complex_user.rst @@ -99,9 +99,6 @@ the program output is: [-0.171433, 0.367393] [-0.909111, 0.745853] 0 interval(s) in dimension 1: - -.. testoutput:: - Nerve is of dimension 1 - 41 simplices - 21 vertices. [0] [1] -- cgit v1.2.3 From 47e5c110b6c647a8cb2069bd488fa45bb579cfeb Mon Sep 17 00:00:00 2001 From: ROUVREAU Vincent Date: Thu, 28 May 2020 22:01:35 +0200 Subject: just code, no test --- src/python/doc/nerve_gic_complex_user.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/python') diff --git a/src/python/doc/nerve_gic_complex_user.rst b/src/python/doc/nerve_gic_complex_user.rst index abb7bf7a..0b820abf 100644 --- a/src/python/doc/nerve_gic_complex_user.rst +++ b/src/python/doc/nerve_gic_complex_user.rst @@ -50,7 +50,7 @@ The cover C comes from the preimages of intervals (10 intervals with gain 0.3) covering the height function (coordinate 2), which are then refined into their connected components using the triangulation of the .OFF file. -.. testcode:: +.. code-block:: python import gudhi nerve_complex = gudhi.CoverComplex() -- cgit v1.2.3