Skip to content

Commit dfa6d77

Browse files
Add param "isconstant" to stumpy/mmotifs.py (#877)
* pass the optional argument to ensure correct output when isconstant is provided by user * add param isconstant to mmotifs * add naive test function * Update test_mmotifs.py
1 parent 029a6d2 commit dfa6d77

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

stumpy/mmotifs.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@
1212
from .mstump import mdl
1313

1414

15-
@core.non_normalized(aamp_mmotifs)
15+
@core.non_normalized(
16+
aamp_mmotifs,
17+
exclude=[
18+
"normalize",
19+
"T_subseq_isconstant",
20+
],
21+
)
1622
def mmotifs(
1723
T,
1824
P,
@@ -27,6 +33,7 @@ def mmotifs(
2733
include=None,
2834
normalize=True,
2935
p=2.0,
36+
T_subseq_isconstant=None,
3037
):
3138
"""
3239
Discover the top motifs for the multi-dimensional time series `T`
@@ -92,6 +99,15 @@ def mmotifs(
9299
and the Euclidean distance, respectively. This parameter is ignored when
93100
`normalize == True`.
94101
102+
T_subseq_isconstant : numpy.ndarray, function, or list, default None
103+
A parameter that is used to show whether a subsequence of a time series in `T`
104+
is constant (True) or not. T_subseq_isconstant can be a 2D boolean numpy.ndarry
105+
or a function that can be applied to each time series in `T`. Alternatively, for
106+
maximum flexibility, a list (with length equal to the total number of time
107+
series) may also be used. In this case, T_subseq_isconstant[i] corresponds to
108+
the i-th time series T[i] and each element in the list can either be a 1D
109+
boolean np.ndarray, a function, or None.
110+
95111
Returns
96112
-------
97113
motif_distances: numpy.ndarray
@@ -154,7 +170,9 @@ def mmotifs(
154170
warnings.warn(msg)
155171
max_motifs = 1
156172

157-
T, M_T, Σ_T, T_subseq_isconstant = core.preprocess(T, m)
173+
T, M_T, Σ_T, T_subseq_isconstant = core.preprocess(
174+
T, m, T_subseq_isconstant=T_subseq_isconstant
175+
)
158176
P = P.copy()
159177

160178
excl_zone = int(np.ceil(m / config.STUMPY_EXCL_ZONE_DENOM))
@@ -214,6 +232,9 @@ def mmotifs(
214232
normalize=normalize,
215233
p=p,
216234
T_subseq_isconstant=T_subseq_isconstant[subspace_k],
235+
Q_subseq_isconstant=np.expand_dims(
236+
T_subseq_isconstant[subspace_k, motif_idx], axis=1
237+
),
217238
)
218239

219240
if len(query_matches) > min_neighbors:

tests/test_mmotifs.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,37 @@ def test_mmotifs_two_motif_pairs_max_motifs_2(T):
193193
npt.assert_array_almost_equal(motif_indices_ref, motif_indices_cmp)
194194
npt.assert_array_almost_equal(motif_subspaces_ref, motif_subspaces_cmp)
195195
npt.assert_array_almost_equal(motif_mdls_ref, motif_mdls_cmp)
196+
197+
198+
@pytest.mark.parametrize("T", test_data)
199+
def test_mmotifs_with_default_parameters_with_isconstant(T):
200+
motif_distances_ref = np.array([[0.0000000e00, 1.1151008e-07]])
201+
motif_indices_ref = np.array([[2, 9]])
202+
motif_subspaces_ref = [np.array([1])]
203+
motif_mdls_ref = [np.array([232.0, 250.57542476, 260.0, 271.3509059])]
204+
205+
m = 4
206+
excl_zone = int(np.ceil(m / config.STUMPY_EXCL_ZONE_DENOM))
207+
208+
# The following `T_subseq_isconstant` is basically equivalent to
209+
# `T_subseq_isconstant=None` (default). The goal is to test its
210+
# functionality.
211+
T_subseq_isconstant = [
212+
None,
213+
naive.rolling_isconstant(T[1], m),
214+
None,
215+
naive.is_ptp_zero_1d,
216+
]
217+
218+
P, I = naive.mstump(T, m, excl_zone, T_subseq_isconstant=T_subseq_isconstant)
219+
(
220+
motif_distances_cmp,
221+
motif_indices_cmp,
222+
motif_subspaces_cmp,
223+
motif_mdls_cmp,
224+
) = mmotifs(T, P, I, T_subseq_isconstant=T_subseq_isconstant)
225+
226+
npt.assert_array_almost_equal(motif_distances_ref, motif_distances_cmp)
227+
npt.assert_array_almost_equal(motif_indices_ref, motif_indices_cmp)
228+
npt.assert_array_almost_equal(motif_subspaces_ref, motif_subspaces_cmp)
229+
npt.assert_array_almost_equal(motif_mdls_ref, motif_mdls_cmp)

0 commit comments

Comments
 (0)