code: def predict_sequence(self, X, A, pi, inference='smoothing'):
          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