diff --git a/stumpy/aamp.py b/stumpy/aamp.py index 940a20b2b..b5b0455a3 100644 --- a/stumpy/aamp.py +++ b/stumpy/aamp.py @@ -396,6 +396,7 @@ def aamp(T_A, m, T_B=None, ignore_trivial=True, p=2.0, k=1): """ if T_B is None: T_B = T_A.copy() + core.check_self_join(ignore_trivial) ignore_trivial = True T_A, T_A_subseq_isfinite = core.preprocess_non_normalized(T_A, m) diff --git a/stumpy/aamped.py b/stumpy/aamped.py index 14e6d237e..8da759dfa 100644 --- a/stumpy/aamped.py +++ b/stumpy/aamped.py @@ -375,6 +375,7 @@ def aamped(client, T_A, m, T_B=None, ignore_trivial=True, p=2.0, k=1): """ if T_B is None: T_B = T_A.copy() + core.check_self_join(ignore_trivial) ignore_trivial = True T_A, T_A_subseq_isfinite = core.preprocess_non_normalized(T_A, m) diff --git a/stumpy/core.py b/stumpy/core.py index 507a516db..4f286f706 100644 --- a/stumpy/core.py +++ b/stumpy/core.py @@ -3738,11 +3738,10 @@ def check_ignore_trivial(T_A, T_B, ignore_trivial): T_B : numpy.ndarray The time series or sequence that will be used to annotate T_A. For every - subsequence in T_A, its nearest neighbor in T_B will be recorded. Default is - `None` which corresponds to a self-join. + subsequence in T_A, its nearest neighbor in T_B will be recorded. ignore_trivial : bool - Set to `True` if this is a self-join. Otherwise, for AB-join, set this + Set to `True` if this is a self-join. Otherwise, for an AB-join, set this to `False`. Returns @@ -3752,7 +3751,7 @@ def check_ignore_trivial(T_A, T_B, ignore_trivial): Notes ----- - These warnings may be supressed by using a context manager + These warnings may be suppressed by using a context manager ``` import stumpy import numpy as np @@ -4509,3 +4508,40 @@ def _update_incremental_PI(D, P, I, excl_zone, n_appended=0): _shift_insert_at_index(I[-1], idx, i + n_appended) return + + +def check_self_join(ignore_trivial): + """ + A simple function to check whether `ignore_trivial` is `True` for a self-join + + Otherwise, warn the user. + + Parameters + ---------- + ignore_trivial : bool + Set to True if this is a self-join. Otherwise, for AB-join, set this to False. + + Returns + ------- + None + + Notes + ----- + These warnings may be suppressed by using a context manager + ``` + import stumpy + import numpy as np + import warnings + + T = np.random.rand(10_000) + m = 50 + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", message="`ignore_trivial` cannot be `False`") + for _ in range(5): + stumpy.stump(T, m, ignore_trivial=False) + ``` + """ + if ignore_trivial is False: + msg = "`ignore_trivial` cannot be `False` for a self-join and " + msg += "has been automatically overridden and set to `True`." + warnings.warn(msg) diff --git a/stumpy/gpu_aamp.py b/stumpy/gpu_aamp.py index fc0c74068..9797f2252 100644 --- a/stumpy/gpu_aamp.py +++ b/stumpy/gpu_aamp.py @@ -519,6 +519,7 @@ def gpu_aamp(T_A, m, T_B=None, ignore_trivial=True, device_id=0, p=2.0, k=1): """ if T_B is None: # Self join! T_B = T_A + core.check_self_join(ignore_trivial) ignore_trivial = True T_A, T_A_subseq_isfinite = core.preprocess_non_normalized(T_A, m) diff --git a/stumpy/gpu_stump.py b/stumpy/gpu_stump.py index 16166ffb2..8eb54a88c 100644 --- a/stumpy/gpu_stump.py +++ b/stumpy/gpu_stump.py @@ -515,8 +515,11 @@ def gpu_stump( Default is ``None`` which corresponds to a self-join. ignore_trivial : bool, default True - Set to ``True`` if this is a self-join. Otherwise, for AB-join, set this - to ``False``. + Set to ``True`` if this is a self-join (i.e., for a single time series + ``T_A`` without ``T_B``). This ensures that an exclusion zone is applied + to each subsequence in ``T_A`` and all trivial/self-matches are ignored. + Otherwise, for an AB-join (i.e., between two times series, ``T_A`` and + ``T_B``), set this to ``False``. device_id : int or list, default 0 The (GPU) device number to use. The default value is ``0``. A list of @@ -644,6 +647,7 @@ def gpu_stump( """ if T_B is None: # Self join! T_B = T_A + core.check_self_join(ignore_trivial) ignore_trivial = True T_B_subseq_isconstant = T_A_subseq_isconstant diff --git a/stumpy/scraamp.py b/stumpy/scraamp.py index c0d9b5ee1..e4f9417c4 100644 --- a/stumpy/scraamp.py +++ b/stumpy/scraamp.py @@ -621,6 +621,7 @@ def __init__( if T_B is None: T_B = T_A + core.check_self_join(self._ignore_trivial) self._ignore_trivial = True self._m = m diff --git a/stumpy/scrump.py b/stumpy/scrump.py index 55e15ca6d..e837a7268 100644 --- a/stumpy/scrump.py +++ b/stumpy/scrump.py @@ -810,8 +810,11 @@ def __init__( subsequence in T_A, its nearest neighbor in T_B will be recorded. ignore_trivial : bool, default True - Set to `True` if this is a self-join. Otherwise, for AB-join, set this to - `False`. Default is `True`. + Set to ``True`` if this is a self-join (i.e., for a single time series + ``T_A`` without ``T_B``). This ensures that an exclusion zone is applied + to each subsequence in ``T_A`` and all trivial/self-matches are ignored. + Otherwise, for an AB-join (i.e., between two times series, ``T_A`` and + ``T_B``), set this to ``False``. percentage : float, default 0.01 Approximate percentage completed. The value is between 0.0 and 1.0. @@ -867,6 +870,7 @@ def __init__( if T_B is None: T_B = T_A + core.check_self_join(self._ignore_trivial) self._ignore_trivial = True T_B_subseq_isconstant = T_A_subseq_isconstant diff --git a/stumpy/stomp.py b/stumpy/stomp.py index 251d0fdc9..fc81aa03a 100644 --- a/stumpy/stomp.py +++ b/stumpy/stomp.py @@ -70,6 +70,7 @@ def _stomp(T_A, m, T_B=None, ignore_trivial=True): if T_B is None: T_B = T_A + core.check_self_join(ignore_trivial) ignore_trivial = True T_A, μ_Q, σ_Q, Q_subseq_isconstant = core.preprocess(T_A, m) diff --git a/stumpy/stump.py b/stumpy/stump.py index b70a776aa..c5bd435db 100644 --- a/stumpy/stump.py +++ b/stumpy/stump.py @@ -542,8 +542,11 @@ def stump( Default is ``None`` which corresponds to a self-join. ignore_trivial : bool, default True - Set to ``True`` if this is a self-join. Otherwise, for AB-join, set this - to ``False``. + Set to ``True`` if this is a self-join (i.e., for a single time series + ``T_A`` without ``T_B``). This ensures that an exclusion zone is applied + to each subsequence in ``T_A`` and all trivial/self-matches are ignored. + Otherwise, for an AB-join (i.e., between two times series, ``T_A`` and + ``T_B``), set this to ``False``. normalize : bool, default True When set to ``True``, this z-normalizes subsequences prior to computing @@ -677,6 +680,7 @@ def stump( mparray([4, 3, 0, 1, 0]) """ if T_B is None: + core.check_self_join(ignore_trivial) ignore_trivial = True T_B = T_A T_B_subseq_isconstant = T_A_subseq_isconstant diff --git a/stumpy/stumped.py b/stumpy/stumped.py index 0cfa331b2..c097b3719 100644 --- a/stumpy/stumped.py +++ b/stumpy/stumped.py @@ -429,8 +429,11 @@ def stumped( Default is ``None`` which corresponds to a self-join. ignore_trivial : bool, default True - Set to ``True`` if this is a self-join. Otherwise, for AB-join, set this - to ``False``. + Set to ``True`` if this is a self-join (i.e., for a single time series + ``T_A`` without ``T_B``). This ensures that an exclusion zone is applied + to each subsequence in ``T_A`` and all trivial/self-matches are ignored. + Otherwise, for an AB-join (i.e., between two times series, ``T_A`` and + ``T_B``), set this to ``False``. normalize : bool, default True When set to ``True``, this z-normalizes subsequences prior to computing @@ -585,6 +588,7 @@ def stumped( """ if T_B is None: T_B = T_A + core.check_self_join(ignore_trivial) ignore_trivial = True T_B_subseq_isconstant = T_A_subseq_isconstant diff --git a/tests/test_core.py b/tests/test_core.py index 17059d5dc..109754b9b 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1963,3 +1963,9 @@ def test_update_incremental_PI_egressTrue_MemoryCheck(): npt.assert_almost_equal(P_ref, P_comp) npt.assert_almost_equal(I_ref, I_comp) + + +def test_check_self_join(): + with pytest.warns(UserWarning): + ignore_trivial = False + core.check_self_join(ignore_trivial)