code: def sample_pdf(bins, weights, N_samples, det=False, device="cpu"):
      # Get pdf
      weights = weights + 1e-5  # prevent nans
      pdf = weights / torch.sum(weights, -1, keepdim=True)
      cdf = torch.cumsum(pdf, -1)
      cdf = torch.cat(
          [torch.zeros_like(cdf[..., :1]), cdf], -1
      )  # (batch, len(bins))
  
      # Take uniform samples
      if det:
          u = torch.linspace(0.0, 1.0, steps=N_samples, device=device)
          u = u.expand(list(cdf.shape[:-1]) + [N_samples])
      else:
          u = torch.rand(
              list(cdf.shape[:-1]) + [N_samples], device=device
          )
  
      # Invert CDF
      u = u.contiguous()
      inds = torch.searchsorted(cdf, u, right=True)
      below = torch.max(torch.zeros_like(inds - 1), inds - 1)
      above = torch.min(
          (cdf.shape[-1] - 1) * torch.ones_like(inds), inds
      )
      inds_g = torch.stack([below, above], -1)  # (batch, N_samples, 2)
  
      matched_shape = [inds_g.shape[0], inds_g.shape[1], cdf.shape[-1]]
      cdf_g = torch.gather(
          cdf.unsqueeze(1).expand(matched_shape), 2, inds_g
      )
      bins_g = torch.gather(
          bins.unsqueeze(1).expand(matched_shape), 2, inds_g
      )
  
      denom = cdf_g[..., 1] - cdf_g[..., 0]
      denom = torch.where(denom < 1e-5, torch.ones_like(denom), denom)
      t = (u - cdf_g[..., 0]) / denom
      samples = bins_g[..., 0] + t * (bins_g[..., 1] - bins_g[..., 0])
  
      return samples
  
file_path: ml-neuman/utils/ray_utils.py
imports: import numpy
  import torch
  import igl
  from geometry.pcd_projector import PointCloudProjectorNp
  from utils.constant import DEFAULT_GEO_THRESH, PERTURB_EPSILON
label_desc: Use image node_id 9 for calling a global function with example usage: sample_pdf(bins, weights, N_samples, det, device) and returns: samples