From cb8a80147a32485d4a706985958aace8f94ab5f5 Mon Sep 17 00:00:00 2001 From: Sean Law Date: Fri, 24 Jul 2026 22:21:47 -0400 Subject: [PATCH 1/4] Initial commit - add failing tests cases --- tests/test_precision.py | 51 +++++++++++------------------------------ 1 file changed, 13 insertions(+), 38 deletions(-) diff --git a/tests/test_precision.py b/tests/test_precision.py index 043406bba..fb38b50cd 100644 --- a/tests/test_precision.py +++ b/tests/test_precision.py @@ -2,13 +2,12 @@ from unittest.mock import patch import naive -import numba import numpy as np import numpy.testing as npt import pytest from numba import cuda -from stumpy import cache, config, core, fastmath, rng, sdp +from stumpy import config, core, rng, sdp if cuda.is_available(): from stumpy.gpu_stump import gpu_stump @@ -118,18 +117,19 @@ def test_calculate_squared_distance(): npt.assert_almost_equal(ref, comp, decimal=14) -def test_snippets(): +@pytest.mark.parametrize( + "seed, m, k, s", [(2135137202, 10, 3, 3), (2636, 9, 3, 3), (332, 10, 3, 3)] +) +def test_snippets(seed, m, k, s): # This test function raises an error if there is a considerable loss of precision # that violates the symmetry property of a distance measure. - m = 10 - k = 3 - s = 3 - with rng.fix_seed(332): - T = rng.RNG.uniform(-1000.0, 1000.0, [64]) + with rng.fix_seed(seed): + T = rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64) isconstant_custom_func = functools.partial( naive.isconstant_func_stddev_threshold, quantile_threshold=0.05 ) + ( ref_snippets, ref_indices, @@ -138,9 +138,12 @@ def test_snippets(): ref_areas, ref_regimes, ) = naive.mpdist_snippets( - T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func + T, + m, + k, + s=s, + mpdist_T_subseq_isconstant=isconstant_custom_func, ) - ( cmp_snippets, cmp_indices, @@ -150,29 +153,6 @@ def test_snippets(): cmp_regimes, ) = snippets(T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func) - if ( - not np.allclose(ref_snippets, cmp_snippets) and not numba.config.DISABLE_JIT - ): # pragma: no cover - # Revise fastmath flags by removing reassoc (to improve precision), - # recompile njit functions, and re-compute snippets. - fastmath._set( - "core", - "_calculate_squared_distance", - {"nsz", "arcp", "contract", "afn"}, - ) - cache._recompile() - - ( - cmp_snippets, - cmp_indices, - cmp_profiles, - cmp_fractions, - cmp_areas, - cmp_regimes, - ) = snippets( - T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func - ) - npt.assert_almost_equal( ref_snippets, cmp_snippets, decimal=config.STUMPY_TEST_PRECISION ) @@ -190,11 +170,6 @@ def test_snippets(): ) npt.assert_almost_equal(ref_regimes, cmp_regimes) - if not numba.config.DISABLE_JIT: # pragma: no cover - # Revert fastmath flag back to their default values - fastmath._reset("core", "_calculate_squared_distance") - cache._recompile() - @pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning) @patch("stumpy.config.STUMPY_THREADS_PER_BLOCK", TEST_THREADS_PER_BLOCK) From 9f2370f08392b60b2289b34e0edcd2565e9770d5 Mon Sep 17 00:00:00 2001 From: Sean Law Date: Fri, 24 Jul 2026 23:17:15 -0400 Subject: [PATCH 2/4] Refactored and fixed all failing snippets unit tests --- tests/naive.py | 26 ++++++++++++++++---------- tests/test_precision.py | 11 ++++++++++- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/tests/naive.py b/tests/naive.py index 26667aa32..b9cd569d5 100644 --- a/tests/naive.py +++ b/tests/naive.py @@ -1591,16 +1591,18 @@ def mpdist_snippets( mpdist_percentage=0.05, mpdist_k=None, mpdist_T_subseq_isconstant=None, + D=None, ): - D = get_all_mpdist_profiles( - T, - m, - percentage, - s, - mpdist_percentage, - mpdist_k, - mpdist_T_subseq_isconstant=mpdist_T_subseq_isconstant, - ) + if D is None: + D = get_all_mpdist_profiles( + T, + m, + percentage, + s, + mpdist_percentage, + mpdist_k, + mpdist_T_subseq_isconstant=mpdist_T_subseq_isconstant, + ) snippets = np.empty((k, m)) snippets_indices = np.empty(k, dtype=np.int64) @@ -1718,8 +1720,12 @@ def aampdist_snippets( mpdist_percentage=0.05, mpdist_k=None, p=2.0, + D=None, ): - D = get_all_aampdist_profiles(T, m, percentage, s, mpdist_percentage, mpdist_k, p=p) + if D is None: + D = get_all_aampdist_profiles( + T, m, percentage, s, mpdist_percentage, mpdist_k, p=p + ) pad_width = (0, int(m * np.ceil(T.shape[0] / m) - T.shape[0])) T_padded = np.pad(T, pad_width, mode="constant", constant_values=np.nan) diff --git a/tests/test_precision.py b/tests/test_precision.py index fb38b50cd..aa0befe05 100644 --- a/tests/test_precision.py +++ b/tests/test_precision.py @@ -13,7 +13,8 @@ from stumpy.gpu_stump import gpu_stump else: # pragma: no cover from stumpy.core import _gpu_stump_driver_not_found as gpu_stump # noqa: F401 -from stumpy.snippets import snippets + +from stumpy.snippets import _get_all_profiles, snippets try: from numba.errors import NumbaPerformanceWarning @@ -130,6 +131,13 @@ def test_snippets(seed, m, k, s): naive.isconstant_func_stddev_threshold, quantile_threshold=0.05 ) + D = _get_all_profiles( + T, + m, + s=s, + mpdist_T_subseq_isconstant=isconstant_custom_func, + ) + ( ref_snippets, ref_indices, @@ -143,6 +151,7 @@ def test_snippets(seed, m, k, s): k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func, + D=D, ) ( cmp_snippets, From 97e317c5de778a51c6b5ffa8c19a19969bf1e2fe Mon Sep 17 00:00:00 2001 From: Sean Law Date: Sat, 25 Jul 2026 22:24:15 -0400 Subject: [PATCH 3/4] Final commit --- tests/naive.py | 4 +- tests/test_aampdist_snippets.py | 84 +++++++++++++++++++++++++++------ tests/test_precision.py | 2 - tests/test_snippets.py | 33 +++++++++++-- 4 files changed, 101 insertions(+), 22 deletions(-) diff --git a/tests/naive.py b/tests/naive.py index b9cd569d5..31fb2e150 100644 --- a/tests/naive.py +++ b/tests/naive.py @@ -1593,7 +1593,7 @@ def mpdist_snippets( mpdist_T_subseq_isconstant=None, D=None, ): - if D is None: + if D is None: # pragma: no cover D = get_all_mpdist_profiles( T, m, @@ -1722,7 +1722,7 @@ def aampdist_snippets( p=2.0, D=None, ): - if D is None: + if D is None: # pragma: no cover D = get_all_aampdist_profiles( T, m, percentage, s, mpdist_percentage, mpdist_k, p=p ) diff --git a/tests/test_aampdist_snippets.py b/tests/test_aampdist_snippets.py index c5ed74183..07655583d 100644 --- a/tests/test_aampdist_snippets.py +++ b/tests/test_aampdist_snippets.py @@ -4,7 +4,7 @@ import pytest from stumpy import config, rng -from stumpy.aampdist_snippets import aampdist_snippets +from stumpy.aampdist_snippets import _get_all_aampdist_profiles, aampdist_snippets test_data = [rng.RNG.uniform(-1000, 1000, size=64).astype(np.float64)] s = [6, 7, 8] @@ -13,21 +13,55 @@ k = [1, 2, 3] +@pytest.mark.parametrize("T", test_data) +@pytest.mark.parametrize("m", m) +def test_get_all_aampdist_profiles(T, m): + ref_profiles = naive.get_all_aampdist_profiles(T, m) + cmp_profiles = _get_all_aampdist_profiles(T, m) + + npt.assert_almost_equal( + ref_profiles, cmp_profiles, decimal=config.STUMPY_TEST_PRECISION + ) + + +@pytest.mark.parametrize("T", test_data) +@pytest.mark.parametrize("m", m) +@pytest.mark.parametrize("s", s) +def test_get_all_aampdist_profiles_s(T, m, s): + ref_profiles = naive.get_all_aampdist_profiles(T, m, s=s) + cmp_profiles = _get_all_aampdist_profiles(T, m, s=s) + + npt.assert_almost_equal( + ref_profiles, cmp_profiles, decimal=config.STUMPY_TEST_PRECISION + ) + + @pytest.mark.parametrize("T", test_data) @pytest.mark.parametrize("m", m) @pytest.mark.parametrize("k", k) def test_aampdist_snippets(T, m, k): for p in [1.0, 2.0, 3.0]: + D = _get_all_aampdist_profiles( + T, + m, + p=p, + ) ( - ref_snippets, + ref_aampdist_snippets, ref_indices, ref_profiles, ref_fractions, ref_areas, ref_regimes, - ) = naive.aampdist_snippets(T, m, k, p=p) + ) = naive.aampdist_snippets( + T, + m, + k, + p=p, + D=D, + ) ( - cmp_snippets, + cmp_aampdist_snippets, cmp_indices, cmp_profiles, cmp_fractions, @@ -36,7 +70,9 @@ def test_aampdist_snippets(T, m, k): ) = aampdist_snippets(T, m, k, p=p) npt.assert_almost_equal( - ref_snippets, cmp_snippets, decimal=config.STUMPY_TEST_PRECISION + ref_aampdist_snippets, + cmp_aampdist_snippets, + decimal=config.STUMPY_TEST_PRECISION, ) npt.assert_almost_equal( ref_indices, cmp_indices, decimal=config.STUMPY_TEST_PRECISION @@ -57,17 +93,22 @@ def test_aampdist_snippets(T, m, k): @pytest.mark.parametrize("m", m) @pytest.mark.parametrize("k", k) @pytest.mark.parametrize("percentage", percentage) -def test_mpdist_snippets_percentage(T, m, k, percentage): +def test_aampdist_snippets_percentage(T, m, k, percentage): + D = _get_all_aampdist_profiles( + T, + m, + percentage=percentage, + ) ( - ref_snippets, + ref_aampdist_snippets, ref_indices, ref_profiles, ref_fractions, ref_areas, ref_regimes, - ) = naive.aampdist_snippets(T, m, k, percentage=percentage) + ) = naive.aampdist_snippets(T, m, k, percentage=percentage, D=D) ( - cmp_snippets, + cmp_aampdist_snippets, cmp_indices, cmp_profiles, cmp_fractions, @@ -76,7 +117,9 @@ def test_mpdist_snippets_percentage(T, m, k, percentage): ) = aampdist_snippets(T, m, k, percentage=percentage) npt.assert_almost_equal( - ref_snippets, cmp_snippets, decimal=config.STUMPY_TEST_PRECISION + ref_aampdist_snippets, + cmp_aampdist_snippets, + decimal=config.STUMPY_TEST_PRECISION, ) npt.assert_almost_equal( ref_indices, cmp_indices, decimal=config.STUMPY_TEST_PRECISION @@ -98,16 +141,27 @@ def test_mpdist_snippets_percentage(T, m, k, percentage): @pytest.mark.parametrize("k", k) @pytest.mark.parametrize("s", s) def test_aampdist_snippets_s(T, m, k, s): + D = _get_all_aampdist_profiles( + T, + m, + s=s, + ) ( - ref_snippets, + ref_aampdist_snippets, ref_indices, ref_profiles, ref_fractions, ref_areas, ref_regimes, - ) = naive.aampdist_snippets(T, m, k, s=s) + ) = naive.aampdist_snippets( + T, + m, + k, + s=s, + D=D, + ) ( - cmp_snippets, + cmp_aampdist_snippets, cmp_indices, cmp_profiles, cmp_fractions, @@ -116,7 +170,9 @@ def test_aampdist_snippets_s(T, m, k, s): ) = aampdist_snippets(T, m, k, s=s) npt.assert_almost_equal( - ref_snippets, cmp_snippets, decimal=config.STUMPY_TEST_PRECISION + ref_aampdist_snippets, + cmp_aampdist_snippets, + decimal=config.STUMPY_TEST_PRECISION, ) npt.assert_almost_equal( ref_indices, cmp_indices, decimal=config.STUMPY_TEST_PRECISION diff --git a/tests/test_precision.py b/tests/test_precision.py index aa0befe05..536b90270 100644 --- a/tests/test_precision.py +++ b/tests/test_precision.py @@ -122,8 +122,6 @@ def test_calculate_squared_distance(): "seed, m, k, s", [(2135137202, 10, 3, 3), (2636, 9, 3, 3), (332, 10, 3, 3)] ) def test_snippets(seed, m, k, s): - # This test function raises an error if there is a considerable loss of precision - # that violates the symmetry property of a distance measure. with rng.fix_seed(seed): T = rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64) diff --git a/tests/test_snippets.py b/tests/test_snippets.py index c57e0d085..63a3f3e47 100644 --- a/tests/test_snippets.py +++ b/tests/test_snippets.py @@ -72,6 +72,10 @@ def test_get_all_mpdist_profiles_with_isconstant(T, m): @pytest.mark.parametrize("m", m) @pytest.mark.parametrize("k", k) def test_mpdist_snippets(T, m, k): + D = _get_all_profiles( + T, + m, + ) ( ref_snippets, ref_indices, @@ -79,7 +83,7 @@ def test_mpdist_snippets(T, m, k): ref_fractions, ref_areas, ref_regimes, - ) = naive.mpdist_snippets(T, m, k) + ) = naive.mpdist_snippets(T, m, k, D=D) ( cmp_snippets, cmp_indices, @@ -110,6 +114,11 @@ def test_mpdist_snippets(T, m, k): @pytest.mark.parametrize("k", k) @pytest.mark.parametrize("percentage", percentage) def test_mpdist_snippets_percentage(T, m, k, percentage): + D = _get_all_profiles( + T, + m, + percentage=percentage, + ) ( ref_snippets, ref_indices, @@ -117,7 +126,7 @@ def test_mpdist_snippets_percentage(T, m, k, percentage): ref_fractions, ref_areas, ref_regimes, - ) = naive.mpdist_snippets(T, m, k, percentage=percentage) + ) = naive.mpdist_snippets(T, m, k, percentage=percentage, D=D) ( cmp_snippets, cmp_indices, @@ -148,6 +157,11 @@ def test_mpdist_snippets_percentage(T, m, k, percentage): @pytest.mark.parametrize("k", k) @pytest.mark.parametrize("s", s) def test_mpdist_snippets_s(T, m, k, s): + D = _get_all_profiles( + T, + m, + s=s, + ) ( ref_snippets, ref_indices, @@ -155,7 +169,7 @@ def test_mpdist_snippets_s(T, m, k, s): ref_fractions, ref_areas, ref_regimes, - ) = naive.mpdist_snippets(T, m, k, s=s) + ) = naive.mpdist_snippets(T, m, k, s=s, D=D) ( cmp_snippets, cmp_indices, @@ -189,6 +203,12 @@ def test_mpdist_snippets_s_with_isconstant(T, m, k, s): isconstant_custom_func = functools.partial( naive.isconstant_func_stddev_threshold, quantile_threshold=0.05 ) + D = _get_all_profiles( + T, + m, + s=s, + mpdist_T_subseq_isconstant=isconstant_custom_func, + ) ( ref_snippets, ref_indices, @@ -197,7 +217,12 @@ def test_mpdist_snippets_s_with_isconstant(T, m, k, s): ref_areas, ref_regimes, ) = naive.mpdist_snippets( - T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func + T, + m, + k, + s=s, + mpdist_T_subseq_isconstant=isconstant_custom_func, + D=D, ) ( cmp_snippets, From 455426df31946642e6a29e467064e7e42e31f6b0 Mon Sep 17 00:00:00 2001 From: Sean Law Date: Sat, 25 Jul 2026 22:30:02 -0400 Subject: [PATCH 4/4] Added an additional unit test --- tests/test_precision.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_precision.py b/tests/test_precision.py index 536b90270..9ab92580a 100644 --- a/tests/test_precision.py +++ b/tests/test_precision.py @@ -119,7 +119,8 @@ def test_calculate_squared_distance(): @pytest.mark.parametrize( - "seed, m, k, s", [(2135137202, 10, 3, 3), (2636, 9, 3, 3), (332, 10, 3, 3)] + "seed, m, k, s", + [(2135137202, 10, 3, 3), (2636, 9, 3, 3), (332, 10, 3, 3), (1615, 10, 3, 3)], ) def test_snippets(seed, m, k, s): with rng.fix_seed(seed): @@ -197,7 +198,7 @@ def test_distance_symmetry_property_in_gpu(): # This test raises an error if arithmetic operation in ... # ... `gpu_stump._compute_and_update_PI_kernel` does not - # generates the same result if values of variable for mean and std + # generate the same result if values of variable for mean and std # are swapped. T_A = T[i : i + m]