docs: def error_perturbation(C, S):
      r"""Error perturbation for given sensitivity matrix.
  
      Parameters
      ----------
      C : (M, M) ndarray
          Count matrix
      S : (M, M) ndarray or (K, M, M) ndarray
          Sensitivity matrix (for scalar observable) or sensitivity
          tensor for vector observable
  
      Returns
      -------
      X : float or (K, K) ndarray
          error-perturbation (for scalar observables) or covariance matrix
          (for vector-valued observable)
  
      Notes
      -----
  
      **Scalar observable**
  
      The sensitivity matrix :math:`S=(s_{ij})` of a scalar observable
      :math:`f(T)` is defined as
  
      .. math:: S= \left(\left. \frac{\partial f(T)}{\partial t_{ij}} \right \rvert_{T_0} \right)
  
      evaluated at a suitable transition matrix :math:`T_0`.
  
      The sensitivity is the variance of the observable
  
      .. math:: \mathbb{V}(f)=\sum_{i,j,k,l} s_{ij} \text{cov}[t_{ij}, t_{kl}] s_{kl}
  
      **Vector valued observable**
  
      The sensitivity tensor :math:`S=(s_{ijk})` for a vector
      valued observable :math:`(f_1(T),\dots,f_K(T))` is defined as
  
      .. math:: S= \left( \left. \frac{\partial f_i(T)}{\partial t_{jk}} \right\rvert_{T_0} \right)
      evaluated at a suitable transition matrix :math:`T_0`.
  
      The sensitivity is the covariance matrix for the observable
  
      .. math:: \text{cov}[f_{\alpha}(T),f_{\beta}(T)] = \sum_{i,j,k,l} s_{\alpha i j}
                                                         \text{cov}[t_{ij}, t_{kl}] s_{\beta kl}
  
      """
      if issparse(C):
          warnings.warn("Error-perturbation will be dense for sparse input")
          C = C.toarray()
      return dense.covariance.error_perturbation(C, S)