1010from functools import lru_cache
1111
1212from . import core , config
13- from .maamp import maamp , maamp_subspace
13+ from .maamp import maamp_multi_distance_profile , maamp , maamp_subspace
1414
1515logger = logging .getLogger (__name__ )
1616
@@ -336,24 +336,22 @@ def subspace(T, m, subseq_idx, nn_idx, k, include=None, discords=False, normaliz
336336 return S
337337
338338
339- def _query_mstump_profile (
339+ def _multi_distance_profile (
340340 query_idx , T_A , T_B , m , excl_zone , M_T , Σ_T , μ_Q , σ_Q , include = None , discords = False
341341):
342342 """
343- Multi-dimensional wrapper to compute the multi-dimensional matrix profile and
344- the multi-dimensional matrix profile index for a given query window within the times
345- series or sequence that is denoted by the `query_idx` index. Essentially, this is a
346- convenience wrapper around `_multi_mass`.
343+ Multi-dimensional wrapper to compute the multi-dimensional distance profile for a
344+ given query window within the times series or sequence that is denoted by the
345+ `query_idx` index. Essentially, this is a convenience wrapper around `_multi_mass`.
347346
348347 Parameters
349348 ----------
350349 query_idx : int
351- The window index to calculate the first multi-dimensional matrix profile and
352- multi-dimensional matrix profile indices
350+ The window index to calculate the multi-dimensional distance profile for
353351
354352 T_A : numpy.ndarray
355- The time series or sequence for which the multi-dimensional matrix profile and
356- multi-dimensional matrix profile indices
353+ The time series or sequence for which the multi-dimensional distance profile
354+ is computed
357355
358356 T_B : numpy.ndarray
359357 The time series or sequence that contains your query subsequences
@@ -371,10 +369,10 @@ def _query_mstump_profile(
371369 Sliding standard deviation for `T_A`
372370
373371 μ_Q : numpy.ndarray
374- Sliding mean for `T_B`
372+ Sliding mean for the query subsequence `T_B`
375373
376374 σ_Q : numpy.ndarray
377- Sliding standard deviation for `T_B`
375+ Sliding standard deviation for the query subsequence `T_B`
378376
379377 include : numpy.ndarray, default None
380378 A list of (zero-based) indices corresponding to the dimensions in `T` that
@@ -390,13 +388,9 @@ def _query_mstump_profile(
390388
391389 Returns
392390 -------
393- P : numpy.ndarray
394- Multi-dimensional matrix profile for the window with index equal to
391+ D : numpy.ndarray
392+ Multi-dimensional distance profile for the window with index equal to
395393 `query_idx`
396-
397- I : numpy.ndarray
398- Multi-dimensional matrix profile indices for the window with index
399- equal to `query_idx`
400394 """
401395 d , n = T_A .shape
402396 k = n - m + 1
@@ -427,17 +421,73 @@ def _query_mstump_profile(
427421
428422 core .apply_exclusion_zone (D , query_idx , excl_zone )
429423
430- P = np .full (d , np .inf , dtype = np .float64 )
431- I = np .full (d , - 1 , dtype = np .int64 )
424+ return D
432425
433- for i in range (d ):
434- min_index = np .argmin (D [i ])
435- I [i ] = min_index
436- P [i ] = D [i , min_index ]
437- if np .isinf (P [i ]): # pragma nocover
438- I [i ] = - 1
439426
440- return P , I
427+ @core .non_normalized (maamp_multi_distance_profile )
428+ def multi_distance_profile (
429+ query_idx , T , m , include = None , discords = False , normalize = True
430+ ):
431+ """
432+ Multi-dimensional wrapper to compute the multi-dimensional distance profile for a
433+ given query window within the times series or sequence that is denoted by the
434+ `query_idx` index.
435+
436+ Parameters
437+ ----------
438+ query_idx : int
439+ The window index to calculate the multi-dimensional distance profile for
440+
441+ T : numpy.ndarray
442+ The multi-dimensional time series or sequence for which the multi-dimensional
443+ distance profile will be returned
444+
445+ m : int
446+ Window size
447+
448+ include : numpy.ndarray, default None
449+ A list of (zero-based) indices corresponding to the dimensions in `T` that
450+ must be included in the constrained multidimensional motif search.
451+ For more information, see Section IV D in:
452+
453+ `DOI: 10.1109/ICDM.2017.66 \
454+ <https://www.cs.ucr.edu/~eamonn/Motif_Discovery_ICDM.pdf>`__
455+
456+ discords : bool, default False
457+ When set to `True`, this reverses the distance profile to favor discords rather
458+ than motifs. Note that indices in `include` are still maintained and respected.
459+
460+ normalize : bool, default True
461+ When set to `True`, this z-normalizes subsequences prior to computing distances.
462+ Otherwise, this function gets re-routed to its complementary non-normalized
463+ equivalent set in the `@core.non_normalized` function decorator.
464+
465+ Returns
466+ -------
467+ D : numpy.ndarray
468+ Multi-dimensional distance profile for the window with index equal to
469+ `query_idx`
470+ """
471+ T , M_T , Σ_T = core .preprocess (T , m )
472+
473+ if T .ndim <= 1 : # pragma: no cover
474+ err = f"T is { T .ndim } -dimensional and must be at least 1-dimensional"
475+ raise ValueError (f"{ err } " )
476+
477+ core .check_window_size (m , max_size = T .shape [1 ])
478+
479+ if include is not None : # pragma: no cover
480+ include = _preprocess_include (include )
481+
482+ excl_zone = int (
483+ np .ceil (m / config .STUMPY_EXCL_ZONE_DENOM )
484+ ) # See Definition 3 and Figure 3
485+
486+ D = _multi_distance_profile (
487+ query_idx , T , T , m , excl_zone , M_T , Σ_T , M_T , Σ_T , include , discords
488+ )
489+
490+ return D
441491
442492
443493def _get_first_mstump_profile (
@@ -448,8 +498,8 @@ def _get_first_mstump_profile(
448498 and multi-dimensional matrix profile index for a given window within the
449499 times series or sequence that is denoted by the `start` index.
450500 Essentially, this is a convenience wrapper around `_multi_mass`. This is a
451- convenience wrapper for the `_query_mstump_profile ` function but does not return
452- the multi-dimensional matrix profile subspace.
501+ convenience wrapper for the `_multi_distance_profile ` function but does not
502+ return the multi-dimensional matrix profile subspace.
453503
454504 Parameters
455505 ----------
@@ -505,9 +555,21 @@ def _get_first_mstump_profile(
505555 Multi-dimensional matrix profile indices for the window with index
506556 equal to `start`
507557 """
508- P , I = _query_mstump_profile (
558+ D = _multi_distance_profile (
509559 start , T_A , T_B , m , excl_zone , M_T , Σ_T , μ_Q , σ_Q , include , discords
510560 )
561+
562+ d = T_A .shape [0 ]
563+ P = np .full (d , np .inf , dtype = np .float64 )
564+ I = np .full (d , - 1 , dtype = np .int64 )
565+
566+ for i in range (d ):
567+ min_index = np .argmin (D [i ])
568+ I [i ] = min_index
569+ P [i ] = D [i , min_index ]
570+ if np .isinf (P [i ]): # pragma nocover
571+ I [i ] = - 1
572+
511573 return P , I
512574
513575
0 commit comments