Skip to content

Commit

Permalink
Fix bug in persim.bottleneck calculation (#75)
Browse files Browse the repository at this point in the history
* Add issue test

* Remove modificatin of ds

* Bump version, fix broken badges in docs

* Bump version, add tests

* Modify test for matching shape

* Remove old travis badge
  • Loading branch information
catanzaromj authored Feb 25, 2024
1 parent 112665d commit 71187b2
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 19 deletions.
3 changes: 3 additions & 0 deletions RELEASE.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
0.3.4
- Fix bug of Issue #70 (https://github.com/scikit-tda/persim/issues/70).

0.3.3
- Fix plotting methods of Persistence Landscapes, add doc strings.
- Update to notebooks.
Expand Down
6 changes: 2 additions & 4 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
|PyPI version| |Downloads| |Build Status| |Codecov| |License: MIT|
|PyPI version| |Downloads| |Codecov| |License: MIT|

Persim is a Python package for many tools used in analyzing Persistence Diagrams. It currently includes implementations of most of the popular methods of working with persistence diagrams, including

Expand Down Expand Up @@ -50,12 +50,10 @@ Documentation
notebooks/Persistence Landscapes and Machine Learning


.. |Downloads| image:: https://pypip.in/download/persim/badge.svg
.. |Downloads| image:: https://img.shields.io/pypi/dm/persim
:target: https://pypi.python.org/pypi/persim/
.. |PyPI version| image:: https://badge.fury.io/py/persim.svg
:target: https://badge.fury.io/py/persim
.. |Build Status| image:: https://travis-ci.org/scikit-tda/persim.svg?branch=master
:target: https://travis-ci.org/scikit-tda/persim
.. |Codecov| image:: https://codecov.io/gh/scikit-tda/persim/branch/master/graph/badge.svg
:target: https://codecov.io/gh/scikit-tda/persim
.. |License: MIT| image:: https://img.shields.io/badge/License-MIT-yellow.svg
Expand Down
2 changes: 1 addition & 1 deletion persim/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.3.3"
__version__ = "0.3.4"
21 changes: 9 additions & 12 deletions persim/bottleneck.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ def bottleneck(dgm1, dgm2, matching=False):
Parameters
-----------
dgm1: Mx(>=2)
dgm1: Mx(>=2)
array of birth/death pairs for PD 1
dgm2: Nx(>=2)
dgm2: Nx(>=2)
array of birth/death paris for PD 2
matching: bool, default False
if True, return matching infromation and cross-similarity matrix
Expand All @@ -47,15 +47,13 @@ def bottleneck(dgm1, dgm2, matching=False):
"""

return_matching = matching

S = np.array(dgm1)
M = min(S.shape[0], S.size)
if S.size > 0:
S = S[np.isfinite(S[:, 1]), :]
if S.shape[0] < M:
warnings.warn(
"dgm1 has points with non-finite death times;"+
"ignoring those points"
"dgm1 has points with non-finite death times;" + "ignoring those points"
)
M = S.shape[0]
T = np.array(dgm2)
Expand All @@ -64,8 +62,7 @@ def bottleneck(dgm1, dgm2, matching=False):
T = T[np.isfinite(T[:, 1]), :]
if T.shape[0] < N:
warnings.warn(
"dgm2 has points with non-finite death times;"+
"ignoring those points"
"dgm2 has points with non-finite death times;" + "ignoring those points"
)
N = T.shape[0]

Expand Down Expand Up @@ -101,7 +98,7 @@ def bottleneck(dgm1, dgm2, matching=False):

# Step 2: Perform a binary search + Hopcroft Karp to find the
# bottleneck distance
ds = np.sort(np.unique(D.flatten()))[0:-1] # Everything but np.inf
ds = np.sort(np.unique(D.flatten())) # [0:-1] # Everything but np.inf
bdist = ds[-1]
matching = {}
while len(ds) >= 1:
Expand All @@ -118,18 +115,18 @@ def bottleneck(dgm1, dgm2, matching=False):
matching = res
ds = ds[0:idx]
else:
ds = ds[idx + 1::]
ds = ds[idx + 1 : :]

if return_matching:
matchidx = []
for i in range(M+N):
for i in range(M + N):
j = matching["{}".format(i)]
d = D[i, j]
if i < M:
if j >= N:
j = -1 # Diagonal match from first persistence diagram
j = -1 # Diagonal match from first persistence diagram
else:
if j >= N: # Diagonal to diagonal, so don't include this
if j >= N: # Diagonal to diagonal, so don't include this
continue
i = -1
matchidx.append([i, j, d])
Expand Down
11 changes: 9 additions & 2 deletions test/test_distances.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
import pytest
import scipy.sparse as sps

from persim import (bottleneck, gromov_hausdorff, heat, sliced_wasserstein,
wasserstein)
from persim import bottleneck, gromov_hausdorff, heat, sliced_wasserstein, wasserstein


class TestBottleneck:
Expand Down Expand Up @@ -103,6 +102,14 @@ def test_repeated(self):
dist = bottleneck(G, H)
assert dist == 0.5

def test_one_diagonal(self):
# Issue #70: https://github.com/scikit-tda/persim/issues/70
dgm1 = np.array([[0, 10]])
dgm2 = np.array([[5, 5]])
dist, returned_matching = bottleneck(dgm1, dgm2, matching=True)
assert dist == 5.0
assert returned_matching.shape[1] == 3


class TestWasserstein:
def test_single(self):
Expand Down

0 comments on commit 71187b2

Please sign in to comment.