code: def correlation_decomp(P, obs1, obs2=None, times=[1], k=None):
      r
      if obs2 is None:
          obs2 = obs1
      R, D, L = rdl_decomposition(P, k=k)
      """Stationary vector"""
      mu = L[0, :]
      """Extract eigenvalues"""
      ev = np.diagonal(D)
      """Amplitudes"""
      amplitudes = np.dot(mu * obs1, R) * np.dot(L, obs2)
      """Propgate eigenvalues"""
      times = np.asarray(times)
      ev_t = ev[np.newaxis, :] ** times[:, np.newaxis]
      """Compute result"""
      res = np.dot(ev_t, amplitudes)
      """Truncate imaginary part - should be zero anyways"""
      res = res.real
      return res
docs: r"""Time-correlation for equilibrium experiment - via decomposition.
  
      Parameters
      ----------
      P : (M, M) ndarray
          Transition matrix
      obs1 : (M,) ndarray
          Observable, represented as vector on state space
      obs2 : (M,) ndarray (optional)
          Second observable, for cross-correlations
      times : list of int (optional)
          List of times (in tau) at which to compute correlation
      k : int (optional)
          Number of eigenvalues and eigenvectors to use for computation
  
      Returns
      -------
      correlations : ndarray
          Correlation values at given times