From 47884e62e7027f545033280bce41982b5f3de00b Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Sun, 21 Jul 2024 18:38:46 -0400 Subject: [PATCH 1/9] Add test to catch warning divide-by-zero raised by process_diagonal --- tests/test_core.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/test_core.py b/tests/test_core.py index 0e84cf8c3..1a1d2a1df 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1,6 +1,7 @@ import functools import math import os +import warnings from unittest.mock import patch import naive @@ -1753,3 +1754,16 @@ def test_process_isconstant_2d(): T_subseq_isconstant_comp = core.process_isconstant(T, m, T_subseq_isconstant) npt.assert_array_equal(T_subseq_isconstant_ref, T_subseq_isconstant_comp) + + +def test_preprocess_diagonal_std_inverse(): + T = np.random.rand(64) + m = 3 + T[:m] = np.nan + + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + core.preprocess_diagonal(T, m) + for item in w: + if issubclass(item.category, RuntimeWarning): + assert "divide by zero encountered in divide" not in str(item.message) From 1977825f500e5c926fb51036156b1ed920215c7f Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Mon, 22 Jul 2024 18:36:17 -0400 Subject: [PATCH 2/9] Add code to resolve warning --- stumpy/core.py | 1 + tests/test_core.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/stumpy/core.py b/stumpy/core.py index af3bf7a3b..816331e90 100644 --- a/stumpy/core.py +++ b/stumpy/core.py @@ -2254,6 +2254,7 @@ def preprocess_diagonal( M_T, Σ_T = compute_mean_std(T, m) Σ_T[T_subseq_isconstant] = 1.0 # Avoid divide by zero in next inversion step + Σ_T[~T_subseq_isfinite] = 1.0 Σ_T_inverse = 1.0 / Σ_T M_T_m_1, _ = compute_mean_std(T, m - 1) diff --git a/tests/test_core.py b/tests/test_core.py index 1a1d2a1df..838f5ab4b 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -881,9 +881,11 @@ def test_preprocess_non_normalized(): def test_preprocess_diagonal(): T = np.array([0, np.nan, 2, 3, 4, 5, 6, 7, np.inf, 9]) m = 3 + T_subseq_isfinite = core.rolling_isfinite(T, m) ref_T = np.array([0, 0, 2, 3, 4, 5, 6, 7, 0, 9], dtype=float) ref_M, ref_Σ = naive.compute_mean_std(ref_T, m) + ref_Σ[~T_subseq_isfinite] = 1.0 ref_Σ_inverse = 1.0 / ref_Σ ref_M_m_1, _ = naive.compute_mean_std(ref_T, m - 1) From 096b33270e46fec0375ce2fab393e723a9c31322 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Tue, 23 Jul 2024 18:43:47 -0400 Subject: [PATCH 3/9] set std of non-finite subseq to np.nan to avoid divide by 0 warning --- stumpy/core.py | 2 +- tests/test_core.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/stumpy/core.py b/stumpy/core.py index 816331e90..085397296 100644 --- a/stumpy/core.py +++ b/stumpy/core.py @@ -2254,7 +2254,7 @@ def preprocess_diagonal( M_T, Σ_T = compute_mean_std(T, m) Σ_T[T_subseq_isconstant] = 1.0 # Avoid divide by zero in next inversion step - Σ_T[~T_subseq_isfinite] = 1.0 + Σ_T[~T_subseq_isfinite] = np.nan Σ_T_inverse = 1.0 / Σ_T M_T_m_1, _ = compute_mean_std(T, m - 1) diff --git a/tests/test_core.py b/tests/test_core.py index 838f5ab4b..4a701d8c3 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -885,7 +885,7 @@ def test_preprocess_diagonal(): ref_T = np.array([0, 0, 2, 3, 4, 5, 6, 7, 0, 9], dtype=float) ref_M, ref_Σ = naive.compute_mean_std(ref_T, m) - ref_Σ[~T_subseq_isfinite] = 1.0 + ref_Σ[~T_subseq_isfinite] = np.nan ref_Σ_inverse = 1.0 / ref_Σ ref_M_m_1, _ = naive.compute_mean_std(ref_T, m - 1) From f154e2e29a8f6f7341096f484fe131997063b7ab Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Wed, 24 Jul 2024 22:40:28 -0400 Subject: [PATCH 4/9] add test for divide-by-zero warning --- tests/test_core.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/tests/test_core.py b/tests/test_core.py index 4a701d8c3..01267251e 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1,7 +1,6 @@ import functools import math import os -import warnings from unittest.mock import patch import naive @@ -1758,14 +1757,11 @@ def test_process_isconstant_2d(): npt.assert_array_equal(T_subseq_isconstant_ref, T_subseq_isconstant_comp) -def test_preprocess_diagonal_std_inverse(): +@pytest.mark.filterwarnings( + "error:divide by zero encountered in divide", category=RuntimeWarning +) +def test_preprocess_diagonal_divide_by_zero(): T = np.random.rand(64) m = 3 T[:m] = np.nan - - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always") - core.preprocess_diagonal(T, m) - for item in w: - if issubclass(item.category, RuntimeWarning): - assert "divide by zero encountered in divide" not in str(item.message) + core.preprocess_diagonal(T, m) From f1e250a5ce3f590a7bbb4d1ff2a58649710d9f6b Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Thu, 25 Jul 2024 08:24:54 -0400 Subject: [PATCH 5/9] add test to capture divide-by-zero warning in ostinato --- tests/test_ostinato.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test_ostinato.py b/tests/test_ostinato.py index 7916a34d8..542fc8adb 100644 --- a/tests/test_ostinato.py +++ b/tests/test_ostinato.py @@ -249,3 +249,13 @@ def test_extract_several_consensus_ostinatoed(dask_cluster): Ts_ref[i][np.isfinite(Ts_ref[i])], Ts_comp[i][np.isfinite(Ts_comp[i])], ) + + +@pytest.mark.filterwarnings( + "error:divide by zero encountered in divide", category=RuntimeWarning +) +def test_ostinato_divide_by_zero(): + Ts = [np.random.rand(n) for n in [64, 128, 256]] + m = 5 + Ts[0][:m] = np.nan + stumpy.ostinato(Ts, m) From 09b7fa8bd3b50fc0a542d3b6b13409850103314d Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Thu, 25 Jul 2024 08:33:04 -0400 Subject: [PATCH 6/9] Fix the divide-by-zero warning caused by passing processed data to stump --- stumpy/ostinato.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/stumpy/ostinato.py b/stumpy/ostinato.py index 424da525f..4dd6a2e85 100644 --- a/stumpy/ostinato.py +++ b/stumpy/ostinato.py @@ -58,10 +58,9 @@ def _across_series_nearest_neighbors( nns_subseq_idx = np.zeros(k, dtype=np.int64) for i in range(k): - QT = core.sliding_dot_product(Ts[Ts_idx][subseq_idx : subseq_idx + m], Ts[i]) - distance_profile = core._mass( - Q, - Ts[i], + QT = core.sliding_dot_product(Q, Ts[i]) + distance_profile = core.calculate_distance_profile( + m, QT, M_Ts[Ts_idx][subseq_idx], Σ_Ts[Ts_idx][subseq_idx], @@ -256,9 +255,8 @@ def _ostinato( ( radius, np.min( - core._mass( - Ts[j][q : q + m], - Ts[i], + core.calculate_distance_profile( + m, QT, M_Ts[j][q], Σ_Ts[j][q], @@ -373,9 +371,10 @@ def ostinato(Ts, m, normalize=True, p=2.0, Ts_subseq_isconstant=None): Ts_subseq_isconstant = [None] * len(Ts) for i, T in enumerate(Ts): - Ts_copy[i], M_Ts[i], Σ_Ts[i], Ts_subseq_isconstant[i] = core.preprocess( + _, M_Ts[i], Σ_Ts[i], Ts_subseq_isconstant[i] = core.preprocess( T, m, copy=True, T_subseq_isconstant=Ts_subseq_isconstant[i] ) + Ts_copy[i] = T.copy() bsf_radius, bsf_Ts_idx, bsf_subseq_idx = _ostinato( Ts_copy, m, M_Ts, Σ_Ts, Ts_subseq_isconstant From 408441503731a3510d30de5704960935c60c8540 Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Thu, 25 Jul 2024 08:39:11 -0400 Subject: [PATCH 7/9] add test for ostinatoed to capture divide by zero warning and fix code --- stumpy/ostinato.py | 3 ++- tests/test_ostinato.py | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/stumpy/ostinato.py b/stumpy/ostinato.py index 4dd6a2e85..746c8ea0e 100644 --- a/stumpy/ostinato.py +++ b/stumpy/ostinato.py @@ -515,9 +515,10 @@ def ostinatoed(client, Ts, m, normalize=True, p=2.0, Ts_subseq_isconstant=None): if Ts_subseq_isconstant is None: Ts_subseq_isconstant = [None] * len(Ts) for i, T in enumerate(Ts): - Ts_copy[i], M_Ts[i], Σ_Ts[i], Ts_subseq_isconstant[i] = core.preprocess( + _, M_Ts[i], Σ_Ts[i], Ts_subseq_isconstant[i] = core.preprocess( T, m, copy=True, T_subseq_isconstant=Ts_subseq_isconstant[i] ) + Ts_copy[i] = T.copy() bsf_radius, bsf_Ts_idx, bsf_subseq_idx = _ostinato( Ts_copy, diff --git a/tests/test_ostinato.py b/tests/test_ostinato.py index 542fc8adb..dbc5ceb06 100644 --- a/tests/test_ostinato.py +++ b/tests/test_ostinato.py @@ -259,3 +259,14 @@ def test_ostinato_divide_by_zero(): m = 5 Ts[0][:m] = np.nan stumpy.ostinato(Ts, m) + + +@pytest.mark.filterwarnings( + "error:divide by zero encountered in divide", category=RuntimeWarning +) +def test_ostinatoed_divide_by_zero(dask_cluster): + Ts = [np.random.rand(n) for n in [64, 128, 256]] + m = 5 + Ts[0][:m] = np.nan + with Client(dask_cluster) as dask_client: + stumpy.ostinatoed(dask_client, Ts, m) From c5cc377c1f42e11f0c5f099bda3517669e84f7dd Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Thu, 25 Jul 2024 08:42:35 -0400 Subject: [PATCH 8/9] Rename test functions for sake of consistency --- tests/test_ostinato.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_ostinato.py b/tests/test_ostinato.py index dbc5ceb06..7e0181de5 100644 --- a/tests/test_ostinato.py +++ b/tests/test_ostinato.py @@ -254,7 +254,7 @@ def test_extract_several_consensus_ostinatoed(dask_cluster): @pytest.mark.filterwarnings( "error:divide by zero encountered in divide", category=RuntimeWarning ) -def test_ostinato_divide_by_zero(): +def test_divide_by_zero_ostinato(): Ts = [np.random.rand(n) for n in [64, 128, 256]] m = 5 Ts[0][:m] = np.nan @@ -264,7 +264,7 @@ def test_ostinato_divide_by_zero(): @pytest.mark.filterwarnings( "error:divide by zero encountered in divide", category=RuntimeWarning ) -def test_ostinatoed_divide_by_zero(dask_cluster): +def test_divide_by_zero_ostinatoed(dask_cluster): Ts = [np.random.rand(n) for n in [64, 128, 256]] m = 5 Ts[0][:m] = np.nan From 5e056d31c4dffaa305b91d6bb9e85a503f314dfb Mon Sep 17 00:00:00 2001 From: NimaSarajpoor Date: Thu, 25 Jul 2024 20:10:24 -0400 Subject: [PATCH 9/9] minor change to fix the computed joint matrix profile --- stumpy/gpu_ostinato.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stumpy/gpu_ostinato.py b/stumpy/gpu_ostinato.py index cdcda2e5a..5effc933b 100644 --- a/stumpy/gpu_ostinato.py +++ b/stumpy/gpu_ostinato.py @@ -113,9 +113,10 @@ def gpu_ostinato(Ts, m, device_id=0, normalize=True, p=2.0, Ts_subseq_isconstant M_Ts = [None] * len(Ts) Σ_Ts = [None] * len(Ts) for i, T in enumerate(Ts): - Ts_copy[i], M_Ts[i], Σ_Ts[i], Ts_subseq_isconstant[i] = core.preprocess( + _, M_Ts[i], Σ_Ts[i], Ts_subseq_isconstant[i] = core.preprocess( T, m, copy=True, T_subseq_isconstant=Ts_subseq_isconstant[i] ) + Ts_copy[i] = T.copy() bsf_radius, bsf_Ts_idx, bsf_subseq_idx = _ostinato( Ts_copy,