class_docstr: FastAP - autograd function definition
  
  This class implements the FastAP loss from the following paper:
  "Deep Metric Learning to Rank",
  F. Cakir, K. He, X. Xia, B. Kulis, S. Sclaroff. CVPR 2019
  
  NOTE:
      Given a input batch, FastAP does not sample triplets from it as it's not
      a triplet-based method. Therefore, FastAP does not take a Sampler as input.
      Rather, we specify how the input batch is selected.
class_docstr_tok: ["FastAP","-","autograd","function","definition","This","class","implements","the","FastAP","loss","from","the","following","paper",":","''","Deep","Metric","Learning","to","Rank","''",",","F.","Cakir",",","K.","He",",","X.","Xia",",","B.","Kulis",",","S.","Sclaroff",".","CVPR","2019","NOTE",":","Given","a","input","batch",",","FastAP","does","not","sample","triplets","from","it","as","it","'s","not","a","triplet-based","method",".","Therefore",",","FastAP","does","not","take","a","Sampler","as","input",".","Rather",",","we","specify","how","the","input","batch","is","selected","."]
docstr: Args:
      input:     torch.Tensor(N x embed_dim), embedding matrix
      target:    torch.Tensor(N x 1), class labels
      num_bins:  int, number of bins in distance histogram
docstr_tok: ["Args",":","input",":","torch.Tensor","(","N","x","embed_dim",")",",","embedding","matrix","target",":","torch.Tensor","(","N","x","1",")",",","class","labels","num_bins",":","int",",","number","of","bins","in","distance","histogram"]
code: def forward(ctx, input, target, num_bins):
      """
      Args:
          input:     torch.Tensor(N x embed_dim), embedding matrix
          target:    torch.Tensor(N x 1), class labels
          num_bins:  int, number of bins in distance histogram
      """
      N = target.size()[0]
      assert input.size()[0] == N, "Batch size donesn't match!"
  
      # 1. get affinity matrix
      Y = target.unsqueeze(1)
      Aff = 2 * (Y == Y.t()).type(input.dtype) - 1
      Aff.masked_fill_(
          torch.eye(N, N).bool().to(input.device), 0
      )  # set diagonal to 0
  
      I_pos = (Aff > 0).type(input.dtype).to(input.device)
      I_neg = (Aff < 0).type(input.dtype).to(input.device)
      N_pos = torch.sum(I_pos, 1)
  
      # 2. compute distances from embeddings
      # squared Euclidean distance with range [0,4]
      dist2 = 2 - 2 * torch.mm(input, input.t())
  
      # 3. estimate discrete histograms
      Delta = torch.tensor(4.0 / num_bins).to(input.device)
      Z = torch.linspace(0.0, 4.0, steps=num_bins + 1).to(input.device)
      L = Z.size()[0]
      h_pos = torch.zeros((N, L), dtype=input.dtype).to(input.device)
      h_neg = torch.zeros((N, L), dtype=input.dtype).to(input.device)
      for l in range(L):
          pulse = softBinning(dist2, Z[l], Delta)
          h_pos[:, l] = torch.sum(pulse * I_pos, 1)
          h_neg[:, l] = torch.sum(pulse * I_neg, 1)
  
      H_pos = torch.cumsum(h_pos, 1)
      h = h_pos + h_neg
      H = torch.cumsum(h, 1)
  
      # 4. compate FastAP
      FastAP = h_pos * H_pos / H
      FastAP[torch.isnan(FastAP) | torch.isinf(FastAP)] = 0
      FastAP = torch.sum(FastAP, 1) / N_pos
      FastAP = FastAP[~torch.isnan(FastAP)]
      loss = 1 - torch.mean(FastAP)
  
      # 6. save for backward
      ctx.save_for_backward(input, target)
      ctx.Z = Z
      ctx.Delta = Delta
      ctx.dist2 = dist2
      ctx.I_pos = I_pos
      ctx.I_neg = I_neg
      ctx.h_pos = h_pos
      ctx.h_neg = h_neg
      ctx.H_pos = H_pos
      ctx.N_pos = N_pos
      ctx.h = h
      ctx.H = H
      ctx.L = torch.tensor(L)
  
      return loss
  
file_path: pytorch-metric-learning/tests/losses/test_fastap_loss.py
imports: import torch
  from torch.autograd import Variable
  import unittest
  from pytorch_metric_learning.losses import FastAPLoss
  from ..None import TEST_DEVICE, TEST_DTYPES
  from ..zzz_testing_utils.testing_utils import angle_to_coord
label_desc: Use image node_id 1 for calling the OriginalImplementationFastAP obj's underlying member method code with example usage: obj.forward(ctx, input, target, num_bins) and returns: loss