docs: def generate_nb_state_data(means, weights, R):
      """
      Generates data according to the Negative Binomial Convex Mixture Model.
  
      Args:
          means (array): Cell types- genes x clusters
          weights (array): Cell cluster assignments- clusters x cells
          R (array): dispersion parameter - 1 x genes
  
      Returns:
          data matrix - genes x cells
      """
      cells = weights.shape[1]
      # x_true = true means
      x_true = np.dot(means, weights)
      # convert means into P
      R_ = np.tile(R, (cells, 1)).T
      P_true = x_true/(R_ + x_true)
      sample = np.random.negative_binomial(np.tile(R, (cells, 1)).T, P_true)
      return sample.astype(float)