diff --git a/RELEASE.txt b/RELEASE.txt index 2c95a56a..6929a5dd 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -1,6 +1,6 @@ 0.4.0 - Replace the abandoned GPLv3 `hopcroftkarp` dependency with `scipy.sparse.csgraph.maximum_bipartite_matching` in bottleneck, Issue #106 (https://github.com/scikit-tda/persim/issues/106). - - `bottleneck(..., matching=True)` may now return a different optimal matching where several exist. The distance returned is unchanged. + - `bottleneck(..., matching=True)` may now return a different optimal matching where several exist! The distance returned is unchanged. A UserWarning is now emitted on `matching=True` noting this; one-time notice for the 0.4.x series, will be removed in 0.5.0. 0.3.7 - Fix bug of Issue #81 (https://github.com/scikit-tda/persim/issues/81) diff --git a/persim/bottleneck.py b/persim/bottleneck.py index a22a27ed..c117b0a0 100644 --- a/persim/bottleneck.py +++ b/persim/bottleneck.py @@ -48,6 +48,15 @@ def bottleneck(dgm1, dgm2, matching=False): """ return_matching = matching + if return_matching: + warnings.warn( + "As of 0.4.0, bottleneck(..., matching=True) may return a different " + "optimal matching than earlier versions when several matchings tie " + "for the bottleneck distance; the distance itself is unaffected. " + "This is a one-time notice for the 0.4.x series and will be removed " + "in 0.5.0.", + UserWarning, + ) S = np.array(dgm1) M = min(S.shape[0], S.size) if S.size > 0: diff --git a/test/test_distances.py b/test/test_distances.py index 09c186b6..7f144275 100644 --- a/test/test_distances.py +++ b/test/test_distances.py @@ -1,3 +1,5 @@ +import warnings + import numpy as np import pytest import scipy.sparse as sps @@ -33,6 +35,21 @@ def test_different_size(self): d = bottleneck(np.array([[0.5, 1], [0.6, 1.1]]), np.array([[0.5, 1.1]])) assert d == 0.25 + def test_matching_true_warns_about_tie_breaking(self): + dgm1 = np.array([[0.5, 1], [0.6, 1.1]]) + dgm2 = np.array([[0.5, 1.1], [0.6, 1.3]]) + + with pytest.warns(UserWarning, match="optimal matching"): + bottleneck(dgm1, dgm2, matching=True) + + def test_matching_false_does_not_warn(self): + dgm1 = np.array([[0.5, 1], [0.6, 1.1]]) + dgm2 = np.array([[0.5, 1.1], [0.6, 1.3]]) + + with warnings.catch_warnings(): + warnings.simplefilter("error") + bottleneck(dgm1, dgm2, matching=False) + def test_matching(self): dgm1 = np.array([[0.5, 1], [0.6, 1.1]]) dgm2 = np.array(