code: def piecewise_linear_inverse_transform(
      y, q_tilde, compute_jacobian=True, outlier_passthru=True
  ):
      """
      Apply inverse of an element-wise piecewise-linear transformation to some
      variables
  
      Args:
          y : torch.Tensor
              a tensor with shape (N,k) where N is the batch dimension while k is the dimension of the variable space. This variable span the k-dimensional unit hypercube
  
          q_tilde: torch.Tensor
                  is a tensor with shape (N,k,b) where b is the number of bins. This contains the un-normalized heights of the bins of the piecewise-constant PDF for dimension k, i.e. q_tilde lives in all of R and we don't impose a constraint on their sum yet. Normalization is imposed in this function using softmax.
  
          compute_jacobian : bool, optional
                              determines whether the jacobian should be compute or None is returned
  
      Returns:
          tuple of torch.Tensor
              pair `(x,h)`.
              - `x` is a tensor with shape (N,k) living in the k-dimensional unit hypercube
              - `j` is the jacobian of the transformation with shape (N,) if compute_jacobian==True, else None.
      """
  
      third_dimension_softmax = torch.nn.Softmax(dim=2)
      # Compute the bin width w
      N, k, b = q_tilde.shape
      Ny, ky = y.shape
      assert N == Ny and k == ky, "Shape mismatch"
  
      w = 1.0 / b
  
      # Compute normalized bin heights with softmax function on the bin dimension
      q = 1.0 / w * third_dimension_softmax(q_tilde)
  
      # Compute the integral over the left-bins in the forward transform.
      # 1. Compute all integrals: cumulative sum of bin height * bin weight.
      # We want that index i contains the cumsum *strictly to the left*,
      # so we shift by 1 leaving the first entry null,
      # which is achieved with a roll and assignment
      q_left_integrals = torch.roll(
          torch.cumsum(q.float(), 2) * w, 1, 2
      )
      q_left_integrals[:, :, 0] = 0
  
      # Find which bin each y belongs to by finding the smallest bin such that
      # y - q_left_integral is positive
  
      edges = (y.unsqueeze(-1) - q_left_integrals).detach()
      # y and q_left_integrals are between 0 and 1,
      # so that their difference is at most 1.
      # By setting the negative values to 2., we know that the
      # smallest value left is the smallest positive
      edges[edges < 0] = 2.0
      edges = torch.clamp(torch.argmin(edges, dim=2), 0, b - 1).to(
          torch.long
      )
  
      # Need special error handling because trying to index with mx
      # if it contains nans will lock the GPU. (device-side assert triggered)
      if (
          torch.any(torch.isnan(edges)).item()
          or torch.any(edges < 0)
          or torch.any(edges >= b)
      ):
          raise AvertedCUDARuntimeError(
              "NaN detected in PWLinear bin indexing"
          )
  
      # Gather the left integrals at each edge. See comment about gathering in q_left_integrals
      # for the unsqueeze
      q_left_integrals = q_left_integrals.gather(
          2, edges.unsqueeze(-1)
      ).squeeze(-1)
  
      # Gather the slope at each edge.
      q = q.gather(2, edges.unsqueeze(-1)).squeeze(-1)
  
      # Build the output
      x = (y - q_left_integrals) / q + edges * w
  
      # Regularization: points must be strictly within the unit hypercube
      # Use the dtype information from pytorch
      eps = torch.finfo(x.dtype).eps
      x = x.clamp(min=eps, max=1.0 - eps)
      oob_mask = torch.logical_or(y < 0.0, y > 1.0).detach().float()
      if outlier_passthru:
          x = x * (1 - oob_mask) + y * oob_mask
          q = q * (1 - oob_mask) + oob_mask
  
      # Prepare the jacobian
      logj = None
      if compute_jacobian:
          # logj = - torch.log(torch.prod(q, 1))
          logj = -torch.sum(torch.log(q.float()), 1)
      return x.detach(), logj
  
file_path: NeMo/nemo/collections/tts/parts/utils/splines.py
imports: import numpy
  import torch
  import torch.nn.functional
label_desc: Use image node_id 2 for calling a global function with example usage: piecewise_linear_inverse_transform(y, q_tilde, compute_jacobian, outlier_passthru) and returns: x,  logj