def forward(self, distance: torch.Tensor) -> torch.Tensor:
        """Compute the CFA loss given distance features.

        The loss has two components:
            1. Attraction loss (`l_att`): Encourages normal samples to lie within
               the hypersphere by penalizing distances greater than `radius`.
            2. Repulsion loss (`l_rep`): Pushes anomalous samples outside the
               hypersphere by penalizing distances less than `radius + margin`.

        Args:
            distance (torch.Tensor): Distance tensor of shape
                ``(batch_size, num_pixels, 1)`` computed using target-oriented
                features.

        Returns:
            torch.Tensor: Scalar loss value combining attraction and repulsion
                components.
        """
        num_neighbors = self.num_nearest_neighbors + self.num_hard_negative_features
        distance = distance.topk(num_neighbors, largest=False).values  # noqa: PD011

        score = distance[:, :, : self.num_nearest_neighbors] - (self.radius**2).to(distance.device)
        l_att = torch.mean(torch.max(torch.zeros_like(score), score))

        score = (self.radius**2).to(distance.device) - distance[:, :, self.num_hard_negative_features :]
        l_rep = torch.mean(torch.max(torch.zeros_like(score), score - 0.1))

        return (l_att + l_rep) * 1000
Compute the CFA loss given distance features.

        The loss has two components:
            1. Attraction loss (`l_att`): Encourages normal samples to lie within
               the hypersphere by penalizing distances greater than `radius`.
            2. Repulsion loss (`l_rep`): Pushes anomalous samples outside the
               hypersphere by penalizing distances less than `radius + margin`.

        Args:
            distance (torch.Tensor): Distance tensor of shape
                ``(batch_size, num_pixels, 1)`` computed using target-oriented
                features.

        Returns:
            torch.Tensor: Scalar loss value combining attraction and repulsion
                components.
        
src/anomalib/models/image/cfa/loss.py