class_docstr: Distribution class for the Incremental (Spline) Quantile Function in the
  paper ``Learning Quantile Functions without Quantile Crossing for
  Distribution-free Time Series Forecasting``
  by Park, Robinson, Aubet, Kan, Gasthaus, Wang
  
  Parameters
  ----------
  spline_knots, spline_heights
      Tensor parametrizing the x-positions (y-positions) of the spline knots
      Shape: (*batch_shape, (num_qk-1), num_pieces)
  qk_x, qk_y
      Tensor containing the increasing x-positions (y-positions) of the
      quantile knots, Shape: (*batch_shape, num_qk)
  beta_l, beta_r
      Tensor containing the non-negative learnable parameter of the
      left (right) tail, Shape: (*batch_shape,)
class_docstr_tok: ["Distribution","class","for","the","Incremental","(","Spline",")","Quantile","Function","in","the","paper","``","Learning","Quantile","Functions","without","Quantile","Crossing","for","Distribution-free","Time","Series","Forecasting","``","by","Park",",","Robinson",",","Aubet",",","Kan",",","Gasthaus",",","Wang","Parameters","--","--","--","--","--","spline_knots",",","spline_heights","Tensor","parametrizing","the","x-positions","(","y-positions",")","of","the","spline","knots","Shape",":","(","*","batch_shape",",","(","num_qk-1",")",",","num_pieces",")","qk_x",",","qk_y","Tensor","containing","the","increasing","x-positions","(","y-positions",")","of","the","quantile","knots",",","Shape",":","(","*","batch_shape",",","num_qk",")","beta_l",",","beta_r","Tensor","containing","the","non-negative","learnable","parameter","of","the","left","(","right",")","tail",",","Shape",":","(","*","batch_shape",",",")"]
docstr: Evaluates the quantile function at the quantile levels input_alpha
  Parameters
  ----------
  alpha
      Tensor of shape = (*batch_shape,) if axis=None, or containing an
      additional axis on the specified position, otherwise
  axis
      Index of the axis containing the different quantile levels which
      are to be computed.
      Read the description below for detailed information
  Returns
  -------
  Tensor
      Quantiles tensor, of the same shape as alpha
code: def quantile_internal(
      self, alpha: Tensor, axis: Optional[int] = None
  ) -> Tensor:
      r"""
      Evaluates the quantile function at the quantile levels input_alpha
      Parameters
      ----------
      alpha
          Tensor of shape = (*batch_shape,) if axis=None, or containing an
          additional axis on the specified position, otherwise
      axis
          Index of the axis containing the different quantile levels which
          are to be computed.
          Read the description below for detailed information
      Returns
      -------
      Tensor
          Quantiles tensor, of the same shape as alpha
      """
  
      F = self.F
      qk_x, qk_x_l, qk_x_plus = self.qk_x, self.qk_x_l, self.qk_x_plus
  
      # The following describes the parameters reshaping in
      # quantile_internal, quantile_spline and quantile_tail
  
      # tail parameters: tail_al, tail_ar, tail_bl, tail_br,
      # shape = (*batch_shape,)
      # spline parameters: sk_x, sk_x_plus, sk_y, sk_y_plus,
      # shape = (*batch_shape, num_qk-1, num_pieces)
      # quantile knots parameters: qk_x, qk_x_plus, qk_y, qk_y_plus,
      # shape = (*batch_shape, num_qk-1)
  
      # axis=None - passed at inference when num_samples is None
      # shape of input_alpha = (*batch_shape,), will be expanded to
      # (*batch_shape, 1, 1) to perform operation
      # The shapes of parameters are as described above,
      # no reshaping is needed
  
      # axis=0 - passed at inference when num_samples is not None
      # shape of input_alpha = (num_samples, *batch_shape)
      # it will be expanded to
      # (num_samples, *batch_shape, 1, 1) to perform operation
      #
      # The shapes of tail parameters
      # should be (num_samples, *batch_shape)
      #
      # The shapes of spline parameters
      # should be (num_samples, *batch_shape, num_qk-1, num_pieces)
      #
      # The shapes of quantile knots parameters
      # should be (num_samples, *batch_shape, num_qk-1)
      #
      # We expand axis=0 for all of them
  
      # axis=-2 - passed at training when we evaluate quantiles at
      # spline knots in order to compute alpha_tilde
      #
      # This is only for the quantile_spline function
      # shape of input_alpha = (*batch_shape, num_qk-1, num_pieces)
      # it will be expanded to
      # (*batch_shape, num_qk-1, num_pieces, 1) to perform operation
      #
      # The shapes of spline and quantile knots parameters should be
      # (*batch_shape, num_qk-1, 1, num_pieces)
      # and (*batch_shape, num_qk-1, 1), respectively
      #
      # We expand axis=-2 and axis=-1 for
      # spline and quantile knots parameters, respectively
  
      if axis is not None:
          qk_x_l = F.expand_dims(qk_x_l, axis=axis)
          qk_x = F.expand_dims(qk_x, axis=axis)
          qk_x_plus = F.expand_dims(qk_x_plus, axis=axis)
  
      quantile = F.where(
          F.broadcast_lesser(alpha, qk_x_l),
          self.quantile_tail(alpha, axis=axis, left_tail=True),
          self.quantile_tail(alpha, axis=axis, left_tail=False),
      )
  
      spline_val = self.quantile_spline(alpha, axis=axis)
  
      for spline_idx in range(self.num_qk - 1):
          is_in_between = F.broadcast_logical_and(
              F.broadcast_lesser_equal(
                  F.slice_axis(
                      qk_x,
                      axis=-1,
                      begin=spline_idx,
                      end=spline_idx + 1,
                  ).squeeze(-1),
                  alpha,
              ),
              F.broadcast_lesser(
                  alpha,
                  F.slice_axis(
                      qk_x_plus,
                      axis=-1,
                      begin=spline_idx,
                      end=spline_idx + 1,
                  ).squeeze(-1),
              ),
          )
  
          quantile = F.where(
              is_in_between,
              F.slice_axis(
                  spline_val,
                  axis=-1,
                  begin=spline_idx,
                  end=spline_idx + 1,
              ).squeeze(-1),
              quantile,
          )
  
      return quantile
  
imports: from typing import Dict, List, Optional, Tuple
  import numpy
  from gluonts.core.component import validated
  from gluonts.mx import Tensor
  from gluonts.mx.util import cumsum
  from .bijection import AffineTransformation, Bijection
  from .distribution import Distribution, getF
  from .distribution_output import DistributionOutput
  from .transformed_distribution import TransformedDistribution
label_desc: Use image node_id 8 for calling the ISQF obj's underlying member method code with example usage: obj.quantile_internal(alpha, axis) and returns: quantile