docs: def initialize_means_weights(data, clusters, init_means=None, init_weights=None, initialization='tsvd', max_assign_weight=0.75):
      """
      Generates initial means and weights for state estimation.
      """
      genes, cells = data.shape
      if init_means is None:
          if init_weights is not None:
              if len(init_weights.shape)==1:
                  means = initialize_means(data, init_weights, clusters)
              else:
                  means = initialize_means(data, init_weights.argmax(0),
                          clusters, max_assign_weight=max_assign_weight)
          elif initialization=='cluster':
              assignments, means = poisson_cluster(data, clusters)
              if init_weights is None:
                  init_weights = initialize_from_assignments(assignments, clusters,
                          max_assign_weight=max_assign_weight)
          elif initialization=='kmpp':
              means, assignments = kmeans_pp(data, clusters)
          elif initialization=='km':
              km = KMeans(clusters)
              assignments = km.fit_predict(log1p(cell_normalize(data)).T)
              init_weights = initialize_from_assignments(assignments, clusters,
                      max_assign_weight)
              means = initialize_means(data, assignments, clusters)
          elif initialization=='tsvd':
              n_components = min(50, genes-1)
              #tsvd = TruncatedSVD(min(50, genes-1))
              km = KMeans(clusters)
              # remove dependence on sklearn tsvd b/c it has a bug that
              # prevents it from working properly on long inputs 
              # if num elements > 2**31
              #data_reduced = tsvd.fit_transform(log1p(cell_normalize(data)).T)
              U, Sigma, VT = randomized_svd(log1p(cell_normalize(data)).T,
                      n_components)
              data_reduced = U*Sigma
              assignments = km.fit_predict(data_reduced)
              init_weights = initialize_from_assignments(assignments, clusters,
                      max_assign_weight)
              means = initialize_means(data, assignments, clusters)
          elif initialization == 'random' or initialization == 'rand':
              # choose k random cells and set means to those
              selected_cells = np.random.choice(range(cells), size=clusters,
                      replace=False)
              means = data[:, selected_cells]
              if sparse.issparse(means):
                  means = means.toarray()
      else:
          means = init_means.copy()
      means = means.astype(float)
      if init_weights is None:
          if init_means is not None:
              if initialization == 'cluster':
                  assignments, means = poisson_cluster(data, clusters,
                          init=init_means, max_iters=1)
                  w_init = initialize_from_assignments(assignments, clusters,
                          max_assign_weight)
              elif initialization == 'km':
                  km = KMeans(clusters, init=log1p(init_means.T), max_iter=1)
                  assignments = km.fit_predict(log1p(cell_normalize(data)).T)
                  w_init = initialize_from_assignments(assignments, clusters,
                          max_assign_weight)
              else:
                  w_init = np.random.random((clusters, cells))
                  w_init = w_init/w_init.sum(0)
          else:
              w_init = np.random.random((clusters, cells))
              w_init = w_init/w_init.sum(0)
      else:
          if len(init_weights.shape)==1:
              init_weights = initialize_from_assignments(init_weights, clusters,
                      max_assign_weight)
          w_init = init_weights.copy()
      return means, w_init