docs: def coarsegrain(F, sets):
      r"""Coarse-grains the flux to the given sets
  
      $fc_{i,j} = \sum_{i \in I,j \in J} f_{i,j}$
      Note that if you coarse-grain a net flux, it does not necessarily have a net
      flux property anymore. If want to make sure you get a netflux,
      use to_netflux(coarsegrain(F,sets)).
  
      Parameters
      ----------
      F : (n, n) ndarray
          Matrix of flux values between pairs of states.
      sets : list of array-like of ints
          The sets of states onto which the flux is coarse-grained.
  
      """
      nnew = len(sets)
      Fin = F.tocsr()
      Fc = csr_matrix((nnew, nnew))
      for i in range(0, nnew - 1):
          for j in range(i, nnew):
              I = list(sets[i])
              J = list(sets[j])
              Fc[i, j] = (Fin[I, :][:, J]).sum()
              Fc[j, i] = (Fin[J, :][:, I]).sum()
      return Fc