Calculate class probabilities for a sequence of data.

        Parameters
        ----------
        X : array
            Test data, of dimension N times d (rows are time frames, columns
            are data dimensions)
        A : class transition matrix, where A[i,j] contains p(y_t=j|y_{t-1}=i)
        pi : vector of initial class probabilities
        inference : can be 'smoothing' or 'filtering'.

        Returns:
        -------
        y_prob : array
            An array of dimension N times n_inlier_classes+1, containing
            the probabilities of each row of X being one of the inlier
            classes, or the outlier class (last column).

def predict_sequence(self, X, A, pi, inference='smoothing'):
        """
        Calculate class probabilities for a sequence of data.

        Parameters
        ----------
        X : array
            Test data, of dimension N times d (rows are time frames, columns
            are data dimensions)
        A : class transition matrix, where A[i,j] contains p(y_t=j|y_{t-1}=i)
        pi : vector of initial class probabilities
        inference : can be 'smoothing' or 'filtering'.

        Returns:
        -------
        y_prob : array
            An array of dimension N times n_inlier_classes+1, containing
            the probabilities of each row of X being one of the inlier
            classes, or the outlier class (last column).
        """
        obsll = self.predict_proba(X)
        T, S = obsll.shape
        alpha = np.zeros((T, S))

        alpha[0, :] = pi
        for t in range(1, T):
            alpha[t, :] = np.dot(alpha[t-1, :], A)
            for s in range(S):
                alpha[t, s] *= obsll[t, s]
            alpha[t, :] = alpha[t, :]/sum(alpha[t, :])

        if inference == 'filtering':
            return alpha
        else:
            beta = np.zeros((T, S))
            gamma = np.zeros((T, S))
            beta[T-1, :] = np.ones(S)
            for t in range(T-2, -1, -1):
                for i in range(S):
                    for j in range(S):
                        beta[t, i] += A[i, j]*obsll[t+1, j]*beta[t+1, j]
                beta[t, :] = beta[t, :]/sum(beta[t, :])

            for t in range(T):
                gamma[t, :] = alpha[t, :]*beta[t, :]
                gamma[t, :] = gamma[t, :]/sum(gamma[t, :])

            return gamma