diff --git a/conftest.py b/conftest.py index fe4951163..d0d9387d8 100644 --- a/conftest.py +++ b/conftest.py @@ -4,3 +4,15 @@ # to fix eventual module import errors that can arise, for example when # running tests from inside VS code. # See https://stackoverflow.com/a/34520971 + +from stumpy import rng + + +def pytest_configure(config): + """ + Called after command line options have been parsed + and all plugins and initial conftest files been loaded. + """ + # rng.set_seed(seed) # Replace this with your failed unit test seed + + print(f"conftest.py: rng.set_seed({rng.SEED})") diff --git a/stumpy/floss.py b/stumpy/floss.py index d73912154..e740597ab 100644 --- a/stumpy/floss.py +++ b/stumpy/floss.py @@ -7,7 +7,7 @@ import numpy as np import scipy.stats -from . import config, core +from . import config, core, rng def _nnmark(I): @@ -84,34 +84,36 @@ def _iac( IAC : numpy.ndarray Idealized arc curve (IAC) """ - np.random.seed(seed) + with rng.fix_seed(seed): + I = rng.RNG.randint(0, width, size=width, dtype=np.int64) + if bidirectional is False: # Idealized 1-dimensional matrix profile index + I[:-1] = width + for i in range(width - 1): + I[i] = rng.RNG.randint(i + 1, width, dtype=np.int64) + + target_AC = _nnmark(I) + + params = np.empty((n_iter, 2), dtype=np.float64) + for i in range(n_iter): + hist_dist = scipy.stats.rv_histogram( + (target_AC, np.append(np.arange(width), width)) + ) + hist_dist.random_state = rng.RNG + data = hist_dist.rvs(size=n_samples) + a, b, c, d = scipy.stats.beta.fit(data, floc=0, fscale=width) - I = np.random.randint(0, width, size=width, dtype=np.int64) - if bidirectional is False: # Idealized 1-dimensional matrix profile index - I[:-1] = width - for i in range(width - 1): - I[i] = np.random.randint(i + 1, width, dtype=np.int64) + params[i, 0] = a + params[i, 1] = b - target_AC = _nnmark(I) + a_mean = np.round(np.mean(params[:, 0]), 2) + b_mean = np.round(np.mean(params[:, 1]), 2) - params = np.empty((n_iter, 2), dtype=np.float64) - for i in range(n_iter): - hist_dist = scipy.stats.rv_histogram( - (target_AC, np.append(np.arange(width), width)) + IAC = scipy.stats.beta.pdf(np.arange(width), a_mean, b_mean, loc=0, scale=width) + slope, _, _, _ = np.linalg.lstsq( + np.expand_dims(IAC, axis=1), target_AC, rcond=None ) - data = hist_dist.rvs(size=n_samples) - a, b, c, d = scipy.stats.beta.fit(data, floc=0, fscale=width) - - params[i, 0] = a - params[i, 1] = b - - a_mean = np.round(np.mean(params[:, 0]), 2) - b_mean = np.round(np.mean(params[:, 1]), 2) - - IAC = scipy.stats.beta.pdf(np.arange(width), a_mean, b_mean, loc=0, scale=width) - slope, _, _, _ = np.linalg.lstsq(np.expand_dims(IAC, axis=1), target_AC, rcond=None) - IAC *= slope + IAC *= slope return IAC diff --git a/stumpy/rng.py b/stumpy/rng.py new file mode 100644 index 000000000..c73541e58 --- /dev/null +++ b/stumpy/rng.py @@ -0,0 +1,79 @@ +from contextlib import contextmanager + +import numpy as np + +# Note that an initial SEED = 0 is disallowed +# in order to account for unit testing +SEED = np.random.randint(1, 4_294_967_295, dtype=np.uint32) +RNG = np.random.RandomState(seed=SEED) + + +def set_seed(seed): + """ + Permanently set the RNG seed to a different value + + Parameters + ---------- + seed : int + The random seed for (permanently) setting the random number generator to + + Returns + ------- + None + """ + global SEED + global RNG + SEED = seed + RNG = np.random.RandomState(seed=SEED) + + +@contextmanager +def fix_seed(seed): + """ + A context manager for setting the RNG seed to a fixed, hardcoded, safe seed + and then returning the RNG back to its previous state prior to the seed change + + This is typically used when you want to generate a specific random sequence once. + To repeat the same random sequence, use `fix_state` instead. If you are picking + a random seed directly before calling `fix_seed` then you probably want to use + `fix_state` instead! + + Parameters + ---------- + seed : int + The random seed for (temporarily) setting the random number generator to + + Returns + ------- + None + """ + state = RNG.get_state() + RNG.seed(seed) + try: + yield + finally: + RNG.set_state(state) + + +@contextmanager +def fix_state(): + """ + A context manager for setting the RNG state to a fixed, hardcoded, safe state + and then returning the RNG back to its previous state prior to the state change + + This is typically used when you want to repeat the same random sequence more than + once. + + Parameters + ---------- + None + + Returns + ------- + None + """ + curr_state = RNG.get_state() + try: + yield + finally: + RNG.set_state(curr_state) diff --git a/stumpy/scraamp.py b/stumpy/scraamp.py index dc17726cc..f9c932d95 100644 --- a/stumpy/scraamp.py +++ b/stumpy/scraamp.py @@ -6,7 +6,7 @@ import numpy as np from numba import njit, prange -from . import config, core +from . import config, core, rng from .aamp import _aamp @@ -78,7 +78,7 @@ def _preprocess_prescraamp(T_A, m, T_B=None, s=None): else: # AB-join s = int(np.ceil(m / config.STUMPY_EXCL_ZONE_DENOM)) - indices = np.random.permutation(range(0, l, s)).astype(np.int64) + indices = rng.RNG.permutation(range(0, l, s)).astype(np.int64) return (T_A, T_B, T_A_subseq_isfinite, T_B_subseq_isfinite, indices, s, excl_zone) @@ -718,7 +718,7 @@ def __init__( core._merge_topk_PI(self._P, P, self._I, I) if self._ignore_trivial: - self._diags = np.random.permutation( + self._diags = rng.RNG.permutation( range(self._excl_zone + 1, self._n_A - self._m + 1) ).astype(np.int64) if self._diags.shape[0] == 0: # pragma: no cover @@ -728,7 +728,7 @@ def __init__( f"Please try a value of `m <= {max_m}`" ) else: - self._diags = np.random.permutation( + self._diags = rng.RNG.permutation( range(-(self._n_A - self._m + 1) + 1, self._n_B - self._m + 1) ).astype(np.int64) diff --git a/stumpy/scrump.py b/stumpy/scrump.py index 03739cdd6..752d729e2 100644 --- a/stumpy/scrump.py +++ b/stumpy/scrump.py @@ -6,7 +6,7 @@ import numpy as np from numba import njit, prange -from . import config, core, sdp +from . import config, core, rng, sdp from .scraamp import prescraamp, scraamp from .stump import _stump @@ -116,7 +116,7 @@ def _preprocess_prescrump( else: # AB-join s = int(np.ceil(m / config.STUMPY_EXCL_ZONE_DENOM)) - indices = np.random.permutation(range(0, l, s)).astype(np.int64) + indices = rng.RNG.permutation(range(0, l, s)).astype(np.int64) return ( T_A, @@ -997,7 +997,7 @@ def __init__( core._merge_topk_PI(self._P, P, self._I, I) if self._ignore_trivial: - self._diags = np.random.permutation( + self._diags = rng.RNG.permutation( range(self._excl_zone + 1, self._n_A - self._m + 1) ).astype(np.int64) if self._diags.shape[0] == 0: # pragma: no cover @@ -1007,7 +1007,7 @@ def __init__( f"Please try a value of `m <= {max_m}`" ) else: - self._diags = np.random.permutation( + self._diags = rng.RNG.permutation( range(-(self._n_A - self._m + 1) + 1, self._n_B - self._m + 1) ).astype(np.int64) diff --git a/tests/naive.py b/tests/naive.py index c316a87e8..26667aa32 100644 --- a/tests/naive.py +++ b/tests/naive.py @@ -4,7 +4,7 @@ from scipy.spatial.distance import cdist from scipy.stats import norm -from stumpy import config, core +from stumpy import config, core, rng def is_ptp_zero_1d(a, w): # `a` is 1-D @@ -1818,7 +1818,7 @@ def prescrump( P = np.full((l, k), np.inf, dtype=np.float64) I = np.full((l, k), -1, dtype=np.int64) - for i in np.random.permutation(range(0, l, s)): + for i in rng.RNG.permutation(range(0, l, s)): distance_profile = dist_matrix[i] if exclusion_zone is not None: apply_exclusion_zone(distance_profile, i, exclusion_zone, np.inf) @@ -1914,11 +1914,11 @@ def scrump( pass if exclusion_zone is not None: - diags = np.random.permutation(range(exclusion_zone + 1, n_A - m + 1)).astype( + diags = rng.RNG.permutation(range(exclusion_zone + 1, n_A - m + 1)).astype( np.int64 ) else: - diags = np.random.permutation(range(-(n_A - m + 1) + 1, n_B - m + 1)).astype( + diags = rng.RNG.permutation(range(-(n_A - m + 1) + 1, n_B - m + 1)).astype( np.int64 ) @@ -1981,7 +1981,7 @@ def prescraamp(T_A, m, T_B, s, exclusion_zone=None, p=2.0, k=1): P = np.full((l, k), np.inf, dtype=np.float64) I = np.full((l, k), -1, dtype=np.int64) - for i in np.random.permutation(range(0, l, s)): + for i in rng.RNG.permutation(range(0, l, s)): distance_profile = distance_matrix[i] if exclusion_zone is not None: apply_exclusion_zone(distance_profile, i, exclusion_zone, np.inf) @@ -2054,11 +2054,11 @@ def scraamp(T_A, m, T_B, percentage, exclusion_zone, pre_scraamp, s, p=2.0, k=1) l = n_A - m + 1 if exclusion_zone is not None: - diags = np.random.permutation(range(exclusion_zone + 1, n_A - m + 1)).astype( + diags = rng.RNG.permutation(range(exclusion_zone + 1, n_A - m + 1)).astype( np.int64 ) else: - diags = np.random.permutation(range(-(n_A - m + 1) + 1, n_B - m + 1)).astype( + diags = rng.RNG.permutation(range(-(n_A - m + 1) + 1, n_B - m + 1)).astype( np.int64 ) diff --git a/tests/test_aamp.py b/tests/test_aamp.py index ab5dfc64a..ac83786a9 100644 --- a/tests/test_aamp.py +++ b/tests/test_aamp.py @@ -4,7 +4,7 @@ import pandas as pd import pytest -from stumpy import config +from stumpy import config, rng from stumpy.aamp import aamp test_data = [ @@ -13,8 +13,8 @@ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), ), ( - np.random.uniform(-1000, 1000, [8]).astype(np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, size=8).astype(np.float64), + rng.RNG.uniform(-1000, 1000, size=64).astype(np.float64), ), ] @@ -72,7 +72,7 @@ def test_aamp_constant_subsequence_self_join(): def test_aamp_one_constant_subsequence_A_B_join(): - T_A = np.random.rand(20) + T_A = rng.RNG.random(20) T_B = np.concatenate((np.zeros(20, dtype=np.float64), np.ones(5, dtype=np.float64))) m = 3 ref_mp = naive.aamp(T_A, m, T_B=T_B) @@ -122,8 +122,8 @@ def test_aamp_two_constant_subsequences_A_B_join(): def test_aamp_identical_subsequence_self_join(): - identical = np.random.rand(8) - T_A = np.random.rand(20) + identical = rng.RNG.random(8) + T_A = rng.RNG.random(20) T_A[1 : 1 + identical.shape[0]] = identical T_A[11 : 11 + identical.shape[0]] = identical m = 3 @@ -143,9 +143,9 @@ def test_aamp_identical_subsequence_self_join(): def test_aamp_identical_subsequence_A_B_join(): - identical = np.random.rand(8) - T_A = np.random.rand(20) - T_B = np.random.rand(20) + identical = rng.RNG.random(8) + T_A = rng.RNG.random(20) + T_B = rng.RNG.random(20) T_A[1 : 1 + identical.shape[0]] = identical T_B[11 : 11 + identical.shape[0]] = identical m = 3 diff --git a/tests/test_aamp_mmotifs.py b/tests/test_aamp_mmotifs.py index b205fa2a5..ce9da91d2 100755 --- a/tests/test_aamp_mmotifs.py +++ b/tests/test_aamp_mmotifs.py @@ -3,7 +3,7 @@ import numpy.testing as npt import pytest -from stumpy import config +from stumpy import config, rng from stumpy.aamp_mmotifs import aamp_mmotifs test_data = [ @@ -60,23 +60,23 @@ def test_aamp_mmotifs_default_parameters(): np.array([411.60964047, 423.69925001, 449.11032383, 476.95855027, 506.62406252]) ] - np.random.seed(0) - T = np.random.rand(500).reshape(5, 100) - - m = 5 - excl_zone = int(np.ceil(m / config.STUMPY_EXCL_ZONE_DENOM)) - P, I = naive.maamp(T, m, excl_zone) - ( - motif_distances_cmp, - motif_indices_cmp, - motif_subspaces_cmp, - motif_mdls_cmp, - ) = aamp_mmotifs(T, P, I) - - npt.assert_array_almost_equal(motif_distances_ref, motif_distances_cmp) - npt.assert_array_almost_equal(motif_indices_ref, motif_indices_cmp) - npt.assert_array_almost_equal(motif_subspaces_ref, motif_subspaces_cmp) - npt.assert_array_almost_equal(motif_mdls_ref, motif_mdls_cmp) + with rng.fix_seed(0): + T = rng.RNG.rand(500).reshape(5, 100) + + m = 5 + excl_zone = int(np.ceil(m / config.STUMPY_EXCL_ZONE_DENOM)) + P, I = naive.maamp(T, m, excl_zone) + ( + motif_distances_cmp, + motif_indices_cmp, + motif_subspaces_cmp, + motif_mdls_cmp, + ) = aamp_mmotifs(T, P, I) + + npt.assert_array_almost_equal(motif_distances_ref, motif_distances_cmp) + npt.assert_array_almost_equal(motif_indices_ref, motif_indices_cmp) + npt.assert_array_almost_equal(motif_subspaces_ref, motif_subspaces_cmp) + npt.assert_array_almost_equal(motif_mdls_ref, motif_mdls_cmp) @pytest.mark.parametrize("T", test_data) diff --git a/tests/test_aamp_motifs.py b/tests/test_aamp_motifs.py index 3f7f7dde6..0164b1818 100644 --- a/tests/test_aamp_motifs.py +++ b/tests/test_aamp_motifs.py @@ -3,7 +3,7 @@ import numpy.testing as npt import pytest -from stumpy import core +from stumpy import core, rng from stumpy.aamp_motifs import aamp_match, aamp_motifs test_data = [ @@ -15,7 +15,7 @@ np.array([0.0, 1.0, 2.0]), np.array([0.1, 1.0, 2.0, 3.0, -1.0, 0.1, 1.0, 2.0, -0.5]), ), - (np.random.uniform(-1000, 1000, [8]), np.random.uniform(-1000, 1000, [64])), + (rng.RNG.uniform(-1000, 1000, [8]), rng.RNG.uniform(-1000, 1000, [64])), ] @@ -71,61 +71,57 @@ def test_aamp_motifs_one_motif(): def test_aamp_motifs_two_motifs(): # Fix seed, because in some case motifs can be off by an index resulting in test # fails, which is caused since one of the motifs is not repeated perfectly in T. - np.random.seed(1234) - - # The time series is random noise with two motifs for m=10: - # * (almost) identical step functions at indices 10, 110 and 210 - # * identical linear slopes at indices 70 and 170 - T = np.random.normal(size=300) - m = 20 - - T[10:30] = 1 - T[12:28] = 2 - - # This is not part of the motif in the aamp case - T[110:130] = 3 - T[112:128] = 6 - T[120] = 6.6 - - T[210:230] = 1 - T[212:228] = 2 - T[220] = 1.9 - # naive.distance(naive.z_norm(T[10:30]), naive.z_norm(T[110:130])) = 0.47 - # naive.distance(naive.z_norm(T[10:30]), naive.z_norm(T[210:230])) = 0.24 - # naive.distance(naive.z_norm(T[110:130]), naive.z_norm(T[210:230])) = 0.72 - # Hence T[10:30] is the motif representative for this motif - - T[70:90] = np.arange(m) * 0.1 - T[170:190] = np.arange(m) * 0.1 - # naive.distance(naive.z_norm(T[70:90]), naive.z_norm(T[170:190])) = 0.0 - - max_motifs = 2 - - mp = naive.aamp(T, m) - - # left_indices = [[70, 170], [10, 210]] - left_profile_values = [ - [0.0, 0.0], - [ - 0.0, - naive.distance(T[10:30], T[210:230]), - ], - ] - - right_distance_values, right_indices = aamp_motifs( - T, - mp[:, 0], - max_motifs=max_motifs, - max_distance=0.5, - cutoff=np.inf, - ) + with rng.fix_seed(1234): + # The time series is random noise with two motifs for m=10: + # * (almost) identical step functions at indices 10, 110 and 210 + # * identical linear slopes at indices 70 and 170 + T = rng.RNG.normal(size=300) + m = 20 + + T[10:30] = 1 + T[12:28] = 2 + + # This is not part of the motif in the aamp case + T[110:130] = 3 + T[112:128] = 6 + T[120] = 6.6 + + T[210:230] = 1 + T[212:228] = 2 + T[220] = 1.9 + # naive.distance(naive.z_norm(T[10:30]), naive.z_norm(T[110:130])) = 0.47 + # naive.distance(naive.z_norm(T[10:30]), naive.z_norm(T[210:230])) = 0.24 + # naive.distance(naive.z_norm(T[110:130]), naive.z_norm(T[210:230])) = 0.72 + # Hence T[10:30] is the motif representative for this motif + + T[70:90] = np.arange(m) * 0.1 + T[170:190] = np.arange(m) * 0.1 + # naive.distance(naive.z_norm(T[70:90]), naive.z_norm(T[170:190])) = 0.0 + + max_motifs = 2 + + mp = naive.aamp(T, m) + + # left_indices = [[70, 170], [10, 210]] + left_profile_values = [ + [0.0, 0.0], + [ + 0.0, + naive.distance(T[10:30], T[210:230]), + ], + ] - # We ignore indices because of sorting ambiguities for equal distances. - # As long as the distances are correct, the indices will be too. - npt.assert_almost_equal(left_profile_values, right_distance_values, decimal=6) + right_distance_values, right_indices = aamp_motifs( + T, + mp[:, 0], + max_motifs=max_motifs, + max_distance=0.5, + cutoff=np.inf, + ) - # Reset seed - np.random.seed(None) + # We ignore indices because of sorting ambiguities for equal distances. + # As long as the distances are correct, the indices will be too. + npt.assert_almost_equal(left_profile_values, right_distance_values, decimal=6) def test_aamp_naive_match_exact(): @@ -242,7 +238,7 @@ def test_aamp_match_T_subseq_isfinite(Q, T): def test_aamp_match_query_idx(): - T = np.random.uniform(-1000, 1000, [64]) + T = rng.RNG.uniform(-1000, 1000, [64]) m = 8 query_idx = 20 Q = T[query_idx : query_idx + m] diff --git a/tests/test_aamp_ostinato.py b/tests/test_aamp_ostinato.py index e74b58c86..ed36307be 100644 --- a/tests/test_aamp_ostinato.py +++ b/tests/test_aamp_ostinato.py @@ -5,7 +5,7 @@ import tornado.ioloop from dask.distributed import Client, LocalCluster -from stumpy import core +from stumpy import core, rng from stumpy.aamp_ostinato import aamp_ostinato, aamp_ostinatoed @@ -25,69 +25,71 @@ def dask_cluster(): @pytest.mark.parametrize( - "seed", np.random.choice(np.arange(10000), size=25, replace=False) + "seed", rng.RNG.choice(np.arange(10000), size=25, replace=False) ) def test_random_ostinato(seed): m = 50 - np.random.seed(seed) - Ts = [np.random.rand(n) for n in [64, 128, 256]] + with rng.fix_seed(seed): + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] - ref_radius, ref_Ts_idx, ref_subseq_idx = naive.aamp_ostinato(Ts, m) - comp_radius, comp_Ts_idx, comp_subseq_idx = aamp_ostinato(Ts, m) + ref_radius, ref_Ts_idx, ref_subseq_idx = naive.aamp_ostinato(Ts, m) + comp_radius, comp_Ts_idx, comp_subseq_idx = aamp_ostinato(Ts, m) - npt.assert_almost_equal(ref_radius, comp_radius) - npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) - npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) + npt.assert_almost_equal(ref_radius, comp_radius) + npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) + npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) @pytest.mark.parametrize("seed", [41, 88, 290, 292, 310, 328, 538, 556, 563, 570]) def test_deterministic_ostinato(seed): m = 50 - np.random.seed(seed) - Ts = [np.random.rand(n) for n in [64, 128, 256]] + with rng.fix_seed(seed): + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] - for p in [1.0, 2.0, 3.0]: - ref_radius, ref_Ts_idx, ref_subseq_idx = naive.aamp_ostinato(Ts, m, p=p) - comp_radius, comp_Ts_idx, comp_subseq_idx = aamp_ostinato(Ts, m, p=p) + for p in [1.0, 2.0, 3.0]: + ref_radius, ref_Ts_idx, ref_subseq_idx = naive.aamp_ostinato(Ts, m, p=p) + comp_radius, comp_Ts_idx, comp_subseq_idx = aamp_ostinato(Ts, m, p=p) - npt.assert_almost_equal(ref_radius, comp_radius) - npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) - npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) + npt.assert_almost_equal(ref_radius, comp_radius) + npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) + npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) @pytest.mark.parametrize( - "seed", np.random.choice(np.arange(10000), size=25, replace=False) + "seed", rng.RNG.choice(np.arange(10000), size=25, replace=False) ) def test_random_ostinatoed(seed, dask_cluster): with Client(dask_cluster) as dask_client: m = 50 - np.random.seed(seed) - Ts = [np.random.rand(n) for n in [64, 128, 256]] + with rng.fix_seed(seed): + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] - ref_radius, ref_Ts_idx, ref_subseq_idx = naive.aamp_ostinato(Ts, m) - comp_radius, comp_Ts_idx, comp_subseq_idx = aamp_ostinatoed(dask_client, Ts, m) + ref_radius, ref_Ts_idx, ref_subseq_idx = naive.aamp_ostinato(Ts, m) + comp_radius, comp_Ts_idx, comp_subseq_idx = aamp_ostinatoed( + dask_client, Ts, m + ) - npt.assert_almost_equal(ref_radius, comp_radius) - npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) - npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) + npt.assert_almost_equal(ref_radius, comp_radius) + npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) + npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) @pytest.mark.parametrize("seed", [41, 88, 290, 292, 310, 328, 538, 556, 563, 570]) def test_deterministic_ostinatoed(seed, dask_cluster): with Client(dask_cluster) as dask_client: m = 50 - np.random.seed(seed) - Ts = [np.random.rand(n) for n in [64, 128, 256]] + with rng.fix_seed(seed): + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] - for p in [1.0, 2.0, 3.0]: - ref_radius, ref_Ts_idx, ref_subseq_idx = naive.aamp_ostinato(Ts, m, p=p) - comp_radius, comp_Ts_idx, comp_subseq_idx = aamp_ostinatoed( - dask_client, Ts, m, p=p - ) + for p in [1.0, 2.0, 3.0]: + ref_radius, ref_Ts_idx, ref_subseq_idx = naive.aamp_ostinato(Ts, m, p=p) + comp_radius, comp_Ts_idx, comp_subseq_idx = aamp_ostinatoed( + dask_client, Ts, m, p=p + ) - npt.assert_almost_equal(ref_radius, comp_radius) - npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) - npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) + npt.assert_almost_equal(ref_radius, comp_radius) + npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) + npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) def test_input_not_overwritten_ostinato(): @@ -95,7 +97,7 @@ def test_input_not_overwritten_ostinato(): # by replacing nan value with 0 in each time series. # This test ensures that the original input is not overwritten m = 50 - Ts = [np.random.rand(n) for n in [64, 128, 256]] + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] for T in Ts: T[0] = np.nan @@ -111,7 +113,7 @@ def test_input_not_overwritten_ostinato(): def test_extract_several_consensus_ostinato(): # This test is to further ensure that the function `aamp_ostinato` # does not tamper with the original data. - Ts = [np.random.rand(n) for n in [256, 512, 1024]] + Ts = [rng.RNG.rand(n) for n in [256, 512, 1024]] Ts_ref = [T.copy() for T in Ts] Ts_comp = [T.copy() for T in Ts] @@ -149,7 +151,7 @@ def test_input_not_overwritten_ostinatoed(dask_cluster): # This test ensures that the original input is not overwritten with Client(dask_cluster) as dask_client: m = 50 - Ts = [np.random.rand(n) for n in [64, 128, 256]] + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] for T in Ts: T[0] = np.nan @@ -167,7 +169,7 @@ def test_input_not_overwritten_ostinatoed(dask_cluster): def test_extract_several_consensus_ostinatoed(dask_cluster): # This test is to further ensure that the function `ostinatoed` # does not tamper with the original data. - Ts = [np.random.rand(n) for n in [256, 512, 1024]] + Ts = [rng.RNG.rand(n) for n in [256, 512, 1024]] Ts_ref = [T.copy() for T in Ts] Ts_comp = [T.copy() for T in Ts] diff --git a/tests/test_aamp_stimp.py b/tests/test_aamp_stimp.py index 7f5faa202..3e83724ab 100644 --- a/tests/test_aamp_stimp.py +++ b/tests/test_aamp_stimp.py @@ -5,11 +5,12 @@ import tornado.ioloop from dask.distributed import Client, LocalCluster +from stumpy import rng from stumpy.aamp_stimp import aamp_stimp, aamp_stimped T = [ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, size=64).astype(np.float64), ] n = [9, 10, 16] @@ -37,34 +38,32 @@ def test_aamp_stimp_1_percent(T): min_m = 3 n = T.shape[0] - min_m + 1 - seed = np.random.randint(100000) - - np.random.seed(seed) - pan = aamp_stimp( - T, - min_m=min_m, - max_m=None, - step=1, - percentage=percentage, - pre_scraamp=True, - ) + with rng.fix_state(): + pan = aamp_stimp( + T, + min_m=min_m, + max_m=None, + step=1, + percentage=percentage, + pre_scraamp=True, + ) - for i in range(n): - pan.update() + for i in range(n): + pan.update() - ref_PAN = np.full((pan.M_.shape[0], T.shape[0]), fill_value=np.inf) + ref_PAN = np.full((pan.M_.shape[0], T.shape[0]), fill_value=np.inf) - np.random.seed(seed) - for idx, m in enumerate(pan.M_[:n]): - zone = int(np.ceil(m / 4)) - s = zone - tmp_P, tmp_I = naive.prescraamp(T, m, T, s=s, exclusion_zone=zone) - ref_P, ref_I, _, _ = naive.scraamp(T, m, T, percentage, zone, True, s) - naive.merge_topk_PI(ref_P, tmp_P, ref_I, tmp_I) - ref_PAN[pan._bfs_indices[idx], : ref_P.shape[0]] = ref_P + with rng.fix_state(): + for idx, m in enumerate(pan.M_[:n]): + zone = int(np.ceil(m / 4)) + s = zone + tmp_P, tmp_I = naive.prescraamp(T, m, T, s=s, exclusion_zone=zone) + ref_P, ref_I, _, _ = naive.scraamp(T, m, T, percentage, zone, True, s) + naive.merge_topk_PI(ref_P, tmp_P, ref_I, tmp_I) + ref_PAN[pan._bfs_indices[idx], : ref_P.shape[0]] = ref_P - # Compare raw pan - cmp_PAN = pan._PAN + # Compare raw pan + cmp_PAN = pan._PAN naive.replace_inf(ref_PAN) naive.replace_inf(cmp_PAN) @@ -97,34 +96,32 @@ def test_aamp_stimp_max_m(T): max_m = 5 n = T.shape[0] - min_m + 1 - seed = np.random.randint(100000) - - np.random.seed(seed) - pan = aamp_stimp( - T, - min_m=min_m, - max_m=max_m, - step=1, - percentage=percentage, - pre_scraamp=True, - ) + with rng.fix_state(): + pan = aamp_stimp( + T, + min_m=min_m, + max_m=max_m, + step=1, + percentage=percentage, + pre_scraamp=True, + ) - for i in range(n): - pan.update() + for i in range(n): + pan.update() - ref_PAN = np.full((pan.M_.shape[0], T.shape[0]), fill_value=np.inf) + ref_PAN = np.full((pan.M_.shape[0], T.shape[0]), fill_value=np.inf) - np.random.seed(seed) - for idx, m in enumerate(pan.M_[:n]): - zone = int(np.ceil(m / 4)) - s = zone - tmp_P, tmp_I = naive.prescraamp(T, m, T, s=s, exclusion_zone=zone) - ref_P, ref_I, _, _ = naive.scraamp(T, m, T, percentage, zone, True, s) - naive.merge_topk_PI(ref_P, tmp_P, ref_I, tmp_I) - ref_PAN[pan._bfs_indices[idx], : ref_P.shape[0]] = ref_P + with rng.fix_state(): + for idx, m in enumerate(pan.M_[:n]): + zone = int(np.ceil(m / 4)) + s = zone + tmp_P, tmp_I = naive.prescraamp(T, m, T, s=s, exclusion_zone=zone) + ref_P, ref_I, _, _ = naive.scraamp(T, m, T, percentage, zone, True, s) + naive.merge_topk_PI(ref_P, tmp_P, ref_I, tmp_I) + ref_PAN[pan._bfs_indices[idx], : ref_P.shape[0]] = ref_P - # Compare raw pan - cmp_PAN = pan._PAN + # Compare raw pan + cmp_PAN = pan._PAN naive.replace_inf(ref_PAN) naive.replace_inf(cmp_PAN) diff --git a/tests/test_aampdist.py b/tests/test_aampdist.py index f1c915d62..ed361a09d 100644 --- a/tests/test_aampdist.py +++ b/tests/test_aampdist.py @@ -5,6 +5,7 @@ import tornado.ioloop from dask.distributed import Client, LocalCluster +from stumpy import rng from stumpy.aampdist import _aampdist_vect, aampdist, aampdisted @@ -29,8 +30,8 @@ def dask_cluster(): np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), ), ( - np.random.uniform(-1000, 1000, [8]).astype(np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, size=8).astype(np.float64), + rng.RNG.uniform(-1000, 1000, size=64).astype(np.float64), ), ] diff --git a/tests/test_aampdist_snippets.py b/tests/test_aampdist_snippets.py index 7356f3101..c5ed74183 100644 --- a/tests/test_aampdist_snippets.py +++ b/tests/test_aampdist_snippets.py @@ -3,10 +3,10 @@ import numpy.testing as npt import pytest -from stumpy import config +from stumpy import config, rng from stumpy.aampdist_snippets import aampdist_snippets -test_data = [np.random.uniform(-1000, 1000, [64]).astype(np.float64)] +test_data = [rng.RNG.uniform(-1000, 1000, size=64).astype(np.float64)] s = [6, 7, 8] percentage = [0.7, 0.8, 0.9] m = [8, 9, 10] diff --git a/tests/test_aamped.py b/tests/test_aamped.py index df35ff318..9433f99d2 100644 --- a/tests/test_aamped.py +++ b/tests/test_aamped.py @@ -6,7 +6,7 @@ import tornado.ioloop from dask.distributed import Client, LocalCluster -from stumpy import config +from stumpy import config, rng from stumpy.aamped import aamped @@ -31,8 +31,8 @@ def dask_cluster(): np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), ), ( - np.random.uniform(-1000, 1000, [8]).astype(np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, size=8).astype(np.float64), + rng.RNG.uniform(-1000, 1000, size=64).astype(np.float64), ), ] @@ -191,7 +191,7 @@ def test_aamped_one_constant_subsequence_self_join_df(dask_cluster): @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_aamped_one_constant_subsequence_A_B_join(dask_cluster): with Client(dask_cluster) as dask_client: - T_A = np.random.rand(20) + T_A = rng.RNG.random(20) T_B = np.concatenate( (np.zeros(20, dtype=np.float64), np.ones(5, dtype=np.float64)) ) @@ -211,7 +211,7 @@ def test_aamped_one_constant_subsequence_A_B_join(dask_cluster): @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_aamped_one_constant_subsequence_A_B_join_df(dask_cluster): with Client(dask_cluster) as dask_client: - T_A = np.random.rand(20) + T_A = rng.RNG.random(20) T_B = np.concatenate( (np.zeros(20, dtype=np.float64), np.ones(5, dtype=np.float64)) ) @@ -233,7 +233,7 @@ def test_aamped_one_constant_subsequence_A_B_join_df(dask_cluster): @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_aamped_one_constant_subsequence_A_B_join_swap(dask_cluster): with Client(dask_cluster) as dask_client: - T_A = np.random.rand(20) + T_A = rng.RNG.rand(20) T_B = np.concatenate( (np.zeros(20, dtype=np.float64), np.ones(5, dtype=np.float64)) ) @@ -253,7 +253,7 @@ def test_aamped_one_constant_subsequence_A_B_join_swap(dask_cluster): @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_aamped_one_constant_subsequence_A_B_join_df_swap(dask_cluster): with Client(dask_cluster) as dask_client: - T_A = np.random.rand(20) + T_A = rng.RNG.rand(20) T_B = np.concatenate( (np.zeros(20, dtype=np.float64), np.ones(5, dtype=np.float64)) ) @@ -275,8 +275,8 @@ def test_aamped_one_constant_subsequence_A_B_join_df_swap(dask_cluster): @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_aamped_identical_subsequence_self_join(dask_cluster): with Client(dask_cluster) as dask_client: - identical = np.random.rand(8) - T_A = np.random.rand(20) + identical = rng.RNG.rand(8) + T_A = rng.RNG.rand(20) T_A[1 : 1 + identical.shape[0]] = identical T_A[11 : 11 + identical.shape[0]] = identical m = 3 @@ -297,9 +297,9 @@ def test_aamped_identical_subsequence_self_join(dask_cluster): @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_aamped_identical_subsequence_A_B_join(dask_cluster): with Client(dask_cluster) as dask_client: - identical = np.random.rand(8) - T_A = np.random.rand(20) - T_B = np.random.rand(20) + identical = rng.RNG.rand(8) + T_A = rng.RNG.rand(20) + T_B = rng.RNG.rand(20) T_A[1 : 1 + identical.shape[0]] = identical T_B[11 : 11 + identical.shape[0]] = identical m = 3 diff --git a/tests/test_aampi.py b/tests/test_aampi.py index 03c6d6914..5aa3b1c8c 100644 --- a/tests/test_aampi.py +++ b/tests/test_aampi.py @@ -4,7 +4,7 @@ import pandas as pd import pytest -from stumpy import config, core +from stumpy import config, core, rng from stumpy.aampi import aampi substitution_locations = [(slice(0, 0), 0, -1, slice(1, 3), [0, 3])] @@ -20,114 +20,84 @@ def test_aampi_self_join(): m = 3 for p in [1.0, 2.0, 3.0]: - seed = np.random.randint(100000) - np.random.seed(seed) - - n = 30 - T = np.random.rand(n) - stream = aampi(T, m, egress=False, p=p) - for i in range(34): - t = np.random.rand() - stream.update(t) + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(n) + stream = aampi(T, m, egress=False, p=p) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) - comp_P = stream.P_ - comp_I = stream.I_ - comp_left_P = stream.left_P_ - comp_left_I = stream.left_I_ + comp_P = stream.P_ + comp_I = stream.I_ + comp_left_P = stream.left_P_ + comp_left_I = stream.left_I_ - ref_mp = naive.aamp(stream.T_, m, p=p) - ref_P = ref_mp[:, 0] - ref_I = ref_mp[:, 1] - ref_left_P = np.full(ref_P.shape, np.inf) - ref_left_I = ref_mp[:, 2] - for i, j in enumerate(ref_left_I): - if j >= 0: - ref_left_P[i] = np.linalg.norm( - stream.T_[i : i + m] - stream.T_[j : j + m], ord=p - ) + ref_mp = naive.aamp(stream.T_, m, p=p) + ref_P = ref_mp[:, 0] + ref_I = ref_mp[:, 1] + ref_left_P = np.full(ref_P.shape, np.inf) + ref_left_I = ref_mp[:, 2] + for i, j in enumerate(ref_left_I): + if j >= 0: + ref_left_P[i] = np.linalg.norm( + stream.T_[i : i + m] - stream.T_[j : j + m], ord=p + ) - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) - np.random.seed(seed) - n = 30 - T = np.random.rand(n) - T = pd.Series(T) - stream = aampi(T, m, egress=False, p=p) - for i in range(34): - t = np.random.rand() - stream.update(t) + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(n) + T = pd.Series(T) + stream = aampi(T, m, egress=False, p=p) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) - comp_P = stream.P_ - comp_I = stream.I_ - comp_left_P = stream.left_P_ - comp_left_I = stream.left_I_ + comp_P = stream.P_ + comp_I = stream.I_ + comp_left_P = stream.left_P_ + comp_left_I = stream.left_I_ - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) def test_aampi_self_join_egress(): m = 3 for p in [1.0, 2.0, 3.0]: - seed = np.random.randint(100000) - np.random.seed(seed) - - n = 30 - T = np.random.rand(n) - - ref_mp = naive.aampi_egress(T, m, p=p) - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ - - stream = aampi(T, m, egress=True, p=p) - - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(n) - for i in range(34): - t = np.random.rand() + ref_mp = naive.aampi_egress(T, m, p=p) + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ - ref_mp.update(t) - stream.update(t) + stream = aampi(T, m, egress=True, p=p) comp_P = stream.P_.copy() comp_I = stream.I_ comp_left_P = stream.left_P_.copy() comp_left_I = stream.left_I_ - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ - naive.replace_inf(ref_P) naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) @@ -138,44 +108,161 @@ def test_aampi_self_join_egress(): npt.assert_almost_equal(ref_left_P, comp_left_P) npt.assert_almost_equal(ref_left_I, comp_left_I) - np.random.seed(seed) - T = np.random.rand(n) - T = pd.Series(T) + for i in range(34): + t = rng.RNG.rand() - ref_mp = naive.aampi_egress(T, m, p=p) - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ + ref_mp.update(t) + stream.update(t) - stream = aampi(T, m, egress=True, p=p) + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ - comp_P = stream.P_.copy() - comp_I = stream.I_ + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) - for i in range(34): - t = np.random.rand() + with rng.fix_state(): + T = rng.RNG.rand(n) + T = pd.Series(T) - ref_mp.update(t) - stream.update(t) + ref_mp = naive.aampi_egress(T, m, p=p) + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + + stream = aampi(T, m, egress=True, p=p) comp_P = stream.P_.copy() comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) + + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + + for i in range(34): + t = rng.RNG.rand() + + ref_mp.update(t) + stream.update(t) + + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ + + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ + + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) + + +@pytest.mark.parametrize("substitute", substitution_values) +@pytest.mark.parametrize("substitution_locations", substitution_locations) +def test_aampi_init_nan_inf_self_join(substitute, substitution_locations): + m = 3 + + for substitution_location in substitution_locations: + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(n) + + if substitution_location == -1: + substitution_location = T.shape[0] - 1 + T[substitution_location] = substitute + stream = aampi(T, m, egress=False) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) + + comp_P = stream.P_ + comp_I = stream.I_ + + stream.T_[substitution_location] = substitute + ref_mp = naive.aamp(stream.T_, m) + ref_P = ref_mp[:, 0] + ref_I = ref_mp[:, 1] + + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(n) + + if substitution_location == -1: # pragma: no cover + substitution_location = T.shape[0] - 1 + T[substitution_location] = substitute + T = pd.Series(T) + stream = aampi(T, m, egress=False) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) + + comp_P = stream.P_ + comp_I = stream.I_ + + naive.replace_inf(comp_P) + + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + + +@pytest.mark.parametrize("substitute", substitution_values) +@pytest.mark.parametrize("substitution_locations", substitution_locations) +def test_aampi_init_nan_inf_self_join_egress(substitute, substitution_locations): + m = 3 + + for substitution_location in substitution_locations: + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(n) + + if substitution_location == -1: + substitution_location = T.shape[0] - 1 + T[substitution_location] = substitute + + ref_mp = naive.aampi_egress(T, m) ref_P = ref_mp.P_.copy() ref_I = ref_mp.I_ ref_left_P = ref_mp.left_P_.copy() ref_left_I = ref_mp.left_I_ + stream = aampi(T, m, egress=True) + + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ + naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) + naive.replace_inf(ref_left_P) naive.replace_inf(comp_left_P) npt.assert_almost_equal(ref_P, comp_P) @@ -183,122 +270,158 @@ def test_aampi_self_join_egress(): npt.assert_almost_equal(ref_left_P, comp_left_P) npt.assert_almost_equal(ref_left_I, comp_left_I) + for i in range(34): + t = rng.RNG.rand() -@pytest.mark.parametrize("substitute", substitution_values) -@pytest.mark.parametrize("substitution_locations", substitution_locations) -def test_aampi_init_nan_inf_self_join(substitute, substitution_locations): - m = 3 + ref_mp.update(t) + stream.update(t) - seed = np.random.randint(100000) - # seed = 58638 + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ - for substitution_location in substitution_locations: - np.random.seed(seed) - n = 30 - T = np.random.rand(n) + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ - if substitution_location == -1: - substitution_location = T.shape[0] - 1 - T[substitution_location] = substitute - stream = aampi(T, m, egress=False) - for i in range(34): - t = np.random.rand() - stream.update(t) + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - comp_P = stream.P_ - comp_I = stream.I_ + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) - stream.T_[substitution_location] = substitute - ref_mp = naive.aamp(stream.T_, m) - ref_P = ref_mp[:, 0] - ref_I = ref_mp[:, 1] + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(n) + T = pd.Series(T) - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + ref_mp = naive.aampi_egress(T, m) + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ - np.random.seed(seed) - n = 30 - T = np.random.rand(n) + stream = aampi(T, m, egress=True) - if substitution_location == -1: # pragma: no cover - substitution_location = T.shape[0] - 1 - T[substitution_location] = substitute - T = pd.Series(T) - stream = aampi(T, m, egress=False) - for i in range(34): - t = np.random.rand() - stream.update(t) + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ - comp_P = stream.P_ - comp_I = stream.I_ + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_left_P) - naive.replace_inf(comp_P) + for i in range(34): + t = rng.RNG.rand() - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + ref_mp.update(t) + stream.update(t) + + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ + + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ + + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) @pytest.mark.parametrize("substitute", substitution_values) @pytest.mark.parametrize("substitution_locations", substitution_locations) -def test_aampi_init_nan_inf_self_join_egress(substitute, substitution_locations): +def test_aampi_stream_nan_inf_self_join(substitute, substitution_locations): m = 3 - seed = np.random.randint(100000) - # seed = 58638 - for substitution_location in substitution_locations: - np.random.seed(seed) - n = 30 - T = np.random.rand(n) + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(64) - if substitution_location == -1: - substitution_location = T.shape[0] - 1 - T[substitution_location] = substitute + stream = aampi(T[:n], m, egress=False) + if substitution_location == -1: + substitution_location = T[n:].shape[0] - 1 + T[n:][substitution_location] = substitute + for t in T[n:]: + stream.update(t) - ref_mp = naive.aampi_egress(T, m) - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ + comp_P = stream.P_ + comp_I = stream.I_ - stream = aampi(T, m, egress=True) + stream.T_[n:][substitution_location] = substitute + ref_mp = naive.aamp(stream.T_, m) + ref_P = ref_mp[:, 0] + ref_I = ref_mp[:, 1] - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_left_P) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + with rng.fix_state(): + T = rng.RNG.rand(64) + + stream = aampi(pd.Series(T[:n]), m, egress=False) + if substitution_location == -1: # pragma: no cover + substitution_location = T[n:].shape[0] - 1 + T[n:][substitution_location] = substitute + for t in T[n:]: + stream.update(t) + + comp_P = stream.P_ + comp_I = stream.I_ + + naive.replace_inf(comp_P) + + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) - for i in range(34): - t = np.random.rand() - ref_mp.update(t) - stream.update(t) +@pytest.mark.parametrize("substitute", substitution_values) +@pytest.mark.parametrize("substitution_locations", substitution_locations) +def test_aampi_stream_nan_inf_self_join_egress(substitute, substitution_locations): + m = 3 - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ + for substitution_location in substitution_locations: + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(64) + ref_mp = naive.aampi_egress(T[:n], m) ref_P = ref_mp.P_.copy() ref_I = ref_mp.I_ ref_left_P = ref_mp.left_P_.copy() ref_left_I = ref_mp.left_I_ + stream = aampi(T[:n], m, egress=True) + + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ + naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) + naive.replace_inf(ref_left_P) naive.replace_inf(comp_left_P) npt.assert_almost_equal(ref_P, comp_P) @@ -306,132 +429,150 @@ def test_aampi_init_nan_inf_self_join_egress(substitute, substitution_locations) npt.assert_almost_equal(ref_left_P, comp_left_P) npt.assert_almost_equal(ref_left_I, comp_left_I) - np.random.seed(seed) - n = 30 - T = np.random.rand(n) - T = pd.Series(T) + if substitution_location == -1: + substitution_location = T[n:].shape[0] - 1 + T[n:][substitution_location] = substitute + for t in T[n:]: + ref_mp.update(t) + stream.update(t) - ref_mp = naive.aampi_egress(T, m) - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ - stream = aampi(T, m, egress=True) + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_left_P) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) - for i in range(34): - t = np.random.rand() + with rng.fix_state(): + T = rng.RNG.rand(64) - ref_mp.update(t) - stream.update(t) + ref_mp = naive.aampi_egress(T[:n], m) + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ + + stream = aampi(pd.Series(T[:n]), m, egress=True) comp_P = stream.P_.copy() comp_I = stream.I_ comp_left_P = stream.left_P_.copy() comp_left_I = stream.left_I_ - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) + naive.replace_inf(ref_left_P) naive.replace_inf(comp_left_P) npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) npt.assert_almost_equal(ref_left_P, comp_left_P) npt.assert_almost_equal(ref_left_I, comp_left_I) + if substitution_location == -1: # pragma: no cover + substitution_location = T[n:].shape[0] - 1 + T[n:][substitution_location] = substitute + for t in T[n:]: + ref_mp.update(t) + stream.update(t) + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ -@pytest.mark.parametrize("substitute", substitution_values) -@pytest.mark.parametrize("substitution_locations", substitution_locations) -def test_aampi_stream_nan_inf_self_join(substitute, substitution_locations): - m = 3 + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ + + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - seed = np.random.randint(100000) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) - for substitution_location in substitution_locations: - np.random.seed(seed) - n = 30 - T = np.random.rand(64) - - stream = aampi(T[:n], m, egress=False) - if substitution_location == -1: - substitution_location = T[n:].shape[0] - 1 - T[n:][substitution_location] = substitute - for t in T[n:]: + +def test_aampi_constant_subsequence_self_join(): + m = 3 + + with rng.fix_state(): + T = np.concatenate( + (np.zeros(20, dtype=np.float64), np.ones(10, dtype=np.float64)) + ) + stream = aampi(T, m, egress=False) + for i in range(34): + t = rng.RNG.rand() stream.update(t) comp_P = stream.P_ - comp_I = stream.I_ + # comp_I = stream.I_ - stream.T_[n:][substitution_location] = substitute ref_mp = naive.aamp(stream.T_, m) ref_P = ref_mp[:, 0] - ref_I = ref_mp[:, 1] + # ref_I = ref_mp[:, 1] naive.replace_inf(ref_P) naive.replace_inf(comp_P) npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - - np.random.seed(seed) - T = np.random.rand(64) + # npt.assert_almost_equal(ref_I, comp_I) - stream = aampi(pd.Series(T[:n]), m, egress=False) - if substitution_location == -1: # pragma: no cover - substitution_location = T[n:].shape[0] - 1 - T[n:][substitution_location] = substitute - for t in T[n:]: + with rng.fix_state(): + T = np.concatenate( + (np.zeros(20, dtype=np.float64), np.ones(10, dtype=np.float64)) + ) + T = pd.Series(T) + stream = aampi(T, m, egress=False) + for i in range(34): + t = rng.RNG.rand() stream.update(t) comp_P = stream.P_ - comp_I = stream.I_ + # comp_I = stream.I_ naive.replace_inf(comp_P) npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + # npt.assert_almost_equal(ref_I, comp_I) -@pytest.mark.parametrize("substitute", substitution_values) -@pytest.mark.parametrize("substitution_locations", substitution_locations) -def test_aampi_stream_nan_inf_self_join_egress(substitute, substitution_locations): +def test_aampi_constant_subsequence_self_join_egress(): m = 3 - seed = np.random.randint(100000) - - for substitution_location in substitution_locations: - np.random.seed(seed) - n = 30 - T = np.random.rand(64) + with rng.fix_state(): + T = np.concatenate( + (np.zeros(20, dtype=np.float64), np.ones(10, dtype=np.float64)) + ) - ref_mp = naive.aampi_egress(T[:n], m) + ref_mp = naive.aampi_egress(T, m) ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ + # ref_I = ref_mp.I_ ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ + # ref_left_I = ref_mp.left_I_ - stream = aampi(T[:n], m, egress=True) + stream = aampi(T, m, egress=True) comp_P = stream.P_.copy() - comp_I = stream.I_ + # comp_I = stream.I_ comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ + # comp_left_I = stream.left_I_ naive.replace_inf(ref_P) naive.replace_inf(comp_P) @@ -439,26 +580,24 @@ def test_aampi_stream_nan_inf_self_join_egress(substitute, substitution_location naive.replace_inf(comp_left_P) npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + # npt.assert_almost_equal(ref_I, comp_I) npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + # npt.assert_almost_equal(ref_left_I, comp_left_I) - if substitution_location == -1: - substitution_location = T[n:].shape[0] - 1 - T[n:][substitution_location] = substitute - for t in T[n:]: + for i in range(34): + t = rng.RNG.rand() ref_mp.update(t) stream.update(t) comp_P = stream.P_.copy() - comp_I = stream.I_ + # comp_I = stream.I_ comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ + # comp_left_I = stream.left_I_ ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ + # ref_I = ref_mp.I_ ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ + # ref_left_I = ref_mp.left_I_ naive.replace_inf(ref_P) naive.replace_inf(ref_left_P) @@ -466,25 +605,28 @@ def test_aampi_stream_nan_inf_self_join_egress(substitute, substitution_location naive.replace_inf(comp_left_P) npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + # npt.assert_almost_equal(ref_I, comp_I) npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + # npt.assert_almost_equal(ref_left_I, comp_left_I) - np.random.seed(seed) - T = np.random.rand(64) + with rng.fix_state(): + T = np.concatenate( + (np.zeros(20, dtype=np.float64), np.ones(10, dtype=np.float64)) + ) + T = pd.Series(T) - ref_mp = naive.aampi_egress(T[:n], m) + ref_mp = naive.aampi_egress(T, m) ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ + # ref_I = ref_mp.I_ ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ + # ref_left_I = ref_mp.left_I_ - stream = aampi(pd.Series(T[:n]), m, egress=True) + stream = aampi(T, m, egress=True) comp_P = stream.P_.copy() - comp_I = stream.I_ + # comp_I = stream.I_ comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ + # comp_left_I = stream.left_I_ naive.replace_inf(ref_P) naive.replace_inf(comp_P) @@ -492,25 +634,24 @@ def test_aampi_stream_nan_inf_self_join_egress(substitute, substitution_location naive.replace_inf(comp_left_P) npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + # npt.assert_almost_equal(ref_I, comp_I) npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) - if substitution_location == -1: # pragma: no cover - substitution_location = T[n:].shape[0] - 1 - T[n:][substitution_location] = substitute - for t in T[n:]: + # npt.assert_almost_equal(ref_left_I, comp_left_I) + + for i in range(34): + t = rng.RNG.rand() ref_mp.update(t) stream.update(t) comp_P = stream.P_.copy() - comp_I = stream.I_ + # comp_I = stream.I_ comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ + # comp_left_I = stream.left_I_ ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ + # ref_I = ref_mp.I_ ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ + # ref_left_I = ref_mp.left_I_ naive.replace_inf(ref_P) naive.replace_inf(ref_left_P) @@ -518,168 +659,15 @@ def test_aampi_stream_nan_inf_self_join_egress(substitute, substitution_location naive.replace_inf(comp_left_P) npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + # npt.assert_almost_equal(ref_I, comp_I) npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) - - -def test_aampi_constant_subsequence_self_join(): - m = 3 - - seed = np.random.randint(100000) - np.random.seed(seed) - - T = np.concatenate((np.zeros(20, dtype=np.float64), np.ones(10, dtype=np.float64))) - stream = aampi(T, m, egress=False) - for i in range(34): - t = np.random.rand() - stream.update(t) - - comp_P = stream.P_ - # comp_I = stream.I_ - - ref_mp = naive.aamp(stream.T_, m) - ref_P = ref_mp[:, 0] - # ref_I = ref_mp[:, 1] - - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) - - npt.assert_almost_equal(ref_P, comp_P) - # npt.assert_almost_equal(ref_I, comp_I) - - np.random.seed(seed) - T = np.concatenate((np.zeros(20, dtype=np.float64), np.ones(10, dtype=np.float64))) - T = pd.Series(T) - stream = aampi(T, m, egress=False) - for i in range(34): - t = np.random.rand() - stream.update(t) - - comp_P = stream.P_ - # comp_I = stream.I_ - - naive.replace_inf(comp_P) - - npt.assert_almost_equal(ref_P, comp_P) - # npt.assert_almost_equal(ref_I, comp_I) - - -def test_aampi_constant_subsequence_self_join_egress(): - m = 3 - - seed = np.random.randint(100000) - np.random.seed(seed) - - T = np.concatenate((np.zeros(20, dtype=np.float64), np.ones(10, dtype=np.float64))) - - ref_mp = naive.aampi_egress(T, m) - ref_P = ref_mp.P_.copy() - # ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - # ref_left_I = ref_mp.left_I_ - - stream = aampi(T, m, egress=True) - - comp_P = stream.P_.copy() - # comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - # comp_left_I = stream.left_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P) - # npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - # npt.assert_almost_equal(ref_left_I, comp_left_I) - - for i in range(34): - t = np.random.rand() - ref_mp.update(t) - stream.update(t) - - comp_P = stream.P_.copy() - # comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - # comp_left_I = stream.left_I_ - - ref_P = ref_mp.P_.copy() - # ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - # ref_left_I = ref_mp.left_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P) - # npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - # npt.assert_almost_equal(ref_left_I, comp_left_I) - - np.random.seed(seed) - T = np.concatenate((np.zeros(20, dtype=np.float64), np.ones(10, dtype=np.float64))) - T = pd.Series(T) - - ref_mp = naive.aampi_egress(T, m) - ref_P = ref_mp.P_.copy() - # ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - # ref_left_I = ref_mp.left_I_ - - stream = aampi(T, m, egress=True) - - comp_P = stream.P_.copy() - # comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - # comp_left_I = stream.left_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P) - # npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - # npt.assert_almost_equal(ref_left_I, comp_left_I) - - for i in range(34): - t = np.random.rand() - ref_mp.update(t) - stream.update(t) - - comp_P = stream.P_.copy() - # comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - # comp_left_I = stream.left_I_ - - ref_P = ref_mp.P_.copy() - # ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - # ref_left_I = ref_mp.left_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P) - # npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - # npt.assert_almost_equal(ref_left_I, comp_left_I) + # npt.assert_almost_equal(ref_left_I, comp_left_I) def test_aampi_update_constant_subsequence_self_join(): m = 3 - seed = np.random.randint(100000) - np.random.seed(seed) - T_full = np.random.rand(64) # generate random data + T_full = rng.RNG.rand(64) # generate random data T_full[40:55] = 3 # add constant level interval T_stream = T_full[:10].copy() @@ -715,10 +703,7 @@ def test_aampi_update_constant_subsequence_self_join(): def test_aampi_update_constant_subsequence_self_join_egress(): m = 3 - seed = np.random.randint(100000) - np.random.seed(seed) - - T_full = np.random.rand(64) # generate random data + T_full = rng.RNG.rand(64) # generate random data T_full[40:55] = 3 # add constant level interval T_stream = T_full[:10].copy() @@ -778,105 +763,74 @@ def test_aampi_update_constant_subsequence_self_join_egress(): def test_aampi_identical_subsequence_self_join(): m = 3 - seed = np.random.randint(100000) - np.random.seed(seed) - - identical = np.random.rand(8) - T = np.random.rand(20) - T[1 : 1 + identical.shape[0]] = identical - T[11 : 11 + identical.shape[0]] = identical - stream = aampi(T, m, egress=False) - for i in range(34): - t = np.random.rand() - stream.update(t) + with rng.fix_state(): + identical = rng.RNG.rand(8) + T = rng.RNG.rand(20) + T[1 : 1 + identical.shape[0]] = identical + T[11 : 11 + identical.shape[0]] = identical + stream = aampi(T, m, egress=False) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) - comp_P = stream.P_ - # comp_I = stream.I_ + comp_P = stream.P_ + # comp_I = stream.I_ - ref_mp = naive.aamp(stream.T_, m) - ref_P = ref_mp[:, 0] - # ref_I = ref_mp[:, 1] + ref_mp = naive.aamp(stream.T_, m) + ref_P = ref_mp[:, 0] + # ref_I = ref_mp[:, 1] + + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) + npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) + # npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) - # npt.assert_almost_equal(ref_I, comp_I) - - np.random.seed(seed) - identical = np.random.rand(8) - T = np.random.rand(20) - T[1 : 1 + identical.shape[0]] = identical - T[11 : 11 + identical.shape[0]] = identical - T = pd.Series(T) - stream = aampi(T, m, egress=False) - for i in range(34): - t = np.random.rand() - stream.update(t) + with rng.fix_state(): + identical = rng.RNG.rand(8) + T = rng.RNG.rand(20) + T[1 : 1 + identical.shape[0]] = identical + T[11 : 11 + identical.shape[0]] = identical + T = pd.Series(T) + stream = aampi(T, m, egress=False) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) - comp_P = stream.P_ - # comp_I = stream.I_ + comp_P = stream.P_ + # comp_I = stream.I_ - naive.replace_inf(comp_P) + naive.replace_inf(comp_P) - npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) - # npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) + # npt.assert_almost_equal(ref_I, comp_I) def test_aampi_identical_subsequence_self_join_egress(): m = 3 - seed = np.random.randint(100000) - np.random.seed(seed) + with rng.fix_state(): + identical = rng.RNG.rand(8) + T = rng.RNG.rand(20) + T[1 : 1 + identical.shape[0]] = identical + T[11 : 11 + identical.shape[0]] = identical - identical = np.random.rand(8) - T = np.random.rand(20) - T[1 : 1 + identical.shape[0]] = identical - T[11 : 11 + identical.shape[0]] = identical - - ref_mp = naive.aampi_egress(T, m) - ref_P = ref_mp.P_.copy() - # ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - # ref_left_I = ref_mp.left_I_ - - stream = aampi(T, m, egress=True) - - comp_P = stream.P_.copy() - # comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - # comp_left_I = stream.left_I_ + ref_mp = naive.aampi_egress(T, m) + ref_P = ref_mp.P_.copy() + # ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + # ref_left_I = ref_mp.left_I_ - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) - # npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal( - ref_left_P, comp_left_P, decimal=config.STUMPY_TEST_PRECISION - ) - # npt.assert_almost_equal(ref_left_I, comp_left_I) - - for i in range(34): - t = np.random.rand() - ref_mp.update(t) - stream.update(t) + stream = aampi(T, m, egress=True) comp_P = stream.P_.copy() # comp_I = stream.I_ comp_left_P = stream.left_P_.copy() # comp_left_I = stream.left_I_ - ref_P = ref_mp.P_.copy() - # ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - # ref_left_I = ref_mp.left_I_ - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) + naive.replace_inf(ref_left_P) naive.replace_inf(comp_left_P) npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) @@ -886,56 +840,56 @@ def test_aampi_identical_subsequence_self_join_egress(): ) # npt.assert_almost_equal(ref_left_I, comp_left_I) - np.random.seed(seed) - identical = np.random.rand(8) - T = np.random.rand(20) - T[1 : 1 + identical.shape[0]] = identical - T[11 : 11 + identical.shape[0]] = identical - T = pd.Series(T) - - ref_mp = naive.aampi_egress(T, m) - ref_P = ref_mp.P_.copy() - # ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - # ref_left_I = ref_mp.left_I_ + for i in range(34): + t = rng.RNG.rand() + ref_mp.update(t) + stream.update(t) - stream = aampi(T, m, egress=True) + comp_P = stream.P_.copy() + # comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + # comp_left_I = stream.left_I_ - comp_P = stream.P_.copy() - # comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - # comp_left_I = stream.left_I_ + ref_P = ref_mp.P_.copy() + # ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + # ref_left_I = ref_mp.left_I_ - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) - # npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal( - ref_left_P, comp_left_P, decimal=config.STUMPY_TEST_PRECISION - ) - # npt.assert_almost_equal(ref_left_I, comp_left_I) - - for i in range(34): - t = np.random.rand() - ref_mp.update(t) - stream.update(t) + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - comp_P = stream.P_.copy() - # comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - # comp_left_I = stream.left_I_ + npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) + # npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal( + ref_left_P, comp_left_P, decimal=config.STUMPY_TEST_PRECISION + ) + # npt.assert_almost_equal(ref_left_I, comp_left_I) + + with rng.fix_state(): + identical = rng.RNG.rand(8) + T = rng.RNG.rand(20) + T[1 : 1 + identical.shape[0]] = identical + T[11 : 11 + identical.shape[0]] = identical + T = pd.Series(T) + ref_mp = naive.aampi_egress(T, m) ref_P = ref_mp.P_.copy() # ref_I = ref_mp.I_ ref_left_P = ref_mp.left_P_.copy() # ref_left_I = ref_mp.left_I_ + stream = aampi(T, m, egress=True) + + comp_P = stream.P_.copy() + # comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + # comp_left_I = stream.left_I_ + naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) + naive.replace_inf(ref_left_P) naive.replace_inf(comp_left_P) npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) @@ -945,9 +899,36 @@ def test_aampi_identical_subsequence_self_join_egress(): ) # npt.assert_almost_equal(ref_left_I, comp_left_I) + for i in range(34): + t = rng.RNG.rand() + ref_mp.update(t) + stream.update(t) + + comp_P = stream.P_.copy() + # comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + # comp_left_I = stream.left_I_ + + ref_P = ref_mp.P_.copy() + # ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + # ref_left_I = ref_mp.left_I_ + + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + + npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) + # npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal( + ref_left_P, comp_left_P, decimal=config.STUMPY_TEST_PRECISION + ) + # npt.assert_almost_equal(ref_left_I, comp_left_I) + def test_aampi_profile_index_match(): - T_full = np.random.rand(64) + T_full = rng.RNG.rand(64) m = 3 T_full_subseq = core.rolling_window(T_full, m) warm_start = 8 @@ -984,115 +965,85 @@ def test_aampi_self_join_KNN(): m = 3 for k in range(2, 4): for p in [1.0, 2.0, 3.0]: - seed = np.random.randint(100000) - np.random.seed(seed) - - n = 30 - T = np.random.rand(n) - stream = aampi(T, m, egress=False, p=p, k=k) - for i in range(34): - t = np.random.rand() - stream.update(t) - - comp_P = stream.P_ - comp_I = stream.I_ - comp_left_P = stream.left_P_ - comp_left_I = stream.left_I_ + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(n) + stream = aampi(T, m, egress=False, p=p, k=k) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) + + comp_P = stream.P_ + comp_I = stream.I_ + comp_left_P = stream.left_P_ + comp_left_I = stream.left_I_ - ref_mp = naive.aamp(stream.T_, m, p=p, k=k) - ref_P = ref_mp[:, :k] - ref_I = ref_mp[:, k : 2 * k] + ref_mp = naive.aamp(stream.T_, m, p=p, k=k) + ref_P = ref_mp[:, :k] + ref_I = ref_mp[:, k : 2 * k] - ref_left_I = ref_mp[:, 2 * k] - ref_left_P = np.full_like(ref_left_I, np.inf, dtype=np.float64) - for i, j in enumerate(ref_left_I): - if j >= 0: - ref_left_P[i] = np.linalg.norm( - stream.T_[i : i + m] - stream.T_[j : j + m], ord=p - ) + ref_left_I = ref_mp[:, 2 * k] + ref_left_P = np.full_like(ref_left_I, np.inf, dtype=np.float64) + for i, j in enumerate(ref_left_I): + if j >= 0: + ref_left_P[i] = np.linalg.norm( + stream.T_[i : i + m] - stream.T_[j : j + m], ord=p + ) - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) - np.random.seed(seed) - n = 30 - T = np.random.rand(n) - T = pd.Series(T) - stream = aampi(T, m, egress=False, p=p, k=k) - for i in range(34): - t = np.random.rand() - stream.update(t) + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(n) + T = pd.Series(T) + stream = aampi(T, m, egress=False, p=p, k=k) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) - comp_P = stream.P_ - comp_I = stream.I_ - comp_left_P = stream.left_P_ - comp_left_I = stream.left_I_ + comp_P = stream.P_ + comp_I = stream.I_ + comp_left_P = stream.left_P_ + comp_left_I = stream.left_I_ - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) def test_aampi_self_join_egress_KNN(): m = 3 for k in range(2, 4): for p in [1.0, 2.0, 3.0]: - seed = np.random.randint(100000) - np.random.seed(seed) - - n = 30 - T = np.random.rand(n) - - ref_mp = naive.aampi_egress(T, m, p=p, k=k) - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ - - stream = aampi(T, m, egress=True, p=p, k=k) - - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(n) - for i in range(34): - t = np.random.rand() + ref_mp = naive.aampi_egress(T, m, p=p, k=k) + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ - ref_mp.update(t) - stream.update(t) + stream = aampi(T, m, egress=True, p=p, k=k) comp_P = stream.P_.copy() comp_I = stream.I_ comp_left_P = stream.left_P_.copy() comp_left_I = stream.left_I_ - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ - naive.replace_inf(ref_P) naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) @@ -1103,102 +1054,100 @@ def test_aampi_self_join_egress_KNN(): npt.assert_almost_equal(ref_left_P, comp_left_P) npt.assert_almost_equal(ref_left_I, comp_left_I) - np.random.seed(seed) - T = np.random.rand(n) - T = pd.Series(T) + for i in range(34): + t = rng.RNG.rand() - ref_mp = naive.aampi_egress(T, m, p=p, k=k) - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ + ref_mp.update(t) + stream.update(t) - stream = aampi(T, m, egress=True, p=p, k=k) + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ - comp_P = stream.P_.copy() - comp_I = stream.I_ + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) - for i in range(34): - t = np.random.rand() + with rng.fix_state(): + T = rng.RNG.rand(n) + T = pd.Series(T) - ref_mp.update(t) - stream.update(t) + ref_mp = naive.aampi_egress(T, m, p=p, k=k) + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + + stream = aampi(T, m, egress=True, p=p, k=k) comp_P = stream.P_.copy() comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ - - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + for i in range(34): + t = rng.RNG.rand() -def test_aampi_self_join_egress_passing_mp(): - m = 3 + ref_mp.update(t) + stream.update(t) - for p in [1.0, 2.0, 3.0]: - seed = np.random.randint(100000) - np.random.seed(seed) + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ - n = 30 - T = np.random.rand(n) - mp = naive.aamp(T, m, p=p) + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ - ref_mp = naive.aampi_egress(T, m, p=p, mp=mp) - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - stream = aampi(T, m, egress=True, p=p, mp=mp) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) +def test_aampi_self_join_egress_passing_mp(): + m = 3 - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + for p in [1.0, 2.0, 3.0]: + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(n) + mp = naive.aamp(T, m, p=p) - for i in range(34): - t = np.random.rand() + ref_mp = naive.aampi_egress(T, m, p=p, mp=mp) + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ - ref_mp.update(t) - stream.update(t) + stream = aampi(T, m, egress=True, p=p, mp=mp) comp_P = stream.P_.copy() comp_I = stream.I_ comp_left_P = stream.left_P_.copy() comp_left_I = stream.left_I_ - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ - naive.replace_inf(ref_P) naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) @@ -1208,3 +1157,29 @@ def test_aampi_self_join_egress_passing_mp(): npt.assert_almost_equal(ref_I, comp_I) npt.assert_almost_equal(ref_left_P, comp_left_P) npt.assert_almost_equal(ref_left_I, comp_left_I) + + for i in range(34): + t = rng.RNG.rand() + + ref_mp.update(t) + stream.update(t) + + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ + + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ + + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) diff --git a/tests/test_cache.py b/tests/test_cache.py index 4b70b48ae..ffd4fe1ce 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -1,7 +1,6 @@ import numba -import numpy as np -from stumpy import cache +from stumpy import cache, rng from stumpy.stump import stump @@ -11,7 +10,7 @@ def test_cache_get_njit_funcs(): def test_cache_save_after_clear(): - T = np.random.rand(10) + T = rng.RNG.rand(10) m = 3 cache_dir = "stumpy/__pycache__" diff --git a/tests/test_core.py b/tests/test_core.py index 5be54321e..61371e984 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -11,7 +11,7 @@ from numba import cuda from scipy.spatial.distance import cdist -from stumpy import config, core +from stumpy import config, core, rng from stumpy.stump import stump if cuda.is_available(): @@ -141,7 +141,7 @@ def naive_bfs_indices(n, fill_value=None): np.array([9, 8100, -60], dtype=np.float64), np.array([584, -11, 23, 79, 1001], dtype=np.float64), ), - (np.random.uniform(-1000, 1000, [8]), np.random.uniform(-1000, 1000, [64])), + (rng.RNG.uniform(-1000, 1000, [8]), rng.RNG.uniform(-1000, 1000, [64])), ] n = list(range(1, 50)) @@ -150,11 +150,11 @@ def naive_bfs_indices(n, fill_value=None): def test_check_bad_dtype(): for dtype in [np.int32, np.int64, np.float32]: with pytest.raises(TypeError): - core.check_dtype(np.random.rand(10).astype(dtype)) + core.check_dtype(rng.RNG.rand(10).astype(dtype)) def test_check_dtype_float64(): - assert core.check_dtype(np.random.rand(10)) + assert core.check_dtype(rng.RNG.rand(10)) def test_get_max_window_size(): @@ -188,7 +188,7 @@ def test_check_max_window_size(): def test_check_window_size_excl_zone(): # To ensure warning is raised if there is at least one subsequence # that has no non-trivial neighbor - T = np.random.rand(10) + T = rng.RNG.rand(10) m = 7 # For `len(T) == 10` and `m == 7`, the `excl_zone` is ceil(m / 4) = 2. @@ -208,7 +208,7 @@ def test_sliding_dot_product(Q, T): def test_welford_nanvar(): - T = np.random.rand(64) + T = rng.RNG.rand(64) m = 10 ref_var = np.nanvar(T) @@ -230,7 +230,7 @@ def test_welford_nanvar_catastrophic_cancellation(): def test_welford_nanvar_nan(): - T = np.random.rand(64) + T = rng.RNG.rand(64) m = 10 T[1] = np.nan @@ -247,7 +247,7 @@ def test_welford_nanvar_nan(): def test_welford_nanstd(): - T = np.random.rand(64) + T = rng.RNG.rand(64) m = 10 ref_var = np.nanstd(T) @@ -260,7 +260,7 @@ def test_welford_nanstd(): def test_rolling_std_1d(): - a = np.random.rand(64) + a = rng.RNG.rand(64) for w in range(3, 6): ref_std = naive.rolling_nanstd(a, w) @@ -276,7 +276,7 @@ def test_rolling_std_1d(): def test_rolling_std_2d(): w = 5 for n_rows in range(1, 4): - a = np.random.rand(n_rows * 64).reshape(n_rows, 64) + a = rng.RNG.rand(n_rows * 64).reshape(n_rows, 64) ref_std = naive.rolling_nanstd(a, w) # welford = False (default) @@ -289,7 +289,7 @@ def test_rolling_std_2d(): def test_rolling_nanmin_1d(): - T = np.random.rand(64) + T = rng.RNG.rand(64) for m in range(1, 12): ref_min = np.nanmin(T) comp_min = core._rolling_nanmin_1d(T) @@ -301,7 +301,7 @@ def test_rolling_nanmin_1d(): def test_rolling_nanmin(): - T = np.random.rand(64) + T = rng.RNG.rand(64) for m in range(1, 12): ref_min = np.nanmin(core.rolling_window(T, m), axis=1) comp_min = core.rolling_nanmin(T, m) @@ -313,7 +313,7 @@ def test_rolling_nanmin(): def test_rolling_nanmax_1d(): - T = np.random.rand(64) + T = rng.RNG.rand(64) for m in range(1, 12): ref_max = np.nanmax(T) comp_max = core._rolling_nanmax_1d(T) @@ -325,7 +325,7 @@ def test_rolling_nanmax_1d(): def test_rolling_nanmax(): - T = np.random.rand(64) + T = rng.RNG.rand(64) for m in range(1, 12): ref_max = np.nanmax(core.rolling_window(T, m), axis=1) comp_max = core.rolling_nanmax(T, m) @@ -387,8 +387,8 @@ def test_compute_mean_std_chunked_many(Q, T): def test_compute_mean_std_multidimensional(Q, T): m = Q.shape[0] - Q = np.array([Q, np.random.uniform(-1000, 1000, [Q.shape[0]])]) - T = np.array([T, T, np.random.uniform(-1000, 1000, [T.shape[0]])]) + Q = np.array([Q, rng.RNG.uniform(-1000, 1000, [Q.shape[0]])]) + T = np.array([T, T, rng.RNG.uniform(-1000, 1000, [T.shape[0]])]) ref_μ_Q, ref_σ_Q = naive_compute_mean_std_multidimensional(Q, m) ref_M_T, ref_Σ_T = naive_compute_mean_std_multidimensional(T, m) @@ -405,8 +405,8 @@ def test_compute_mean_std_multidimensional(Q, T): def test_compute_mean_std_multidimensional_chunked(Q, T): m = Q.shape[0] - Q = np.array([Q, np.random.uniform(-1000, 1000, [Q.shape[0]])]) - T = np.array([T, T, np.random.uniform(-1000, 1000, [T.shape[0]])]) + Q = np.array([Q, rng.RNG.uniform(-1000, 1000, [Q.shape[0]])]) + T = np.array([T, T, rng.RNG.uniform(-1000, 1000, [T.shape[0]])]) with patch("stumpy.config.STUMPY_MEAN_STD_NUM_CHUNKS", 2): ref_μ_Q, ref_σ_Q = naive_compute_mean_std_multidimensional(Q, m) @@ -424,8 +424,8 @@ def test_compute_mean_std_multidimensional_chunked(Q, T): def test_compute_mean_std_multidimensional_chunked_many(Q, T): m = Q.shape[0] - Q = np.array([Q, np.random.uniform(-1000, 1000, [Q.shape[0]])]) - T = np.array([T, T, np.random.uniform(-1000, 1000, [T.shape[0]])]) + Q = np.array([Q, rng.RNG.uniform(-1000, 1000, [Q.shape[0]])]) + T = np.array([T, T, rng.RNG.uniform(-1000, 1000, [T.shape[0]])]) with patch("stumpy.config.STUMPY_MEAN_STD_NUM_CHUNKS", 128): ref_μ_Q, ref_σ_Q = naive_compute_mean_std_multidimensional(Q, m) @@ -918,7 +918,7 @@ def test_preprocess_diagonal(): def test_replace_distance(): - right = np.random.rand(30).reshape(5, 6) + right = rng.RNG.rand(30).reshape(5, 6) left = right.copy() np.fill_diagonal(right, config.STUMPY_MAX_DISTANCE - 1e-9) np.fill_diagonal(left, np.inf) @@ -926,7 +926,7 @@ def test_replace_distance(): def test_array_to_temp_file(): - left = np.random.rand() + left = rng.RNG.rand() fname = core.array_to_temp_file(left) right = np.load(fname, allow_pickle=False) os.remove(fname) @@ -938,7 +938,7 @@ def test_count_diagonal_ndist(): for n_A in range(10, 15): for n_B in range(10, 15): for m in range(3, 6): - diags = np.random.permutation( + diags = rng.RNG.permutation( range(-(n_A - m + 1) + 1, n_B - m + 1) ).astype(np.int64) ones_matrix = np.ones((n_A - m + 1, n_B - m + 1), dtype=np.int64) @@ -1107,12 +1107,12 @@ def test_get_mask_slices(): def test_idx_to_mp(): n = 64 m = 5 - T = np.random.rand(n) + T = rng.RNG.rand(n) # T[1] = np.nan # T[8] = np.inf # T[:] = 1.0 l = n - m + 1 - I = np.random.randint(0, l, l) + I = rng.RNG.randint(0, l, l) # `normalize == True` and `T_subseq_isconstant` is None (default) ref_mp = naive_idx_to_mp(I, T, m) @@ -1120,7 +1120,7 @@ def test_idx_to_mp(): npt.assert_almost_equal(ref_mp, cmp_mp) # `normalize == True` and `T_subseq_isconstant` is provided - T_subseq_isconstant = np.random.choice([True, False], l, replace=True) + T_subseq_isconstant = rng.RNG.choice([True, False], l, replace=True) ref_mp = naive_idx_to_mp(I, T, m, T_subseq_isconstant=T_subseq_isconstant) cmp_mp = core._idx_to_mp(I, T, m, T_subseq_isconstant=T_subseq_isconstant) npt.assert_almost_equal(ref_mp, cmp_mp) @@ -1171,7 +1171,7 @@ def test_bfs_indices_fill_value(n): def test_select_P_ABBA_val_inf(): - P_ABBA = np.random.rand(10) + P_ABBA = rng.RNG.rand(10) k = 2 P_ABBA[k:] = np.inf p_abba = P_ABBA.copy() @@ -1187,13 +1187,13 @@ def test_merge_topk_PI_without_overlap(): # is no overlap between row IA[i] and row IB[i]. n = 50 for k in range(1, 6): - PA = np.random.rand(n * k).reshape(n, k) + PA = rng.RNG.rand(n * k).reshape(n, k) PA[:, :] = np.sort(PA, axis=1) # sorting each row separately - PB = np.random.rand(n * k).reshape(n, k) - col_idx = np.random.randint(0, k, size=n) + PB = rng.RNG.rand(n * k).reshape(n, k) + col_idx = rng.RNG.randint(0, k, size=n) for i in range(n): # creating ties between values of PA and PB - val = np.random.choice(PA[i], size=1, replace=False) + val = rng.RNG.choice(PA[i], size=1, replace=False) PB[i, col_idx[i]] = val.item() PB[:, :] = np.sort(PB, axis=1) # sorting each row separately @@ -1220,17 +1220,17 @@ def test_merge_topk_PI_with_overlap(): for k in range(1, 6): # note: we do not have overlap issue when k is 1. The `k=1` is considered # for the sake of consistency with the `without-overlap` test function. - PA = np.random.rand(n * k).reshape(n, k) - PB = np.random.rand(n * k).reshape(n, k) + PA = rng.RNG.rand(n * k).reshape(n, k) + PB = rng.RNG.rand(n * k).reshape(n, k) IA = np.arange(n * k).reshape(n, k) IB = IA + n * k - num_overlaps = np.random.randint(1, k + 1, size=n) + num_overlaps = rng.RNG.randint(1, k + 1, size=n) for i in range(n): # create overlaps - col_IDX = np.random.choice(np.arange(k), num_overlaps[i], replace=False) - imprecision = np.random.uniform(low=-1e-06, high=1e-06, size=len(col_IDX)) + col_IDX = rng.RNG.choice(np.arange(k), num_overlaps[i], replace=False) + imprecision = rng.RNG.uniform(low=-1e-06, high=1e-06, size=len(col_IDX)) PB[i, col_IDX] = PA[i, col_IDX] + imprecision IB[i, col_IDX] = IA[i, col_IDX] @@ -1259,15 +1259,15 @@ def test_merge_topk_PI_with_overlap(): def test_merge_topk_PI_with_1D_input(): # including some overlaps randomly n = 50 - PA = np.random.rand(n) - PB = np.random.rand(n) + PA = rng.RNG.rand(n) + PB = rng.RNG.rand(n) IA = np.arange(n) IB = IA + n - n_overlaps = np.random.randint(1, n + 1) - IDX_rows_with_overlaps = np.random.choice(np.arange(n), n_overlaps, replace=False) - imprecision = np.random.uniform(low=-1e-06, high=1e-06, size=n_overlaps) + n_overlaps = rng.RNG.randint(1, n + 1) + IDX_rows_with_overlaps = rng.RNG.choice(np.arange(n), n_overlaps, replace=False) + imprecision = rng.RNG.uniform(low=-1e-06, high=1e-06, size=n_overlaps) PB[IDX_rows_with_overlaps] = PA[IDX_rows_with_overlaps] + imprecision IB[IDX_rows_with_overlaps] = IA[IDX_rows_with_overlaps] @@ -1312,13 +1312,13 @@ def test_merge_topk_ρI_without_overlap(): # is no overlap between row IA[i] and row IB[i]. n = 50 for k in range(1, 6): - ρA = np.random.rand(n * k).reshape(n, k) + ρA = rng.RNG.rand(n * k).reshape(n, k) ρA[:, :] = np.sort(ρA, axis=1) # sorting each row separately - ρB = np.random.rand(n * k).reshape(n, k) - col_idx = np.random.randint(0, k, size=n) + ρB = rng.RNG.rand(n * k).reshape(n, k) + col_idx = rng.RNG.randint(0, k, size=n) for i in range(n): # creating ties between values of PA and PB - val = np.random.choice(ρA[i], size=1, replace=False) + val = rng.RNG.choice(ρA[i], size=1, replace=False) ρB[i, col_idx[i]] = val.item() ρB[:, :] = np.sort(ρB, axis=1) # sorting each row separately @@ -1345,17 +1345,17 @@ def test_merge_topk_ρI_with_overlap(): for k in range(1, 6): # note: we do not have overlap issue when k is 1. The `k=1` is considered # for the sake of consistency with the `without-overlap` test function. - ρA = np.random.rand(n * k).reshape(n, k) - ρB = np.random.rand(n * k).reshape(n, k) + ρA = rng.RNG.rand(n * k).reshape(n, k) + ρB = rng.RNG.rand(n * k).reshape(n, k) IA = np.arange(n * k).reshape(n, k) IB = IA + n * k - num_overlaps = np.random.randint(1, k + 1, size=n) + num_overlaps = rng.RNG.randint(1, k + 1, size=n) for i in range(n): # create overlaps - col_IDX = np.random.choice(np.arange(k), num_overlaps[i], replace=False) - imprecision = np.random.uniform(low=-1e-06, high=1e-06, size=len(col_IDX)) + col_IDX = rng.RNG.choice(np.arange(k), num_overlaps[i], replace=False) + imprecision = rng.RNG.uniform(low=-1e-06, high=1e-06, size=len(col_IDX)) ρB[i, col_IDX] = ρA[i, col_IDX] + imprecision IB[i, col_IDX] = IA[i, col_IDX] @@ -1384,15 +1384,15 @@ def test_merge_topk_ρI_with_overlap(): def test_merge_topk_ρI_with_1D_input(): # including some overlaps randomly n = 50 - ρA = np.random.rand(n) - ρB = np.random.rand(n) + ρA = rng.RNG.rand(n) + ρB = rng.RNG.rand(n) IA = np.arange(n) IB = IA + n - n_overlaps = np.random.randint(1, n + 1) - IDX_rows_with_overlaps = np.random.choice(np.arange(n), n_overlaps, replace=False) - imprecision = np.random.uniform(low=-1e-06, high=1e-06, size=n_overlaps) + n_overlaps = rng.RNG.randint(1, n + 1) + IDX_rows_with_overlaps = rng.RNG.choice(np.arange(n), n_overlaps, replace=False) + imprecision = rng.RNG.uniform(low=-1e-06, high=1e-06, size=n_overlaps) ρB[IDX_rows_with_overlaps] = ρA[IDX_rows_with_overlaps] + imprecision IB[IDX_rows_with_overlaps] = IA[IDX_rows_with_overlaps] @@ -1434,12 +1434,12 @@ def test_merge_topk_ρI_with_1D_input_hardcoded(): def test_shift_insert_at_index(): for k in range(1, 6): - a = np.random.rand(k) + a = rng.RNG.rand(k) ref = np.empty(k, dtype=np.float64) comp = np.empty(k, dtype=np.float64) indices = np.arange(k + 1) - values = np.random.rand(k + 1) + values = rng.RNG.rand(k + 1) # test shift = "right" for idx, v in zip(indices, values): @@ -1468,13 +1468,13 @@ def test_shift_insert_at_index(): def test_check_P(): with pytest.raises(ValueError): - core._check_P(np.random.rand(10).reshape(2, 5)) + core._check_P(rng.RNG.rand(10).reshape(2, 5)) def test_find_matches_all(): # max_matches: None, i.e. find all matches max_distance = np.inf - D = np.random.rand(64) + D = rng.RNG.rand(64) for excl_zone in range(3): ref = naive.find_matches(D, excl_zone, max_distance, max_matches=None) comp = core._find_matches(D, excl_zone, max_distance, max_matches=None) @@ -1484,9 +1484,9 @@ def test_find_matches_all(): def test_find_matches_maxmatch(): max_distance = np.inf - D = np.random.rand(64) + D = rng.RNG.rand(64) for excl_zone in range(3): - max_matches = np.random.randint(0, 100) + max_matches = rng.RNG.randint(0, 100) ref = naive.find_matches(D, excl_zone, max_distance, max_matches) comp = core._find_matches(D, excl_zone, max_distance, max_matches) @@ -1509,11 +1509,11 @@ def test_gpu_searchsorted(): device_bfs = cuda.to_device(core._bfs_indices(k, fill_value=-1)) nlevel = np.floor(np.log2(k) + 1).astype(np.int64) - A = np.sort(np.random.rand(n, k), axis=1) + A = np.sort(rng.RNG.rand(n, k), axis=1) device_A = cuda.to_device(A) - V[:] = np.random.rand(n) - for i, idx in enumerate(np.random.choice(np.arange(n), size=k, replace=False)): + V[:] = rng.RNG.rand(n) + for i, idx in enumerate(rng.RNG.choice(np.arange(n), size=k, replace=False)): V[idx] = A[idx, i] # create ties device_V = cuda.to_device(V) @@ -1548,7 +1548,7 @@ def test_client_to_func(): def test_apply_include(): - D = np.random.uniform(-1000, 1000, [10, 20]).astype(np.float64) + D = rng.RNG.uniform(-1000, 1000, [10, 20]).astype(np.float64) ref_D = np.empty(D.shape) comp_D = np.empty(D.shape) for width in range(D.shape[0]): @@ -1683,7 +1683,7 @@ def test_process_isconstant_1d(): m = 8 # case 1: without nan - T = np.random.rand(n) + T = rng.RNG.rand(n) T_subseq_isconstant_ref = naive.rolling_isconstant(T, m, isconstant_custom_func) T_subseq_isconstant_comp = core.process_isconstant(T, m, isconstant_custom_func) @@ -1691,10 +1691,10 @@ def test_process_isconstant_1d(): npt.assert_array_equal(T_subseq_isconstant_ref, T_subseq_isconstant_comp) # case 2: with nan - T = np.random.rand(n) - idx = np.random.randint(n) + T = rng.RNG.rand(n) + idx = rng.RNG.randint(n) T[idx] = np.nan - T_subseq_isconstant = np.random.choice([True, False], n - m + 1, replace=True) + T_subseq_isconstant = rng.RNG.choice([True, False], n - m + 1, replace=True) T_subseq_isfinite = core.rolling_isfinite(T, m) @@ -1714,11 +1714,11 @@ def test_process_isconstant_2d(): d = 3 # case 1: without nan - T = np.random.rand(d, n) + T = rng.RNG.rand(d, n) T_subseq_isconstant = [ None, isconstant_custom_func, - np.random.choice([True, False], n - m + 1, replace=True), + rng.RNG.choice([True, False], n - m + 1, replace=True), ] T_subseq_isconstant_ref = np.array( @@ -1730,8 +1730,8 @@ def test_process_isconstant_2d(): npt.assert_array_equal(T_subseq_isconstant_ref, T_subseq_isconstant_comp) # case 2: with nan - T = np.random.rand(d, n) - i, j = np.random.choice(np.arange(n - m + 1), size=2, replace=False) + T = rng.RNG.rand(d, n) + i, j = rng.RNG.choice(np.arange(n - m + 1), size=2, replace=False) T[-1, i : i + m] = 0.0 T[-1, j : j + m] = 0.0 T[-1, j] = np.nan @@ -1764,7 +1764,7 @@ def test_process_isconstant_1d_default(): m = 8 # case 1: without nan - T = np.random.rand(n) + T = rng.RNG.rand(n) T[:m] = 0.5 # constant subsequence T_subseq_isconstant_ref = naive.rolling_isconstant(T, m, a_subseq_isconstant=None) @@ -1773,7 +1773,7 @@ def test_process_isconstant_1d_default(): npt.assert_array_equal(T_subseq_isconstant_ref, T_subseq_isconstant_comp) # case 2: with nan - T = np.random.rand(n) + T = rng.RNG.rand(n) T[:m] = 0.5 # constant subsequence T[-m:] = np.nan # non-finite subsequence @@ -1787,8 +1787,8 @@ def test_update_incremental_PI_egressFalse(): # This tests the function `core._update_incremental_PI` # when `egress` is False, meaning new data point is being # appended to the historical data. - T = np.random.rand(64) - t = np.random.rand() # new datapoint + T = rng.RNG.rand(64) + t = rng.RNG.rand() # new datapoint T_new = np.append(T, t) m = 3 @@ -1829,8 +1829,8 @@ def test_update_incremental_PI_egressFalse(): def test_update_incremental_PI_egressTrue(): - T = np.random.rand(64) - t = np.random.rand() # new data point + T = rng.RNG.rand(64) + t = rng.RNG.rand() # new data point m = 3 excl_zone = int(np.ceil(m / config.STUMPY_EXCL_ZONE_DENOM)) @@ -1891,66 +1891,66 @@ def test_update_incremental_PI_egressTrue_MemoryCheck(): # a new data point is appended. However, the updated matrix profile index for the # middle subsequence `s` should still refer to the first subsequence in # the historical data. - seed = 0 - np.random.seed(seed) + with rng.fix_seed(0): + T = rng.RNG.rand(64) + m = 3 + excl_zone = int(np.ceil(m / config.STUMPY_EXCL_ZONE_DENOM)) - T = np.random.rand(64) - m = 3 - excl_zone = int(np.ceil(m / config.STUMPY_EXCL_ZONE_DENOM)) - - s = np.random.rand(m) - T[:m] = s - T[30 : 30 + m] = s - T[-m:] = s - - t = np.random.rand() # new data point - T_with_t = np.append(T, t) - - # In egress=True mode, a new data point, t, is being appended - # to the historical data, T, while the oldest data point is - # being removed. Therefore, the first subsequence in T - # and the last subsequence does not get a chance to meet each - # other. Therefore, their pairwise distances should be excluded - # from the distance matrix. - D = naive.distance_matrix(T_with_t, T_with_t, m) - D[-1, 0] = np.inf - D[0, -1] = np.inf + s = rng.RNG.rand(m) + T[:m] = s + T[30 : 30 + m] = s + T[-m:] = s - l = len(T_with_t) - m + 1 - for i in range(l): - core.apply_exclusion_zone(D[i], i, excl_zone, np.inf) + t = rng.RNG.rand() # new data point + T_with_t = np.append(T, t) - T_new = np.append(T[1:], t) - dist_profile = naive.distance_profile(T_new[-m:], T_new, m) - core.apply_exclusion_zone(dist_profile, len(dist_profile) - 1, excl_zone, np.inf) + # In egress=True mode, a new data point, t, is being appended + # to the historical data, T, while the oldest data point is + # being removed. Therefore, the first subsequence in T + # and the last subsequence does not get a chance to meet each + # other. Therefore, their pairwise distances should be excluded + # from the distance matrix. + D = naive.distance_matrix(T_with_t, T_with_t, m) + D[-1, 0] = np.inf + D[0, -1] = np.inf - for k in range(1, 4): - # ref - P = np.empty((l, k), dtype=np.float64) - I = np.empty((l, k), dtype=np.int64) + l = len(T_with_t) - m + 1 for i in range(l): - IDX = np.argsort(D[i], kind="mergesort")[:k] - I[i] = IDX - P[i] = D[i, IDX] - - P_ref = P[1:].copy() - I_ref = I[1:].copy() - - # comp - mp = naive.stump(T, m, row_wise=True, k=k) - P_comp = mp[:, :k].astype(np.float64) - I_comp = mp[:, k : 2 * k].astype(np.int64) + core.apply_exclusion_zone(D[i], i, excl_zone, np.inf) - P_comp[:-1] = P_comp[1:] - P_comp[-1] = np.inf - I_comp[:-1] = I_comp[1:] - I_comp[-1] = -1 - core._update_incremental_PI( - dist_profile, P_comp, I_comp, excl_zone, n_appended=1 + T_new = np.append(T[1:], t) + dist_profile = naive.distance_profile(T_new[-m:], T_new, m) + core.apply_exclusion_zone( + dist_profile, len(dist_profile) - 1, excl_zone, np.inf ) - npt.assert_almost_equal(P_ref, P_comp) - npt.assert_almost_equal(I_ref, I_comp) + for k in range(1, 4): + # ref + P = np.empty((l, k), dtype=np.float64) + I = np.empty((l, k), dtype=np.int64) + for i in range(l): + IDX = np.argsort(D[i], kind="mergesort")[:k] + I[i] = IDX + P[i] = D[i, IDX] + + P_ref = P[1:].copy() + I_ref = I[1:].copy() + + # comp + mp = naive.stump(T, m, row_wise=True, k=k) + P_comp = mp[:, :k].astype(np.float64) + I_comp = mp[:, k : 2 * k].astype(np.int64) + + P_comp[:-1] = P_comp[1:] + P_comp[-1] = np.inf + I_comp[:-1] = I_comp[1:] + I_comp[-1] = -1 + core._update_incremental_PI( + dist_profile, P_comp, I_comp, excl_zone, n_appended=1 + ) + + npt.assert_almost_equal(P_ref, P_comp) + npt.assert_almost_equal(I_ref, I_comp) def test_check_self_join(): diff --git a/tests/test_floss.py b/tests/test_floss.py index af06c71e5..8852558bf 100644 --- a/tests/test_floss.py +++ b/tests/test_floss.py @@ -5,7 +5,7 @@ import numpy.testing as npt import pytest -from stumpy import core +from stumpy import core, rng from stumpy.aamp import aamp from stumpy.floss import _cac, _iac, _nnmark, _rea, floss, fluss from stumpy.stump import stump @@ -94,7 +94,7 @@ def naive_rea(cac, n_regimes, L, excl_factor): return np.array(loc_regimes, dtype=np.int64) -test_data = [np.random.randint(0, 50, size=50, dtype=np.int64)] +test_data = [rng.RNG.randint(0, 50, size=50, dtype=np.int64)] substitution_locations = [(slice(0, 0), 0, -1, slice(1, 3), [0, 3])] substitution_values = [np.nan, np.inf] @@ -154,7 +154,7 @@ def test_fluss(I): def test_floss(): - data = np.random.uniform(-1000, 1000, [64]) + data = rng.RNG.uniform(-1000, 1000, [64]) m = 5 n = 30 old_data = data[:n] @@ -215,7 +215,7 @@ def test_floss(): def test_aamp_floss(): - data = np.random.uniform(-1000, 1000, [64]) + data = rng.RNG.uniform(-1000, 1000, [64]) m = 5 n = 30 old_data = data[:n] @@ -287,7 +287,7 @@ def test_aamp_floss(): @pytest.mark.parametrize("substitute", substitution_values) @pytest.mark.parametrize("substitution_locations", substitution_locations) def test_floss_inf_nan(substitute, substitution_locations): - T = np.random.uniform(-1000, 1000, [64]) + T = rng.RNG.uniform(-1000, 1000, [64]) m = 5 n = 30 data = T.copy() @@ -359,7 +359,7 @@ def test_floss_inf_nan(substitute, substitution_locations): @pytest.mark.parametrize("substitute", substitution_values) @pytest.mark.parametrize("substitution_locations", substitution_locations) def test_aamp_floss_inf_nan(substitute, substitution_locations): - T = np.random.uniform(-1000, 1000, [64]) + T = rng.RNG.uniform(-1000, 1000, [64]) m = 5 n = 30 data = T.copy() @@ -431,7 +431,7 @@ def test_aamp_floss_inf_nan(substitute, substitution_locations): def test_floss_with_isconstant(): - data = np.random.uniform(-1, 1, [64]) + data = rng.RNG.uniform(-1, 1, [64]) m = 5 n = 30 old_data = data[:n] @@ -475,7 +475,7 @@ def test_floss_with_isconstant(): ref_Q_isconstant = isconstant_custom_func(ref_Q, m)[0] ref_T_subseq_isconstant = isconstant_custom_func(ref_T, m) D = naive.distance_profile(ref_Q, ref_T, m) - for j in range(len(D)): + for j in range(len(D)): # pragma: no cover if ref_Q_isconstant and ref_T_subseq_isconstant[j]: D[j] = 0 elif ref_Q_isconstant or ref_T_subseq_isconstant[j]: diff --git a/tests/test_gpu_aamp.py b/tests/test_gpu_aamp.py index 7b180bc24..70ae496e8 100644 --- a/tests/test_gpu_aamp.py +++ b/tests/test_gpu_aamp.py @@ -5,7 +5,7 @@ import pandas as pd from numba import cuda -from stumpy import config +from stumpy import config, rng if cuda.is_available(): from stumpy.gpu_aamp import gpu_aamp @@ -33,8 +33,8 @@ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), ), ( - np.random.uniform(-1000, 1000, [8]).astype(np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [8]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64), ), ] @@ -188,7 +188,7 @@ def test_gpu_aamp_constant_subsequence_self_join(): @pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning) @patch("stumpy.config.STUMPY_THREADS_PER_BLOCK", TEST_THREADS_PER_BLOCK) def test_gpu_aamp_one_constant_subsequence_A_B_join(): - T_A = np.random.rand(20) + T_A = rng.RNG.rand(20) T_B = np.concatenate((np.zeros(20, dtype=np.float64), np.ones(5, dtype=np.float64))) m = 3 ref_mp = naive.aamp(T_B, m, T_B=T_A) @@ -244,8 +244,8 @@ def test_gpu_aamp_two_constant_subsequences_A_B_join(): @pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning) @patch("stumpy.config.STUMPY_THREADS_PER_BLOCK", TEST_THREADS_PER_BLOCK) def test_gpu_aamp_identical_subsequence_self_join(): - identical = np.random.rand(8) - T_A = np.random.rand(20) + identical = rng.RNG.rand(8) + T_A = rng.RNG.rand(20) T_A[1 : 1 + identical.shape[0]] = identical T_A[11 : 11 + identical.shape[0]] = identical m = 3 @@ -268,9 +268,9 @@ def test_gpu_aamp_identical_subsequence_self_join(): @pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning) @patch("stumpy.config.STUMPY_THREADS_PER_BLOCK", TEST_THREADS_PER_BLOCK) def test_gpu_aamp_identical_subsequence_A_B_join(): - identical = np.random.rand(8) - T_A = np.random.rand(20) - T_B = np.random.rand(20) + identical = rng.RNG.rand(8) + T_A = rng.RNG.rand(20) + T_B = rng.RNG.rand(20) T_A[1 : 1 + identical.shape[0]] = identical T_B[11 : 11 + identical.shape[0]] = identical m = 3 diff --git a/tests/test_gpu_aamp_ostinato.py b/tests/test_gpu_aamp_ostinato.py index 39069a49a..67daa7391 100644 --- a/tests/test_gpu_aamp_ostinato.py +++ b/tests/test_gpu_aamp_ostinato.py @@ -12,7 +12,7 @@ import naive import pytest -from stumpy import core +from stumpy import core, rng if cuda.is_available(): from stumpy.gpu_aamp_ostinato import gpu_aamp_ostinato @@ -29,13 +29,13 @@ @pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning) @pytest.mark.parametrize( - "seed", np.random.choice(np.arange(10000), size=2, replace=False) + "seed", rng.RNG.choice(np.arange(10000), size=2, replace=False) ) @patch("stumpy.config.STUMPY_THREADS_PER_BLOCK", TEST_THREADS_PER_BLOCK) def test_random_gpu_aamp_ostinato(seed): m = 50 - np.random.seed(seed) - Ts = [np.random.rand(n) for n in [64, 128, 256]] + rng.RNG.seed(seed) + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] ref_radius, ref_Ts_idx, ref_subseq_idx = naive.aamp_ostinato(Ts, m) comp_radius, comp_Ts_idx, comp_subseq_idx = gpu_aamp_ostinato(Ts, m) @@ -50,16 +50,16 @@ def test_random_gpu_aamp_ostinato(seed): @patch("stumpy.config.STUMPY_THREADS_PER_BLOCK", TEST_THREADS_PER_BLOCK) def test_deterministic_gpu_aamp_ostinato(seed): m = 50 - np.random.seed(seed) - Ts = [np.random.rand(n) for n in [64, 128, 256]] + with rng.fix_seed(seed): + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] - for p in [1.0, 2.0, 3.0]: - ref_radius, ref_Ts_idx, ref_subseq_idx = naive.aamp_ostinato(Ts, m, p=p) - comp_radius, comp_Ts_idx, comp_subseq_idx = gpu_aamp_ostinato(Ts, m, p=p) + for p in [1.0, 2.0, 3.0]: + ref_radius, ref_Ts_idx, ref_subseq_idx = naive.aamp_ostinato(Ts, m, p=p) + comp_radius, comp_Ts_idx, comp_subseq_idx = gpu_aamp_ostinato(Ts, m, p=p) - npt.assert_almost_equal(ref_radius, comp_radius) - npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) - npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) + npt.assert_almost_equal(ref_radius, comp_radius) + npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) + npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) @pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning) @@ -69,7 +69,7 @@ def test_input_not_overwritten(): # by replacing nan value with 0 in each time series. # This test ensures that the original input is not overwritten m = 50 - Ts = [np.random.rand(n) for n in [64, 128, 256]] + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] for T in Ts: T[0] = np.nan @@ -87,7 +87,7 @@ def test_input_not_overwritten(): def test_extract_several_consensus(): # This test is to further ensure that the function `gpu_aamp_ostinato` # does not tamper with the original data. - Ts = [np.random.rand(n) for n in [64, 128]] + Ts = [rng.RNG.rand(n) for n in [64, 128]] Ts_ref = [T.copy() for T in Ts] Ts_comp = [T.copy() for T in Ts] diff --git a/tests/test_gpu_aamp_stimp.py b/tests/test_gpu_aamp_stimp.py index e1226b457..88f5a656d 100644 --- a/tests/test_gpu_aamp_stimp.py +++ b/tests/test_gpu_aamp_stimp.py @@ -19,6 +19,8 @@ import naive import pytest +from stumpy import rng + TEST_THREADS_PER_BLOCK = 10 if not cuda.is_available(): # pragma: no cover @@ -27,7 +29,7 @@ T = [ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64), ] diff --git a/tests/test_gpu_aampdist.py b/tests/test_gpu_aampdist.py index c53b1bd88..302b08619 100644 --- a/tests/test_gpu_aampdist.py +++ b/tests/test_gpu_aampdist.py @@ -17,6 +17,8 @@ import naive import pytest +from stumpy import rng + TEST_THREADS_PER_BLOCK = 10 if not cuda.is_available(): # pragma: no cover @@ -29,8 +31,8 @@ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), ), ( - np.random.uniform(-1000, 1000, [8]).astype(np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [8]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64), ), ] diff --git a/tests/test_gpu_mpdist.py b/tests/test_gpu_mpdist.py index 49850d3d9..2c1b1bd28 100644 --- a/tests/test_gpu_mpdist.py +++ b/tests/test_gpu_mpdist.py @@ -18,6 +18,8 @@ import naive import pytest +from stumpy import rng + TEST_THREADS_PER_BLOCK = 10 if not cuda.is_available(): # pragma: no cover @@ -30,8 +32,8 @@ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), ), ( - np.random.uniform(-1000, 1000, [8]).astype(np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [8]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64), ), ] diff --git a/tests/test_gpu_ostinato.py b/tests/test_gpu_ostinato.py index 081de959d..d50df5ad8 100644 --- a/tests/test_gpu_ostinato.py +++ b/tests/test_gpu_ostinato.py @@ -14,7 +14,7 @@ import naive import pytest -from stumpy import core +from stumpy import core, rng if cuda.is_available(): from stumpy.gpu_ostinato import gpu_ostinato @@ -30,20 +30,20 @@ @pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning) @pytest.mark.parametrize( - "seed", np.random.choice(np.arange(10000), size=2, replace=False) + "seed", rng.RNG.choice(np.arange(10000), size=2, replace=False) ) @patch("stumpy.config.STUMPY_THREADS_PER_BLOCK", TEST_THREADS_PER_BLOCK) def test_random_gpu_ostinato(seed): m = 50 - np.random.seed(seed) - Ts = [np.random.rand(n) for n in [64, 128, 256]] + with rng.fix_seed(seed): + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] - ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato(Ts, m) - comp_radius, comp_Ts_idx, comp_subseq_idx = gpu_ostinato(Ts, m) + ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato(Ts, m) + comp_radius, comp_Ts_idx, comp_subseq_idx = gpu_ostinato(Ts, m) - npt.assert_almost_equal(ref_radius, comp_radius) - npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) - npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) + npt.assert_almost_equal(ref_radius, comp_radius) + npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) + npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) @pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning) @@ -51,20 +51,20 @@ def test_random_gpu_ostinato(seed): @patch("stumpy.config.STUMPY_THREADS_PER_BLOCK", TEST_THREADS_PER_BLOCK) def test_deterministic_gpu_ostinato(seed): m = 50 - np.random.seed(seed) - Ts = [np.random.rand(n) for n in [64, 128, 256]] + with rng.fix_seed(seed): + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] - ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato(Ts, m) - comp_radius, comp_Ts_idx, comp_subseq_idx = gpu_ostinato(Ts, m) + ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato(Ts, m) + comp_radius, comp_Ts_idx, comp_subseq_idx = gpu_ostinato(Ts, m) - npt.assert_almost_equal(ref_radius, comp_radius) - npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) - npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) + npt.assert_almost_equal(ref_radius, comp_radius) + npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) + npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) @pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning) @pytest.mark.parametrize( - "seed", np.random.choice(np.arange(10000), size=25, replace=False) + "seed", rng.RNG.choice(np.arange(10000), size=25, replace=False) ) @patch("stumpy.config.STUMPY_THREADS_PER_BLOCK", TEST_THREADS_PER_BLOCK) def test_random_gpu_ostinato_with_isconstant(seed): @@ -73,20 +73,20 @@ def test_random_gpu_ostinato_with_isconstant(seed): ) m = 50 - np.random.seed(seed) - Ts = [np.random.rand(n) for n in [64, 128, 256]] - Ts_subseq_isconstant = [isconstant_custom_func for _ in range(len(Ts))] + with rng.fix_seed(seed): + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] + Ts_subseq_isconstant = [isconstant_custom_func for _ in range(len(Ts))] - ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato( - Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant - ) - comp_radius, comp_Ts_idx, comp_subseq_idx = gpu_ostinato( - Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant - ) + ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato( + Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant + ) + comp_radius, comp_Ts_idx, comp_subseq_idx = gpu_ostinato( + Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant + ) - npt.assert_almost_equal(ref_radius, comp_radius) - npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) - npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) + npt.assert_almost_equal(ref_radius, comp_radius) + npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) + npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) @pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning) @@ -98,28 +98,28 @@ def test_deterministic_gpu_ostinato_with_isconstant(seed): ) m = 50 - np.random.seed(seed) - Ts = [np.random.rand(n) for n in [64, 128, 256]] - - l = 64 - m + 1 - subseq_isconsant = np.full(l, 0, dtype=bool) - subseq_isconsant[np.random.randint(0, l)] = True - Ts_subseq_isconstant = [ - subseq_isconsant, - None, - isconstant_custom_func, - ] - - ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato( - Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant - ) - comp_radius, comp_Ts_idx, comp_subseq_idx = gpu_ostinato( - Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant - ) - - npt.assert_almost_equal(ref_radius, comp_radius) - npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) - npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) + with rng.fix_seed(seed): + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] + + l = 64 - m + 1 + subseq_isconsant = np.full(l, 0, dtype=bool) + subseq_isconsant[rng.RNG.randint(0, l)] = True + Ts_subseq_isconstant = [ + subseq_isconsant, + None, + isconstant_custom_func, + ] + + ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato( + Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant + ) + comp_radius, comp_Ts_idx, comp_subseq_idx = gpu_ostinato( + Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant + ) + + npt.assert_almost_equal(ref_radius, comp_radius) + npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) + npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) @pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning) @@ -129,7 +129,7 @@ def test_input_not_overwritten(): # by replacing nan value with 0 in each time series. # This test ensures that the original input is not overwritten m = 50 - Ts = [np.random.rand(n) for n in [64, 128, 256]] + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] for T in Ts: T[0] = np.nan @@ -147,7 +147,7 @@ def test_input_not_overwritten(): def test_extract_several_consensus(): # This test is to further ensure that the function `gpu_ostinato` # does not tamper with the original data. - Ts = [np.random.rand(n) for n in [64, 128]] + Ts = [rng.RNG.rand(n) for n in [64, 128]] Ts_ref = [T.copy() for T in Ts] Ts_comp = [T.copy() for T in Ts] diff --git a/tests/test_gpu_stimp.py b/tests/test_gpu_stimp.py index 0507adf9a..837f0bf80 100644 --- a/tests/test_gpu_stimp.py +++ b/tests/test_gpu_stimp.py @@ -18,6 +18,8 @@ import naive import pytest +from stumpy import rng + TEST_THREADS_PER_BLOCK = 10 if not cuda.is_available(): # pragma: no cover @@ -26,7 +28,7 @@ T = [ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64), ] @@ -80,7 +82,7 @@ def test_gpu_stimp(T): @pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning) @patch("stumpy.config.STUMPY_THREADS_PER_BLOCK", TEST_THREADS_PER_BLOCK) def test_gpu_stimp_with_isconstant(): - T = np.random.uniform(-1, 1, [64]) + T = rng.RNG.uniform(-1, 1, [64]) isconstant_func = functools.partial( naive.isconstant_func_stddev_threshold, stddev_threshold=0.5 ) diff --git a/tests/test_gpu_stump.py b/tests/test_gpu_stump.py index 78913bd24..6e53b7f95 100644 --- a/tests/test_gpu_stump.py +++ b/tests/test_gpu_stump.py @@ -6,7 +6,7 @@ import pandas as pd from numba import cuda -from stumpy import config +from stumpy import config, rng if cuda.is_available(): from stumpy.gpu_stump import gpu_stump @@ -34,8 +34,8 @@ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), ), ( - np.random.uniform(-1000, 1000, [8]).astype(np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [8]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64), ), ] @@ -185,7 +185,7 @@ def test_gpu_stump_constant_subsequence_self_join(): @pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning) @patch("stumpy.config.STUMPY_THREADS_PER_BLOCK", TEST_THREADS_PER_BLOCK) def test_gpu_stump_one_constant_subsequence_A_B_join(): - T_A = np.random.rand(20) + T_A = rng.RNG.rand(20) T_B = np.concatenate((np.zeros(20, dtype=np.float64), np.ones(5, dtype=np.float64))) m = 3 ref_mp = naive.stump(T_B, m, T_B=T_A, row_wise=True) @@ -241,8 +241,8 @@ def test_gpu_stump_two_constant_subsequences_A_B_join(): @pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning) @patch("stumpy.config.STUMPY_THREADS_PER_BLOCK", TEST_THREADS_PER_BLOCK) def test_gpu_stump_identical_subsequence_self_join(): - identical = np.random.rand(8) - T_A = np.random.rand(20) + identical = rng.RNG.rand(8) + T_A = rng.RNG.rand(20) T_A[1 : 1 + identical.shape[0]] = identical T_A[11 : 11 + identical.shape[0]] = identical m = 3 @@ -265,9 +265,9 @@ def test_gpu_stump_identical_subsequence_self_join(): @pytest.mark.filterwarnings("ignore", category=NumbaPerformanceWarning) @patch("stumpy.config.STUMPY_THREADS_PER_BLOCK", TEST_THREADS_PER_BLOCK) def test_gpu_stump_identical_subsequence_A_B_join(): - identical = np.random.rand(8) - T_A = np.random.rand(20) - T_B = np.random.rand(20) + identical = rng.RNG.rand(8) + T_A = rng.RNG.rand(20) + T_B = rng.RNG.rand(20) T_A[1 : 1 + identical.shape[0]] = identical T_B[11 : 11 + identical.shape[0]] = identical m = 3 diff --git a/tests/test_maamp.py b/tests/test_maamp.py index 6ee8d4731..123fe6843 100644 --- a/tests/test_maamp.py +++ b/tests/test_maamp.py @@ -4,7 +4,7 @@ import pandas as pd import pytest -from stumpy import config, core +from stumpy import config, core, rng from stumpy.maamp import ( _get_first_maamp_profile, _multi_mass_absolute, @@ -16,7 +16,7 @@ test_data = [ (np.array([[584, -11, 23, 79, 1001, 0, -19]], dtype=np.float64), 3), - (np.random.uniform(-1000, 1000, [5, 20]).astype(np.float64), 5), + (rng.RNG.uniform(-1000, 1000, [5, 20]).astype(np.float64), 5), ] substitution_locations = [(slice(0, 0), 0, -1, slice(1, 3), [0, 3])] @@ -24,22 +24,22 @@ def test_multi_mass_absolute_seeded(): - np.random.seed(5) - T = np.random.uniform(-1000, 1000, [3, 10]).astype(np.float64) - m = 5 + with rng.fix_seed(5): + T = rng.RNG.uniform(-1000, 1000, [3, 10]).astype(np.float64) + m = 5 - trivial_idx = 2 + trivial_idx = 2 - Q = T[:, trivial_idx : trivial_idx + m] + Q = T[:, trivial_idx : trivial_idx + m] - ref = naive.multi_mass_absolute(Q, T, m) + ref = naive.multi_mass_absolute(Q, T, m) - T, T_subseq_isfinite = core.preprocess_non_normalized(T, m) - comp = _multi_mass_absolute( - Q, T, m, T_subseq_isfinite[:, trivial_idx], T_subseq_isfinite - ) + T, T_subseq_isfinite = core.preprocess_non_normalized(T, m) + comp = _multi_mass_absolute( + Q, T, m, T_subseq_isfinite[:, trivial_idx], T_subseq_isfinite + ) - npt.assert_almost_equal(ref, comp, decimal=config.STUMPY_TEST_PRECISION) + npt.assert_almost_equal(ref, comp, decimal=config.STUMPY_TEST_PRECISION) @pytest.mark.parametrize("T, m", test_data) @@ -160,7 +160,7 @@ def test_maamp_mdl(T, m): def test_naive_maamp(): - T = np.random.uniform(-1000, 1000, [1, 1000]).astype(np.float64) + T = rng.RNG.uniform(-1000, 1000, [1, 1000]).astype(np.float64) m = 20 zone = int(np.ceil(m / 4)) @@ -272,7 +272,7 @@ def test_maamp_wrapper_include(T, m): def test_constant_subsequence_self_join(): T_A = np.concatenate((np.zeros(20, dtype=np.float64), np.ones(5, dtype=np.float64))) - T = np.array([T_A, T_A, np.random.rand(T_A.shape[0])]) + T = np.array([T_A, T_A, rng.RNG.rand(T_A.shape[0])]) m = 3 excl_zone = int(np.ceil(m / 4)) @@ -284,11 +284,11 @@ def test_constant_subsequence_self_join(): def test_identical_subsequence_self_join(): - identical = np.random.rand(8) - T_A = np.random.rand(20) + identical = rng.RNG.rand(8) + T_A = rng.RNG.rand(20) T_A[1 : 1 + identical.shape[0]] = identical T_A[11 : 11 + identical.shape[0]] = identical - T = np.array([T_A, T_A, np.random.rand(T_A.shape[0])]) + T = np.array([T_A, T_A, rng.RNG.rand(T_A.shape[0])]) m = 3 excl_zone = int(np.ceil(m / 4)) diff --git a/tests/test_maamped.py b/tests/test_maamped.py index 81afc7227..e5c42cc52 100644 --- a/tests/test_maamped.py +++ b/tests/test_maamped.py @@ -6,7 +6,7 @@ import tornado.ioloop from dask.distributed import Client, LocalCluster -from stumpy import config +from stumpy import config, rng from stumpy.maamped import maamped @@ -27,7 +27,7 @@ def dask_cluster(): test_data = [ (np.array([[584, -11, 23, 79, 1001, 0, -19]], dtype=np.float64), 3), - (np.random.uniform(-1000, 1000, [5, 20]).astype(np.float64), 5), + (rng.RNG.uniform(-1000, 1000, [5, 20]).astype(np.float64), 5), ] substitution_locations = [slice(0, 0), 0, -1, slice(1, 3), [0, 3]] @@ -119,7 +119,7 @@ def test_maamped_constant_subsequence_self_join(dask_cluster): T_A = np.concatenate( (np.zeros(20, dtype=np.float64), np.ones(5, dtype=np.float64)) ) - T = np.array([T_A, T_A, np.random.rand(T_A.shape[0])]) + T = np.array([T_A, T_A, rng.RNG.rand(T_A.shape[0])]) m = 3 excl_zone = int(np.ceil(m / 4)) @@ -133,11 +133,11 @@ def test_maamped_constant_subsequence_self_join(dask_cluster): @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_maamped_identical_subsequence_self_join(dask_cluster): with Client(dask_cluster) as dask_client: - identical = np.random.rand(8) - T_A = np.random.rand(20) + identical = rng.RNG.rand(8) + T_A = rng.RNG.rand(20) T_A[1 : 1 + identical.shape[0]] = identical T_A[11 : 11 + identical.shape[0]] = identical - T = np.array([T_A, T_A, np.random.rand(T_A.shape[0])]) + T = np.array([T_A, T_A, rng.RNG.rand(T_A.shape[0])]) m = 3 excl_zone = int(np.ceil(m / 4)) diff --git a/tests/test_mmparray.py b/tests/test_mmparray.py index b5803b94d..e18239df4 100644 --- a/tests/test_mmparray.py +++ b/tests/test_mmparray.py @@ -3,12 +3,13 @@ import numpy.testing as npt import pytest +from stumpy import rng from stumpy.maamp import maamp from stumpy.mstump import mstump test_data = [ (np.array([[584, -11, 23, 79, 1001, 0, -19]], dtype=np.float64), 3), - (np.random.uniform(-1000, 1000, [5, 20]).astype(np.float64), 5), + (rng.RNG.uniform(-1000, 1000, [5, 20]).astype(np.float64), 5), ] diff --git a/tests/test_motifs.py b/tests/test_motifs.py index cfe56c170..8b0fb25ef 100644 --- a/tests/test_motifs.py +++ b/tests/test_motifs.py @@ -5,7 +5,7 @@ import numpy.testing as npt import pytest -from stumpy import core +from stumpy import core, rng from stumpy.motifs import match, motifs @@ -155,7 +155,7 @@ def naive_match( np.array([0.0, 1.0, 2.0]), np.array([0.1, 1.0, 2.0, 3.0, -1.0, 0.1, 1.0, 2.0, -0.5]), ), - (np.random.uniform(-1000, 1000, [8]), np.random.uniform(-1000, 1000, [64])), + (rng.RNG.uniform(-1000, 1000, [8]), rng.RNG.uniform(-1000, 1000, [64])), ] @@ -184,61 +184,57 @@ def test_motifs_one_motif(): def test_motifs_two_motifs(): # Fix seed, because in some case motifs can be off by an index resulting in test # fails, which is caused since one of the motifs is not repeated perfectly in T. - np.random.seed(1234) - - # The time series is random noise with two motifs for m=10: - # * (almost) identical step functions at indices 10, 110 and 210 - # * identical linear slopes at indices 70 and 170 - T = np.random.normal(size=300) - m = 20 - - T[10:30] = 1 - T[12:28] = 2 - - T[110:130] = 3 - T[112:128] = 6 - T[120] = 6.6 - - T[210:230] = 1 - T[212:228] = 2 - T[220] = 1.9 - # naive.distance(naive.z_norm(T[10:30]), naive.z_norm(T[110:130])) = 0.47 - # naive.distance(naive.z_norm(T[10:30]), naive.z_norm(T[210:230])) = 0.24 - # naive.distance(naive.z_norm(T[110:130]), naive.z_norm(T[210:230])) = 0.72 - # Hence T[10:30] is the motif representative for this motif - - T[70:90] = np.arange(m) * 0.1 - T[170:190] = np.arange(m) * 0.1 - # naive.distance(naive.z_norm(T[70:90]), naive.z_norm(T[170:190])) = 0.0 - - max_motifs = 2 - - mp = naive.stump(T, m) - - # left_indices = [[70, 170, -1], [10, 210, 110]] - left_profile_values = [ - [0.0, 0.0, np.nan], - [ - 0.0, - naive.distance(core.z_norm(T[10:30]), core.z_norm(T[210:230])), - naive.distance(core.z_norm(T[10:30]), core.z_norm(T[110:130])), - ], - ] - - right_distance_values, right_indices = motifs( - T, - mp[:, 0], - max_motifs=max_motifs, - max_distance=0.5, - cutoff=np.inf, - ) + with rng.fix_seed(1234): + # The time series is random noise with two motifs for m=10: + # * (almost) identical step functions at indices 10, 110 and 210 + # * identical linear slopes at indices 70 and 170 + T = rng.RNG.normal(size=300) + m = 20 + + T[10:30] = 1 + T[12:28] = 2 + + T[110:130] = 3 + T[112:128] = 6 + T[120] = 6.6 + + T[210:230] = 1 + T[212:228] = 2 + T[220] = 1.9 + # naive.distance(naive.z_norm(T[10:30]), naive.z_norm(T[110:130])) = 0.47 + # naive.distance(naive.z_norm(T[10:30]), naive.z_norm(T[210:230])) = 0.24 + # naive.distance(naive.z_norm(T[110:130]), naive.z_norm(T[210:230])) = 0.72 + # Hence T[10:30] is the motif representative for this motif + + T[70:90] = np.arange(m) * 0.1 + T[170:190] = np.arange(m) * 0.1 + # naive.distance(naive.z_norm(T[70:90]), naive.z_norm(T[170:190])) = 0.0 + + max_motifs = 2 + + mp = naive.stump(T, m) + + # left_indices = [[70, 170, -1], [10, 210, 110]] + left_profile_values = [ + [0.0, 0.0, np.nan], + [ + 0.0, + naive.distance(core.z_norm(T[10:30]), core.z_norm(T[210:230])), + naive.distance(core.z_norm(T[10:30]), core.z_norm(T[110:130])), + ], + ] - # We ignore indices because of sorting ambiguities for equal distances. - # As long as the distances are correct, the indices will be too. - npt.assert_almost_equal(left_profile_values, right_distance_values) + right_distance_values, right_indices = motifs( + T, + mp[:, 0], + max_motifs=max_motifs, + max_distance=0.5, + cutoff=np.inf, + ) - # Reset seed - np.random.seed(None) + # We ignore indices because of sorting ambiguities for equal distances. + # As long as the distances are correct, the indices will be too. + npt.assert_almost_equal(left_profile_values, right_distance_values) def test_motifs_max_matches(): @@ -530,8 +526,8 @@ def test_match_mean_stddev_isconstant(Q, T): def test_multi_match(): - T = np.random.uniform(-1000, 1000, size=(2, 64)) - Q = np.random.uniform(-1000, 1000, size=(2, 64)) + T = rng.RNG.uniform(-1000, 1000, size=(2, 64)) + Q = rng.RNG.uniform(-1000, 1000, size=(2, 64)) m = Q.shape[-1] excl_zone = int(np.ceil(m / 4)) @@ -555,8 +551,8 @@ def test_multi_match(): def test_multi_match_isconstant(): - T = np.random.rand(2, 64) - Q = np.random.rand(2, 8) + T = rng.RNG.rand(2, 64) + Q = rng.RNG.rand(2, 8) m = Q.shape[-1] excl_zone = int(np.ceil(m / 4)) @@ -595,7 +591,7 @@ def test_multi_match_isconstant(): def test_motifs(): - T = np.random.rand(64) + T = rng.RNG.rand(64) m = 3 max_motifs = 3 @@ -628,7 +624,7 @@ def test_motifs_with_isconstant(): naive.isconstant_func_stddev_threshold, quantile_threshold=0.05 ) - T = np.random.rand(64) + T = rng.RNG.rand(64) m = 3 max_motifs = 3 @@ -660,7 +656,7 @@ def test_motifs_with_isconstant(): def test_motifs_with_max_matches_none(): - T = np.random.rand(16) + T = rng.RNG.rand(16) m = 3 max_motifs = 1 diff --git a/tests/test_mparray.py b/tests/test_mparray.py index 1ac0cf34a..97e157980 100644 --- a/tests/test_mparray.py +++ b/tests/test_mparray.py @@ -4,7 +4,7 @@ import pandas as pd import pytest -from stumpy import config +from stumpy import config, rng from stumpy.aamp import aamp from stumpy.mparray import mparray from stumpy.stump import stump @@ -15,8 +15,8 @@ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), ), ( - np.random.uniform(-1000, 1000, [8]).astype(np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [8]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64), ), ] diff --git a/tests/test_mpdist.py b/tests/test_mpdist.py index 7e0984f10..3977d0919 100644 --- a/tests/test_mpdist.py +++ b/tests/test_mpdist.py @@ -7,6 +7,7 @@ import tornado.ioloop from dask.distributed import Client, LocalCluster +from stumpy import rng from stumpy.mpdist import _mpdist_vect, mpdist, mpdisted @@ -31,8 +32,8 @@ def dask_cluster(): np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), ), ( - np.random.uniform(-1000, 1000, [8]).astype(np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [8]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64), ), ] @@ -111,10 +112,10 @@ def test_mpdist(T_A, T_B): @pytest.mark.parametrize("T_A, T_B", test_data) def test_mpdist_with_isconstant(T_A, T_B): m = 3 - T_A_subseq_isconstant = np.random.choice( + T_A_subseq_isconstant = rng.RNG.choice( [True, False], size=len(T_A) - m + 1, replace=True ) - T_B_subseq_isconstant = np.random.choice( + T_B_subseq_isconstant = rng.RNG.choice( [True, False], size=len(T_B) - m + 1, replace=True ) ref_mpdist = naive.mpdist( @@ -177,10 +178,10 @@ def test_mpdisted(T_A, T_B, dask_cluster): def test_mpdisted_with_isconstant(T_A, T_B, dask_cluster): with Client(dask_cluster) as dask_client: m = 3 - T_A_subseq_isconstant = np.random.choice( + T_A_subseq_isconstant = rng.RNG.choice( [True, False], size=len(T_A) - m + 1, replace=True ) - T_B_subseq_isconstant = np.random.choice( + T_B_subseq_isconstant = rng.RNG.choice( [True, False], size=len(T_B) - m + 1, replace=True ) ref_mpdist = naive.mpdist( diff --git a/tests/test_mstump.py b/tests/test_mstump.py index 3e97cf58a..9f75063d3 100644 --- a/tests/test_mstump.py +++ b/tests/test_mstump.py @@ -7,7 +7,7 @@ import polars as pl import pytest -from stumpy import config, core +from stumpy import config, core, rng from stumpy.mstump import ( _get_first_mstump_profile, _get_multi_QT, @@ -29,7 +29,7 @@ def naive_rolling_window_dot_product(Q, T): test_data = [ (np.array([[584, -11, 23, 79, 1001, 0, -19]], dtype=np.float64), 3), - (np.random.uniform(-1000, 1000, [5, 20]).astype(np.float64), 5), + (rng.RNG.uniform(-1000, 1000, [5, 20]).astype(np.float64), 5), ] substitution_locations = [(slice(0, 0), 0, -1, slice(1, 3), [0, 3])] @@ -37,35 +37,35 @@ def naive_rolling_window_dot_product(Q, T): def test_multi_mass_seeded(): - np.random.seed(5) - T = np.random.uniform(-1000, 1000, [3, 10]).astype(np.float64) - m = 5 + with rng.fix_seed(5): + T = rng.RNG.uniform(-1000, 1000, [3, 10]).astype(np.float64) + m = 5 - trivial_idx = 2 - - Q = T[:, trivial_idx : trivial_idx + m] + trivial_idx = 2 - ref = naive.multi_mass(Q, T, m) + Q = T[:, trivial_idx : trivial_idx + m] - T_subseq_isconstant = core.rolling_isconstant(T, m) - M_T, Σ_T = core.compute_mean_std(T, m) + ref = naive.multi_mass(Q, T, m) - Q_subseq_isconstant = np.expand_dims(T_subseq_isconstant[:, trivial_idx], 1) + T_subseq_isconstant = core.rolling_isconstant(T, m) + M_T, Σ_T = core.compute_mean_std(T, m) - comp = _multi_mass( - Q, - T, - m, - M_T, - Σ_T, - M_T[:, trivial_idx], - Σ_T[:, trivial_idx], - T_subseq_isconstant=T_subseq_isconstant, - Q_subseq_isconstant=Q_subseq_isconstant, - query_idx=trivial_idx, - ) + Q_subseq_isconstant = np.expand_dims(T_subseq_isconstant[:, trivial_idx], 1) + + comp = _multi_mass( + Q, + T, + m, + M_T, + Σ_T, + M_T[:, trivial_idx], + Σ_T[:, trivial_idx], + T_subseq_isconstant=T_subseq_isconstant, + Q_subseq_isconstant=Q_subseq_isconstant, + query_idx=trivial_idx, + ) - npt.assert_almost_equal(ref, comp, decimal=config.STUMPY_TEST_PRECISION) + npt.assert_almost_equal(ref, comp, decimal=config.STUMPY_TEST_PRECISION) @pytest.mark.parametrize("T, m", test_data) @@ -222,7 +222,7 @@ def test_mdl(T, m): def test_naive_mstump(): - T = np.random.uniform(-1000, 1000, [1, 1000]).astype(np.float64) + T = rng.RNG.uniform(-1000, 1000, [1, 1000]).astype(np.float64) m = 20 zone = int(np.ceil(m / 4)) @@ -339,7 +339,7 @@ def test_mstump_wrapper_include(T, m): def test_constant_subsequence_self_join(): T_A = np.concatenate((np.zeros(20, dtype=np.float64), np.ones(5, dtype=np.float64))) - T = np.array([T_A, T_A, np.random.rand(T_A.shape[0])]) + T = np.array([T_A, T_A, rng.RNG.rand(T_A.shape[0])]) m = 3 excl_zone = int(np.ceil(m / 4)) @@ -351,11 +351,11 @@ def test_constant_subsequence_self_join(): def test_identical_subsequence_self_join(): - identical = np.random.rand(8) - T_A = np.random.rand(20) + identical = rng.RNG.rand(8) + T_A = rng.RNG.rand(20) T_A[1 : 1 + identical.shape[0]] = identical T_A[11 : 11 + identical.shape[0]] = identical - T = np.array([T_A, T_A, np.random.rand(T_A.shape[0])]) + T = np.array([T_A, T_A, rng.RNG.rand(T_A.shape[0])]) m = 3 excl_zone = int(np.ceil(m / 4)) @@ -414,13 +414,13 @@ def test_multi_mass_with_isconstant(): m = 8 # case 1: Q is not multi-subseq of T - T = np.random.uniform(-1000, 1000, size=[d, n]) - T_subseq_isconstant = np.random.choice( + T = rng.RNG.uniform(-1000, 1000, size=[d, n]) + T_subseq_isconstant = rng.RNG.choice( [True, False], size=(d, n - m + 1), replace=True ) - Q = np.random.uniform(-1000, 1000, size=[d, m]) - Q_subseq_isconstant = np.random.choice([True, False], size=(d, 1), replace=True) + Q = rng.RNG.uniform(-1000, 1000, size=[d, m]) + Q_subseq_isconstant = rng.RNG.choice([True, False], size=(d, 1), replace=True) ref = naive.multi_mass( Q, @@ -451,12 +451,12 @@ def test_multi_mass_with_isconstant(): npt.assert_almost_equal(ref, comp, decimal=config.STUMPY_TEST_PRECISION) # case 2: Q is a multi-subseq of T - T = np.random.uniform(-1000, 1000, size=[d, n]) - T_subseq_isconstant = np.random.choice( + T = rng.RNG.uniform(-1000, 1000, size=[d, n]) + T_subseq_isconstant = rng.RNG.choice( [True, False], size=(d, n - m + 1), replace=True ) - query_idx = np.random.randint(0, n - m + 1) + query_idx = rng.RNG.randint(0, n - m + 1) Q = T[:, query_idx : query_idx + m] Q_subseq_isconstant = np.expand_dims(T_subseq_isconstant[:, query_idx], 1) @@ -496,8 +496,8 @@ def test_multi_distance_profile_with_isconstant_case1(): n = 64 m = 8 - T = np.random.uniform(-1000, 1000, size=[d, n]) - T_subseq_isconstant = np.random.choice( + T = rng.RNG.uniform(-1000, 1000, size=[d, n]) + T_subseq_isconstant = rng.RNG.choice( [True, False], size=(d, n - m + 1), replace=True ) @@ -519,12 +519,12 @@ def test_multi_distance_profile_with_isconstant_case2(): n = 64 m = 8 - T = np.random.uniform(-1000, 1000, size=[d, n]) + T = rng.RNG.uniform(-1000, 1000, size=[d, n]) T_subseq_isconstant = functools.partial( naive.isconstant_func_stddev_threshold, quantile_threshold=0.05 ) - query_idx = np.random.randint(0, n - m + 1) + query_idx = rng.RNG.randint(0, n - m + 1) ref_D = naive.multi_distance_profile( query_idx, T, m, T_subseq_isconstant=T_subseq_isconstant @@ -543,16 +543,16 @@ def test_multi_distance_profile_with_isconstant_case3(): n = 64 m = 8 - T = np.random.uniform(-1000, 1000, size=[d, n]) + T = rng.RNG.uniform(-1000, 1000, size=[d, n]) T_subseq_isconstant = [ None, - np.random.choice([True, False], n - m + 1, replace=True), + rng.RNG.choice([True, False], n - m + 1, replace=True), functools.partial( naive.isconstant_func_stddev_threshold, quantile_threshold=0.05 ), ] - query_idx = np.random.randint(0, n - m + 1) + query_idx = rng.RNG.randint(0, n - m + 1) ref_D = naive.multi_distance_profile( query_idx, T, m, T_subseq_isconstant=T_subseq_isconstant @@ -570,7 +570,7 @@ def test_mstump_with_isconstant_case1(): n = 64 m = 8 - T = np.random.uniform(-1000, 1000, size=[d, n]) + T = rng.RNG.uniform(-1000, 1000, size=[d, n]) T_subseq_isconstant = functools.partial( naive.isconstant_func_stddev_threshold, quantile_threshold=0.05 ) @@ -592,10 +592,10 @@ def test_mstump_with_isconstant_case2(): n = 64 m = 8 - T = np.random.uniform(-1000, 1000, size=[d, n]) + T = rng.RNG.uniform(-1000, 1000, size=[d, n]) T_subseq_isconstant = [ None, - np.random.choice([True, False], n - m + 1, replace=True), + rng.RNG.choice([True, False], n - m + 1, replace=True), functools.partial( naive.isconstant_func_stddev_threshold, quantile_threshold=0.05 ), diff --git a/tests/test_mstumped.py b/tests/test_mstumped.py index aaa669921..537cd4b4b 100644 --- a/tests/test_mstumped.py +++ b/tests/test_mstumped.py @@ -8,7 +8,7 @@ import tornado.ioloop from dask.distributed import Client, LocalCluster -from stumpy import config +from stumpy import config, rng from stumpy.mstumped import mstumped @@ -29,7 +29,7 @@ def dask_cluster(): test_data = [ (np.array([[584, -11, 23, 79, 1001, 0, -19]], dtype=np.float64), 3), - (np.random.uniform(-1000, 1000, [5, 20]).astype(np.float64), 5), + (rng.RNG.uniform(-1000, 1000, [5, 20]).astype(np.float64), 5), ] substitution_locations = [slice(0, 0), 0, -1, slice(1, 3), [0, 3]] @@ -121,7 +121,7 @@ def test_mstumped_constant_subsequence_self_join(dask_cluster): T_A = np.concatenate( (np.zeros(20, dtype=np.float64), np.ones(5, dtype=np.float64)) ) - T = np.array([T_A, T_A, np.random.rand(T_A.shape[0])]) + T = np.array([T_A, T_A, rng.RNG.rand(T_A.shape[0])]) m = 3 excl_zone = int(np.ceil(m / 4)) @@ -135,11 +135,11 @@ def test_mstumped_constant_subsequence_self_join(dask_cluster): @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_mstumped_identical_subsequence_self_join(dask_cluster): with Client(dask_cluster) as dask_client: - identical = np.random.rand(8) - T_A = np.random.rand(20) + identical = rng.RNG.rand(8) + T_A = rng.RNG.rand(20) T_A[1 : 1 + identical.shape[0]] = identical T_A[11 : 11 + identical.shape[0]] = identical - T = np.array([T_A, T_A, np.random.rand(T_A.shape[0])]) + T = np.array([T_A, T_A, rng.RNG.rand(T_A.shape[0])]) m = 3 excl_zone = int(np.ceil(m / 4)) @@ -234,10 +234,10 @@ def test_mstumped_with_isconstant(dask_cluster): n = 64 m = 8 - T = np.random.uniform(-1000, 1000, size=[d, n]) + T = rng.RNG.uniform(-1000, 1000, size=[d, n]) T_subseq_isconstant = [ None, - np.random.choice([True, False], n - m + 1, replace=True), + rng.RNG.choice([True, False], n - m + 1, replace=True), functools.partial( naive.isconstant_func_stddev_threshold, quantile_threshold=0.05 ), diff --git a/tests/test_non_normalized_decorator.py b/tests/test_non_normalized_decorator.py index fb8038ec1..b96580c99 100644 --- a/tests/test_non_normalized_decorator.py +++ b/tests/test_non_normalized_decorator.py @@ -5,7 +5,7 @@ from dask.distributed import Client, LocalCluster from numba import cuda -from stumpy import core +from stumpy import core, rng from stumpy.aamp import aamp from stumpy.aamp_mmotifs import aamp_mmotifs from stumpy.aamp_motifs import aamp_match, aamp_motifs @@ -80,19 +80,19 @@ def dask_cluster(): test_data = [ (np.array([[584, -11, 23, 79, 1001, 0, -19]], dtype=np.float64), 3), - (np.random.uniform(-1000, 1000, [5, 20]).astype(np.float64), 5), + (rng.RNG.uniform(-1000, 1000, [5, 20]).astype(np.float64), 5), ] def test_mass(): - Q = np.random.rand(10) - T = np.random.rand(20) + Q = rng.RNG.random(10) + T = rng.RNG.random(20) ref = core.mass_absolute(Q, T) comp = core.mass(Q, T, normalize=False) npt.assert_almost_equal(ref, comp) - Q = np.random.rand(10) - T = np.random.rand(20) + Q = rng.RNG.random(10) + T = rng.RNG.random(20) T, T_subseq_isfinite = core.preprocess_non_normalized(T, 10) T_squared = np.sum(core.rolling_window(T * T, Q.shape[0]), axis=-1) ref = core.mass_absolute(Q, T) @@ -132,12 +132,10 @@ def test_scrump(T, m): T = T.copy() T = T[0] - seed = np.random.randint(100000) - - np.random.seed(seed) - ref = scraamp(T, m) - np.random.seed(seed) - comp = scrump(T, m, normalize=False) + with rng.fix_state(): + ref = scraamp(T, m) + with rng.fix_state(): + comp = scrump(T, m, normalize=False) npt.assert_almost_equal(ref.P_, comp.P_) for i in range(10): @@ -151,12 +149,10 @@ def test_scrump_plus_plus(T, m): if T.ndim > 1: T = T.copy() T = T[0] - seed = np.random.randint(100000) - - np.random.seed(seed) - ref = scraamp(T, m, pre_scraamp=True) - np.random.seed(seed) - comp = scrump(T, m, pre_scrump=True, normalize=False) + with rng.fix_state(): + ref = scraamp(T, m, pre_scraamp=True) + with rng.fix_state(): + comp = scrump(T, m, pre_scrump=True, normalize=False) npt.assert_almost_equal(ref.P_, comp.P_) for i in range(10): @@ -171,12 +167,10 @@ def test_scrump_plus_plus_full(T, m): T = T.copy() T = T[0] - seed = np.random.randint(100000) - - np.random.seed(seed) - ref = scraamp(T, m, percentage=0.1, pre_scraamp=True) - np.random.seed(seed) - comp = scrump(T, m, percentage=0.1, pre_scrump=True, normalize=False) + with rng.fix_state(): + ref = scraamp(T, m, percentage=0.1, pre_scraamp=True) + with rng.fix_state(): + comp = scrump(T, m, percentage=0.1, pre_scrump=True, normalize=False) npt.assert_almost_equal(ref.P_, comp.P_) for i in range(10): @@ -222,7 +216,7 @@ def test_stumpi(T, m): ref_stream = aampi(T, m) comp_stream = stumpi(T, m, normalize=False) for i in range(10): - t = np.random.rand() + t = rng.RNG.random() ref_stream.update(t) comp_stream.update(t) npt.assert_almost_equal(ref_stream.P_, comp_stream.P_) @@ -230,7 +224,7 @@ def test_stumpi(T, m): def test_ostinato(): m = 50 - Ts = [np.random.rand(n) for n in [64, 128, 256]] + Ts = [rng.RNG.random(n) for n in [64, 128, 256]] ref_radius, ref_Ts_idx, ref_subseq_idx = aamp_ostinato(Ts, m) comp_radius, comp_Ts_idx, comp_subseq_idx = ostinato(Ts, m, normalize=False) @@ -243,7 +237,7 @@ def test_ostinato(): @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_ostinatoed(dask_cluster): m = 50 - Ts = [np.random.rand(n) for n in [64, 128, 256]] + Ts = [rng.RNG.random(n) for n in [64, 128, 256]] with Client(dask_cluster) as dask_client: ref_radius, ref_Ts_idx, ref_subseq_idx = aamp_ostinatoed(dask_client, Ts, m) @@ -262,7 +256,7 @@ def test_gpu_ostinato(): pytest.skip("Skipping Tests No GPUs Available") m = 50 - Ts = [np.random.rand(n) for n in [64, 128, 256]] + Ts = [rng.RNG.random(n) for n in [64, 128, 256]] ref_radius, ref_Ts_idx, ref_subseq_idx = gpu_aamp_ostinato(Ts, m) comp_radius, comp_Ts_idx, comp_subseq_idx = gpu_ostinato(Ts, m, normalize=False) @@ -273,8 +267,8 @@ def test_gpu_ostinato(): def test_mpdist(): - T_A = np.random.uniform(-1000, 1000, [8]).astype(np.float64) - T_B = np.random.uniform(-1000, 1000, [64]).astype(np.float64) + T_A = rng.RNG.uniform(-1000, 1000, size=8).astype(np.float64) + T_B = rng.RNG.uniform(-1000, 1000, size=64).astype(np.float64) m = 5 ref = aampdist(T_A, T_B, m) @@ -284,8 +278,8 @@ def test_mpdist(): @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_mpdisted(dask_cluster): - T_A = np.random.uniform(-1000, 1000, [8]).astype(np.float64) - T_B = np.random.uniform(-1000, 1000, [64]).astype(np.float64) + T_A = rng.RNG.uniform(-1000, 1000, size=8).astype(np.float64) + T_B = rng.RNG.uniform(-1000, 1000, size=64).astype(np.float64) m = 5 with Client(dask_cluster) as dask_client: @@ -299,8 +293,8 @@ def test_gpu_mpdist(): if not cuda.is_available(): # pragma: no cover pytest.skip("Skipping Tests No GPUs Available") - T_A = np.random.uniform(-1000, 1000, [8]).astype(np.float64) - T_B = np.random.uniform(-1000, 1000, [64]).astype(np.float64) + T_A = rng.RNG.uniform(-1000, 1000, size=8).astype(np.float64) + T_B = rng.RNG.uniform(-1000, 1000, size=64).astype(np.float64) m = 5 ref = gpu_aampdist(T_A, T_B, m) @@ -392,7 +386,7 @@ def test_mmotifs(T, m): @pytest.mark.filterwarnings("ignore:All-NaN slice encountered") def test_snippets(): - T = np.random.rand(64) + T = rng.RNG.random(64) m = 10 k = 2 @@ -421,21 +415,19 @@ def test_stimp(T, m): T = T.copy() T = T[0] n = 3 - seed = np.random.randint(100000) - - np.random.seed(seed) - ref = aamp_stimp(T, m) - for i in range(n): - ref.update() + with rng.fix_state(): + ref = aamp_stimp(T, m) + for i in range(n): + ref.update() - np.random.seed(seed) - cmp = stimp(T, m, normalize=False) - for i in range(n): - cmp.update() + with rng.fix_state(): + cmp = stimp(T, m, normalize=False) + for i in range(n): + cmp.update() - # Compare raw pan - ref_PAN = ref._PAN - cmp_PAN = cmp._PAN + # Compare raw pan + ref_PAN = ref._PAN + cmp_PAN = cmp._PAN naive.replace_inf(ref_PAN) naive.replace_inf(cmp_PAN) @@ -453,21 +445,20 @@ def test_stimped(T, m, dask_cluster): T = T.copy() T = T[0] n = 3 - seed = np.random.randint(100000) with Client(dask_cluster) as dask_client: - np.random.seed(seed) - ref = aamp_stimped(dask_client, T, m) - for i in range(n): - ref.update() + with rng.fix_state(): + ref = aamp_stimped(dask_client, T, m) + for i in range(n): + ref.update() - np.random.seed(seed) - cmp = stimped(dask_client, T, m, normalize=False) - for i in range(n): - cmp.update() + with rng.fix_state(): + cmp = stimped(dask_client, T, m, normalize=False) + for i in range(n): + cmp.update() - # Compare raw pan - ref_PAN = ref._PAN - cmp_PAN = cmp._PAN + # Compare raw pan + ref_PAN = ref._PAN + cmp_PAN = cmp._PAN naive.replace_inf(ref_PAN) naive.replace_inf(cmp_PAN) @@ -488,21 +479,19 @@ def test_gpu_stimp(T, m): T = T.copy() T = T[0] n = 3 - seed = np.random.randint(100000) - - np.random.seed(seed) - ref = gpu_aamp_stimp(T, m) - for i in range(n): - ref.update() + with rng.fix_state(): + ref = gpu_aamp_stimp(T, m) + for i in range(n): + ref.update() - np.random.seed(seed) - cmp = gpu_stimp(T, m, normalize=False) - for i in range(n): - cmp.update() + with rng.fix_state(): + cmp = gpu_stimp(T, m, normalize=False) + for i in range(n): + cmp.update() - # Compare raw pan - ref_PAN = ref._PAN - cmp_PAN = cmp._PAN + # Compare raw pan + ref_PAN = ref._PAN + cmp_PAN = cmp._PAN naive.replace_inf(ref_PAN) naive.replace_inf(cmp_PAN) diff --git a/tests/test_ostinato.py b/tests/test_ostinato.py index 75189dfdf..26f727753 100644 --- a/tests/test_ostinato.py +++ b/tests/test_ostinato.py @@ -7,7 +7,7 @@ import tornado.ioloop from dask.distributed import Client, LocalCluster -from stumpy import core +from stumpy import core, rng from stumpy.ostinato import ostinato, ostinatoed @@ -27,69 +27,69 @@ def dask_cluster(): @pytest.mark.parametrize( - "seed", np.random.choice(np.arange(10000), size=25, replace=False) + "seed", rng.RNG.choice(np.arange(10000), size=25, replace=False) ) def test_random_ostinato(seed): m = 50 - np.random.seed(seed) - Ts = [np.random.rand(n) for n in [64, 128, 256]] + with rng.fix_seed(seed): + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] - ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato(Ts, m) - comp_radius, comp_Ts_idx, comp_subseq_idx = ostinato(Ts, m) + ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato(Ts, m) + comp_radius, comp_Ts_idx, comp_subseq_idx = ostinato(Ts, m) - npt.assert_almost_equal(ref_radius, comp_radius) - npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) - npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) + npt.assert_almost_equal(ref_radius, comp_radius) + npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) + npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) @pytest.mark.parametrize("seed", [79, 109, 112, 133, 151, 161, 251, 275, 309, 355]) def test_deterministic_ostinato(seed): m = 50 - np.random.seed(seed) - Ts = [np.random.rand(n) for n in [64, 128, 256]] + with rng.fix_seed(seed): + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] - ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato(Ts, m) - comp_radius, comp_Ts_idx, comp_subseq_idx = ostinato(Ts, m) + ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato(Ts, m) + comp_radius, comp_Ts_idx, comp_subseq_idx = ostinato(Ts, m) - npt.assert_almost_equal(ref_radius, comp_radius) - npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) - npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) + npt.assert_almost_equal(ref_radius, comp_radius) + npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) + npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) @pytest.mark.parametrize( - "seed", np.random.choice(np.arange(10000), size=25, replace=False) + "seed", rng.RNG.choice(np.arange(10000), size=25, replace=False) ) def test_random_ostinatoed(seed, dask_cluster): with Client(dask_cluster) as dask_client: m = 50 - np.random.seed(seed) - Ts = [np.random.rand(n) for n in [64, 128, 256]] + with rng.fix_seed(seed): + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] - ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato(Ts, m) - comp_radius, comp_Ts_idx, comp_subseq_idx = ostinatoed(dask_client, Ts, m) + ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato(Ts, m) + comp_radius, comp_Ts_idx, comp_subseq_idx = ostinatoed(dask_client, Ts, m) - npt.assert_almost_equal(ref_radius, comp_radius) - npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) - npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) + npt.assert_almost_equal(ref_radius, comp_radius) + npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) + npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) @pytest.mark.parametrize("seed", [79, 109, 112, 133, 151, 161, 251, 275, 309, 355]) def test_deterministic_ostinatoed(seed, dask_cluster): with Client(dask_cluster) as dask_client: m = 50 - np.random.seed(seed) - Ts = [np.random.rand(n) for n in [64, 128, 256]] + with rng.fix_seed(seed): + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] - ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato(Ts, m) - comp_radius, comp_Ts_idx, comp_subseq_idx = ostinatoed(dask_client, Ts, m) + ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato(Ts, m) + comp_radius, comp_Ts_idx, comp_subseq_idx = ostinatoed(dask_client, Ts, m) - npt.assert_almost_equal(ref_radius, comp_radius) - npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) - npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) + npt.assert_almost_equal(ref_radius, comp_radius) + npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) + npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) @pytest.mark.parametrize( - "seed", np.random.choice(np.arange(10000), size=25, replace=False) + "seed", rng.RNG.choice(np.arange(10000), size=25, replace=False) ) def test_random_ostinato_with_isconstant(seed): isconstant_custom_func = functools.partial( @@ -97,20 +97,20 @@ def test_random_ostinato_with_isconstant(seed): ) m = 50 - np.random.seed(seed) - Ts = [np.random.rand(n) for n in [64, 128, 256]] - Ts_subseq_isconstant = [isconstant_custom_func for _ in range(len(Ts))] + with rng.fix_seed(seed): + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] + Ts_subseq_isconstant = [isconstant_custom_func for _ in range(len(Ts))] - ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato( - Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant - ) - comp_radius, comp_Ts_idx, comp_subseq_idx = ostinato( - Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant - ) + ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato( + Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant + ) + comp_radius, comp_Ts_idx, comp_subseq_idx = ostinato( + Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant + ) - npt.assert_almost_equal(ref_radius, comp_radius) - npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) - npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) + npt.assert_almost_equal(ref_radius, comp_radius) + npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) + npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) @pytest.mark.parametrize("seed", [79, 109, 112, 133, 151, 161, 251, 275, 309, 355]) @@ -121,28 +121,28 @@ def test_deterministic_ostinatoed_with_isconstant(seed, dask_cluster): with Client(dask_cluster) as dask_client: m = 50 - np.random.seed(seed) - Ts = [np.random.rand(n) for n in [64, 128, 256]] - - l = 64 - m + 1 - subseq_isconsant = np.full(l, 0, dtype=bool) - subseq_isconsant[np.random.randint(0, l)] = True - Ts_subseq_isconstant = [ - subseq_isconsant, - None, - isconstant_custom_func, - ] - - ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato( - Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant - ) - comp_radius, comp_Ts_idx, comp_subseq_idx = ostinatoed( - dask_client, Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant - ) + with rng.fix_seed(seed): + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] + + l = 64 - m + 1 + subseq_isconsant = np.full(l, 0, dtype=bool) + subseq_isconsant[rng.RNG.randint(0, l)] = True + Ts_subseq_isconstant = [ + subseq_isconsant, + None, + isconstant_custom_func, + ] + + ref_radius, ref_Ts_idx, ref_subseq_idx = naive.ostinato( + Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant + ) + comp_radius, comp_Ts_idx, comp_subseq_idx = ostinatoed( + dask_client, Ts, m, Ts_subseq_isconstant=Ts_subseq_isconstant + ) - npt.assert_almost_equal(ref_radius, comp_radius) - npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) - npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) + npt.assert_almost_equal(ref_radius, comp_radius) + npt.assert_almost_equal(ref_Ts_idx, comp_Ts_idx) + npt.assert_almost_equal(ref_subseq_idx, comp_subseq_idx) def test_input_not_overwritten_ostinato(): @@ -150,7 +150,7 @@ def test_input_not_overwritten_ostinato(): # by replacing nan value with 0 in each time series. # This test ensures that the original input is not overwritten m = 50 - Ts = [np.random.rand(n) for n in [64, 128, 256]] + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] for T in Ts: T[0] = np.nan @@ -166,7 +166,7 @@ def test_input_not_overwritten_ostinato(): def test_extract_several_consensus_ostinato(): # This test is to further ensure that the function `ostinato` # does not tamper with the original data. - Ts = [np.random.rand(n) for n in [256, 512, 1024]] + Ts = [rng.RNG.rand(n) for n in [256, 512, 1024]] Ts_ref = [T.copy() for T in Ts] Ts_comp = [T.copy() for T in Ts] @@ -200,7 +200,7 @@ def test_input_not_overwritten_ostinatoed(dask_cluster): # This test ensures that the original input is not overwritten with Client(dask_cluster) as dask_client: m = 50 - Ts = [np.random.rand(n) for n in [64, 128, 256]] + Ts = [rng.RNG.rand(n) for n in [64, 128, 256]] for T in Ts: T[0] = np.nan @@ -218,7 +218,7 @@ def test_input_not_overwritten_ostinatoed(dask_cluster): def test_extract_several_consensus_ostinatoed(dask_cluster): # This test is to further ensure that the function `ostinatoed` # does not tamper with the original data. - Ts = [np.random.rand(n) for n in [256, 512, 1024]] + Ts = [rng.RNG.rand(n) for n in [256, 512, 1024]] Ts_ref = [T.copy() for T in Ts] Ts_comp = [T.copy() for T in Ts] diff --git a/tests/test_precision.py b/tests/test_precision.py index 12654bd7c..043406bba 100644 --- a/tests/test_precision.py +++ b/tests/test_precision.py @@ -8,7 +8,7 @@ import pytest from numba import cuda -from stumpy import cache, config, core, fastmath, sdp +from stumpy import cache, config, core, fastmath, rng, sdp if cuda.is_available(): from stumpy.gpu_stump import gpu_stump @@ -29,39 +29,38 @@ def test_mpdist_snippets_s(): # a subsequence (of length `s`) and itelf becomes non-zero # in the performant version. Fixing this loss-of-precision can # result in this test being passed. - seed = 0 - np.random.seed(seed) - T = np.random.uniform(-1000, 1000, [64]).astype(np.float64) - m = 10 - k = 3 - s = 3 + with rng.fix_seed(0): + T = rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64) + m = 10 + k = 3 + s = 3 - ( - ref_snippets, - ref_indices, - ref_profiles, - ref_fractions, - ref_areas, - ref_regimes, - ) = naive.mpdist_snippets(T, m, k, s=s) - ( - cmp_snippets, - cmp_indices, - cmp_profiles, - cmp_fractions, - cmp_areas, - cmp_regimes, - ) = snippets(T, m, k, s=s) - - npt.assert_almost_equal( - ref_fractions, cmp_fractions, decimal=config.STUMPY_TEST_PRECISION - ) + ( + ref_snippets, + ref_indices, + ref_profiles, + ref_fractions, + ref_areas, + ref_regimes, + ) = naive.mpdist_snippets(T, m, k, s=s) + ( + cmp_snippets, + cmp_indices, + cmp_profiles, + cmp_fractions, + cmp_areas, + cmp_regimes, + ) = snippets(T, m, k, s=s) + + npt.assert_almost_equal( + ref_fractions, cmp_fractions, decimal=config.STUMPY_TEST_PRECISION + ) def test_distace_profile(): # This test function raises an error when the distance profile between # the query `Q = T[i: i+m]` and `T` becomes non-zero at index `i`. - T = np.random.rand(64) + T = rng.RNG.rand(64) m = 3 T, M_T, Σ_T, T_subseq_isconstant = core.preprocess(T, m) @@ -78,46 +77,45 @@ def test_distace_profile(): def test_calculate_squared_distance(): # This test function raises an error if the distance between a subsequence # and another does not satisfy the symmetry property. - seed = 332 - np.random.seed(seed) - T = np.random.uniform(-1000.0, 1000.0, [64]) - m = 3 - - T_subseq_isconstant = core.rolling_isconstant(T, m) - M_T, Σ_T = core.compute_mean_std(T, m) - - n = len(T) - k = n - m + 1 - for i in range(k): - for j in range(k): - QT_i = sdp._njit_sliding_dot_product(T[i : i + m], T) - dist_ij = core._calculate_squared_distance( - m, - QT_i[j], - M_T[i], - Σ_T[i], - M_T[j], - Σ_T[j], - T_subseq_isconstant[i], - T_subseq_isconstant[j], - ) - - QT_j = sdp._njit_sliding_dot_product(T[j : j + m], T) - dist_ji = core._calculate_squared_distance( - m, - QT_j[i], - M_T[j], - Σ_T[j], - M_T[i], - Σ_T[i], - T_subseq_isconstant[j], - T_subseq_isconstant[i], - ) - - comp = dist_ij - dist_ji - ref = 0.0 - - npt.assert_almost_equal(ref, comp, decimal=14) + with rng.fix_seed(332): + T = rng.RNG.uniform(-1000.0, 1000.0, [64]) + m = 3 + + T_subseq_isconstant = core.rolling_isconstant(T, m) + M_T, Σ_T = core.compute_mean_std(T, m) + + n = len(T) + k = n - m + 1 + for i in range(k): + for j in range(k): + QT_i = sdp._njit_sliding_dot_product(T[i : i + m], T) + dist_ij = core._calculate_squared_distance( + m, + QT_i[j], + M_T[i], + Σ_T[i], + M_T[j], + Σ_T[j], + T_subseq_isconstant[i], + T_subseq_isconstant[j], + ) + + QT_j = sdp._njit_sliding_dot_product(T[j : j + m], T) + dist_ji = core._calculate_squared_distance( + m, + QT_j[i], + M_T[j], + Σ_T[j], + M_T[i], + Σ_T[i], + T_subseq_isconstant[j], + T_subseq_isconstant[i], + ) + + comp = dist_ij - dist_ji + ref = 0.0 + + npt.assert_almost_equal(ref, comp, decimal=14) def test_snippets(): @@ -126,42 +124,22 @@ def test_snippets(): m = 10 k = 3 s = 3 - seed = 332 - np.random.seed(seed) - T = np.random.uniform(-1000.0, 1000.0, [64]) - - isconstant_custom_func = functools.partial( - naive.isconstant_func_stddev_threshold, quantile_threshold=0.05 - ) - ( - ref_snippets, - ref_indices, - ref_profiles, - ref_fractions, - ref_areas, - ref_regimes, - ) = naive.mpdist_snippets( - T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func - ) - - ( - 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) - - 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"} + with rng.fix_seed(332): + T = rng.RNG.uniform(-1000.0, 1000.0, [64]) + + isconstant_custom_func = functools.partial( + naive.isconstant_func_stddev_threshold, quantile_threshold=0.05 + ) + ( + ref_snippets, + ref_indices, + ref_profiles, + ref_fractions, + ref_areas, + ref_regimes, + ) = naive.mpdist_snippets( + T, m, k, s=s, mpdist_T_subseq_isconstant=isconstant_custom_func ) - cache._recompile() ( cmp_snippets, @@ -172,20 +150,45 @@ def test_snippets(): 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 - ) - npt.assert_almost_equal( - ref_indices, cmp_indices, decimal=config.STUMPY_TEST_PRECISION - ) - npt.assert_almost_equal( - ref_profiles, cmp_profiles, decimal=config.STUMPY_TEST_PRECISION - ) - npt.assert_almost_equal( - ref_fractions, cmp_fractions, decimal=config.STUMPY_TEST_PRECISION - ) - npt.assert_almost_equal(ref_areas, cmp_areas, decimal=config.STUMPY_TEST_PRECISION) - npt.assert_almost_equal(ref_regimes, cmp_regimes) + 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 + ) + npt.assert_almost_equal( + ref_indices, cmp_indices, decimal=config.STUMPY_TEST_PRECISION + ) + npt.assert_almost_equal( + ref_profiles, cmp_profiles, decimal=config.STUMPY_TEST_PRECISION + ) + npt.assert_almost_equal( + ref_fractions, cmp_fractions, decimal=config.STUMPY_TEST_PRECISION + ) + npt.assert_almost_equal( + ref_areas, cmp_areas, decimal=config.STUMPY_TEST_PRECISION + ) + 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 @@ -201,31 +204,30 @@ def test_distance_symmetry_property_in_gpu(): # This test function raises an error if the distance between a subsequence # and another one does not satisfy the symmetry property. - seed = 332 - np.random.seed(seed) - T = np.random.uniform(-1000.0, 1000.0, [64]) - m = 3 + with rng.fix_seed(332): + T = rng.RNG.uniform(-1000.0, 1000.0, [64]) + m = 3 - i, j = 2, 10 - # M_T, Σ_T = core.compute_mean_std(T, m) - # Σ_T[i] is `650.912209452633` - # Σ_T[j] is `722.0717285148525` + i, j = 2, 10 + # M_T, Σ_T = core.compute_mean_std(T, m) + # Σ_T[i] is `650.912209452633` + # Σ_T[j] is `722.0717285148525` - # 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 - # are swapped. + # 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 + # are swapped. - T_A = T[i : i + m] - T_B = T[j : j + m] + T_A = T[i : i + m] + T_B = T[j : j + m] - mp_AB = gpu_stump(T_A, m, T_B) - mp_BA = gpu_stump(T_B, m, T_A) + mp_AB = gpu_stump(T_A, m, T_B) + mp_BA = gpu_stump(T_B, m, T_A) - d_ij = mp_AB[0, 0] - d_ji = mp_BA[0, 0] + d_ij = mp_AB[0, 0] + d_ji = mp_BA[0, 0] - comp = d_ij - d_ji - ref = 0.0 + comp = d_ij - d_ji + ref = 0.0 - npt.assert_almost_equal(comp, ref, decimal=15) + npt.assert_almost_equal(comp, ref, decimal=15) diff --git a/tests/test_ray.py b/tests/test_ray.py index 58e752bea..97b9045a2 100644 --- a/tests/test_ray.py +++ b/tests/test_ray.py @@ -9,6 +9,7 @@ RAY_IMPORTED = True except ImportError: # pragma: no cover RAY_IMPORTED = False +from stumpy import rng from stumpy.aamp_stimp import aamp_stimped from stumpy.aamped import aamped from stumpy.maamped import maamped @@ -36,19 +37,19 @@ def ray_cluster(): np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), ), ( - np.random.uniform(-1000, 1000, [8]).astype(np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [8]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64), ), ] test_mdata = [ (np.array([[584, -11, 23, 79, 1001, 0, -19]], dtype=np.float64), 3), - (np.random.uniform(-1000, 1000, [5, 20]).astype(np.float64), 5), + (rng.RNG.uniform(-1000, 1000, [5, 20]).astype(np.float64), 5), ] T = [ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64), ] diff --git a/tests/test_rng.py b/tests/test_rng.py new file mode 100644 index 000000000..1d423ad03 --- /dev/null +++ b/tests/test_rng.py @@ -0,0 +1,42 @@ +import numpy.testing as npt + +from stumpy import rng + + +def test_set_seed(): + init_state = rng.RNG.get_state() + + rng.set_seed(0) + seed = rng.RNG.get_state()[1][0] + assert seed == 0 + + rng.RNG.set_state(init_state) + + +def test_fix_seed(): + init_state = rng.RNG.get_state() + init_seed = init_state[1][0] # This returns the seed + + with rng.fix_seed(0): + state = rng.RNG.get_state() + seed = state[1][0] + assert seed != init_seed + + state = rng.RNG.get_state() + seed = state[1][0] + assert seed == init_seed + + +def test_random(): + with rng.fix_seed(0): + assert rng.RNG.rand() == 0.5488135039273248 + assert rng.RNG.randint(1_000_000) == 435829 + assert rng.RNG.uniform(0, 1_000_000) == 844265.7485810174 + npt.assert_almost_equal( + rng.RNG.permutation([10, 20, 30, 40, 50]), [10, 30, 20, 50, 40] + ) + npt.assert_almost_equal( + rng.RNG.choice([10, 20, 30, 40, 50], 10, replace=True), + [30, 50, 10, 10, 50, 30, 20, 10, 20, 20], + ) + assert rng.RNG.normal() == 0.44386323274542566 diff --git a/tests/test_scraamp.py b/tests/test_scraamp.py index faccf0fa6..339928fab 100644 --- a/tests/test_scraamp.py +++ b/tests/test_scraamp.py @@ -3,7 +3,7 @@ import numpy.testing as npt import pytest -from stumpy import config +from stumpy import config, rng from stumpy.aamp import aamp from stumpy.scraamp import prescraamp, scraamp @@ -13,8 +13,8 @@ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), ), ( - np.random.uniform(-1000, 1000, [8]).astype(np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, size=8).astype(np.float64), + rng.RNG.uniform(-1000, 1000, size=64).astype(np.float64), ), ] @@ -31,13 +31,13 @@ def test_prescraamp_self_join(T_A, T_B): m = 3 zone = int(np.ceil(m / 4)) for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescraamp(T_B, m, T_B, s=s, exclusion_zone=zone, p=p) + with rng.fix_state(): + ref_P, ref_I = naive.prescraamp( + T_B, m, T_B, s=s, exclusion_zone=zone, p=p + ) - np.random.seed(seed) - comp_P, comp_I = prescraamp(T_B, m, s=s, p=p) + with rng.fix_state(): + comp_P, comp_I = prescraamp(T_B, m, s=s, p=p) npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) @@ -49,13 +49,11 @@ def test_prescraamp_A_B_join(T_A, T_B): m = 3 zone = int(np.ceil(m / 4)) for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescraamp(T_A, m, T_B, s=s, p=p) + with rng.fix_state(): + ref_P, ref_I = naive.prescraamp(T_A, m, T_B, s=s, p=p) - np.random.seed(seed) - comp_P, comp_I = prescraamp(T_A, m, T_B=T_B, s=s, p=p) + with rng.fix_state(): + comp_P, comp_I = prescraamp(T_A, m, T_B=T_B, s=s, p=p) npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) @@ -66,13 +64,11 @@ def test_prescraamp_A_B_join_swap(T_A, T_B): m = 3 zone = int(np.ceil(m / 4)) for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescraamp(T_B, m, T_A, s=s) + with rng.fix_state(): + ref_P, ref_I = naive.prescraamp(T_B, m, T_A, s=s) - np.random.seed(seed) - comp_P, comp_I = prescraamp(T_B, m, T_B=T_A, s=s) + with rng.fix_state(): + comp_P, comp_I = prescraamp(T_B, m, T_B=T_A, s=s) npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) @@ -84,13 +80,11 @@ def test_prescraamp_self_join_larger_window(T_A, T_B, m): if len(T_B) > m: zone = int(np.ceil(m / 4)) for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescraamp(T_B, m, T_B, s=s, exclusion_zone=zone) + with rng.fix_state(): + ref_P, ref_I = naive.prescraamp(T_B, m, T_B, s=s, exclusion_zone=zone) - np.random.seed(seed) - comp_P, comp_I = prescraamp(T_B, m, s=s) + with rng.fix_state(): + comp_P, comp_I = prescraamp(T_B, m, s=s) npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) @@ -111,27 +105,25 @@ def test_scraamp_self_join(T_A, T_B, percentages): for p in [1.0, 2.0, 3.0]: for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I, ref_left_I, ref_right_I = naive.scraamp( - T_B, m, T_B, percentage, zone, False, None, p=p - ) + with rng.fix_state(): + ref_P, ref_I, ref_left_I, ref_right_I = naive.scraamp( + T_B, m, T_B, percentage, zone, False, None, p=p + ) - np.random.seed(seed) - approx = scraamp( - T_B, - m, - ignore_trivial=True, - percentage=percentage, - pre_scraamp=False, - p=p, - ) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scraamp( + T_B, + m, + ignore_trivial=True, + percentage=percentage, + pre_scraamp=False, + p=p, + ) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ naive.replace_inf(ref_P) naive.replace_inf(comp_P) @@ -148,28 +140,26 @@ def test_scraamp_A_B_join(T_A, T_B, percentages): for p in [1.0, 2.0, 3.0]: for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I, ref_left_I, ref_right_I = naive.scraamp( - T_A, m, T_B, percentage, None, False, None, p=p - ) + with rng.fix_state(): + ref_P, ref_I, ref_left_I, ref_right_I = naive.scraamp( + T_A, m, T_B, percentage, None, False, None, p=p + ) - np.random.seed(seed) - approx = scraamp( - T_A, - m, - T_B, - ignore_trivial=False, - percentage=percentage, - pre_scraamp=False, - p=p, - ) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scraamp( + T_A, + m, + T_B, + ignore_trivial=False, + percentage=percentage, + pre_scraamp=False, + p=p, + ) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ naive.replace_inf(ref_P) naive.replace_inf(comp_P) @@ -186,22 +176,25 @@ def test_scraamp_A_B_join_swap(T_A, T_B, percentages): m = 3 for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, _, ref_left_I, ref_right_I = naive.scraamp( - T_B, m, T_A, percentage, None, False, None - ) + with rng.fix_state(): + ref_P, _, ref_left_I, ref_right_I = naive.scraamp( + T_B, m, T_A, percentage, None, False, None + ) - np.random.seed(seed) - approx = scraamp( - T_B, m, T_A, ignore_trivial=False, percentage=percentage, pre_scraamp=False - ) - approx.update() - comp_P = approx.P_ - # comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scraamp( + T_B, + m, + T_A, + ignore_trivial=False, + percentage=percentage, + pre_scraamp=False, + ) + approx.update() + comp_P = approx.P_ + # comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ naive.replace_inf(ref_P) naive.replace_inf(comp_P) @@ -220,22 +213,24 @@ def test_scraamp_self_join_larger_window(T_A, T_B, m, percentages): zone = int(np.ceil(m / 4)) for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I, ref_left_I, ref_right_I = naive.scraamp( - T_B, m, T_B, percentage, zone, False, None - ) + with rng.fix_state(): + ref_P, ref_I, ref_left_I, ref_right_I = naive.scraamp( + T_B, m, T_B, percentage, zone, False, None + ) - np.random.seed(seed) - approx = scraamp( - T_B, m, ignore_trivial=True, percentage=percentage, pre_scraamp=False - ) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scraamp( + T_B, + m, + ignore_trivial=True, + percentage=percentage, + pre_scraamp=False, + ) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ naive.replace_inf(ref_P) naive.replace_inf(comp_P) @@ -388,33 +383,31 @@ def test_scraamp_plus_plus_self_join(T_A, T_B, percentages): for p in [1.0, 2.0, 3.0]: for s in range(1, zone + 1): for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescraamp( - T_B, m, T_B, s=s, exclusion_zone=zone, p=p - ) - ref_P_aux, ref_I_aux, _, _ = naive.scraamp( - T_B, m, T_B, percentage, zone, True, s, p=p - ) + with rng.fix_state(): + ref_P, ref_I = naive.prescraamp( + T_B, m, T_B, s=s, exclusion_zone=zone, p=p + ) + ref_P_aux, ref_I_aux, _, _ = naive.scraamp( + T_B, m, T_B, percentage, zone, True, s, p=p + ) naive.merge_topk_PI(ref_P, ref_P_aux, ref_I, ref_I_aux) - np.random.seed(seed) - approx = scraamp( - T_B, - m, - ignore_trivial=True, - percentage=percentage, - pre_scraamp=True, - s=s, - p=p, - ) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - # comp_left_I = approx.left_I_ - # comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scraamp( + T_B, + m, + ignore_trivial=True, + percentage=percentage, + pre_scraamp=True, + s=s, + p=p, + ) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + # comp_left_I = approx.left_I_ + # comp_right_I = approx.right_I_ naive.replace_inf(ref_P) naive.replace_inf(comp_P) @@ -434,33 +427,33 @@ def test_scraamp_plus_plus_A_B_join(T_A, T_B, percentages): for p in [1.0, 2.0, 3.0]: for s in range(1, zone + 1): for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescraamp(T_A, m, T_B, s=s, p=p) - ref_P_aux, ref_I_aux, ref_left_I_aux, ref_right_I_aux = naive.scraamp( - T_A, m, T_B, percentage, None, False, None, p=p, k=1 - ) + with rng.fix_state(): + ref_P, ref_I = naive.prescraamp(T_A, m, T_B, s=s, p=p) + ref_P_aux, ref_I_aux, ref_left_I_aux, ref_right_I_aux = ( + naive.scraamp( + T_A, m, T_B, percentage, None, False, None, p=p, k=1 + ) + ) - naive.merge_topk_PI(ref_P, ref_P_aux, ref_I, ref_I_aux) - ref_left_I = ref_left_I_aux - ref_right_I = ref_right_I_aux + naive.merge_topk_PI(ref_P, ref_P_aux, ref_I, ref_I_aux) + ref_left_I = ref_left_I_aux + ref_right_I = ref_right_I_aux - approx = scraamp( - T_A, - m, - T_B, - ignore_trivial=False, - percentage=percentage, - pre_scraamp=True, - s=s, - p=p, - ) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ + approx = scraamp( + T_A, + m, + T_B, + ignore_trivial=False, + percentage=percentage, + pre_scraamp=True, + s=s, + p=p, + ) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ naive.replace_inf(ref_P) naive.replace_inf(comp_P) @@ -566,20 +559,18 @@ def test_scraamp_constant_subsequence_self_join(percentages): zone = int(np.ceil(m / 4)) for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, _, _, _ = naive.scraamp(T, m, T, percentage, zone, False, None) + with rng.fix_state(): + ref_P, _, _, _ = naive.scraamp(T, m, T, percentage, zone, False, None) - np.random.seed(seed) - approx = scraamp( - T, m, ignore_trivial=True, percentage=percentage, pre_scraamp=False - ) - approx.update() - comp_P = approx.P_ - # comp_I = approx.I_ - # comp_left_I = approx.left_I_ - # comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scraamp( + T, m, ignore_trivial=True, percentage=percentage, pre_scraamp=False + ) + approx.update() + comp_P = approx.P_ + # comp_I = approx.I_ + # comp_left_I = approx.left_I_ + # comp_right_I = approx.right_I_ naive.replace_inf(ref_P) naive.replace_inf(comp_P) @@ -592,28 +583,26 @@ def test_scraamp_constant_subsequence_self_join(percentages): @pytest.mark.parametrize("percentages", percentages) def test_scraamp_identical_subsequence_self_join(percentages): - identical = np.random.rand(8) - T = np.random.rand(20) + identical = rng.RNG.random(8) + T = rng.RNG.random(20) T[1 : 1 + identical.shape[0]] = identical T[11 : 11 + identical.shape[0]] = identical m = 3 zone = int(np.ceil(m / 4)) for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, _, _, _ = naive.scraamp(T, m, T, percentage, zone, False, None) + with rng.fix_state(): + ref_P, _, _, _ = naive.scraamp(T, m, T, percentage, zone, False, None) - np.random.seed(seed) - approx = scraamp( - T, m, ignore_trivial=True, percentage=percentage, pre_scraamp=False - ) - approx.update() - comp_P = approx.P_ - # comp_I = approx.I_ - # comp_left_I = approx.left_I_ - # comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scraamp( + T, m, ignore_trivial=True, percentage=percentage, pre_scraamp=False + ) + approx.update() + comp_P = approx.P_ + # comp_I = approx.I_ + # comp_left_I = approx.left_I_ + # comp_right_I = approx.right_I_ naive.replace_inf(ref_P) naive.replace_inf(comp_P) @@ -642,20 +631,18 @@ def test_scraamp_nan_inf_self_join( zone = int(np.ceil(m / 4)) for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I, ref_left_I, ref_right_I = naive.scraamp( - T_B_sub, m, T_B_sub, percentage, zone, False, None - ) + with rng.fix_state(): + ref_P, ref_I, ref_left_I, ref_right_I = naive.scraamp( + T_B_sub, m, T_B_sub, percentage, zone, False, None + ) - np.random.seed(seed) - approx = scraamp(T_B_sub, m, percentage=percentage, pre_scraamp=False) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scraamp(T_B_sub, m, percentage=percentage, pre_scraamp=False) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ naive.replace_inf(ref_P) naive.replace_inf(comp_P) @@ -674,20 +661,18 @@ def test_scraamp_nan_zero_mean_self_join(percentages): zone = int(np.ceil(m / 4)) for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I, ref_left_I, ref_right_I = naive.scraamp( - T, m, T, percentage, zone, False, None - ) + with rng.fix_state(): + ref_P, ref_I, ref_left_I, ref_right_I = naive.scraamp( + T, m, T, percentage, zone, False, None + ) - np.random.seed(seed) - approx = scraamp(T, m, percentage=percentage, pre_scraamp=False) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scraamp(T, m, percentage=percentage, pre_scraamp=False) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ naive.replace_inf(ref_P) naive.replace_inf(comp_P) @@ -704,13 +689,11 @@ def test_prescraamp_A_B_join_larger_window(T_A, T_B): zone = int(np.ceil(m / 4)) if len(T_A) > m and len(T_B) > m: for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescraamp(T_A, m, T_B, s=s) + with rng.fix_state(): + ref_P, ref_I = naive.prescraamp(T_A, m, T_B, s=s) - np.random.seed(seed) - comp_P, comp_I = prescraamp(T_A, m, T_B, s=s) + with rng.fix_state(): + comp_P, comp_I = prescraamp(T_A, m, T_B, s=s) npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) @@ -723,15 +706,13 @@ def test_prescraamp_self_join_KNN(T_A, T_B): for k in range(2, 4): for p in [1.0, 2.0, 3.0]: for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescraamp( - T_B, m, T_B, s=s, exclusion_zone=zone, p=p, k=k - ) + with rng.fix_state(): + ref_P, ref_I = naive.prescraamp( + T_B, m, T_B, s=s, exclusion_zone=zone, p=p, k=k + ) - np.random.seed(seed) - comp_P, comp_I = prescraamp(T_B, m, s=s, p=p, k=k) + with rng.fix_state(): + comp_P, comp_I = prescraamp(T_B, m, s=s, p=p, k=k) npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) @@ -744,13 +725,11 @@ def test_prescraamp_A_B_join_KNN(T_A, T_B): for k in range(2, 4): for p in [1.0, 2.0, 3.0]: for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescraamp(T_A, m, T_B, s=s, p=p, k=k) + with rng.fix_state(): + ref_P, ref_I = naive.prescraamp(T_A, m, T_B, s=s, p=p, k=k) - np.random.seed(seed) - comp_P, comp_I = prescraamp(T_A, m, T_B=T_B, s=s, p=p, k=k) + with rng.fix_state(): + comp_P, comp_I = prescraamp(T_A, m, T_B=T_B, s=s, p=p, k=k) npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) @@ -765,28 +744,26 @@ def test_scraamp_self_join_KNN(T_A, T_B, percentages): for k in range(2, 4): for p in [1.0, 2.0, 3.0]: for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I, ref_left_I, ref_right_I = naive.scraamp( - T_B, m, T_B, percentage, zone, False, None, p=p, k=k - ) + with rng.fix_state(): + ref_P, ref_I, ref_left_I, ref_right_I = naive.scraamp( + T_B, m, T_B, percentage, zone, False, None, p=p, k=k + ) - np.random.seed(seed) - approx = scraamp( - T_B, - m, - ignore_trivial=True, - percentage=percentage, - pre_scraamp=False, - p=p, - k=k, - ) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scraamp( + T_B, + m, + ignore_trivial=True, + percentage=percentage, + pre_scraamp=False, + p=p, + k=k, + ) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ naive.replace_inf(ref_P) naive.replace_inf(comp_P) @@ -803,29 +780,27 @@ def test_scraamp_A_B_join_KNN(T_A, T_B, percentages): for k in range(2, 4): for p in [1.0, 2.0, 3.0]: for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I, ref_left_I, ref_right_I = naive.scraamp( - T_A, m, T_B, percentage, None, False, None, p=p, k=k - ) + with rng.fix_state(): + ref_P, ref_I, ref_left_I, ref_right_I = naive.scraamp( + T_A, m, T_B, percentage, None, False, None, p=p, k=k + ) - np.random.seed(seed) - approx = scraamp( - T_A, - m, - T_B, - ignore_trivial=False, - percentage=percentage, - pre_scraamp=False, - p=p, - k=k, - ) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scraamp( + T_A, + m, + T_B, + ignore_trivial=False, + percentage=percentage, + pre_scraamp=False, + p=p, + k=k, + ) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ naive.replace_inf(ref_P) naive.replace_inf(comp_P) @@ -845,34 +820,32 @@ def test_scraamp_plus_plus_self_join_KNN(T_A, T_B, percentages): for p in [1.0, 2.0, 3.0]: for s in range(1, zone + 1): for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescraamp( - T_B, m, T_B, s=s, exclusion_zone=zone, p=p, k=k - ) - ref_P_aux, ref_I_aux, _, _ = naive.scraamp( - T_B, m, T_B, percentage, zone, True, s, p=p, k=k - ) + with rng.fix_state(): + ref_P, ref_I = naive.prescraamp( + T_B, m, T_B, s=s, exclusion_zone=zone, p=p, k=k + ) + ref_P_aux, ref_I_aux, _, _ = naive.scraamp( + T_B, m, T_B, percentage, zone, True, s, p=p, k=k + ) naive.merge_topk_PI(ref_P, ref_P_aux, ref_I, ref_I_aux) - np.random.seed(seed) - approx = scraamp( - T_B, - m, - ignore_trivial=True, - percentage=percentage, - pre_scraamp=True, - s=s, - p=p, - k=k, - ) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - # comp_left_I = approx.left_I_ - # comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scraamp( + T_B, + m, + ignore_trivial=True, + percentage=percentage, + pre_scraamp=True, + s=s, + p=p, + k=k, + ) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + # comp_left_I = approx.left_I_ + # comp_right_I = approx.right_I_ naive.replace_inf(ref_P) naive.replace_inf(comp_P) @@ -892,13 +865,13 @@ def test_prescraamp_self_join_larger_window_m_5_k_5(T_A, T_B, m): if len(T_B) > m: for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescraamp(T_B, m, T_B, s=s, exclusion_zone=zone, k=k) + with rng.fix_state(): + ref_P, ref_I = naive.prescraamp( + T_B, m, T_B, s=s, exclusion_zone=zone, k=k + ) - np.random.seed(seed) - comp_P, comp_I = prescraamp(T_B, m, s=s, k=k) + with rng.fix_state(): + comp_P, comp_I = prescraamp(T_B, m, s=s, k=k) npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) @@ -912,13 +885,11 @@ def test_prescraamp_A_B_join_larger_window_m_5_k_5(T_A, T_B): if len(T_A) > m and len(T_B) > m: for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescraamp(T_A, m, T_B, s=s, k=k) + with rng.fix_state(): + ref_P, ref_I = naive.prescraamp(T_A, m, T_B, s=s, k=k) - np.random.seed(seed) - comp_P, comp_I = prescraamp(T_A, m, T_B, s=s, k=k) + with rng.fix_state(): + comp_P, comp_I = prescraamp(T_A, m, T_B, s=s, k=k) npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) diff --git a/tests/test_scrump.py b/tests/test_scrump.py index 7c1ea76a6..787e36b09 100644 --- a/tests/test_scrump.py +++ b/tests/test_scrump.py @@ -5,7 +5,7 @@ import numpy.testing as npt import pytest -from stumpy import config +from stumpy import config, rng from stumpy.scrump import prescrump, scrump from stumpy.stump import stump @@ -15,8 +15,8 @@ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), ), ( - np.random.uniform(-1000, 1000, [8]).astype(np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [8]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64), ), ] @@ -31,16 +31,14 @@ def test_prescrump_self_join(T_A, T_B): m = 3 zone = int(np.ceil(m / 4)) for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescrump(T_B, m, T_B, s=s, exclusion_zone=zone) + with rng.fix_state(): + ref_P, ref_I = naive.prescrump(T_B, m, T_B, s=s, exclusion_zone=zone) - np.random.seed(seed) - comp_P, comp_I = prescrump(T_B, m, s=s) + with rng.fix_state(): + comp_P, comp_I = prescrump(T_B, m, s=s) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -48,16 +46,14 @@ def test_prescrump_A_B_join(T_A, T_B): m = 3 zone = int(np.ceil(m / 4)) for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescrump(T_A, m, T_B, s=s) + with rng.fix_state(): + ref_P, ref_I = naive.prescrump(T_A, m, T_B, s=s) - np.random.seed(seed) - comp_P, comp_I = prescrump(T_A, m, T_B=T_B, s=s) + with rng.fix_state(): + comp_P, comp_I = prescrump(T_A, m, T_B=T_B, s=s) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -65,16 +61,14 @@ def test_prescrump_A_B_join_swap(T_A, T_B): m = 3 zone = int(np.ceil(m / 4)) for s in range(1, zone + 1): - seed = np.random.randint(100000) + with rng.fix_state(): + ref_P, ref_I = naive.prescrump(T_B, m, T_A, s=s) - np.random.seed(seed) - ref_P, ref_I = naive.prescrump(T_B, m, T_A, s=s) + with rng.fix_state(): + comp_P, comp_I = prescrump(T_B, m, T_B=T_A, s=s) - np.random.seed(seed) - comp_P, comp_I = prescrump(T_B, m, T_B=T_A, s=s) - - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -83,16 +77,14 @@ def test_prescrump_self_join_larger_window(T_A, T_B, m): if len(T_B) > m: zone = int(np.ceil(m / 4)) for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescrump(T_B, m, T_B, s=s, exclusion_zone=zone) + with rng.fix_state(): + ref_P, ref_I = naive.prescrump(T_B, m, T_B, s=s, exclusion_zone=zone) - np.random.seed(seed) - comp_P, comp_I = prescrump(T_B, m, s=s) + with rng.fix_state(): + comp_P, comp_I = prescrump(T_B, m, s=s) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -104,26 +96,24 @@ def test_prescrump_self_join_with_isconstant(T_A, T_B): m = 3 zone = int(np.ceil(m / 4)) for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescrump( - T_B, - m, - T_B, - s=s, - exclusion_zone=zone, - T_A_subseq_isconstant=isconstant_custom_func, - T_B_subseq_isconstant=isconstant_custom_func, - ) - - np.random.seed(seed) - comp_P, comp_I = prescrump( - T_B, m, s=s, T_A_subseq_isconstant=isconstant_custom_func - ) + with rng.fix_state(): + ref_P, ref_I = naive.prescrump( + T_B, + m, + T_B, + s=s, + exclusion_zone=zone, + T_A_subseq_isconstant=isconstant_custom_func, + T_B_subseq_isconstant=isconstant_custom_func, + ) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + with rng.fix_state(): + comp_P, comp_I = prescrump( + T_B, m, s=s, T_A_subseq_isconstant=isconstant_custom_func + ) + + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) def test_scrump_int_input(): @@ -138,29 +128,27 @@ def test_scrump_self_join(T_A, T_B, percentages): zone = int(np.ceil(m / 4)) for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I, ref_left_I, ref_right_I = naive.scrump( - T_B, m, T_B, percentage, zone, False, None - ) + with rng.fix_state(): + ref_P, ref_I, ref_left_I, ref_right_I = naive.scrump( + T_B, m, T_B, percentage, zone, False, None + ) - np.random.seed(seed) - approx = scrump( - T_B, m, ignore_trivial=True, percentage=percentage, pre_scrump=False - ) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scrump( + T_B, m, ignore_trivial=True, percentage=percentage, pre_scrump=False + ) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_I, comp_left_I) - npt.assert_almost_equal(ref_right_I, comp_right_I) + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_right_I, comp_right_I) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -169,30 +157,33 @@ def test_scrump_A_B_join(T_A, T_B, percentages): m = 3 for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I, ref_left_I, ref_right_I = naive.scrump( - T_A, m, T_B, percentage, None, False, None - ) + with rng.fix_state(): + ref_P, ref_I, ref_left_I, ref_right_I = naive.scrump( + T_A, m, T_B, percentage, None, False, None + ) - np.random.seed(seed) - approx = scrump( - T_A, m, T_B, ignore_trivial=False, percentage=percentage, pre_scrump=False - ) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scrump( + T_A, + m, + T_B, + ignore_trivial=False, + percentage=percentage, + pre_scrump=False, + ) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_I, comp_left_I) - npt.assert_almost_equal(ref_right_I, comp_right_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_right_I, comp_right_I) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -201,30 +192,33 @@ def test_scrump_A_B_join_swap(T_A, T_B, percentages): m = 3 for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, _, ref_left_I, ref_right_I = naive.scrump( - T_B, m, T_A, percentage, None, False, None - ) + with rng.fix_state(): + ref_P, _, ref_left_I, ref_right_I = naive.scrump( + T_B, m, T_A, percentage, None, False, None + ) - np.random.seed(seed) - approx = scrump( - T_B, m, T_A, ignore_trivial=False, percentage=percentage, pre_scrump=False - ) - approx.update() - comp_P = approx.P_ - # comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scrump( + T_B, + m, + T_A, + ignore_trivial=False, + percentage=percentage, + pre_scrump=False, + ) + approx.update() + comp_P = approx.P_ + # comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) - npt.assert_almost_equal(ref_right_I, comp_right_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_right_I, comp_right_I) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -235,16 +229,62 @@ def test_scrump_self_join_larger_window(T_A, T_B, m, percentages): zone = int(np.ceil(m / 4)) for percentage in percentages: - seed = np.random.randint(100000) + with rng.fix_state(): + ref_P, ref_I, ref_left_I, ref_right_I = naive.scrump( + T_B, m, T_B, percentage, zone, False, None + ) + + with rng.fix_state(): + approx = scrump( + T_B, m, ignore_trivial=True, percentage=percentage, pre_scrump=False + ) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ + + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) + + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_right_I, comp_right_I) + + +@pytest.mark.parametrize("T_A, T_B", test_data) +@pytest.mark.parametrize("percentages", percentages) +def test_scrump_self_join_with_isconstant(T_A, T_B, percentages): + isconstant_custom_func = functools.partial( + naive.isconstant_func_stddev_threshold, quantile_threshold=0.05 + ) - np.random.seed(seed) + m = 3 + zone = int(np.ceil(m / 4)) + + for percentage in percentages: + with rng.fix_state(): ref_P, ref_I, ref_left_I, ref_right_I = naive.scrump( - T_B, m, T_B, percentage, zone, False, None + T_B, + m, + T_B, + percentage, + zone, + False, + None, + T_A_subseq_isconstant=isconstant_custom_func, + T_B_subseq_isconstant=isconstant_custom_func, ) - np.random.seed(seed) + with rng.fix_state(): approx = scrump( - T_B, m, ignore_trivial=True, percentage=percentage, pre_scrump=False + T_B, + m, + ignore_trivial=True, + percentage=percentage, + pre_scrump=False, + T_A_subseq_isconstant=isconstant_custom_func, ) approx.update() comp_P = approx.P_ @@ -254,62 +294,12 @@ def test_scrump_self_join_larger_window(T_A, T_B, m, percentages): naive.replace_inf(ref_P) naive.replace_inf(comp_P) - npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) npt.assert_almost_equal(ref_left_I, comp_left_I) npt.assert_almost_equal(ref_right_I, comp_right_I) -@pytest.mark.parametrize("T_A, T_B", test_data) -@pytest.mark.parametrize("percentages", percentages) -def test_scrump_self_join_with_isconstant(T_A, T_B, percentages): - isconstant_custom_func = functools.partial( - naive.isconstant_func_stddev_threshold, quantile_threshold=0.05 - ) - - m = 3 - zone = int(np.ceil(m / 4)) - - for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I, ref_left_I, ref_right_I = naive.scrump( - T_B, - m, - T_B, - percentage, - zone, - False, - None, - T_A_subseq_isconstant=isconstant_custom_func, - T_B_subseq_isconstant=isconstant_custom_func, - ) - - np.random.seed(seed) - approx = scrump( - T_B, - m, - ignore_trivial=True, - percentage=percentage, - pre_scrump=False, - T_A_subseq_isconstant=isconstant_custom_func, - ) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_I, comp_left_I) - npt.assert_almost_equal(ref_right_I, comp_right_I) - - @pytest.mark.parametrize("T_A, T_B", test_data) def test_scrump_self_join_full(T_A, T_B): m = 3 @@ -447,31 +437,36 @@ def test_scrump_plus_plus_self_join(T_A, T_B, percentages): for s in range(1, zone + 1): for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescrump(T_B, m, T_B, s=s, exclusion_zone=zone, k=1) - ref_P_aux, ref_I_aux, _, _ = naive.scrump( - T_B, m, T_B, percentage, zone, True, s, k=1 - ) + with rng.fix_state(): + ref_P, ref_I = naive.prescrump( + T_B, m, T_B, s=s, exclusion_zone=zone, k=1 + ) + ref_P_aux, ref_I_aux, _, _ = naive.scrump( + T_B, m, T_B, percentage, zone, True, s, k=1 + ) - naive.merge_topk_PI(ref_P, ref_P_aux, ref_I, ref_I_aux) + naive.merge_topk_PI(ref_P, ref_P_aux, ref_I, ref_I_aux) - np.random.seed(seed) - approx = scrump( - T_B, m, ignore_trivial=True, percentage=percentage, pre_scrump=True, s=s - ) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ + with rng.fix_state(): + approx = scrump( + T_B, + m, + ignore_trivial=True, + percentage=percentage, + pre_scrump=True, + s=s, + ) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) - ref_P = ref_P - ref_I = ref_I - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + ref_P = ref_P + ref_I = ref_I + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -482,43 +477,41 @@ def test_scrump_plus_plus_A_B_join(T_A, T_B, percentages): for s in range(1, zone + 1): for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescrump(T_A, m, T_B, s=s, k=1) + with rng.fix_state(): + ref_P, ref_I = naive.prescrump(T_A, m, T_B, s=s, k=1) - ref_P_aux, ref_I_aux, ref_left_I_aux, ref_right_I_aux = naive.scrump( - T_A, m, T_B, percentage, None, False, None, k=1 - ) + ref_P_aux, ref_I_aux, ref_left_I_aux, ref_right_I_aux = naive.scrump( + T_A, m, T_B, percentage, None, False, None, k=1 + ) - naive.merge_topk_PI(ref_P, ref_P_aux, ref_I, ref_I_aux) - ref_left_I = ref_left_I_aux - ref_right_I = ref_right_I_aux + naive.merge_topk_PI(ref_P, ref_P_aux, ref_I, ref_I_aux) + ref_left_I = ref_left_I_aux + ref_right_I = ref_right_I_aux - approx = scrump( - T_A, - m, - T_B, - ignore_trivial=False, - percentage=percentage, - pre_scrump=True, - s=s, - ) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ + approx = scrump( + T_A, + m, + T_B, + ignore_trivial=False, + percentage=percentage, + pre_scrump=True, + s=s, + ) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) - ref_P = ref_P - ref_I = ref_I - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_I, comp_left_I) - npt.assert_almost_equal(ref_right_I, comp_right_I) + ref_P = ref_P + ref_I = ref_I + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_right_I, comp_right_I) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -616,64 +609,60 @@ def test_scrump_constant_subsequence_self_join(percentages): zone = int(np.ceil(m / 4)) for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I, ref_left_I, ref_right_I = naive.scrump( - T, m, T, percentage, zone, False, None - ) + with rng.fix_state(): + ref_P, ref_I, ref_left_I, ref_right_I = naive.scrump( + T, m, T, percentage, zone, False, None + ) - np.random.seed(seed) - approx = scrump( - T, m, ignore_trivial=True, percentage=percentage, pre_scrump=False - ) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scrump( + T, m, ignore_trivial=True, percentage=percentage, pre_scrump=False + ) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_I, comp_left_I) - npt.assert_almost_equal(ref_right_I, comp_right_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_right_I, comp_right_I) @pytest.mark.parametrize("percentages", percentages) def test_scrump_identical_subsequence_self_join(percentages): - identical = np.random.rand(8) - T = np.random.rand(20) + identical = rng.RNG.rand(8) + T = rng.RNG.rand(20) T[1 : 1 + identical.shape[0]] = identical T[11 : 11 + identical.shape[0]] = identical m = 3 zone = int(np.ceil(m / 4)) for percentage in percentages: - seed = np.random.randint(100000) + with rng.fix_state(): + ref_P, _, _, _ = naive.scrump(T, m, T, percentage, zone, False, None) - np.random.seed(seed) - ref_P, _, _, _ = naive.scrump(T, m, T, percentage, zone, False, None) - - np.random.seed(seed) - approx = scrump( - T, m, ignore_trivial=True, percentage=percentage, pre_scrump=False - ) - approx.update() - comp_P = approx.P_ - # comp_I = approx.I_ - # comp_left_I = approx.left_I_ - # comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scrump( + T, m, ignore_trivial=True, percentage=percentage, pre_scrump=False + ) + approx.update() + comp_P = approx.P_ + # comp_I = approx.I_ + # comp_left_I = approx.left_I_ + # comp_right_I = approx.right_I_ - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) - npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) - # npt.assert_almost_equal(ref_I, comp_I) - # npt.assert_almost_equal(ref_left_I, comp_left_I) - # npt.assert_almost_equal(ref_right_I, comp_right_I) + npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) + # npt.assert_almost_equal(ref_I, comp_I) + # npt.assert_almost_equal(ref_left_I, comp_left_I) + # npt.assert_almost_equal(ref_right_I, comp_right_I) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -694,15 +683,43 @@ def test_scrump_nan_inf_self_join( zone = int(np.ceil(m / 4)) for percentage in percentages: - seed = np.random.randint(100000) + with rng.fix_state(): + ref_P, ref_I, ref_left_I, ref_right_I = naive.scrump( + T_B_sub, m, T_B_sub, percentage, zone, False, None + ) + + with rng.fix_state(): + approx = scrump(T_B_sub, m, percentage=percentage, pre_scrump=False) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ + + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) + + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_right_I, comp_right_I) + - np.random.seed(seed) +@pytest.mark.parametrize("percentages", percentages) +def test_scrump_nan_zero_mean_self_join(percentages): + T = np.array([-1, 0, 1, np.inf, 1, 0, -1]) + + m = 3 + zone = int(np.ceil(m / 4)) + + for percentage in percentages: + with rng.fix_state(): ref_P, ref_I, ref_left_I, ref_right_I = naive.scrump( - T_B_sub, m, T_B_sub, percentage, zone, False, None + T, m, T, percentage, zone, False, None ) - np.random.seed(seed) - approx = scrump(T_B_sub, m, percentage=percentage, pre_scrump=False) + with rng.fix_state(): + approx = scrump(T, m, percentage=percentage, pre_scrump=False) approx.update() comp_P = approx.P_ comp_I = approx.I_ @@ -718,54 +735,20 @@ def test_scrump_nan_inf_self_join( npt.assert_almost_equal(ref_right_I, comp_right_I) -@pytest.mark.parametrize("percentages", percentages) -def test_scrump_nan_zero_mean_self_join(percentages): - T = np.array([-1, 0, 1, np.inf, 1, 0, -1]) - - m = 3 - zone = int(np.ceil(m / 4)) - - for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I, ref_left_I, ref_right_I = naive.scrump( - T, m, T, percentage, zone, False, None - ) - - np.random.seed(seed) - approx = scrump(T, m, percentage=percentage, pre_scrump=False) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) - - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_I, comp_left_I) - npt.assert_almost_equal(ref_right_I, comp_right_I) - - @pytest.mark.parametrize("T_A, T_B", test_data) def test_prescrump_A_B_join_larger_window(T_A, T_B): m = 5 zone = int(np.ceil(m / 4)) if len(T_A) > m and len(T_B) > m: for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescrump(T_A, m, T_B, s=s) + with rng.fix_state(): + ref_P, ref_I = naive.prescrump(T_A, m, T_B, s=s) - np.random.seed(seed) - comp_P, comp_I = prescrump(T_A, m, T_B, s=s) + with rng.fix_state(): + comp_P, comp_I = prescrump(T_A, m, T_B, s=s) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -774,16 +757,16 @@ def test_prescrump_self_join_KNN(T_A, T_B): zone = int(np.ceil(m / 4)) for k in range(2, 4): for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescrump(T_B, m, T_B, s=s, exclusion_zone=zone, k=k) + with rng.fix_state(): + ref_P, ref_I = naive.prescrump( + T_B, m, T_B, s=s, exclusion_zone=zone, k=k + ) - np.random.seed(seed) - comp_P, comp_I = prescrump(T_B, m, s=s, k=k) + with rng.fix_state(): + comp_P, comp_I = prescrump(T_B, m, s=s, k=k) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -792,16 +775,14 @@ def test_prescrump_A_B_join_KNN(T_A, T_B): zone = int(np.ceil(m / 4)) for k in range(2, 4): for s in range(1, zone + 1): - seed = np.random.randint(100000) + with rng.fix_state(): + ref_P, ref_I = naive.prescrump(T_A, m, T_B, s=s) - np.random.seed(seed) - ref_P, ref_I = naive.prescrump(T_A, m, T_B, s=s) + with rng.fix_state(): + comp_P, comp_I = prescrump(T_A, m, T_B=T_B, s=s) - np.random.seed(seed) - comp_P, comp_I = prescrump(T_A, m, T_B=T_B, s=s) - - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -812,34 +793,32 @@ def test_scrump_self_join_KNN(T_A, T_B, percentages): for k in range(2, 4): for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I, ref_left_I, ref_right_I = naive.scrump( - T_B, m, T_B, percentage, zone, False, None, k=k - ) + with rng.fix_state(): + ref_P, ref_I, ref_left_I, ref_right_I = naive.scrump( + T_B, m, T_B, percentage, zone, False, None, k=k + ) - np.random.seed(seed) - approx = scrump( - T_B, - m, - ignore_trivial=True, - percentage=percentage, - pre_scrump=False, - k=k, - ) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ + with rng.fix_state(): + approx = scrump( + T_B, + m, + ignore_trivial=True, + percentage=percentage, + pre_scrump=False, + k=k, + ) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_I, comp_left_I) - npt.assert_almost_equal(ref_right_I, comp_right_I) + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_right_I, comp_right_I) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -848,77 +827,73 @@ def test_scrump_A_B_join_KNN(T_A, T_B, percentages): m = 3 for k in range(2, 4): for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I, ref_left_I, ref_right_I = naive.scrump( - T_A, m, T_B, percentage, None, False, None, k=k - ) - - np.random.seed(seed) - approx = scrump( - T_A, - m, - T_B, - ignore_trivial=False, - percentage=percentage, - pre_scrump=False, - k=k, - ) - approx.update() - comp_P = approx.P_ - comp_I = approx.I_ - comp_left_I = approx.left_I_ - comp_right_I = approx.right_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) - - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_I, comp_left_I) - npt.assert_almost_equal(ref_right_I, comp_right_I) - - -@pytest.mark.parametrize("T_A, T_B", test_data) -@pytest.mark.parametrize("percentages", percentages) -def test_scrump_plus_plus_self_join_KNN(T_A, T_B, percentages): - m = 3 - zone = int(np.ceil(m / 4)) - - for k in range(2, 4): - for s in range(1, zone + 1): - for percentage in percentages: - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescrump( - T_B, m, T_B, s=s, exclusion_zone=zone, k=k - ) - ref_P_aux, ref_I_aux, _, _ = naive.scrump( - T_B, m, T_B, percentage, zone, True, s, k=k + with rng.fix_state(): + ref_P, ref_I, ref_left_I, ref_right_I = naive.scrump( + T_A, m, T_B, percentage, None, False, None, k=k ) - naive.merge_topk_PI(ref_P, ref_P_aux, ref_I, ref_I_aux) - np.random.seed(seed) + with rng.fix_state(): approx = scrump( - T_B, + T_A, m, - ignore_trivial=True, + T_B, + ignore_trivial=False, percentage=percentage, - pre_scrump=True, - s=s, + pre_scrump=False, k=k, ) approx.update() comp_P = approx.P_ comp_I = approx.I_ + comp_left_I = approx.left_I_ + comp_right_I = approx.right_I_ naive.replace_inf(ref_P) naive.replace_inf(comp_P) npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_right_I, comp_right_I) + + +@pytest.mark.parametrize("T_A, T_B", test_data) +@pytest.mark.parametrize("percentages", percentages) +def test_scrump_plus_plus_self_join_KNN(T_A, T_B, percentages): + m = 3 + zone = int(np.ceil(m / 4)) + + for k in range(2, 4): + for s in range(1, zone + 1): + for percentage in percentages: + with rng.fix_state(): + ref_P, ref_I = naive.prescrump( + T_B, m, T_B, s=s, exclusion_zone=zone, k=k + ) + ref_P_aux, ref_I_aux, _, _ = naive.scrump( + T_B, m, T_B, percentage, zone, True, s, k=k + ) + naive.merge_topk_PI(ref_P, ref_P_aux, ref_I, ref_I_aux) + + with rng.fix_state(): + approx = scrump( + T_B, + m, + ignore_trivial=True, + percentage=percentage, + pre_scrump=True, + s=s, + k=k, + ) + approx.update() + comp_P = approx.P_ + comp_I = approx.I_ + + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) + + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -929,16 +904,16 @@ def test_prescrump_self_join_larger_window_m_5_k_5(T_A, T_B): if len(T_B) > m: for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescrump(T_B, m, T_B, s=s, exclusion_zone=zone, k=k) + with rng.fix_state(): + ref_P, ref_I = naive.prescrump( + T_B, m, T_B, s=s, exclusion_zone=zone, k=k + ) - np.random.seed(seed) - comp_P, comp_I = prescrump(T_B, m, s=s, k=k) + with rng.fix_state(): + comp_P, comp_I = prescrump(T_B, m, s=s, k=k) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -948,16 +923,14 @@ def test_prescrump_A_B_join_larger_window_m_5_k_5(T_A, T_B): zone = int(np.ceil(m / 4)) if len(T_A) > m and len(T_B) > m: for s in range(1, zone + 1): - seed = np.random.randint(100000) + with rng.fix_state(): + ref_P, ref_I = naive.prescrump(T_A, m, T_B, s=s, k=k) - np.random.seed(seed) - ref_P, ref_I = naive.prescrump(T_A, m, T_B, s=s, k=k) + with rng.fix_state(): + comp_P, comp_I = prescrump(T_A, m, T_B, s=s, k=k) - np.random.seed(seed) - comp_P, comp_I = prescrump(T_A, m, T_B, s=s, k=k) - - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) def test_prescrump_self_join_KNN_no_overlap(): @@ -1057,12 +1030,12 @@ def test_prescrump_self_join_KNN_no_overlap(): for (m, k), specified_seeds in test_cases.items(): zone = int(np.ceil(m / 4)) for seed in specified_seeds: - np.random.seed(seed) - ref_P, ref_I = naive.prescrump(T, m, T, s=1, exclusion_zone=zone, k=k) - comp_P, comp_I = prescrump(T, m, s=1, k=k) + with rng.fix_seed(seed): + ref_P, ref_I = naive.prescrump(T, m, T, s=1, exclusion_zone=zone, k=k) + comp_P, comp_I = prescrump(T, m, s=1, k=k) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) @pytest.mark.parametrize("T_A, T_B", test_data) @@ -1077,24 +1050,22 @@ def test_prescrump_self_join_larger_window_m_5_k_5_with_isconstant(T_A, T_B): if len(T_B) > m: for s in range(1, zone + 1): - seed = np.random.randint(100000) - - np.random.seed(seed) - ref_P, ref_I = naive.prescrump( - T_B, - m, - T_B, - s=s, - exclusion_zone=zone, - k=k, - T_A_subseq_isconstant=isconstant_custom_func, - T_B_subseq_isconstant=isconstant_custom_func, - ) + with rng.fix_state(): + ref_P, ref_I = naive.prescrump( + T_B, + m, + T_B, + s=s, + exclusion_zone=zone, + k=k, + T_A_subseq_isconstant=isconstant_custom_func, + T_B_subseq_isconstant=isconstant_custom_func, + ) - np.random.seed(seed) - comp_P, comp_I = prescrump( - T_B, m, s=s, k=k, T_A_subseq_isconstant=isconstant_custom_func - ) + with rng.fix_state(): + comp_P, comp_I = prescrump( + T_B, m, s=s, k=k, T_A_subseq_isconstant=isconstant_custom_func + ) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) diff --git a/tests/test_sdp.py b/tests/test_sdp.py index b8d98eeb9..5490eecd7 100644 --- a/tests/test_sdp.py +++ b/tests/test_sdp.py @@ -3,11 +3,10 @@ from operator import eq, lt import naive -import numpy as np import pytest from numpy import testing as npt -from stumpy import sdp +from stumpy import rng, sdp # README # Real FFT algorithm performs more efficiently when the length @@ -113,8 +112,8 @@ def test_sdp(n_T, remainder, comparator): n_Q_values = sorted(n_Q for n_Q in set(n_Q_values) if n_Q <= n_T) for n_Q in n_Q_values: - Q = np.random.rand(n_Q) - T = np.random.rand(n_T) + Q = rng.RNG.rand(n_Q) + T = rng.RNG.rand(n_T) ref = naive.rolling_window_dot_product(Q, T) for func_name in get_sdp_function_names(): func = getattr(sdp, func_name) @@ -139,8 +138,8 @@ def test_sdp_power2(): n_Q = 2**q for p in range(q, pmax + 1): n_T = 2**p - Q = np.random.rand(n_Q) - T = np.random.rand(n_T) + Q = rng.RNG.rand(n_Q) + T = rng.RNG.rand(n_T) ref = naive.rolling_window_dot_product(Q, T) comp = func(Q, T) diff --git a/tests/test_snippets.py b/tests/test_snippets.py index 1aa893885..c57e0d085 100644 --- a/tests/test_snippets.py +++ b/tests/test_snippets.py @@ -5,10 +5,10 @@ import numpy.testing as npt import pytest -from stumpy import config +from stumpy import config, rng from stumpy.snippets import _get_all_profiles, snippets -test_data = [np.random.uniform(-1000, 1000, [64]).astype(np.float64)] +test_data = [rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64)] s = [3, 6, 7, 8] percentage = [0.4, 0.7, 0.8, 0.9] m = [8, 9, 10] diff --git a/tests/test_stamp.py b/tests/test_stamp.py index 3ec3e9b47..3caeb8fca 100644 --- a/tests/test_stamp.py +++ b/tests/test_stamp.py @@ -5,7 +5,7 @@ import numpy.testing as npt import pytest -from stumpy import core +from stumpy import core, rng from stumpy.stamp import _mass_PI, stamp test_data = [ @@ -14,8 +14,8 @@ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), ), ( - np.random.uniform(-1000, 1000, [8]).astype(np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [8]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64), ), ] @@ -151,7 +151,7 @@ def test_stamp_nan_zero_mean_self_join(): def test_stamp_mass_PI_with_isconstant_case1(): # case1: The query `Q` is not constant - T_B = np.random.uniform(-1, 1, [64]) + T_B = rng.RNG.uniform(-1, 1, [64]) isconstant_custom_func = functools.partial( naive.isconstant_func_stddev_threshold, stddev_threshold=0.5 ) @@ -162,7 +162,7 @@ def test_stamp_mass_PI_with_isconstant_case1(): T_B_subseq_isconstant = naive.rolling_isconstant(T_B, m, isconstant_custom_func) M_T, Σ_T = core.compute_mean_std(T_B, m) - trivial_idx = np.random.choice(np.flatnonzero(~T_B_subseq_isconstant)) + trivial_idx = rng.RNG.choice(np.flatnonzero(~T_B_subseq_isconstant)) Q = T_B[trivial_idx : trivial_idx + m] ref_P, ref_I, ref_left_I, ref_right_I = naive.mass_PI( @@ -220,7 +220,7 @@ def test_stamp_mass_PI_with_isconstant_case1(): def test_stamp_mass_PI_with_isconstant_case2(): # case2: The query `Q` is constant - T_B = np.random.uniform(-1, 1, [64]) + T_B = rng.RNG.uniform(-1, 1, [64]) isconstant_custom_func = functools.partial( naive.isconstant_func_stddev_threshold, stddev_threshold=0.5 ) @@ -231,7 +231,7 @@ def test_stamp_mass_PI_with_isconstant_case2(): T_B_subseq_isconstant = naive.rolling_isconstant(T_B, m, isconstant_custom_func) M_T, Σ_T = core.compute_mean_std(T_B, m) - trivial_idx = np.random.choice(np.flatnonzero(T_B_subseq_isconstant)) + trivial_idx = rng.RNG.choice(np.flatnonzero(T_B_subseq_isconstant)) Q = T_B[trivial_idx : trivial_idx + m] ref_P, ref_I, ref_left_I, ref_right_I = naive.mass_PI( diff --git a/tests/test_stimp.py b/tests/test_stimp.py index e160fb40b..82229e14f 100644 --- a/tests/test_stimp.py +++ b/tests/test_stimp.py @@ -7,11 +7,12 @@ import tornado.ioloop from dask.distributed import Client, LocalCluster +from stumpy import rng from stumpy.stimp import stimp, stimped T = [ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64), ] @@ -37,51 +38,49 @@ def test_stimp_1_percent(T): min_m = 3 n = T.shape[0] - min_m + 1 - seed = np.random.randint(100000) - - np.random.seed(seed) - pan = stimp( - T, - min_m=min_m, - max_m=None, - step=1, - percentage=percentage, - pre_scrump=True, - # normalize=True, - ) + with rng.fix_state(): + pan = stimp( + T, + min_m=min_m, + max_m=None, + step=1, + percentage=percentage, + pre_scrump=True, + # normalize=True, + ) - for i in range(n): - pan.update() + for i in range(n): + pan.update() - ref_PAN = np.full((pan.M_.shape[0], T.shape[0]), fill_value=np.inf) + ref_PAN = np.full((pan.M_.shape[0], T.shape[0]), fill_value=np.inf) - np.random.seed(seed) - for idx, m in enumerate(pan.M_[:n]): - zone = int(np.ceil(m / 4)) - s = zone - tmp_P, tmp_I = naive.prescrump(T, m, T, s=s, exclusion_zone=zone) - ref_P, ref_I, _, _ = naive.scrump(T, m, T, percentage, zone, True, s) - naive.merge_topk_PI(ref_P, tmp_P, ref_I, tmp_I) - ref_PAN[pan._bfs_indices[idx], : ref_P.shape[0]] = ref_P + with rng.fix_state(): + for idx, m in enumerate(pan.M_[:n]): + zone = int(np.ceil(m / 4)) + s = zone + tmp_P, tmp_I = naive.prescrump(T, m, T, s=s, exclusion_zone=zone) + ref_P, ref_I, _, _ = naive.scrump(T, m, T, percentage, zone, True, s) + naive.merge_topk_PI(ref_P, tmp_P, ref_I, tmp_I) + ref_PAN[pan._bfs_indices[idx], : ref_P.shape[0]] = ref_P - # Compare raw pan - cmp_PAN = pan._PAN + # Compare raw pan + cmp_PAN = pan._PAN - naive.replace_inf(ref_PAN) - naive.replace_inf(cmp_PAN) + naive.replace_inf(ref_PAN) + naive.replace_inf(cmp_PAN) - npt.assert_almost_equal(ref_PAN, cmp_PAN) + npt.assert_almost_equal(ref_PAN, cmp_PAN) - # Compare transformed pan - cmp_pan = pan.PAN_ - ref_pan = naive.transform_pan( - pan._PAN, pan._M, threshold, pan._bfs_indices, pan._n_processed - ) + # Compare transformed pan + cmp_pan = pan.PAN_ + ref_pan = naive.transform_pan( + pan._PAN, pan._M, threshold, pan._bfs_indices, pan._n_processed + ) - naive.replace_inf(ref_pan) - naive.replace_inf(cmp_pan) + naive.replace_inf(ref_pan) + naive.replace_inf(cmp_pan) - npt.assert_almost_equal(ref_pan, cmp_pan) + npt.assert_almost_equal(ref_pan, cmp_pan) @pytest.mark.parametrize("T", T) @@ -92,51 +91,49 @@ def test_stimp_max_m(T): max_m = 5 n = T.shape[0] - min_m + 1 - seed = np.random.randint(100000) - - np.random.seed(seed) - pan = stimp( - T, - min_m=min_m, - max_m=max_m, - step=1, - percentage=percentage, - pre_scrump=True, - # normalize=True, - ) + with rng.fix_state(): + pan = stimp( + T, + min_m=min_m, + max_m=max_m, + step=1, + percentage=percentage, + pre_scrump=True, + # normalize=True, + ) - for i in range(n): - pan.update() + for i in range(n): + pan.update() - ref_PAN = np.full((pan.M_.shape[0], T.shape[0]), fill_value=np.inf) + ref_PAN = np.full((pan.M_.shape[0], T.shape[0]), fill_value=np.inf) - np.random.seed(seed) - for idx, m in enumerate(pan.M_[:n]): - zone = int(np.ceil(m / 4)) - s = zone - tmp_P, tmp_I = naive.prescrump(T, m, T, s=s, exclusion_zone=zone) - ref_P, ref_I, _, _ = naive.scrump(T, m, T, percentage, zone, True, s) - naive.merge_topk_PI(ref_P, tmp_P, ref_I, tmp_I) - ref_PAN[pan._bfs_indices[idx], : ref_P.shape[0]] = ref_P + with rng.fix_state(): + for idx, m in enumerate(pan.M_[:n]): + zone = int(np.ceil(m / 4)) + s = zone + tmp_P, tmp_I = naive.prescrump(T, m, T, s=s, exclusion_zone=zone) + ref_P, ref_I, _, _ = naive.scrump(T, m, T, percentage, zone, True, s) + naive.merge_topk_PI(ref_P, tmp_P, ref_I, tmp_I) + ref_PAN[pan._bfs_indices[idx], : ref_P.shape[0]] = ref_P - # Compare raw pan - cmp_PAN = pan._PAN + # Compare raw pan + cmp_PAN = pan._PAN - naive.replace_inf(ref_PAN) - naive.replace_inf(cmp_PAN) + naive.replace_inf(ref_PAN) + naive.replace_inf(cmp_PAN) - npt.assert_almost_equal(ref_PAN, cmp_PAN) + npt.assert_almost_equal(ref_PAN, cmp_PAN) - # Compare transformed pan - cmp_pan = pan.PAN_ - ref_pan = naive.transform_pan( - pan._PAN, pan._M, threshold, pan._bfs_indices, pan._n_processed - ) + # Compare transformed pan + cmp_pan = pan.PAN_ + ref_pan = naive.transform_pan( + pan._PAN, pan._M, threshold, pan._bfs_indices, pan._n_processed + ) - naive.replace_inf(ref_pan) - naive.replace_inf(cmp_pan) + naive.replace_inf(ref_pan) + naive.replace_inf(cmp_pan) - npt.assert_almost_equal(ref_pan, cmp_pan) + npt.assert_almost_equal(ref_pan, cmp_pan) @pytest.mark.parametrize("T", T) @@ -269,7 +266,7 @@ def test_stimped(T, dask_cluster): def test_stimp_1_percent_with_isconstant(): - T = np.random.uniform(-1, 1, [64]) + T = rng.RNG.uniform(-1, 1, [64]) isconstant_func = functools.partial( naive.isconstant_func_stddev_threshold, stddev_threshold=0.5 ) @@ -279,75 +276,73 @@ def test_stimp_1_percent_with_isconstant(): min_m = 3 n = T.shape[0] - min_m + 1 - seed = np.random.randint(100000) - - np.random.seed(seed) - pan = stimp( - T, - min_m=min_m, - max_m=None, - step=1, - percentage=percentage, - pre_scrump=True, - # normalize=True, - T_subseq_isconstant_func=isconstant_func, - ) + with rng.fix_state(): + pan = stimp( + T, + min_m=min_m, + max_m=None, + step=1, + percentage=percentage, + pre_scrump=True, + # normalize=True, + T_subseq_isconstant_func=isconstant_func, + ) - for i in range(n): - pan.update() + for i in range(n): + pan.update() - ref_PAN = np.full((pan.M_.shape[0], T.shape[0]), fill_value=np.inf) + ref_PAN = np.full((pan.M_.shape[0], T.shape[0]), fill_value=np.inf) - np.random.seed(seed) - for idx, m in enumerate(pan.M_[:n]): - zone = int(np.ceil(m / 4)) - s = zone - tmp_P, tmp_I = naive.prescrump( - T, - m, - T, - s=s, - exclusion_zone=zone, - T_A_subseq_isconstant=isconstant_func, - T_B_subseq_isconstant=isconstant_func, - ) - ref_P, ref_I, _, _ = naive.scrump( - T, - m, - T, - percentage, - zone, - True, - s, - T_A_subseq_isconstant=isconstant_func, - T_B_subseq_isconstant=isconstant_func, - ) - naive.merge_topk_PI(ref_P, tmp_P, ref_I, tmp_I) - ref_PAN[pan._bfs_indices[idx], : ref_P.shape[0]] = ref_P + with rng.fix_state(): + for idx, m in enumerate(pan.M_[:n]): + zone = int(np.ceil(m / 4)) + s = zone + tmp_P, tmp_I = naive.prescrump( + T, + m, + T, + s=s, + exclusion_zone=zone, + T_A_subseq_isconstant=isconstant_func, + T_B_subseq_isconstant=isconstant_func, + ) + ref_P, ref_I, _, _ = naive.scrump( + T, + m, + T, + percentage, + zone, + True, + s, + T_A_subseq_isconstant=isconstant_func, + T_B_subseq_isconstant=isconstant_func, + ) + naive.merge_topk_PI(ref_P, tmp_P, ref_I, tmp_I) + ref_PAN[pan._bfs_indices[idx], : ref_P.shape[0]] = ref_P - # Compare raw pan - cmp_PAN = pan._PAN + # Compare raw pan + cmp_PAN = pan._PAN - naive.replace_inf(ref_PAN) - naive.replace_inf(cmp_PAN) + naive.replace_inf(ref_PAN) + naive.replace_inf(cmp_PAN) - npt.assert_almost_equal(ref_PAN, cmp_PAN) + npt.assert_almost_equal(ref_PAN, cmp_PAN) - # Compare transformed pan - cmp_pan = pan.PAN_ - ref_pan = naive.transform_pan( - pan._PAN, pan._M, threshold, pan._bfs_indices, pan._n_processed - ) + # Compare transformed pan + cmp_pan = pan.PAN_ + ref_pan = naive.transform_pan( + pan._PAN, pan._M, threshold, pan._bfs_indices, pan._n_processed + ) - naive.replace_inf(ref_pan) - naive.replace_inf(cmp_pan) + naive.replace_inf(ref_pan) + naive.replace_inf(cmp_pan) - npt.assert_almost_equal(ref_pan, cmp_pan) + npt.assert_almost_equal(ref_pan, cmp_pan) @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_stimped_with_isconstant(dask_cluster): - T = np.random.uniform(-1, 1, [64]) + T = rng.RNG.uniform(-1, 1, [64]) isconstant_func = functools.partial( naive.isconstant_func_stddev_threshold, stddev_threshold=0.5 ) diff --git a/tests/test_stomp.py b/tests/test_stomp.py index 3ae67ce46..2199195c3 100644 --- a/tests/test_stomp.py +++ b/tests/test_stomp.py @@ -3,6 +3,7 @@ import numpy.testing as npt import pytest +from stumpy import rng from stumpy.stomp import _stomp test_data = [ @@ -11,8 +12,8 @@ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), ), ( - np.random.uniform(-1000, 1000, [8]).astype(np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [8]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64), ), ] diff --git a/tests/test_stump.py b/tests/test_stump.py index e26f5def8..d5505de96 100644 --- a/tests/test_stump.py +++ b/tests/test_stump.py @@ -7,7 +7,7 @@ import polars as pl import pytest -from stumpy import config +from stumpy import config, rng from stumpy.stump import stump test_data = [ @@ -16,8 +16,8 @@ np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), ), ( - np.random.uniform(-1000, 1000, [8]).astype(np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [8]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64), ), ] @@ -83,7 +83,7 @@ def test_stump_constant_subsequence_self_join(): def test_stump_one_constant_subsequence_A_B_join(): - T_A = np.random.rand(20) + T_A = rng.RNG.rand(20) T_B = np.concatenate((np.zeros(20, dtype=np.float64), np.ones(5, dtype=np.float64))) m = 3 ref_mp = naive.stump(T_A, m, T_B=T_B, row_wise=True) @@ -133,8 +133,8 @@ def test_stump_two_constant_subsequences_A_B_join(): def test_stump_identical_subsequence_self_join(): - identical = np.random.rand(8) - T_A = np.random.rand(20) + identical = rng.RNG.rand(8) + T_A = rng.RNG.rand(20) T_A[1 : 1 + identical.shape[0]] = identical T_A[11 : 11 + identical.shape[0]] = identical m = 3 @@ -155,9 +155,9 @@ def test_stump_identical_subsequence_self_join(): def test_stump_identical_subsequence_A_B_join(): - identical = np.random.rand(8) - T_A = np.random.rand(20) - T_B = np.random.rand(20) + identical = rng.RNG.rand(8) + T_A = rng.RNG.rand(20) + T_B = rng.RNG.rand(20) T_A[1 : 1 + identical.shape[0]] = identical T_B[11 : 11 + identical.shape[0]] = identical m = 3 diff --git a/tests/test_stumped.py b/tests/test_stumped.py index 86e17f812..f3cf066ba 100644 --- a/tests/test_stumped.py +++ b/tests/test_stumped.py @@ -9,7 +9,7 @@ import tornado.ioloop from dask.distributed import Client, LocalCluster -from stumpy import config +from stumpy import config, rng from stumpy.stumped import stumped @@ -34,8 +34,8 @@ def dask_cluster(): np.array([584, -11, 23, 79, 1001, 0, -19], dtype=np.float64), ), ( - np.random.uniform(-1000, 1000, [8]).astype(np.float64), - np.random.uniform(-1000, 1000, [64]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [8]).astype(np.float64), + rng.RNG.uniform(-1000, 1000, [64]).astype(np.float64), ), ] @@ -202,7 +202,7 @@ def test_stumped_one_constant_subsequence_self_join_df(dask_cluster): @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_stumped_one_constant_subsequence_A_B_join(dask_cluster): with Client(dask_cluster) as dask_client: - T_A = np.random.rand(20) + T_A = rng.RNG.rand(20) T_B = np.concatenate( (np.zeros(20, dtype=np.float64), np.ones(5, dtype=np.float64)) ) @@ -222,7 +222,7 @@ def test_stumped_one_constant_subsequence_A_B_join(dask_cluster): @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_stumped_one_constant_subsequence_A_B_join_df(dask_cluster): with Client(dask_cluster) as dask_client: - T_A = np.random.rand(20) + T_A = rng.RNG.rand(20) T_B = np.concatenate( (np.zeros(20, dtype=np.float64), np.ones(5, dtype=np.float64)) ) @@ -244,7 +244,7 @@ def test_stumped_one_constant_subsequence_A_B_join_df(dask_cluster): @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_stumped_one_constant_subsequence_A_B_join_swap(dask_cluster): with Client(dask_cluster) as dask_client: - T_A = np.random.rand(20) + T_A = rng.RNG.rand(20) T_B = np.concatenate( (np.zeros(20, dtype=np.float64), np.ones(5, dtype=np.float64)) ) @@ -264,7 +264,7 @@ def test_stumped_one_constant_subsequence_A_B_join_swap(dask_cluster): @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_stumped_one_constant_subsequence_A_B_join_df_swap(dask_cluster): with Client(dask_cluster) as dask_client: - T_A = np.random.rand(20) + T_A = rng.RNG.rand(20) T_B = np.concatenate( (np.zeros(20, dtype=np.float64), np.ones(5, dtype=np.float64)) ) @@ -286,8 +286,8 @@ def test_stumped_one_constant_subsequence_A_B_join_df_swap(dask_cluster): @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_stumped_identical_subsequence_self_join(dask_cluster): with Client(dask_cluster) as dask_client: - identical = np.random.rand(8) - T_A = np.random.rand(20) + identical = rng.RNG.rand(8) + T_A = rng.RNG.rand(20) T_A[1 : 1 + identical.shape[0]] = identical T_A[11 : 11 + identical.shape[0]] = identical m = 3 @@ -309,9 +309,9 @@ def test_stumped_identical_subsequence_self_join(dask_cluster): @pytest.mark.filterwarnings("ignore:\\s+Port 8787 is already in use:UserWarning") def test_stumped_identical_subsequence_A_B_join(dask_cluster): with Client(dask_cluster) as dask_client: - identical = np.random.rand(8) - T_A = np.random.rand(20) - T_B = np.random.rand(20) + identical = rng.RNG.rand(8) + T_A = rng.RNG.rand(20) + T_B = rng.RNG.rand(20) T_A[1 : 1 + identical.shape[0]] = identical T_B[11 : 11 + identical.shape[0]] = identical m = 3 diff --git a/tests/test_stumpi.py b/tests/test_stumpi.py index 09559f934..a8d9bcbfe 100644 --- a/tests/test_stumpi.py +++ b/tests/test_stumpi.py @@ -6,7 +6,7 @@ import pandas as pd import pytest -from stumpy import config, core +from stumpy import config, core, rng from stumpy.stumpi import stumpi substitution_locations = [(slice(0, 0), 0, -1, slice(1, 3), [0, 3])] @@ -22,243 +22,66 @@ def test_stumpi_self_join(): m = 3 zone = int(np.ceil(m / 4)) - seed = np.random.randint(100000) - np.random.seed(seed) - - T = np.random.rand(30) - stream = stumpi(T, m, egress=False) - for i in range(34): - t = np.random.rand() - stream.update(t) - - comp_P = stream.P_ - comp_I = stream.I_ - comp_left_P = stream.left_P_ - comp_left_I = stream.left_I_ - - ref_mp = naive.stump(stream.T_, m, exclusion_zone=zone, row_wise=True) - ref_P = ref_mp[:, 0] - ref_I = ref_mp[:, 1] - ref_left_I = ref_mp[:, 2].astype(np.int64) - ref_left_P = np.full_like(ref_left_I, np.inf, dtype=np.float64) - for i, j in enumerate(ref_left_I): - if j >= 0: - D = core.mass(stream.T_[i : i + m], stream.T_[j : j + m]) - ref_left_P[i] = D[0] - - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) - - np.random.seed(seed) - T = np.random.rand(30) - T = pd.Series(T) - stream = stumpi(T, m, egress=False) - for i in range(34): - t = np.random.rand() - stream.update(t) - - comp_P = stream.P_ - comp_I = stream.I_ - comp_left_P = stream.left_P_ - comp_left_I = stream.left_I_ - - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) - - -def test_stumpi_self_join_egress(): - m = 3 - - seed = np.random.randint(100000) - np.random.seed(seed) - n = 30 - T = np.random.rand(n) - - ref_mp = naive.stumpi_egress(T, m) - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ - - stream = stumpi(T, m, egress=True) - - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) - - for i in range(34): - t = np.random.rand() - ref_mp.update(t) - stream.update(t) - - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ - - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) - - np.random.seed(seed) - T = np.random.rand(n) - T = pd.Series(T) - - ref_mp = naive.stumpi_egress(T, m) - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ - - stream = stumpi(T, m, egress=True) - - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) - - for i in range(34): - t = np.random.rand() - t = np.random.rand() - ref_mp.update(t) - stream.update(t) - - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ - - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) - - -@pytest.mark.parametrize("substitute", substitution_values) -@pytest.mark.parametrize("substitution_locations", substitution_locations) -def test_stumpi_init_nan_inf_self_join(substitute, substitution_locations): - m = 3 - zone = int(np.ceil(m / 4)) - - seed = np.random.randint(100000) - # seed = 58638 - - for substitution_location in substitution_locations: - np.random.seed(seed) - T = np.random.rand(30) - - if substitution_location == -1: - substitution_location = T.shape[0] - 1 - T[substitution_location] = substitute + with rng.fix_state(): + T = rng.RNG.rand(30) stream = stumpi(T, m, egress=False) for i in range(34): - t = np.random.rand() + t = rng.RNG.rand() stream.update(t) comp_P = stream.P_ comp_I = stream.I_ + comp_left_P = stream.left_P_ + comp_left_I = stream.left_I_ - stream.T_[substitution_location] = substitute ref_mp = naive.stump(stream.T_, m, exclusion_zone=zone, row_wise=True) ref_P = ref_mp[:, 0] ref_I = ref_mp[:, 1] + ref_left_I = ref_mp[:, 2].astype(np.int64) + ref_left_P = np.full_like(ref_left_I, np.inf, dtype=np.float64) + for i, j in enumerate(ref_left_I): + if j >= 0: + D = core.mass(stream.T_[i : i + m], stream.T_[j : j + m]) + ref_left_P[i] = D[0] naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) - np.random.seed(seed) - T = np.random.rand(30) - - if substitution_location == -1: # pragma: no cover - substitution_location = T.shape[0] - 1 - T[substitution_location] = substitute + with rng.fix_state(): + T = rng.RNG.rand(30) T = pd.Series(T) stream = stumpi(T, m, egress=False) for i in range(34): - t = np.random.rand() + t = rng.RNG.rand() stream.update(t) comp_P = stream.P_ comp_I = stream.I_ + comp_left_P = stream.left_P_ + comp_left_I = stream.left_I_ naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) -@pytest.mark.parametrize("substitute", substitution_values) -@pytest.mark.parametrize("substitution_locations", substitution_locations) -def test_stumpi_init_nan_inf_self_join_egress(substitute, substitution_locations): +def test_stumpi_self_join_egress(): m = 3 - seed = np.random.randint(100000) - # seed = 58638 - - for substitution_location in substitution_locations: - np.random.seed(seed) + with rng.fix_state(): n = 30 - T = np.random.rand(n) - - if substitution_location == -1: - substitution_location = T.shape[0] - 1 - T[substitution_location] = substitute + T = rng.RNG.rand(n) ref_mp = naive.stumpi_egress(T, m) ref_P = ref_mp.P_.copy() @@ -284,7 +107,7 @@ def test_stumpi_init_nan_inf_self_join_egress(substitute, substitution_locations npt.assert_almost_equal(ref_left_I, comp_left_I) for i in range(34): - t = np.random.rand() + t = rng.RNG.rand() ref_mp.update(t) stream.update(t) @@ -308,12 +131,8 @@ def test_stumpi_init_nan_inf_self_join_egress(substitute, substitution_locations npt.assert_almost_equal(ref_left_P, comp_left_P) npt.assert_almost_equal(ref_left_I, comp_left_I) - np.random.seed(seed) - T = np.random.rand(n) - - if substitution_location == -1: # pragma: no cover - substitution_location = T.shape[0] - 1 - T[substitution_location] = substitute + with rng.fix_state(): + T = rng.RNG.rand(n) T = pd.Series(T) ref_mp = naive.stumpi_egress(T, m) @@ -340,7 +159,8 @@ def test_stumpi_init_nan_inf_self_join_egress(substitute, substitution_locations npt.assert_almost_equal(ref_left_I, comp_left_I) for i in range(34): - t = np.random.rand() + t = rng.RNG.rand() + t = rng.RNG.rand() ref_mp.update(t) stream.update(t) @@ -367,108 +187,83 @@ def test_stumpi_init_nan_inf_self_join_egress(substitute, substitution_locations @pytest.mark.parametrize("substitute", substitution_values) @pytest.mark.parametrize("substitution_locations", substitution_locations) -def test_stumpi_stream_nan_inf_self_join(substitute, substitution_locations): +def test_stumpi_init_nan_inf_self_join(substitute, substitution_locations): m = 3 zone = int(np.ceil(m / 4)) - seed = np.random.randint(100000) - for substitution_location in substitution_locations: - np.random.seed(seed) - T = np.random.rand(64) - - stream = stumpi(T[:30], m, egress=False) - if substitution_location == -1: - substitution_location = T[30:].shape[0] - 1 - T[30:][substitution_location] = substitute - for t in T[30:]: - stream.update(t) - - comp_P = stream.P_ - comp_I = stream.I_ - - stream.T_[30:][substitution_location] = substitute - ref_mp = naive.stump(stream.T_, m, exclusion_zone=zone, row_wise=True) - ref_P = ref_mp[:, 0] - ref_I = ref_mp[:, 1] + with rng.fix_state(): + T = rng.RNG.rand(30) + + if substitution_location == -1: + substitution_location = T.shape[0] - 1 + T[substitution_location] = substitute + stream = stumpi(T, m, egress=False) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) + + comp_P = stream.P_ + comp_I = stream.I_ - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) + stream.T_[substitution_location] = substitute + ref_mp = naive.stump(stream.T_, m, exclusion_zone=zone, row_wise=True) + ref_P = ref_mp[:, 0] + ref_I = ref_mp[:, 1] - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) - np.random.seed(seed) - T = np.random.rand(64) + with rng.fix_state(): + T = rng.RNG.rand(30) - stream = stumpi(pd.Series(T[:30]), m, egress=False) - if substitution_location == -1: # pragma: no cover - substitution_location = T[30:].shape[0] - 1 - T[30:][substitution_location] = substitute - for t in T[30:]: - stream.update(t) + if substitution_location == -1: # pragma: no cover + substitution_location = T.shape[0] - 1 + T[substitution_location] = substitute + T = pd.Series(T) + stream = stumpi(T, m, egress=False) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) - comp_P = stream.P_ - comp_I = stream.I_ + comp_P = stream.P_ + comp_I = stream.I_ - naive.replace_inf(comp_P) + naive.replace_inf(comp_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) @pytest.mark.parametrize("substitute", substitution_values) @pytest.mark.parametrize("substitution_locations", substitution_locations) -def test_stumpi_stream_nan_inf_self_join_egress(substitute, substitution_locations): +def test_stumpi_init_nan_inf_self_join_egress(substitute, substitution_locations): m = 3 - seed = np.random.randint(100000) - for substitution_location in substitution_locations: - np.random.seed(seed) - T = np.random.rand(64) - n = 30 - - ref_mp = naive.stumpi_egress(T[:n], m) - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ - - stream = stumpi(T[:n], m, egress=True) - - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(n) - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) + if substitution_location == -1: + substitution_location = T.shape[0] - 1 + T[substitution_location] = substitute - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + ref_mp = naive.stumpi_egress(T, m) + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ - if substitution_location == -1: - substitution_location = T[30:].shape[0] - 1 - T[n:][substitution_location] = substitute - for t in T[n:]: - ref_mp.update(t) - stream.update(t) + stream = stumpi(T, m, egress=True) comp_P = stream.P_.copy() comp_I = stream.I_ comp_left_P = stream.left_P_.copy() comp_left_I = stream.left_I_ - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ - naive.replace_inf(ref_P) naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) @@ -479,49 +274,52 @@ def test_stumpi_stream_nan_inf_self_join_egress(substitute, substitution_locatio npt.assert_almost_equal(ref_left_P, comp_left_P) npt.assert_almost_equal(ref_left_I, comp_left_I) - np.random.seed(seed) - T = np.random.rand(64) - - ref_mp = naive.stumpi_egress(T[:n], m) - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ + for i in range(34): + t = rng.RNG.rand() + ref_mp.update(t) + stream.update(t) - stream = stumpi(T[:n], m, egress=True) + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) - if substitution_location == -1: # pragma: no cover - substitution_location = T[n:].shape[0] - 1 - T[n:][substitution_location] = substitute - for t in T[n:]: - ref_mp.update(t) - stream.update(t) + with rng.fix_state(): + T = rng.RNG.rand(n) - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ + if substitution_location == -1: # pragma: no cover + substitution_location = T.shape[0] - 1 + T[substitution_location] = substitute + T = pd.Series(T) + ref_mp = naive.stumpi_egress(T, m) ref_P = ref_mp.P_.copy() ref_I = ref_mp.I_ ref_left_P = ref_mp.left_P_.copy() ref_left_I = ref_mp.left_I_ + stream = stumpi(T, m, egress=True) + + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ + naive.replace_inf(ref_P) naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) @@ -532,148 +330,316 @@ def test_stumpi_stream_nan_inf_self_join_egress(substitute, substitution_locatio npt.assert_almost_equal(ref_left_P, comp_left_P) npt.assert_almost_equal(ref_left_I, comp_left_I) + for i in range(34): + t = rng.RNG.rand() + ref_mp.update(t) + stream.update(t) -def test_stumpi_constant_subsequence_self_join(): - m = 3 - zone = int(np.ceil(m / 4)) - - seed = np.random.randint(100000) - np.random.seed(seed) - - T = np.concatenate((np.zeros(20, dtype=np.float64), np.ones(10, dtype=np.float64))) - stream = stumpi(T, m, egress=False) - for i in range(34): - t = np.random.rand() - stream.update(t) - - comp_P = stream.P_ - # comp_I = stream.I_ + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ - ref_mp = naive.stump(stream.T_, m, exclusion_zone=zone, row_wise=True) - ref_P = ref_mp[:, 0] - # ref_I = ref_mp[:, 1] + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - npt.assert_almost_equal(ref_P, comp_P) - # npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) - np.random.seed(seed) - T = np.concatenate((np.zeros(20, dtype=np.float64), np.ones(10, dtype=np.float64))) - T = pd.Series(T) - stream = stumpi(T, m, egress=False) - for i in range(34): - t = np.random.rand() - stream.update(t) - comp_P = stream.P_ - # comp_I = stream.I_ +@pytest.mark.parametrize("substitute", substitution_values) +@pytest.mark.parametrize("substitution_locations", substitution_locations) +def test_stumpi_stream_nan_inf_self_join(substitute, substitution_locations): + m = 3 + zone = int(np.ceil(m / 4)) - naive.replace_inf(comp_P) + for substitution_location in substitution_locations: + with rng.fix_state(): + T = rng.RNG.rand(64) - npt.assert_almost_equal(ref_P, comp_P) - # npt.assert_almost_equal(ref_I, comp_I) + stream = stumpi(T[:30], m, egress=False) + if substitution_location == -1: + substitution_location = T[30:].shape[0] - 1 + T[30:][substitution_location] = substitute + for t in T[30:]: + stream.update(t) + comp_P = stream.P_ + comp_I = stream.I_ -def test_stumpi_constant_subsequence_self_join_egress(): - m = 3 + stream.T_[30:][substitution_location] = substitute + ref_mp = naive.stump(stream.T_, m, exclusion_zone=zone, row_wise=True) + ref_P = ref_mp[:, 0] + ref_I = ref_mp[:, 1] - seed = np.random.randint(100000) - np.random.seed(seed) + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) - T = np.concatenate((np.zeros(20, dtype=np.float64), np.ones(10, dtype=np.float64))) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) - ref_mp = naive.stumpi_egress(T, m) - ref_P = ref_mp.P_.copy() - # ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - # ref_left_I = ref_mp.left_I_ + with rng.fix_state(): + T = rng.RNG.rand(64) - stream = stumpi(T, m, egress=True) + stream = stumpi(pd.Series(T[:30]), m, egress=False) + if substitution_location == -1: # pragma: no cover + substitution_location = T[30:].shape[0] - 1 + T[30:][substitution_location] = substitute + for t in T[30:]: + stream.update(t) - comp_P = stream.P_.copy() - # comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - # comp_left_I = stream.left_I_ + comp_P = stream.P_ + comp_I = stream.I_ - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) + naive.replace_inf(comp_P) - npt.assert_almost_equal(ref_P, comp_P) - # npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - # npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) - for i in range(34): - t = np.random.rand() - ref_mp.update(t) - stream.update(t) - comp_P = stream.P_.copy() - # comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - # comp_left_I = stream.left_I_ +@pytest.mark.parametrize("substitute", substitution_values) +@pytest.mark.parametrize("substitution_locations", substitution_locations) +def test_stumpi_stream_nan_inf_self_join_egress(substitute, substitution_locations): + m = 3 - ref_P = ref_mp.P_.copy() - # ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - # ref_left_I = ref_mp.left_I_ + for substitution_location in substitution_locations: + with rng.fix_state(): + T = rng.RNG.rand(64) + n = 30 - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) + ref_mp = naive.stumpi_egress(T[:n], m) + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ - npt.assert_almost_equal(ref_P, comp_P) - # npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - # npt.assert_almost_equal(ref_left_I, comp_left_I) + stream = stumpi(T[:n], m, egress=True) - np.random.seed(seed) - T = np.concatenate((np.zeros(20, dtype=np.float64), np.ones(10, dtype=np.float64))) - T = pd.Series(T) + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ - ref_mp = naive.stumpi_egress(T, m) - ref_P = ref_mp.P_.copy() - # ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - # ref_left_I = ref_mp.left_I_ + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - stream = stumpi(T, m, egress=True) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) - comp_P = stream.P_.copy() - # comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - # comp_left_I = stream.left_I_ + if substitution_location == -1: + substitution_location = T[30:].shape[0] - 1 + T[n:][substitution_location] = substitute + for t in T[n:]: + ref_mp.update(t) + stream.update(t) + + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ + + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ + + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) + + with rng.fix_state(): + T = rng.RNG.rand(64) + + ref_mp = naive.stumpi_egress(T[:n], m) + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) + stream = stumpi(T[:n], m, egress=True) - npt.assert_almost_equal(ref_P, comp_P) - # npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - # npt.assert_almost_equal(ref_left_I, comp_left_I) + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ - for i in range(34): - t = np.random.rand() - ref_mp.update(t) - stream.update(t) + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) + + if substitution_location == -1: # pragma: no cover + substitution_location = T[n:].shape[0] - 1 + T[n:][substitution_location] = substitute + for t in T[n:]: + ref_mp.update(t) + stream.update(t) + + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ + + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ + + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) + + +def test_stumpi_constant_subsequence_self_join(): + m = 3 + zone = int(np.ceil(m / 4)) + + with rng.fix_state(): + T = np.concatenate( + (np.zeros(20, dtype=np.float64), np.ones(10, dtype=np.float64)) + ) + stream = stumpi(T, m, egress=False) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) + + comp_P = stream.P_ + # comp_I = stream.I_ + + ref_mp = naive.stump(stream.T_, m, exclusion_zone=zone, row_wise=True) + ref_P = ref_mp[:, 0] + # ref_I = ref_mp[:, 1] + + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) + + npt.assert_almost_equal(ref_P, comp_P) + # npt.assert_almost_equal(ref_I, comp_I) + + with rng.fix_state(): + T = np.concatenate( + (np.zeros(20, dtype=np.float64), np.ones(10, dtype=np.float64)) + ) + T = pd.Series(T) + stream = stumpi(T, m, egress=False) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) + + comp_P = stream.P_ + # comp_I = stream.I_ + + naive.replace_inf(comp_P) + + npt.assert_almost_equal(ref_P, comp_P) + # npt.assert_almost_equal(ref_I, comp_I) + + +def test_stumpi_constant_subsequence_self_join_egress(): + m = 3 + + with rng.fix_state(): + T = np.concatenate( + (np.zeros(20, dtype=np.float64), np.ones(10, dtype=np.float64)) + ) + + ref_mp = naive.stumpi_egress(T, m) + ref_P = ref_mp.P_.copy() + # ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + # ref_left_I = ref_mp.left_I_ + + stream = stumpi(T, m, egress=True) comp_P = stream.P_.copy() # comp_I = stream.I_ comp_left_P = stream.left_P_.copy() # comp_left_I = stream.left_I_ + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + + npt.assert_almost_equal(ref_P, comp_P) + # npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + # npt.assert_almost_equal(ref_left_I, comp_left_I) + + for i in range(34): + t = rng.RNG.rand() + ref_mp.update(t) + stream.update(t) + + comp_P = stream.P_.copy() + # comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + # comp_left_I = stream.left_I_ + + ref_P = ref_mp.P_.copy() + # ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + # ref_left_I = ref_mp.left_I_ + + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + + npt.assert_almost_equal(ref_P, comp_P) + # npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + # npt.assert_almost_equal(ref_left_I, comp_left_I) + + with rng.fix_state(): + T = np.concatenate( + (np.zeros(20, dtype=np.float64), np.ones(10, dtype=np.float64)) + ) + T = pd.Series(T) + + ref_mp = naive.stumpi_egress(T, m) ref_P = ref_mp.P_.copy() # ref_I = ref_mp.I_ ref_left_P = ref_mp.left_P_.copy() # ref_left_I = ref_mp.left_I_ + stream = stumpi(T, m, egress=True) + + comp_P = stream.P_.copy() + # comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + # comp_left_I = stream.left_I_ + naive.replace_inf(ref_P) naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) @@ -684,107 +650,101 @@ def test_stumpi_constant_subsequence_self_join_egress(): npt.assert_almost_equal(ref_left_P, comp_left_P) # npt.assert_almost_equal(ref_left_I, comp_left_I) + for i in range(34): + t = rng.RNG.rand() + ref_mp.update(t) + stream.update(t) + + comp_P = stream.P_.copy() + # comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + # comp_left_I = stream.left_I_ + + ref_P = ref_mp.P_.copy() + # ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + # ref_left_I = ref_mp.left_I_ + + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + + npt.assert_almost_equal(ref_P, comp_P) + # npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + # npt.assert_almost_equal(ref_left_I, comp_left_I) + def test_stumpi_identical_subsequence_self_join(): m = 3 zone = int(np.ceil(m / 4)) - seed = np.random.randint(100000) - np.random.seed(seed) - - identical = np.random.rand(8) - T = np.random.rand(20) - T[1 : 1 + identical.shape[0]] = identical - T[11 : 11 + identical.shape[0]] = identical - stream = stumpi(T, m, egress=False) - for i in range(34): - t = np.random.rand() - stream.update(t) + with rng.fix_state(): + identical = rng.RNG.rand(8) + T = rng.RNG.rand(20) + T[1 : 1 + identical.shape[0]] = identical + T[11 : 11 + identical.shape[0]] = identical + stream = stumpi(T, m, egress=False) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) - comp_P = stream.P_ - # comp_I = stream.I_ + comp_P = stream.P_ + # comp_I = stream.I_ - ref_mp = naive.stump(stream.T_, m, exclusion_zone=zone, row_wise=True) - ref_P = ref_mp[:, 0] - # ref_I = ref_mp[:, 1] + ref_mp = naive.stump(stream.T_, m, exclusion_zone=zone, row_wise=True) + ref_P = ref_mp[:, 0] + # ref_I = ref_mp[:, 1] - naive.replace_inf(ref_P) - naive.replace_inf(comp_P) + naive.replace_inf(ref_P) + naive.replace_inf(comp_P) - npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) - # npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) + # npt.assert_almost_equal(ref_I, comp_I) - np.random.seed(seed) - identical = np.random.rand(8) - T = np.random.rand(20) - T[1 : 1 + identical.shape[0]] = identical - T[11 : 11 + identical.shape[0]] = identical - T = pd.Series(T) - stream = stumpi(T, m, egress=False) - for i in range(34): - t = np.random.rand() - stream.update(t) + with rng.fix_state(): + identical = rng.RNG.rand(8) + T = rng.RNG.rand(20) + T[1 : 1 + identical.shape[0]] = identical + T[11 : 11 + identical.shape[0]] = identical + T = pd.Series(T) + stream = stumpi(T, m, egress=False) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) - comp_P = stream.P_ - # comp_I = stream.I_ + comp_P = stream.P_ + # comp_I = stream.I_ - naive.replace_inf(comp_P) + naive.replace_inf(comp_P) - npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) - # npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) + # npt.assert_almost_equal(ref_I, comp_I) def test_stumpi_identical_subsequence_self_join_egress(): m = 3 - seed = np.random.randint(100000) - np.random.seed(seed) - - identical = np.random.rand(8) - T = np.random.rand(20) - T[1 : 1 + identical.shape[0]] = identical - T[11 : 11 + identical.shape[0]] = identical - - ref_mp = naive.stumpi_egress(T, m) - ref_P = ref_mp.P_.copy() - # ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - # ref_left_I = ref_mp.left_I_ - - stream = stumpi(T, m, egress=True) - - comp_P = stream.P_.copy() - # comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - # comp_left_I = stream.left_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) - # npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal( - ref_left_P, comp_left_P, decimal=config.STUMPY_TEST_PRECISION - ) - # npt.assert_almost_equal(ref_left_I, comp_left_I) - - for i in range(34): - t = np.random.rand() - ref_mp.update(t) - stream.update(t) - - comp_P = stream.P_.copy() - # comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - # comp_left_I = stream.left_I_ + with rng.fix_state(): + identical = rng.RNG.rand(8) + T = rng.RNG.rand(20) + T[1 : 1 + identical.shape[0]] = identical + T[11 : 11 + identical.shape[0]] = identical + ref_mp = naive.stumpi_egress(T, m) ref_P = ref_mp.P_.copy() # ref_I = ref_mp.I_ ref_left_P = ref_mp.left_P_.copy() # ref_left_I = ref_mp.left_I_ + stream = stumpi(T, m, egress=True) + + comp_P = stream.P_.copy() + # comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + # comp_left_I = stream.left_I_ + naive.replace_inf(ref_P) naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) @@ -797,52 +757,52 @@ def test_stumpi_identical_subsequence_self_join_egress(): ) # npt.assert_almost_equal(ref_left_I, comp_left_I) - np.random.seed(seed) - identical = np.random.rand(8) - T = np.random.rand(20) - T[1 : 1 + identical.shape[0]] = identical - T[11 : 11 + identical.shape[0]] = identical - T = pd.Series(T) - ref_mp = naive.stumpi_egress(T, m) - ref_P = ref_mp.P_.copy() - # ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - # ref_left_I = ref_mp.left_I_ - - stream = stumpi(T, m, egress=True) - - comp_P = stream.P_.copy() - # comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - # comp_left_I = stream.left_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) - # npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal( - ref_left_P, comp_left_P, decimal=config.STUMPY_TEST_PRECISION - ) - # npt.assert_almost_equal(ref_left_I, comp_left_I) - - for i in range(34): - t = np.random.rand() - ref_mp.update(t) - stream.update(t) + for i in range(34): + t = rng.RNG.rand() + ref_mp.update(t) + stream.update(t) - comp_P = stream.P_.copy() - # comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - # comp_left_I = stream.left_I_ + comp_P = stream.P_.copy() + # comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + # comp_left_I = stream.left_I_ + + ref_P = ref_mp.P_.copy() + # ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + # ref_left_I = ref_mp.left_I_ + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + + npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) + # npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal( + ref_left_P, comp_left_P, decimal=config.STUMPY_TEST_PRECISION + ) + # npt.assert_almost_equal(ref_left_I, comp_left_I) + + with rng.fix_state(): + identical = rng.RNG.rand(8) + T = rng.RNG.rand(20) + T[1 : 1 + identical.shape[0]] = identical + T[11 : 11 + identical.shape[0]] = identical + T = pd.Series(T) + ref_mp = naive.stumpi_egress(T, m) ref_P = ref_mp.P_.copy() # ref_I = ref_mp.I_ ref_left_P = ref_mp.left_P_.copy() # ref_left_I = ref_mp.left_I_ + stream = stumpi(T, m, egress=True) + + comp_P = stream.P_.copy() + # comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + # comp_left_I = stream.left_I_ + naive.replace_inf(ref_P) naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) @@ -855,9 +815,36 @@ def test_stumpi_identical_subsequence_self_join_egress(): ) # npt.assert_almost_equal(ref_left_I, comp_left_I) + for i in range(34): + t = rng.RNG.rand() + ref_mp.update(t) + stream.update(t) + + comp_P = stream.P_.copy() + # comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + # comp_left_I = stream.left_I_ + + ref_P = ref_mp.P_.copy() + # ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + # ref_left_I = ref_mp.left_I_ + + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + + npt.assert_almost_equal(ref_P, comp_P, decimal=config.STUMPY_TEST_PRECISION) + # npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal( + ref_left_P, comp_left_P, decimal=config.STUMPY_TEST_PRECISION + ) + # npt.assert_almost_equal(ref_left_I, comp_left_I) + def test_stumpi_profile_index_match(): - T_full = np.random.rand(64) + T_full = rng.RNG.rand(64) m = 3 T_full_subseq = core.rolling_window(T_full, m) warm_start = 8 @@ -899,109 +886,133 @@ def test_stumpi_self_join_KNN(): zone = int(np.ceil(m / 4)) for k in range(2, 4): - seed = np.random.randint(100000) - np.random.seed(seed) - - T = np.random.rand(30) - stream = stumpi(T, m, egress=False, k=k) - for i in range(34): - t = np.random.rand() - stream.update(t) - - comp_P = stream.P_ - comp_I = stream.I_ - comp_left_P = stream.left_P_ - comp_left_I = stream.left_I_ + with rng.fix_state(): + T = rng.RNG.rand(30) + stream = stumpi(T, m, egress=False, k=k) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) + + comp_P = stream.P_ + comp_I = stream.I_ + comp_left_P = stream.left_P_ + comp_left_I = stream.left_I_ - ref_mp = naive.stump(stream.T_, m, exclusion_zone=zone, row_wise=True, k=k) - ref_P = ref_mp[:, :k] - ref_I = ref_mp[:, k : 2 * k] - ref_left_I = ref_mp[:, 2 * k].astype(np.int64) - ref_left_P = np.full_like(ref_left_I, np.inf, dtype=np.float64) - for i, j in enumerate(ref_left_I): - if j >= 0: - D = core.mass(stream.T_[i : i + m], stream.T_[j : j + m]) - ref_left_P[i] = D[0] + ref_mp = naive.stump(stream.T_, m, exclusion_zone=zone, row_wise=True, k=k) + ref_P = ref_mp[:, :k] + ref_I = ref_mp[:, k : 2 * k] + ref_left_I = ref_mp[:, 2 * k].astype(np.int64) + ref_left_P = np.full_like(ref_left_I, np.inf, dtype=np.float64) + for i, j in enumerate(ref_left_I): + if j >= 0: + D = core.mass(stream.T_[i : i + m], stream.T_[j : j + m]) + ref_left_P[i] = D[0] - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) - np.random.seed(seed) - T = np.random.rand(30) - T = pd.Series(T) - stream = stumpi(T, m, egress=False, k=k) - for i in range(34): - t = np.random.rand() - stream.update(t) + with rng.fix_state(): + T = rng.RNG.rand(30) + T = pd.Series(T) + stream = stumpi(T, m, egress=False, k=k) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) - comp_P = stream.P_ - comp_I = stream.I_ - comp_left_P = stream.left_P_ - comp_left_I = stream.left_I_ + comp_P = stream.P_ + comp_I = stream.I_ + comp_left_P = stream.left_P_ + comp_left_I = stream.left_I_ - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) def test_stumpi_self_join_egress_KNN(): m = 3 for k in range(2, 4): - seed = np.random.randint(100000) - np.random.seed(seed) - n = 30 - T = np.random.rand(n) - - ref_mp = naive.stumpi_egress(T, m, k=k) - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(n) - stream = stumpi(T, m, egress=True, k=k) - - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + ref_mp = naive.stumpi_egress(T, m, k=k) + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ - for i in range(34): - t = np.random.rand() - ref_mp.update(t) - stream.update(t) + stream = stumpi(T, m, egress=True, k=k) comp_P = stream.P_.copy() comp_I = stream.I_ comp_left_P = stream.left_P_.copy() comp_left_I = stream.left_I_ + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) + + for i in range(34): + t = rng.RNG.rand() + ref_mp.update(t) + stream.update(t) + + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ + + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ + + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) + + with rng.fix_state(): + T = rng.RNG.rand(n) + T = pd.Series(T) + + ref_mp = naive.stumpi_egress(T, m, k=k) ref_P = ref_mp.P_.copy() ref_I = ref_mp.I_ ref_left_P = ref_mp.left_P_.copy() ref_left_I = ref_mp.left_I_ + stream = stumpi(T, m, egress=True, k=k) + + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ + naive.replace_inf(ref_P) naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) @@ -1012,17 +1023,48 @@ def test_stumpi_self_join_egress_KNN(): npt.assert_almost_equal(ref_left_P, comp_left_P) npt.assert_almost_equal(ref_left_I, comp_left_I) - np.random.seed(seed) - T = np.random.rand(n) - T = pd.Series(T) + for i in range(34): + t = rng.RNG.rand() + t = rng.RNG.rand() + ref_mp.update(t) + stream.update(t) + + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ + + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ + + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) + + +def test_stumpi_self_join_egress_passing_mp(): + m = 3 + + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(n) + mp = naive.stump(T, m) - ref_mp = naive.stumpi_egress(T, m, k=k) + ref_mp = naive.stumpi_egress(T, m, mp=mp) ref_P = ref_mp.P_.copy() ref_I = ref_mp.I_ ref_left_P = ref_mp.left_P_.copy() ref_left_I = ref_mp.left_I_ - stream = stumpi(T, m, egress=True, k=k) + stream = stumpi(T, m, egress=True, mp=mp) comp_P = stream.P_.copy() comp_I = stream.I_ @@ -1040,8 +1082,7 @@ def test_stumpi_self_join_egress_KNN(): npt.assert_almost_equal(ref_left_I, comp_left_I) for i in range(34): - t = np.random.rand() - t = np.random.rand() + t = rng.RNG.rand() ref_mp.update(t) stream.update(t) @@ -1066,248 +1107,195 @@ def test_stumpi_self_join_egress_KNN(): npt.assert_almost_equal(ref_left_I, comp_left_I) -def test_stumpi_self_join_egress_passing_mp(): +def test_stumpi_self_join_with_isconstant(): m = 3 + zone = int(np.ceil(m / 4)) - seed = np.random.randint(100000) - np.random.seed(seed) - n = 30 - T = np.random.rand(n) - mp = naive.stump(T, m) - - ref_mp = naive.stumpi_egress(T, m, mp=mp) - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ - - stream = stumpi(T, m, egress=True, mp=mp) - - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) - - for i in range(34): - t = np.random.rand() - ref_mp.update(t) - stream.update(t) + with rng.fix_state(): + T = rng.RNG.rand(30) - comp_P = stream.P_.copy() + quantile_threshold = 0.5 + sliding_stddev = naive.rolling_nanstd(T, m) + stddev_threshold = np.quantile(sliding_stddev, quantile_threshold) + isconstant_custom_func = functools.partial( + naive.isconstant_func_stddev_threshold, + stddev_threshold=stddev_threshold, + ) + + stream = stumpi( + T, m, egress=False, T_subseq_isconstant_func=isconstant_custom_func + ) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) + + comp_P = stream.P_ comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() + comp_left_P = stream.left_P_ comp_left_I = stream.left_I_ - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ + ref_mp = naive.stump( + stream.T_, + m, + exclusion_zone=zone, + row_wise=True, + T_A_subseq_isconstant=isconstant_custom_func, + ) + ref_P = ref_mp[:, 0] + ref_I = ref_mp[:, 1] + ref_left_I = ref_mp[:, 2].astype(np.int64) + ref_left_P = np.full(len(ref_P), np.inf, dtype=np.float64) + for i, j in enumerate(ref_left_I): + if j >= 0: + D = core.mass( + stream.T_[i : i + m], + stream.T_[j : j + m], + T_subseq_isconstant=isconstant_custom_func, + Q_subseq_isconstant=isconstant_custom_func, + ) + ref_left_P[i] = D[0] naive.replace_inf(ref_P) naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) naive.replace_inf(comp_left_P) + # comparing matrix profile indices are avoided as, in this case, + # the performant version computes matrix profile in a diagonal + # manner, which is different than how the naive version computes + # the full data (i.e. original `T` including egressed points). + # which is in a `row_wise==True` manner + npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) + # npt.assert_almost_equal(ref_I, comp_I) npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) - - -def test_stumpi_self_join_with_isconstant(): - m = 3 - zone = int(np.ceil(m / 4)) - - seed = np.random.randint(100000) - np.random.seed(seed) + # npt.assert_almost_equal(ref_left_I, comp_left_I) - T = np.random.rand(30) + # with passing `mp` + T = rng.RNG.rand(30) - quantile_threshold = 0.5 - sliding_stddev = naive.rolling_nanstd(T, m) - stddev_threshold = np.quantile(sliding_stddev, quantile_threshold) - isconstant_custom_func = functools.partial( - naive.isconstant_func_stddev_threshold, - stddev_threshold=stddev_threshold, - ) + quantile_threshold = 0.5 + sliding_stddev = naive.rolling_nanstd(T, m) + stddev_threshold = np.quantile(sliding_stddev, quantile_threshold) + isconstant_custom_func = functools.partial( + naive.isconstant_func_stddev_threshold, + stddev_threshold=stddev_threshold, + ) - stream = stumpi(T, m, egress=False, T_subseq_isconstant_func=isconstant_custom_func) - for i in range(34): - t = np.random.rand() - stream.update(t) + mp = naive.stump( + T, m, row_wise=True, T_A_subseq_isconstant=isconstant_custom_func + ) + stream = stumpi( + T, m, egress=False, mp=mp, T_subseq_isconstant_func=isconstant_custom_func + ) + for i in range(34): + t = rng.RNG.rand() + stream.update(t) - comp_P = stream.P_ - comp_I = stream.I_ - comp_left_P = stream.left_P_ - comp_left_I = stream.left_I_ - - ref_mp = naive.stump( - stream.T_, - m, - exclusion_zone=zone, - row_wise=True, - T_A_subseq_isconstant=isconstant_custom_func, - ) - ref_P = ref_mp[:, 0] - ref_I = ref_mp[:, 1] - ref_left_I = ref_mp[:, 2].astype(np.int64) - ref_left_P = np.full(len(ref_P), np.inf, dtype=np.float64) - for i, j in enumerate(ref_left_I): - if j >= 0: - D = core.mass( - stream.T_[i : i + m], - stream.T_[j : j + m], - T_subseq_isconstant=isconstant_custom_func, - Q_subseq_isconstant=isconstant_custom_func, - ) - ref_left_P[i] = D[0] - - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) - - # comparing matrix profile indices are avoided as, in this case, - # the performant version computes matrix profile in a diagonal - # manner, which is different than how the naive version computes - # the full data (i.e. original `T` including egressed points). - # which is in a `row_wise==True` manner - - npt.assert_almost_equal(ref_P, comp_P) - # npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - # npt.assert_almost_equal(ref_left_I, comp_left_I) - - # with passing `mp` - T = np.random.rand(30) - - quantile_threshold = 0.5 - sliding_stddev = naive.rolling_nanstd(T, m) - stddev_threshold = np.quantile(sliding_stddev, quantile_threshold) - isconstant_custom_func = functools.partial( - naive.isconstant_func_stddev_threshold, - stddev_threshold=stddev_threshold, - ) - - mp = naive.stump(T, m, row_wise=True, T_A_subseq_isconstant=isconstant_custom_func) - stream = stumpi( - T, m, egress=False, mp=mp, T_subseq_isconstant_func=isconstant_custom_func - ) - for i in range(34): - t = np.random.rand() - stream.update(t) + comp_P = stream.P_ + comp_I = stream.I_ + comp_left_P = stream.left_P_ + comp_left_I = stream.left_I_ - comp_P = stream.P_ - comp_I = stream.I_ - comp_left_P = stream.left_P_ - comp_left_I = stream.left_I_ - - ref_mp = naive.stump( - stream.T_, - m, - exclusion_zone=zone, - row_wise=True, - T_A_subseq_isconstant=isconstant_custom_func, - ) - ref_P = ref_mp[:, 0] - ref_I = ref_mp[:, 1] - ref_left_I = ref_mp[:, 2].astype(np.int64) - ref_left_P = np.full(len(ref_P), np.inf, dtype=np.float64) - for i, j in enumerate(ref_left_I): - if j >= 0: - D = core.mass( - stream.T_[i : i + m], - stream.T_[j : j + m], - T_subseq_isconstant=isconstant_custom_func, - Q_subseq_isconstant=isconstant_custom_func, - ) - ref_left_P[i] = D[0] + ref_mp = naive.stump( + stream.T_, + m, + exclusion_zone=zone, + row_wise=True, + T_A_subseq_isconstant=isconstant_custom_func, + ) + ref_P = ref_mp[:, 0] + ref_I = ref_mp[:, 1] + ref_left_I = ref_mp[:, 2].astype(np.int64) + ref_left_P = np.full(len(ref_P), np.inf, dtype=np.float64) + for i, j in enumerate(ref_left_I): + if j >= 0: + D = core.mass( + stream.T_[i : i + m], + stream.T_[j : j + m], + T_subseq_isconstant=isconstant_custom_func, + Q_subseq_isconstant=isconstant_custom_func, + ) + ref_left_P[i] = D[0] - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I) def test_stumpi_self_join_egress_with_isconstant(): m = 3 - seed = np.random.randint(100000) - np.random.seed(seed) - n = 30 - T = np.random.rand(n) - - quantile_threshold = 0.5 - sliding_stddev = naive.rolling_nanstd(T, m) - stddev_threshold = np.quantile(sliding_stddev, quantile_threshold) - isconstant_custom_func = functools.partial( - naive.isconstant_func_stddev_threshold, - stddev_threshold=stddev_threshold, - ) - - ref_mp = naive.stumpi_egress(T, m, T_subseq_isconstant_func=isconstant_custom_func) - ref_P = ref_mp.P_.copy() - ref_I = ref_mp.I_ - ref_left_P = ref_mp.left_P_.copy() - ref_left_I = ref_mp.left_I_ - - stream = stumpi(T, m, egress=True, T_subseq_isconstant_func=isconstant_custom_func) - - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ - - naive.replace_inf(ref_P) - naive.replace_inf(ref_left_P) - naive.replace_inf(comp_P) - naive.replace_inf(comp_left_P) - - npt.assert_almost_equal(ref_P, comp_P) - npt.assert_almost_equal(ref_I, comp_I) - npt.assert_almost_equal(ref_left_P, comp_left_P) - npt.assert_almost_equal(ref_left_I, comp_left_I) - - for i in range(34): - t = np.random.rand() - ref_mp.update(t) - stream.update(t) - - comp_P = stream.P_.copy() - comp_I = stream.I_ - comp_left_P = stream.left_P_.copy() - comp_left_I = stream.left_I_ + with rng.fix_state(): + n = 30 + T = rng.RNG.rand(n) + + quantile_threshold = 0.5 + sliding_stddev = naive.rolling_nanstd(T, m) + stddev_threshold = np.quantile(sliding_stddev, quantile_threshold) + isconstant_custom_func = functools.partial( + naive.isconstant_func_stddev_threshold, + stddev_threshold=stddev_threshold, + ) + ref_mp = naive.stumpi_egress( + T, m, T_subseq_isconstant_func=isconstant_custom_func + ) ref_P = ref_mp.P_.copy() ref_I = ref_mp.I_ ref_left_P = ref_mp.left_P_.copy() ref_left_I = ref_mp.left_I_ + stream = stumpi( + T, m, egress=True, T_subseq_isconstant_func=isconstant_custom_func + ) + + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ + naive.replace_inf(ref_P) naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) naive.replace_inf(comp_left_P) - # Comparing the matrix profile indices is allowed as - # both the naive and the performant versions follow - # the same approach in updating the matrix profile (indices) - # arrays. npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) npt.assert_almost_equal(ref_left_P, comp_left_P) npt.assert_almost_equal(ref_left_I, comp_left_I) + + for i in range(34): + t = rng.RNG.rand() + ref_mp.update(t) + stream.update(t) + + comp_P = stream.P_.copy() + comp_I = stream.I_ + comp_left_P = stream.left_P_.copy() + comp_left_I = stream.left_I_ + + ref_P = ref_mp.P_.copy() + ref_I = ref_mp.I_ + ref_left_P = ref_mp.left_P_.copy() + ref_left_I = ref_mp.left_I_ + + naive.replace_inf(ref_P) + naive.replace_inf(ref_left_P) + naive.replace_inf(comp_P) + naive.replace_inf(comp_left_P) + + # Comparing the matrix profile indices is allowed as + # both the naive and the performant versions follow + # the same approach in updating the matrix profile (indices) + # arrays. + npt.assert_almost_equal(ref_P, comp_P) + npt.assert_almost_equal(ref_I, comp_I) + npt.assert_almost_equal(ref_left_P, comp_left_P) + npt.assert_almost_equal(ref_left_I, comp_left_I)