-
Notifications
You must be signed in to change notification settings - Fork 89
/
naive_euclidean.py
63 lines (49 loc) · 2.38 KB
/
naive_euclidean.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
"""Naive Euclidean distance profile."""
__author__ = ["baraline"]
import numpy as np
from numba import njit
from aeon.distances import euclidean_distance
from aeon.similarity_search.distance_profiles._commons import _get_input_sizes
def naive_euclidean_profile(X, q, mask):
r"""
Compute a euclidean distance profile in a brute force way.
It computes the distance profiles between the input time series and the query using
the Euclidean distance. The search is made in a brute force way without any
optimizations and can thus be slow.
A distance profile between a (univariate) time series :math:`X_i = {x_1, ..., x_m}`
and a query :math:`Q = {q_1, ..., q_m}` is defined as a vector of size :math:`m-(
l-1)`, such as :math:`P(X_i, Q) = {d(C_1, Q), ..., d(C_m-(l-1), Q)}` with d the
Euclidean distance, and :math:`C_j = {x_j, ..., x_{j+(l-1)}}` the j-th candidate
subsequence of size :math:`l` in :math:`X_i`.
Parameters
----------
X: array shape (n_cases, n_channels, series_length)
The input samples.
q : np.ndarray shape (n_channels, query_length)
The query used for similarity search.
mask : array, shape (n_instances, n_channels, n_timestamps - (q_length - 1))
Boolean mask of the shape of the distance profile indicating for which part
of it the distance should be computed.
Returns
-------
distance_profile : np.ndarray
shape (n_cases, n_channels, series_length - query_length + 1)
The distance profile between q and the input time series X independently
for each channel.
"""
return _naive_euclidean_profile(X, q, mask)
@njit(cache=True, fastmath=True)
def _naive_euclidean_profile(X, q, mask):
n_instances, n_channels, X_length, q_length, profile_size = _get_input_sizes(X, q)
distance_profile = np.full((n_instances, n_channels, profile_size), np.inf)
for i_instance in range(n_instances):
for i_channel in range(n_channels):
for i_candidate in range(profile_size):
if mask[i_instance, i_channel, i_candidate]:
distance_profile[
i_instance, i_channel, i_candidate
] = euclidean_distance(
q[i_channel],
X[i_instance, i_channel, i_candidate : i_candidate + q_length],
)
return distance_profile