Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
87f3873
Add extra check for window size
NimaSarajpoor Mar 27, 2025
f8d6df5
update module to include extra check for self join
NimaSarajpoor Mar 27, 2025
f174ed6
add tests for warning
NimaSarajpoor Mar 28, 2025
f611339
revise comment
NimaSarajpoor Mar 28, 2025
c2073ef
ignore coverage
NimaSarajpoor Mar 28, 2025
6c69155
minor improvement in docstring
NimaSarajpoor Mar 28, 2025
e63860c
fix flake8
NimaSarajpoor Mar 28, 2025
91f767e
Revised test function using expected signature
NimaSarajpoor Mar 29, 2025
ab411aa
fixed format
NimaSarajpoor Mar 29, 2025
b7494d9
Revise function to pass test
NimaSarajpoor Mar 30, 2025
3c87e0d
Update stumpy/core.py
NimaSarajpoor Mar 30, 2025
252d52b
improve comments
NimaSarajpoor Mar 30, 2025
8e5d9af
improve readability of function
NimaSarajpoor Mar 30, 2025
113b5c5
minor improvement in the description of param
NimaSarajpoor Mar 30, 2025
82caebb
remove redundant test function
NimaSarajpoor Mar 30, 2025
f29732f
Revise logic and the comment
NimaSarajpoor Mar 31, 2025
6f308a3
improving comments
NimaSarajpoor Mar 31, 2025
77b878b
minor change
NimaSarajpoor Mar 31, 2025
2c68716
minor change in comment
NimaSarajpoor Apr 1, 2025
643b4b0
minor change in comment
NimaSarajpoor Apr 1, 2025
a15b757
update aamp for checking window size
NimaSarajpoor Apr 1, 2025
316bf07
improve docstring and comments
NimaSarajpoor Apr 2, 2025
9f71816
improve docstring
NimaSarajpoor Apr 2, 2025
445a6cb
use smaller input to make test function more understandable
NimaSarajpoor Apr 2, 2025
7751792
updated stumped and aamped
NimaSarajpoor Apr 2, 2025
8bff40b
updated maamp and maamped modules
NimaSarajpoor Apr 2, 2025
f0cbfae
update different modules to consider the change in core.check_window_…
NimaSarajpoor Apr 2, 2025
aa61b24
minor fix
NimaSarajpoor Apr 2, 2025
9349e2a
improve comments
NimaSarajpoor Apr 2, 2025
54cd2fa
improve comments
NimaSarajpoor Apr 2, 2025
917fcc4
improved the explanations
NimaSarajpoor Apr 2, 2025
be4d6bb
minor change in the description of function
NimaSarajpoor Apr 2, 2025
97e6f2b
improve the clarity of the logic
NimaSarajpoor Apr 5, 2025
32a15f3
improve comment
NimaSarajpoor Apr 5, 2025
90d3901
improve description of function
NimaSarajpoor Apr 5, 2025
17e2db9
minor change
NimaSarajpoor Apr 5, 2025
0a25af1
improve readability and consistency
NimaSarajpoor Apr 5, 2025
e29cdca
minor change
NimaSarajpoor Apr 5, 2025
949db7e
minor changes
NimaSarajpoor Apr 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 37 additions & 2 deletions stumpy/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,11 +554,12 @@ def get_max_window_size(n):
return max_m


def check_window_size(m, max_size=None):
def check_window_size(m, max_size=None, n=None):
"""
Check the window size and ensure that it is greater than or equal to 3 and, if
`max_size` is provided, ensure that the window size is less than or equal to the
`max_size`
`max_size`. Furthermore, if `excl_zone` is provided, then it will also check if the
window size is too large and could lead to meaningless results.

Parameters
----------
Expand All @@ -568,6 +569,9 @@ def check_window_size(m, max_size=None):
max_size : int, default None
The maximum window size allowed

n : int, default None
The length of the time series.

Returns
-------
None
Expand All @@ -589,6 +593,37 @@ def check_window_size(m, max_size=None):
if max_size is not None and m > max_size:
raise ValueError(f"The window size must be less than or equal to {max_size}")

if n is not None:
# The following code raises warning if there is at least one subsequence
# with no non-trivial neighbor. The following logic does not check if
# a subsequence has a non-finite value.

# Logic: For each subsequnece `S_i = T[i : i + m]`, its neighbor `S_j`
# is non-trivial if |i - j| > excl_zone. Let's denote `S_jmax` as
# the neighbor that is furthest away from `S_i` (index-wise). So:
# |i - jmax| >= |i - j|
# Therefore, if `S_i` has at least one non-trivial neighbor, then `S_jmax` is
# definitely a non-trivial neighbor. Because:
# |i - jmax| >= |i - j| > excl_zone
# To ensure ALL subsequences have at least one non-trivial neighbor, we can just
# check the subsequence `S_i` that has the minimum |i - jmax|. Let's denote `d`
# as that minimum value. So, if d > excl_zone, then:
# For any `i` and its corresponding `jmax`, we have:
# |i - jmax| >= d > excl_zone

# The minimum |i - jmax| is achieved when `S_i` is the middle subsequence,
# i.e. i == int(ceil((n - m) / 2)), and its corresponding jmax is 0. Hence,
# we just need to make sure the following inequity is satisfied:
# |int(ceil((n - m) / 2)) - 0| > excl_zone`

excl_zone = int(math.ceil(m / config.STUMPY_EXCL_ZONE_DENOM))
if (int(math.ceil((n - m) / 2)) - 0) <= excl_zone:
msg = (
f"The window size, 'm = {m}', may be too large and could lead to "
+ "meaningless results. Consider reducing 'm' where necessary"
)
warnings.warn(msg)


@njit(fastmath=config.STUMPY_FASTMATH_TRUE)
def _sliding_dot_product(Q, T):
Expand Down
11 changes: 5 additions & 6 deletions stumpy/stump.py
Original file line number Diff line number Diff line change
Expand Up @@ -711,18 +711,17 @@ def stump(
"For multidimensional STUMP use `stumpy.mstump` or `stumpy.mstumped`"
)

core.check_window_size(m, max_size=min(T_A.shape[0], T_B.shape[0]))
ignore_trivial = core.check_ignore_trivial(T_A, T_B, ignore_trivial)

n_A = T_A.shape[0]
n_B = T_B.shape[0]
l = n_A - m + 1

ignore_trivial = core.check_ignore_trivial(T_A, T_B, ignore_trivial)
excl_zone = int(np.ceil(m / config.STUMPY_EXCL_ZONE_DENOM))

if ignore_trivial:
if ignore_trivial: # self-join
core.check_window_size(m, max_size=n_A, n=n_A)
diags = np.arange(excl_zone + 1, n_A - m + 1, dtype=np.int64)
else:
else: # AB-join
core.check_window_size(m, max_size=min(n_A, n_B))
diags = np.arange(-(n_A - m + 1) + 1, n_B - m + 1, dtype=np.int64)

P, PL, PR, I, IL, IR = _stump(
Expand Down
20 changes: 20 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,26 @@ def test_check_max_window_size():
core.check_window_size(m, max_size=3)


def test_check_window_size_excl_zone_case1():
# To ensure warning is raised if there is no subsequence
# with non-trivial neighbor
T = np.random.rand(64)
m = 60

with pytest.warns(UserWarning):
core.check_window_size(m, max_size=len(T), n=len(T))


def test_check_window_size_excl_zone_case2():
# To ensure warning is raised if there is at least one subsequence
# that has no non-trivial neighbor
T = np.random.rand(64)
m = 48

with pytest.warns(UserWarning):
core.check_window_size(m, max_size=len(T), n=len(T))


@pytest.mark.parametrize("Q, T", test_data)
def test_njit_sliding_dot_product(Q, T):
ref_mp = naive_rolling_window_dot_product(Q, T)
Expand Down