def fit(self, embedding: torch.Tensor) -> "SparseRandomProjection":
        """Fit the random projection matrix to the data.

        Args:
            embedding (torch.Tensor): Input tensor of shape
                ``(n_samples, n_features)``.

        Returns:
            SparseRandomProjection: The fitted projector.

        Example:
            >>> projector = SparseRandomProjection()
            >>> data = torch.randn(100, 50)
            >>> projector = projector.fit(data)
        """
        n_samples, n_features = embedding.shape
        device = embedding.device

        self.n_components = self._johnson_lindenstrauss_min_dim(n_samples=n_samples, eps=self.eps)

        # Generate projection matrix
        # torch can't multiply directly on sparse matrix and moving sparse matrix to cuda throws error
        # (Could not run 'aten::empty_strided' with arguments from the 'SparseCsrCUDA' backend)
        # hence sparse matrix is stored as a dense matrix on the device
        self.sparse_random_matrix = self._sparse_random_matrix(n_features=n_features).to(device)

        return self
Fit the random projection matrix to the data.

        Args:
            embedding (torch.Tensor): Input tensor of shape
                ``(n_samples, n_features)``.

        Returns:
            SparseRandomProjection: The fitted projector.

        Example:
            >>> projector = SparseRandomProjection()
            >>> data = torch.randn(100, 50)
            >>> projector = projector.fit(data)
        
src/anomalib/models/components/dimensionality_reduction/random_projection.py