def test_mass(Q, T): m = Q.shape[0] left = np.linalg.norm(core.z_norm(core.rolling_window(T, m), 1) - core.z_norm(Q), axis=1) right = core.mass(Q, T) npt.assert_almost_equal(left, right)
def test_stumpi_self_join(): m = 3 zone = int(np.ceil(m / 4)) seed = np.random.randint(100000) np.random.seed(seed) T = np.random.rand(30) stream = stumpi(T, m, egress=False) for i in range(34): t = np.random.rand() stream.update(t) comp_P = stream.P_ comp_I = stream.I_ comp_left_P = stream.left_P_ comp_left_I = stream.left_I_ ref_mp = naive.stamp(stream.T_, m, exclusion_zone=zone) ref_P = ref_mp[:, 0] ref_I = ref_mp[:, 1] ref_left_P = np.empty(ref_P.shape) ref_left_P[:] = np.inf ref_left_I = ref_mp[:, 2] for i, j in enumerate(ref_left_I): if j >= 0: D = core.mass(stream.T_[i:i + m], stream.T_[j:j + m]) ref_left_P[i] = D[0] naive.replace_inf(ref_P) naive.replace_inf(ref_left_P) naive.replace_inf(comp_P) naive.replace_inf(comp_left_P) npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) npt.assert_almost_equal(ref_left_P, comp_left_P) npt.assert_almost_equal(ref_left_I, comp_left_I) np.random.seed(seed) T = np.random.rand(30) T = pd.Series(T) stream = stumpi(T, m, egress=False) for i in range(34): t = np.random.rand() stream.update(t) comp_P = stream.P_ comp_I = stream.I_ comp_left_P = stream.left_P_ comp_left_I = stream.left_I_ naive.replace_inf(comp_P) naive.replace_inf(comp_left_P) npt.assert_almost_equal(ref_P, comp_P) npt.assert_almost_equal(ref_I, comp_I) npt.assert_almost_equal(ref_left_P, comp_left_P) npt.assert_almost_equal(ref_left_I, comp_left_I)
def test_stumpi_self_join(): m = 3 zone = int(np.ceil(m / 4)) seed = np.random.randint(100000) np.random.seed(seed) T = np.random.rand(30) stream = stumpi(T, m) for i in range(34): t = np.random.rand() stream.update(t) right_P = stream.P_ right_I = stream.I_ right_left_P = stream.left_P_ right_left_I = stream.left_I_ left = naive.stamp(stream.T_, m, exclusion_zone=zone) left_P = left[:, 0] left_I = left[:, 1] left_left_P = np.empty(left_P.shape) left_left_P[:] = np.inf left_left_I = left[:, 2] for i, j in enumerate(left_left_I): if j >= 0: D = core.mass(stream.T_[i:i + m], stream.T_[j:j + m]) left_left_P[i] = D[0] naive.replace_inf(left_P) naive.replace_inf(left_left_P) naive.replace_inf(right_P) naive.replace_inf(right_left_P) npt.assert_almost_equal(left_P, right_P) npt.assert_almost_equal(left_I, right_I) npt.assert_almost_equal(left_left_P, right_left_P) npt.assert_almost_equal(left_left_I, right_left_I) np.random.seed(seed) T = np.random.rand(30) T = pd.Series(T) stream = stumpi(T, m) for i in range(34): t = np.random.rand() stream.update(t) right_P = stream.P_ right_I = stream.I_ right_left_P = stream.left_P_ right_left_I = stream.left_I_ naive.replace_inf(right_P) naive.replace_inf(right_left_P) npt.assert_almost_equal(left_P, right_P) npt.assert_almost_equal(left_I, right_I) npt.assert_almost_equal(left_left_P, right_left_P) npt.assert_almost_equal(left_left_I, right_left_I)
def test_mass(Q, T): Q = Q.copy() T = T.copy() m = Q.shape[0] ref = np.linalg.norm(core.z_norm(core.rolling_window(T, m), 1) - core.z_norm(Q), axis=1) comp = core.mass(Q, T) npt.assert_almost_equal(ref, comp)
def test_mass_inf(Q, T): T[1] = np.inf m = Q.shape[0] left = np.linalg.norm(core.z_norm(core.rolling_window(T, m), 1) - core.z_norm(Q), axis=1) left[np.isnan(left)] = np.inf right = core.mass(Q, T) npt.assert_almost_equal(left, right)
def test_mass_T_nan(Q, T): Q = Q.copy() T = T.copy() T[1] = np.nan m = Q.shape[0] ref = np.linalg.norm(core.z_norm(core.rolling_window(T, m), 1) - core.z_norm(Q), axis=1) ref[np.isnan(ref)] = np.inf comp = core.mass(Q, T) npt.assert_almost_equal(ref, comp)
def __init__(self, T, m, excl_zone=None): self._T = np.asarray(T) self._T = self._T.copy() self._T_isfinite = np.isfinite(self._T) self._m = m if excl_zone is None: self._excl_zone = int(np.ceil(self._m / 4)) self._l = self._T.shape[0] - m + 1 mp = stump(T, m) self.P_ = mp[:, 0] self.I_ = mp[:, 1].astype(np.int64) self.left_P_ = np.full(self.P_.shape, np.inf) self.left_I_ = mp[:, 2].astype(np.int64) for i, j in enumerate(self.left_I_): if j >= 0: D = core.mass(self._T[i : i + self._m], self._T[j : j + self._m]) self.left_P_[i] = D[0] self._n_appended = 0
def update(self, t): self._T[:] = np.roll(self._T, -1) self._T_isfinite[:] = np.roll(self._T_isfinite, -1) if np.isfinite(t): self._T_isfinite[-1] = True self._T[-1] = t else: self._T_isfinite[-1] = False self._T[-1] = 0 self._n_appended += 1 self.P_[:] = np.roll(self.P_, -1) self.I_[:] = np.roll(self.I_, -1) self.left_P_[:] = np.roll(self.left_P_, -1) self.left_I_[:] = np.roll(self.left_I_, -1) D = core.mass(self._T[-self._m :], self._T) T_subseq_isfinite = np.all( core.rolling_window(self._T_isfinite, self._m), axis=1 ) D[~T_subseq_isfinite] = np.inf if np.any(~self._T_isfinite[-self._m :]): D[:] = np.inf apply_exclusion_zone(D, D.shape[0] - 1, self._excl_zone) for j in range(D.shape[0]): if D[j] < self.P_[j]: self.I_[j] = D.shape[0] - 1 + self._n_appended self.P_[j] = D[j] I_last = np.argmin(D) if np.isinf(D[I_last]): self.I_[-1] = -1 self.P_[-1] = np.inf else: self.I_[-1] = I_last + self._n_appended self.P_[-1] = D[I_last] self.left_I_[-1] = I_last + self._n_appended self.left_P_[-1] = D[I_last]
def __init__(self, T, m, excl_zone=None): """ Initialize the `stumpi` object Parameters ---------- T : ndarray The time series or sequence for which the matrix profile and matrix profile indices will be returned m : int Window size excl_zone : int The half width for the exclusion zone relative to the current sliding window """ self._T = T self._m = m if excl_zone is not None: # pragma: no cover self._excl_zone = excl_zone else: self._excl_zone = int(np.ceil(self._m / 4)) self._illegal = np.logical_or(np.isinf(self._T), np.isnan(self._T)) mp = stumpy.stump(self._T, self._m) self._P = mp[:, 0] self._I = mp[:, 1] self._left_I = mp[:, 2] self._left_P = np.empty(self._P.shape) self._left_P[:] = np.inf self._T, self._M_T, self._Σ_T = core.preprocess(self._T, self._m) # Retrieve the left matrix profile values for i, j in enumerate(self._left_I): if j >= 0: D = core.mass(self._T[i:i + self._m], self._T[j:j + self._m]) self._left_P[i] = D[0] Q = self._T[-m:] self._QT = core.sliding_dot_product(Q, self._T)