class_docstr: Compute affinities using nearest neighbors and uniform kernel in
  the ambient space.
  
  Parameters
  ----------
  data: np.ndarray
      The data matrix.
  
  k_neighbors: int
  
  method: str
      Specifies the nearest neighbor method to use. Can be ``exact``, ``annoy``,
      ``pynndescent``, ``hnsw``, ``approx``, or ``auto`` (default). ``approx``
      uses Annoy if the input data matrix is not a sparse object and if Annoy
      supports the given metric. Otherwise, it uses Pynndescent. ``auto`` uses
      exact nearest neighbors for N<1000 and the same heuristic as ``approx``
      for N>=1000.
  
  metric: Union[str, Callable]
      The metric to be used to compute affinities between points in the
      original space.
  
  metric_params: dict
      Additional keyword arguments for the metric function.
  
  symmetrize: Union[str, bool]
      Symmetrize the affinity matrix. During standard t-SNE optimization, the
      affinities are symmetrized. However, when embedding new data points into
      existing embeddings, symmetrization is not performed.
      The uniform affinity supports ``max`` and ``mean`` symmetrization, as
      well as no symmetrization via ``none``.
      The ``max`` symmetrization yields a binary affinity matrix with all
      non-zero elements (corresponding to edges of the kNN graph) being the
      same. The ``mean`` symmetrization performs symmetrization via
      (A + A.T) / 2, resulting in the affinity matrix with two possible
      non-zero values. Applying no symmetrization results in a non-symmetric
      affinity matrix. We default to ``mean`` symmetrization, but the default
      will change to ``max`` in future versions.
  
  n_jobs: int
      The number of threads to use while running t-SNE. This follows the
      scikit-learn convention, ``-1`` meaning all processors, ``-2`` meaning
      all but one, etc.
  
  random_state: Union[int, RandomState]
      If the value is an int, random_state is the seed used by the random
      number generator. If the value is a RandomState instance, then it will
      be used as the random number generator. If the value is None, the random
      number generator is the RandomState instance used by `np.random`.
  
  verbose: bool
  
  knn_index: Optional[nearest_neighbors.KNNIndex]
      Optionally, a precomptued ``openTSNE.nearest_neighbors.KNNIndex`` object
      can be specified. This option will ignore any KNN-related parameters.
      When ``knn_index`` is specified, ``data`` must be set to None.
class_docstr_tok: ["Compute","affinities","using","nearest","neighbors","and","uniform","kernel","in","the","ambient","space",".","Parameters","--","--","--","--","--","data",":","np.ndarray","The","data","matrix",".","k_neighbors",":","int","method",":","str","Specifies","the","nearest","neighbor","method","to","use",".","Can","be","``","exact","``",",","``","annoy","``",",","``","pynndescent","``",",","``","hnsw","``",",","``","approx","``",",","or","``","auto","``","(","default",")",".","``","approx","``","uses","Annoy","if","the","input","data","matrix","is","not","a","sparse","object","and","if","Annoy","supports","the","given","metric",".","Otherwise",",","it","uses","Pynndescent",".","``","auto","``","uses","exact","nearest","neighbors","for","N","<","1000","and","the","same","heuristic","as","``","approx","``","for","N",">","=1000",".","metric",":","Union","[","str",",","Callable","]","The","metric","to","be","used","to","compute","affinities","between","points","in","the","original","space",".","metric_params",":","dict","Additional","keyword","arguments","for","the","metric","function",".","symmetrize",":","Union","[","str",",","bool","]","Symmetrize","the","affinity","matrix",".","During","standard","t-SNE","optimization",",","the","affinities","are","symmetrized",".","However",",","when","embedding","new","data","points","into","existing","embeddings",",","symmetrization","is","not","performed",".","The","uniform","affinity","supports","``","max","``","and","``","mean","``","symmetrization",",","as","well","as","no","symmetrization","via","``","none","``",".","The","``","max","``","symmetrization","yields","a","binary","affinity","matrix","with","all","non-zero","elements","(","corresponding","to","edges","of","the","kNN","graph",")","being","the","same",".","The","``","mean","``","symmetrization","performs","symmetrization","via","(","A","+","A.T",")","\/","2",",","resulting","in","the","affinity","matrix","with","two","possible","non-zero","values",".","Applying","no","symmetrization","results","in","a","non-symmetric","affinity","matrix",".","We","default","to","``","mean","``","symmetrization",",","but","the","default","will","change","to","``","max","``","in","future","versions",".","n_jobs",":","int","The","number","of","threads","to","use","while","running","t-SNE",".","This","follows","the","scikit-learn","convention",",","``","-1","``","meaning","all","processors",",","``","-2","``","meaning","all","but","one",",","etc",".","random_state",":","Union","[","int",",","RandomState","]","If","the","value","is","an","int",",","random_state","is","the","seed","used","by","the","random","number","generator",".","If","the","value","is","a","RandomState","instance",",","then","it","will","be","used","as","the","random","number","generator",".","If","the","value","is","None",",","the","random","number","generator","is","the","RandomState","instance","used","by","`","np.random","`",".","verbose",":","bool","knn_index",":","Optional","[","nearest_neighbors.KNNIndex","]","Optionally",",","a","precomptued","``","openTSNE.nearest_neighbors.KNNIndex","``","object","can","be","specified",".","This","option","will","ignore","any","KNN-related","parameters",".","When","``","knn_index","``","is","specified",",","``","data","``","must","be","set","to","None","."]
code: def __init__(
      self,
      data=None,
      k_neighbors=30,
      method="auto",
      metric="euclidean",
      metric_params=None,
      symmetrize=True,
      n_jobs=1,
      random_state=None,
      verbose=False,
      knn_index=None,
  ):
      # This can't work if neither data nor the knn index are specified
      if data is None and knn_index is None:
          raise ValueError(
              "At least one of the parameters `data` or `knn_index` must be specified!"
          )
      # This can't work if both data and the knn index are specified
      if data is not None and knn_index is not None:
          raise ValueError(
              "Both `data` or `knn_index` were specified! Please pass only one."
          )
  
      if knn_index is None:
          if k_neighbors >= data.shape[0]:
              raise ValueError(
                  "`k_neighbors` (%d) cannot be larger than N-1 (%d)."
                  % (k_neighbors, data.shape[0])
              )
  
          self.knn_index = get_knn_index(
              data,
              method,
              k_neighbors,
              metric,
              metric_params,
              n_jobs,
              random_state,
              verbose,
          )
  
      else:
          self.knn_index = knn_index
          log.info(
              "KNN index provided. Ignoring KNN-related parameters."
          )
  
      neighbors, distances = self.knn_index.build()
  
      k_neighbors = self.knn_index.k
      n_samples = self.knn_index.n_samples
      P = sp.csr_matrix(
          (
              np.ones_like(distances).ravel(),
              neighbors.ravel(),
              range(0, n_samples * k_neighbors + 1, k_neighbors),
          ),
          shape=(n_samples, n_samples),
      )
  
      # Symmetrize the probability matrix
      if symmetrize == "max":
          P = (P + P.T > 0).astype(float)
      elif symmetrize == "mean":
          P = (P + P.T) / 2
      elif symmetrize == "none" or symmetrize is False:
          pass
      elif symmetrize is True:
          # Backward compatibility
          P = (P + P.T) / 2
          warnings.warn(
              f"Using `mean` symmetrization, but the default behaviour is going to "
              f"change to `max` in future versions.",
              category=FutureWarning,
          )
      else:
          raise ValueError(
              f"Symmetrization method `{symmetrize}` is not recognized."
          )
  
      # Convert weights to probabilities
      P /= np.sum(P)
  
      self.P = P
      self.verbose = verbose
      self.n_jobs = n_jobs
  
imports: import logging
  import numbers
  import operator
  from functools import reduce
  import numpy
  import scipy.sparse
  from openTSNE import _tsne
  from openTSNE import nearest_neighbors
  from openTSNE import utils
  from openTSNE.utils import is_package_installed
  import warnings
label_desc: Use image node_id 1 to create a new Uniform object from inherited base classes: Affinities with example: obj = Uniform(data, k_neighbors, method, metric, metric_params, symmetrize, n_jobs, random_state, verbose, knn_index)