예제 #1
0
def test_calculate_distance_profile(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)
    QT = core.sliding_dot_product(Q, T)
    μ_Q, σ_Q = core.compute_mean_std(Q, m)
    M_T, Σ_T = core.compute_mean_std(T, m)
    right = core.calculate_distance_profile(m, QT, μ_Q, σ_Q, M_T, Σ_T)
    npt.assert_almost_equal(left, right)
예제 #2
0
    def update(self, t):
        """
        Append a single new data point, `t`, to the existing time series `T` and update
        the matrix profile and matrix profile indices.

        Parameters
        ----------
        t : float
            A single new data point to be appended to `T`

        Notes
        -----
        `DOI: 10.1007/s10618-017-0519-9 \
        <https://www.cs.ucr.edu/~eamonn/MP_journal.pdf>`__

        See Table V

        Note that line 11 is missing an important `sqrt` operation!
        """
        n = self._T.shape[0]
        l = n - self._m + 1
        T_new = np.append(self._T, t)
        QT_new = np.empty(self._QT.shape[0] + 1)
        S = T_new[l:]
        t_drop = T_new[l - 1]

        if np.isinf(t) or np.isnan(t):
            self._illegal = np.append(self._illegal, True)
            t = 0
            T_new[-1] = 0
            S[-1] = 0
        else:
            self._illegal = np.append(self._illegal, False)

        if np.any(self._illegal[-self._m:]):
            μ_Q = np.inf
            σ_Q = np.nan
        else:
            μ_Q, σ_Q = core.compute_mean_std(S, self._m)
            μ_Q = μ_Q[0]
            σ_Q = σ_Q[0]

        M_T_new = np.append(self._M_T, μ_Q)
        Σ_T_new = np.append(self._Σ_T, σ_Q)

        for j in range(l, 0, -1):
            QT_new[j] = (self._QT[j - 1] - T_new[j - 1] * t_drop +
                         T_new[j + self._m - 1] * t)
        QT_new[0] = 0

        for j in range(self._m):
            QT_new[0] = QT_new[0] + T_new[j] * S[j]

        D = core.calculate_distance_profile(self._m, QT_new, μ_Q, σ_Q, M_T_new,
                                            Σ_T_new)
        if np.any(self._illegal[-self._m:]):
            D[:] = np.inf

        core.apply_exclusion_zone(D, D.shape[0] - 1, self._excl_zone)

        for j in range(l):
            if D[j] < self._P[j]:
                self._I[j] = l
                self._P[j] = D[j]

        I_last = np.argmin(D)
        if np.isinf(D[I_last]):
            I_new = np.append(self._I, -1)
            P_new = np.append(self._P, np.inf)
        else:
            I_new = np.append(self._I, I_last)
            P_new = np.append(self._P, D[I_last])
        left_I_new = np.append(self._left_I, I_last)
        left_P_new = np.append(self._left_P, D[I_last])

        self._T = T_new
        self._P = P_new
        self._I = I_new
        self._left_I = left_I_new
        self._left_P = left_P_new
        self._QT = QT_new
        self._M_T = M_T_new
        self._Σ_T = Σ_T_new