Skip to content

Commit 71187b2

Browse files
authored
Fix bug in persim.bottleneck calculation (#75)
* 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
1 parent 112665d commit 71187b2

File tree

5 files changed

+24
-19
lines changed

5 files changed

+24
-19
lines changed

RELEASE.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
0.3.4
2+
- Fix bug of Issue #70 (https://github.com/scikit-tda/persim/issues/70).
3+
14
0.3.3
25
- Fix plotting methods of Persistence Landscapes, add doc strings.
36
- Update to notebooks.

docs/index.rst

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
|PyPI version| |Downloads| |Build Status| |Codecov| |License: MIT|
1+
|PyPI version| |Downloads| |Codecov| |License: MIT|
22

33
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
44

@@ -50,12 +50,10 @@ Documentation
5050
notebooks/Persistence Landscapes and Machine Learning
5151

5252

53-
.. |Downloads| image:: https://pypip.in/download/persim/badge.svg
53+
.. |Downloads| image:: https://img.shields.io/pypi/dm/persim
5454
:target: https://pypi.python.org/pypi/persim/
5555
.. |PyPI version| image:: https://badge.fury.io/py/persim.svg
5656
:target: https://badge.fury.io/py/persim
57-
.. |Build Status| image:: https://travis-ci.org/scikit-tda/persim.svg?branch=master
58-
:target: https://travis-ci.org/scikit-tda/persim
5957
.. |Codecov| image:: https://codecov.io/gh/scikit-tda/persim/branch/master/graph/badge.svg
6058
:target: https://codecov.io/gh/scikit-tda/persim
6159
.. |License: MIT| image:: https://img.shields.io/badge/License-MIT-yellow.svg

persim/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.3.3"
1+
__version__ = "0.3.4"

persim/bottleneck.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ def bottleneck(dgm1, dgm2, matching=False):
2727
2828
Parameters
2929
-----------
30-
dgm1: Mx(>=2)
30+
dgm1: Mx(>=2)
3131
array of birth/death pairs for PD 1
32-
dgm2: Nx(>=2)
32+
dgm2: Nx(>=2)
3333
array of birth/death paris for PD 2
3434
matching: bool, default False
3535
if True, return matching infromation and cross-similarity matrix
@@ -47,15 +47,13 @@ def bottleneck(dgm1, dgm2, matching=False):
4747
"""
4848

4949
return_matching = matching
50-
5150
S = np.array(dgm1)
5251
M = min(S.shape[0], S.size)
5352
if S.size > 0:
5453
S = S[np.isfinite(S[:, 1]), :]
5554
if S.shape[0] < M:
5655
warnings.warn(
57-
"dgm1 has points with non-finite death times;"+
58-
"ignoring those points"
56+
"dgm1 has points with non-finite death times;" + "ignoring those points"
5957
)
6058
M = S.shape[0]
6159
T = np.array(dgm2)
@@ -64,8 +62,7 @@ def bottleneck(dgm1, dgm2, matching=False):
6462
T = T[np.isfinite(T[:, 1]), :]
6563
if T.shape[0] < N:
6664
warnings.warn(
67-
"dgm2 has points with non-finite death times;"+
68-
"ignoring those points"
65+
"dgm2 has points with non-finite death times;" + "ignoring those points"
6966
)
7067
N = T.shape[0]
7168

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

10299
# Step 2: Perform a binary search + Hopcroft Karp to find the
103100
# bottleneck distance
104-
ds = np.sort(np.unique(D.flatten()))[0:-1] # Everything but np.inf
101+
ds = np.sort(np.unique(D.flatten())) # [0:-1] # Everything but np.inf
105102
bdist = ds[-1]
106103
matching = {}
107104
while len(ds) >= 1:
@@ -118,18 +115,18 @@ def bottleneck(dgm1, dgm2, matching=False):
118115
matching = res
119116
ds = ds[0:idx]
120117
else:
121-
ds = ds[idx + 1::]
118+
ds = ds[idx + 1 : :]
122119

123120
if return_matching:
124121
matchidx = []
125-
for i in range(M+N):
122+
for i in range(M + N):
126123
j = matching["{}".format(i)]
127124
d = D[i, j]
128125
if i < M:
129126
if j >= N:
130-
j = -1 # Diagonal match from first persistence diagram
127+
j = -1 # Diagonal match from first persistence diagram
131128
else:
132-
if j >= N: # Diagonal to diagonal, so don't include this
129+
if j >= N: # Diagonal to diagonal, so don't include this
133130
continue
134131
i = -1
135132
matchidx.append([i, j, d])

test/test_distances.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
import pytest
33
import scipy.sparse as sps
44

5-
from persim import (bottleneck, gromov_hausdorff, heat, sliced_wasserstein,
6-
wasserstein)
5+
from persim import bottleneck, gromov_hausdorff, heat, sliced_wasserstein, wasserstein
76

87

98
class TestBottleneck:
@@ -103,6 +102,14 @@ def test_repeated(self):
103102
dist = bottleneck(G, H)
104103
assert dist == 0.5
105104

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

107114
class TestWasserstein:
108115
def test_single(self):

0 commit comments

Comments
 (0)