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: Function to parametrize the x or y positions of the spline knots
  Parameters
  ----------
  spline_knots
      variable that parameterizes the spline knot positions
  qk
      x or y positions of the quantile knots (qk),
      with index=1, ..., num_qk-1,
      shape: (*batch_shape, num_qk-1)
  qk_plus
      x or y positions of the quantile knots (qk),
      with index=2, ..., num_qk,
      shape: (*batch_shape, num_qk-1)
  num_pieces
      number of spline knot pieces
  tol
      tolerance hyperparameter for numerical stability
  Returns
  -------
  sk
      x or y positions of the spline knots (sk),
      shape: (*batch_shape, num_qk-1, num_pieces)
  delta_sk
      difference of x or y positions of the spline knots (sk),
      shape: (*batch_shape, num_qk-1, num_pieces)
code: def parametrize_spline(
      F,
      spline_knots: Tensor,
      qk: Tensor,
      qk_plus: Tensor,
      num_pieces: int,
      tol: float = 1e-4,
  ) -> Tuple[Tensor, Tensor]:
      r"""
      Function to parametrize the x or y positions of the spline knots
      Parameters
      ----------
      spline_knots
          variable that parameterizes the spline knot positions
      qk
          x or y positions of the quantile knots (qk),
          with index=1, ..., num_qk-1,
          shape: (*batch_shape, num_qk-1)
      qk_plus
          x or y positions of the quantile knots (qk),
          with index=2, ..., num_qk,
          shape: (*batch_shape, num_qk-1)
      num_pieces
          number of spline knot pieces
      tol
          tolerance hyperparameter for numerical stability
      Returns
      -------
      sk
          x or y positions of the spline knots (sk),
          shape: (*batch_shape, num_qk-1, num_pieces)
      delta_sk
          difference of x or y positions of the spline knots (sk),
          shape: (*batch_shape, num_qk-1, num_pieces)
      """
  
      # The spacing between spline knots is parametrized
      # by softmax function (in [0,1] and sum to 1)
      # We add tol to prevent overflow in computing 1/spacing in spline CRPS
      # After adding tol, it is normalized by
      # (1 + num_pieces * tol) to keep the sum-to-1 property
      delta_x = (F.softmax(spline_knots) + tol) / (1 + num_pieces * tol)
  
      # TODO: update to mxnet cumsum when it supports axis=-1
      x = cumsum(F, delta_x, exclusive=True)
  
      qk = F.expand_dims(qk, axis=-1)
      qk_plus = F.expand_dims(qk_plus, axis=-1)
  
      sk = F.broadcast_add(F.broadcast_mul(x, (qk_plus - qk)), qk)
      delta_sk = F.broadcast_mul(delta_x, (qk_plus - qk))
  
      return sk, delta_sk
  
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 5 for calling the ISQF obj's underlying member method code with example usage: obj.parametrize_spline(F, spline_knots, qk, qk_plus, num_pieces, tol) and returns: sk,  delta_sk