Traverse distance matrix diagonally and update the top-k matrix profile and matrix profile indices if the parameter `row_wise` is set to `False`. If the parameter `row_wise` is set to `True`, it is a row-wise traversal.
(T_A, m, T_B=None, exclusion_zone=None, p=2.0, row_wise=False, k=1)
| 345 | |
| 346 | |
| 347 | def aamp(T_A, m, T_B=None, exclusion_zone=None, p=2.0, row_wise=False, k=1): |
| 348 | """ |
| 349 | Traverse distance matrix diagonally and update the top-k matrix profile and |
| 350 | matrix profile indices if the parameter `row_wise` is set to `False`. If the |
| 351 | parameter `row_wise` is set to `True`, it is a row-wise traversal. |
| 352 | """ |
| 353 | T_A = np.asarray(T_A) |
| 354 | T_A = T_A.copy() |
| 355 | |
| 356 | if T_B is None: |
| 357 | ignore_trivial = True |
| 358 | T_B = T_A.copy() |
| 359 | else: |
| 360 | ignore_trivial = False |
| 361 | T_B = np.asarray(T_B) |
| 362 | T_B = T_B.copy() |
| 363 | |
| 364 | T_A[np.isinf(T_A)] = np.nan |
| 365 | T_B[np.isinf(T_B)] = np.nan |
| 366 | |
| 367 | rolling_T_A = core.rolling_window(T_A, m) |
| 368 | rolling_T_B = core.rolling_window(T_B, m) |
| 369 | |
| 370 | distance_matrix = cdist(rolling_T_A, rolling_T_B, metric="minkowski", p=p) |
| 371 | |
| 372 | n_A = T_A.shape[0] |
| 373 | n_B = T_B.shape[0] |
| 374 | l = n_A - m + 1 |
| 375 | if exclusion_zone is None: |
| 376 | exclusion_zone = int(np.ceil(m / config.STUMPY_EXCL_ZONE_DENOM)) |
| 377 | |
| 378 | P = np.full((l, k + 2), np.inf, dtype=np.float64) |
| 379 | I = np.full((l, k + 2), -1, dtype=np.int64) # two more columns are to store |
| 380 | # ... left and right top-1 matrix profile indices |
| 381 | |
| 382 | if row_wise: |
| 383 | if ignore_trivial: # self-join |
| 384 | for i in range(l): |
| 385 | apply_exclusion_zone(distance_matrix[i], i, exclusion_zone, np.inf) |
| 386 | |
| 387 | for i, D in enumerate(distance_matrix): # D: distance profile |
| 388 | # self-join / AB-join: matrix profile and indices |
| 389 | indices = np.argsort(D)[:k] |
| 390 | P[i, :k] = D[indices] |
| 391 | indices[P[i, :k] == np.inf] = -1 |
| 392 | I[i, :k] = indices |
| 393 | |
| 394 | # self-join: left matrix profile index (top-1) |
| 395 | if ignore_trivial and i > 0: |
| 396 | IL = np.argmin(D[:i]) |
| 397 | if D[IL] == np.inf: |
| 398 | IL = -1 |
| 399 | I[i, k] = IL |
| 400 | |
| 401 | # self-join: right matrix profile index (top-1) |
| 402 | if ignore_trivial and i < D.shape[0]: |
| 403 | IR = i + np.argmin(D[i:]) # offset by `i` to get true index |
| 404 | if D[IR] == np.inf: |
no test coverage detected