class_docstr: Sparse Random Projection using PyTorch operations.
  
  Args:
      eps (float, optional): Minimum distortion rate parameter for calculating
          Johnson-Lindenstrauss minimum dimensions. Defaults to 0.1.
      random_state (int | None, optional): Uses the seed to set the random
          state for sample_without_replacement function. Defaults to None.
docstr: Random sparse matrix. Based on https://web.stanford.edu/~hastie/Papers/Ping/KDD06_rp.pdf.
  
  Args:
      n_features (int): Dimentionality of the original source space
  
  Returns:
      Tensor: Sparse matrix of shape (n_components, n_features).
          The generated Gaussian random matrix is in CSR (compressed sparse row)
          format.
docstr_tok: ["Random","sparse","matrix",".","Based","on","https",":","\/\/web.stanford.edu\/~hastie\/Papers\/Ping\/KDD06_rp.pdf",".","Args",":","n_features","(","int",")",":","Dimentionality","of","the","original","source","space","Returns",":","Tensor",":","Sparse","matrix","of","shape","(","n_components",",","n_features",")",".","The","generated","Gaussian","random","matrix","is","in","CSR","(","compressed","sparse","row",")","format","."]
code: def _sparse_random_matrix(self, n_features: int):
      """Random sparse matrix. Based on https://web.stanford.edu/~hastie/Papers/Ping/KDD06_rp.pdf.
  
      Args:
          n_features (int): Dimentionality of the original source space
  
      Returns:
          Tensor: Sparse matrix of shape (n_components, n_features).
              The generated Gaussian random matrix is in CSR (compressed sparse row)
              format.
      """
  
      # Density 'auto'. Factorize density
      density = 1 / np.sqrt(n_features)
  
      if density == 1:
          # skip index generation if totally dense
          binomial = torch.distributions.Binomial(
              total_count=1, probs=0.5
          )
          components = (
              binomial.sample((self.n_components, n_features)) * 2 - 1
          )
          components = 1 / np.sqrt(self.n_components) * components
  
      else:
          # Sparse matrix is not being generated here as it is stored as dense anyways
          components = torch.zeros(
              (self.n_components, n_features), dtype=torch.float64
          )
          for i in range(self.n_components):
              # find the indices of the non-zero components for row i
              nnz_idx = torch.distributions.Binomial(
                  total_count=n_features, probs=density
              ).sample()
              # get nnz_idx column indices
              # pylint: disable=not-callable
              c_idx = torch.tensor(
                  sample_without_replacement(
                      n_population=n_features,
                      n_samples=nnz_idx,
                      random_state=self.random_state,
                  ),
                  dtype=torch.int64,
              )
              data = (
                  torch.distributions.Binomial(
                      total_count=1, probs=0.5
                  ).sample(sample_shape=c_idx.size())
                  * 2
                  - 1
              )
              # assign data to only those columns
              components[i, c_idx] = data.double()
  
          components *= np.sqrt(1 / density) / np.sqrt(
              self.n_components
          )
  
      return components
  
file_path: anomalib/src/anomalib/models/components/dimensionality_reduction/random_projection.py
imports: from __future__ import annotations
  import numpy
  import torch
  from sklearn.utils.random import sample_without_replacement
  from torch import Tensor
label_desc: Use image node_id 2 for calling the SparseRandomProjection obj's underlying member method code with example usage: obj._sparse_random_matrix(n_features) and returns: components