class_docstr: Heston Model with piecewise constant parameters.
  
  Represents the Ito process:
  
  ```None
    dX(t) = -V(t) / 2 * dt + sqrt(V(t)) * dW_{X}(t),
    dV(t) = mean_reversion(t) * (theta(t) - V(t)) * dt
            + volvol(t) * sqrt(V(t)) * dW_{V}(t)
  ```
  
  where `W_{X}` and `W_{V}` are 1D Brownian motions with a correlation
  `rho(t)`. `mean_reversion`, `theta`, `volvol`, and `rho` are positive
  piecewise constant functions of time. Here `V(t)` represents the process
  variance at time `t` and `X` represents logarithm of the spot price at time
  `t`.
  
  `mean_reversion` corresponds to the mean reversion rate, `theta` is the long
  run price variance, and `volvol` is the volatility of the volatility.
  
  See [1] and [2] for details.
  
  #### Example
  
  ```python
  import tf_quant_finance as tff
  import numpy as np
  volvol = tff.math.piecewise.PiecewiseConstantFunc(
      jump_locations=[0.5], values=[1, 1.1], dtype=np.float64)
  process = tff.models.HestonModel(
      mean_reversion=0.5, theta=0.04, volvol=volvol, rho=0.1, dtype=np.float64)
  times = np.linspace(0.0, 1.0, 1000)
  num_samples = 10000  # number of trajectories
  sample_paths = process.sample_paths(
      times,
      time_step=0.01,
      num_samples=num_samples,
      initial_state=np.array([1.0, 0.04]),
      random_type=random.RandomType.SOBOL)
  ```
  
  #### References:
    [1]: Cristian Homescu. Implied volatility surface: construction
      methodologies and characteristics.
      arXiv: https://arxiv.org/pdf/1107.1834.pdf
    [2]: Leif Andersen. Efficient Simulation of the Heston Stochastic
      Volatility Models. 2006.
      Link:
      http://www.ressources-actuarielles.net/ext/isfa/1226.nsf/d512ad5b22d73cc1c1257052003f1aed/1826b88b152e65a7c12574b000347c74/$FILE/LeifAndersenHeston.pdf
class_docstr_tok: ["Heston","Model","with","piecewise","constant","parameters",".","Represents","the","Ito","process",":","``","`","None","dX","(","t",")","=","-V","(","t",")","\/","2","*","dt","+","sqrt","(","V","(","t",")",")","*","dW_","{","X","}","(","t",")",",","dV","(","t",")","=","mean_reversion","(","t",")","*","(","theta","(","t",")","-","V","(","t",")",")","*","dt","+","volvol","(","t",")","*","sqrt","(","V","(","t",")",")","*","dW_","{","V","}","(","t",")","``","`","where","`","W_","{","X","}","`","and","`","W_","{","V","}","`","are","1D","Brownian","motions","with","a","correlation","`","rho","(","t",")","`",".","`","mean_reversion","`",",","`","theta","`",",","`","volvol","`",",","and","`","rho","`","are","positive","piecewise","constant","functions","of","time",".","Here","`","V","(","t",")","`","represents","the","process","variance","at","time","`","t","`","and","`","X","`","represents","logarithm","of","the","spot","price","at","time","`","t","`",".","`","mean_reversion","`","corresponds","to","the","mean","reversion","rate",",","`","theta","`","is","the","long","run","price","variance",",","and","`","volvol","`","is","the","volatility","of","the","volatility",".","See","[","1","]","and","[","2","]","for","details",".","#","#","#","#","Example","``","`","python","import","tf_quant_finance","as","tff","import","numpy","as","np","volvol","=","tff.math.piecewise.PiecewiseConstantFunc","(","jump_locations=","[","0.5","]",",","values=","[","1",",","1.1","]",",","dtype=np.float64",")","process","=","tff.models.HestonModel","(","mean_reversion=0.5",",","theta=0.04",",","volvol=volvol",",","rho=0.1",",","dtype=np.float64",")","times","=","np.linspace","(","0.0",",","1.0",",","1000",")","num_samples","=","10000","#","number","of","trajectories","sample_paths","=","process.sample_paths","(","times",",","time_step=0.01",",","num_samples=num_samples",",","initial_state=np.array","(","[","1.0",",","0.04","]",")",",","random_type=random.RandomType.SOBOL",")","``","`","#","#","#","#","References",":","[","1","]",":","Cristian","Homescu",".","Implied","volatility","surface",":","construction","methodologies","and","characteristics",".","arXiv",":","https",":","\/\/arxiv.org\/pdf\/1107.1834.pdf","[","2","]",":","Leif","Andersen",".","Efficient","Simulation","of","the","Heston","Stochastic","Volatility","Models",".","2006",".","Link",":","http",":","\/\/www.ressources-actuarielles.net\/ext\/isfa\/1226.nsf\/d512ad5b22d73cc1c1257052003f1aed\/1826b88b152e65a7c12574b000347c74\/","$","FILE\/LeifAndersenHeston.pdf"]
docstr: Returns a sample of paths from the process.
  
  Using Quadratic-Exponential (QE) method described in [1] generates samples
  paths started at time zero and returns paths values at the specified time
  points.
  
  Args:
    times: Rank 1 `Tensor` of positive real values. The times at which the
      path points are to be evaluated.
    initial_state: A rank 1 `Tensor` with two elements where the first element
      corresponds to the initial value of the log spot `X(0)` and the second
      to the starting variance value `V(0)`.
    num_samples: Positive scalar `int`. The number of paths to draw.
    random_type: Enum value of `RandomType`. The type of (quasi)-random
      number generator to use to generate the paths.
      Default value: None which maps to the standard pseudo-random numbers.
    seed: Seed for the random number generator. The seed is
      only relevant if `random_type` is one of
      `[STATELESS, PSEUDO, HALTON_RANDOMIZED, PSEUDO_ANTITHETIC,
        STATELESS_ANTITHETIC]`. For `PSEUDO`, `PSEUDO_ANTITHETIC` and
      `HALTON_RANDOMIZED` the seed should be an Python integer. For
      `STATELESS` and  `STATELESS_ANTITHETIC `must be supplied as an integer
      `Tensor` of shape `[2]`.
      Default value: `None` which means no seed is set.
    time_step: Positive Python float to denote time discretization parameter.
    skip: `int32` 0-d `Tensor`. The number of initial points of the Sobol or
      Halton sequence to skip. Used only when `random_type` is 'SOBOL',
      'HALTON', or 'HALTON_RANDOMIZED', otherwise ignored.
    tolerance: Scalar positive real `Tensor`. Specifies minimum time tolerance
      for which the stochastic process `X(t) != X(t + tolerance)`.
      Default value: 1e-6.
    num_time_steps: An optional Scalar integer `Tensor` - a total number of
      time steps performed by the algorithm. The maximal distance between
      points in grid is bounded by
      `times[-1] / (num_time_steps - times.shape[0])`.
      Either this or `time_step` should be supplied.
      Default value: `None`.
    precompute_normal_draws: Python bool. Indicates whether the noise
      increments `N(0, t_{n+1}) - N(0, t_n)` are precomputed. For `HALTON`
      and `SOBOL` random types the increments are always precomputed. While
      the resulting graph consumes more memory, the performance gains might
      be significant.
      Default value: `True`.
    times_grid: An optional rank 1 `Tensor` representing time discretization
      grid. If `times` are not on the grid, then the nearest points from the
      grid are used. When supplied, `num_time_steps` and `time_step` are
      ignored.
      Default value: `None`, which means that times grid is computed using
      `time_step` and `num_time_steps`.
    normal_draws: A `Tensor` of shape broadcastable with
      `[num_samples, num_time_points, 2]` and the same
      `dtype` as `times`. Represents random normal draws to compute increments
      `N(0, t_{n+1}) - N(0, t_n)`. When supplied, `num_samples` argument is
      ignored and the first dimensions of `normal_draws` is used instead.
      Default value: `None` which means that the draws are generated by the
      algorithm. By default normal_draws for each model in the batch are
      independent.
    name: Str. The name to give this op.
      Default value: `sample_paths`.
  
  Returns:
    A `Tensor`s of shape [num_samples, k, 2] where `k` is the size
    of the `times`. For each sample and time the first dimension represents
    the simulated log-state trajectories of the spot price `X(t)`, whereas the
    second one represents the simulated variance trajectories `V(t)`.
  
  Raises:
    ValueError: If `time_step` is not supplied.
  
  #### References:
    [1]: Leif Andersen. Efficient Simulation of the Heston Stochastic
      Volatility Models. 2006.
docstr_tok: ["Returns","a","sample","of","paths","from","the","process",".","Using","Quadratic-Exponential","(","QE",")","method","described","in","[","1","]","generates","samples","paths","started","at","time","zero","and","returns","paths","values","at","the","specified","time","points",".","Args",":","times",":","Rank","1","`","Tensor","`","of","positive","real","values",".","The","times","at","which","the","path","points","are","to","be","evaluated",".","initial_state",":","A","rank","1","`","Tensor","`","with","two","elements","where","the","first","element","corresponds","to","the","initial","value","of","the","log","spot","`","X","(","0",")","`","and","the","second","to","the","starting","variance","value","`","V","(","0",")","`",".","num_samples",":","Positive","scalar","`","int","`",".","The","number","of","paths","to","draw",".","random_type",":","Enum","value","of","`","RandomType","`",".","The","type","of","(","quasi",")","-random","number","generator","to","use","to","generate","the","paths",".","Default","value",":","None","which","maps","to","the","standard","pseudo-random","numbers",".","seed",":","Seed","for","the","random","number","generator",".","The","seed","is","only","relevant","if","`","random_type","`","is","one","of","`","[","STATELESS",",","PSEUDO",",","HALTON_RANDOMIZED",",","PSEUDO_ANTITHETIC",",","STATELESS_ANTITHETIC","]","`",".","For","`","PSEUDO","`",",","`","PSEUDO_ANTITHETIC","`","and","`","HALTON_RANDOMIZED","`","the","seed","should","be","an","Python","integer",".","For","`","STATELESS","`","and","`","STATELESS_ANTITHETIC","`","must","be","supplied","as","an","integer","`","Tensor","`","of","shape","`","[","2","]","`",".","Default","value",":","`","None","`","which","means","no","seed","is","set",".","time_step",":","Positive","Python","float","to","denote","time","discretization","parameter",".","skip",":","`","int32","`","0-d","`","Tensor","`",".","The","number","of","initial","points","of","the","Sobol","or","Halton","sequence","to","skip",".","Used","only","when","`","random_type","`","is","'SOBOL","'",",","'HALTON","'",",","or","'HALTON_RANDOMIZED","'",",","otherwise","ignored",".","tolerance",":","Scalar","positive","real","`","Tensor","`",".","Specifies","minimum","time","tolerance","for","which","the","stochastic","process","`","X","(","t",")","!","=","X","(","t","+","tolerance",")","`",".","Default","value",":","1e-6",".","num_time_steps",":","An","optional","Scalar","integer","`","Tensor","`","-","a","total","number","of","time","steps","performed","by","the","algorithm",".","The","maximal","distance","between","points","in","grid","is","bounded","by","`","times","[","-1","]","\/","(","num_time_steps","-","times.shape","[","0","]",")","`",".","Either","this","or","`","time_step","`","should","be","supplied",".","Default","value",":","`","None","`",".","precompute_normal_draws",":","Python","bool",".","Indicates","whether","the","noise","increments","`","N","(","0",",","t_","{","n+1","}",")","-","N","(","0",",","t_n",")","`","are","precomputed",".","For","`","HALTON","`","and","`","SOBOL","`","random","types","the","increments","are","always","precomputed",".","While","the","resulting","graph","consumes","more","memory",",","the","performance","gains","might","be","significant",".","Default","value",":","`","True","`",".","times_grid",":","An","optional","rank","1","`","Tensor","`","representing","time","discretization","grid",".","If","`","times","`","are","not","on","the","grid",",","then","the","nearest","points","from","the","grid","are","used",".","When","supplied",",","`","num_time_steps","`","and","`","time_step","`","are","ignored",".","Default","value",":","`","None","`",",","which","means","that","times","grid","is","computed","using","`","time_step","`","and","`","num_time_steps","`",".","normal_draws",":","A","`","Tensor","`","of","shape","broadcastable","with","`","[","num_samples",",","num_time_points",",","2","]","`","and","the","same","`","dtype","`","as","`","times","`",".","Represents","random","normal","draws","to","compute","increments","`","N","(","0",",","t_","{","n+1","}",")","-","N","(","0",",","t_n",")","`",".","When","supplied",",","`","num_samples","`","argument","is","ignored","and","the","first","dimensions","of","`","normal_draws","`","is","used","instead",".","Default","value",":","`","None","`","which","means","that","the","draws","are","generated","by","the","algorithm",".","By","default","normal_draws","for","each","model","in","the","batch","are","independent",".","name",":","Str",".","The","name","to","give","this","op",".","Default","value",":","`","sample_paths","`",".","Returns",":","A","`","Tensor","`","s","of","shape","[","num_samples",",","k",",","2","]","where","`","k","`","is","the","size","of","the","`","times","`",".","For","each","sample","and","time","the","first","dimension","represents","the","simulated","log-state","trajectories","of","the","spot","price","`","X","(","t",")","`",",","whereas","the","second","one","represents","the","simulated","variance","trajectories","`","V","(","t",")","`",".","Raises",":","ValueError",":","If","`","time_step","`","is","not","supplied",".","#","#","#","#","References",":","[","1","]",":","Leif","Andersen",".","Efficient","Simulation","of","the","Heston","Stochastic","Volatility","Models",".","2006","."]
code: def sample_paths(
      self,
      times: types.RealTensor,
      initial_state: types.RealTensor,
      num_samples: types.IntTensor = 1,
      random_type: Optional[random.RandomType] = None,
      seed: Optional[types.RealTensor] = None,
      time_step: Optional[types.RealTensor] = None,
      skip: types.IntTensor = 0,
      tolerance: types.RealTensor = 1e-6,
      num_time_steps: Optional[types.IntTensor] = None,
      precompute_normal_draws: types.BoolTensor = True,
      times_grid: Optional[types.RealTensor] = None,
      normal_draws: Optional[types.RealTensor] = None,
      name: Optional[str] = None,
  ) -> types.RealTensor:
      """Returns a sample of paths from the process.
  
      Using Quadratic-Exponential (QE) method described in [1] generates samples
      paths started at time zero and returns paths values at the specified time
      points.
  
      Args:
        times: Rank 1 `Tensor` of positive real values. The times at which the
          path points are to be evaluated.
        initial_state: A rank 1 `Tensor` with two elements where the first element
          corresponds to the initial value of the log spot `X(0)` and the second
          to the starting variance value `V(0)`.
        num_samples: Positive scalar `int`. The number of paths to draw.
        random_type: Enum value of `RandomType`. The type of (quasi)-random
          number generator to use to generate the paths.
          Default value: None which maps to the standard pseudo-random numbers.
        seed: Seed for the random number generator. The seed is
          only relevant if `random_type` is one of
          `[STATELESS, PSEUDO, HALTON_RANDOMIZED, PSEUDO_ANTITHETIC,
            STATELESS_ANTITHETIC]`. For `PSEUDO`, `PSEUDO_ANTITHETIC` and
          `HALTON_RANDOMIZED` the seed should be an Python integer. For
          `STATELESS` and  `STATELESS_ANTITHETIC `must be supplied as an integer
          `Tensor` of shape `[2]`.
          Default value: `None` which means no seed is set.
        time_step: Positive Python float to denote time discretization parameter.
        skip: `int32` 0-d `Tensor`. The number of initial points of the Sobol or
          Halton sequence to skip. Used only when `random_type` is 'SOBOL',
          'HALTON', or 'HALTON_RANDOMIZED', otherwise ignored.
        tolerance: Scalar positive real `Tensor`. Specifies minimum time tolerance
          for which the stochastic process `X(t) != X(t + tolerance)`.
          Default value: 1e-6.
        num_time_steps: An optional Scalar integer `Tensor` - a total number of
          time steps performed by the algorithm. The maximal distance between
          points in grid is bounded by
          `times[-1] / (num_time_steps - times.shape[0])`.
          Either this or `time_step` should be supplied.
          Default value: `None`.
        precompute_normal_draws: Python bool. Indicates whether the noise
          increments `N(0, t_{n+1}) - N(0, t_n)` are precomputed. For `HALTON`
          and `SOBOL` random types the increments are always precomputed. While
          the resulting graph consumes more memory, the performance gains might
          be significant.
          Default value: `True`.
        times_grid: An optional rank 1 `Tensor` representing time discretization
          grid. If `times` are not on the grid, then the nearest points from the
          grid are used. When supplied, `num_time_steps` and `time_step` are
          ignored.
          Default value: `None`, which means that times grid is computed using
          `time_step` and `num_time_steps`.
        normal_draws: A `Tensor` of shape broadcastable with
          `[num_samples, num_time_points, 2]` and the same
          `dtype` as `times`. Represents random normal draws to compute increments
          `N(0, t_{n+1}) - N(0, t_n)`. When supplied, `num_samples` argument is
          ignored and the first dimensions of `normal_draws` is used instead.
          Default value: `None` which means that the draws are generated by the
          algorithm. By default normal_draws for each model in the batch are
          independent.
        name: Str. The name to give this op.
          Default value: `sample_paths`.
  
      Returns:
        A `Tensor`s of shape [num_samples, k, 2] where `k` is the size
        of the `times`. For each sample and time the first dimension represents
        the simulated log-state trajectories of the spot price `X(t)`, whereas the
        second one represents the simulated variance trajectories `V(t)`.
  
      Raises:
        ValueError: If `time_step` is not supplied.
  
      #### References:
        [1]: Leif Andersen. Efficient Simulation of the Heston Stochastic
          Volatility Models. 2006.
      """
      if random_type is None:
          random_type = random.RandomType.PSEUDO
      # Note: all the notations below are the same as in [1].
      name = name or (self._name + "_sample_path")
      with tf.name_scope(name):
          times = tf.convert_to_tensor(times, self._dtype)
          if normal_draws is not None:
              # shape: [num_samples, num_time_points, dim]
              normal_draws = tf.convert_to_tensor(
                  normal_draws, dtype=self._dtype, name="normal_draws"
              )
              # shape: [num_time_points, num_samples, dim]
              perm = [1, 0, 2]
              normal_draws = tf.transpose(normal_draws, perm=perm)
              num_samples = tff_utils.get_shape(normal_draws)[-2]
          current_log_spot = tf.convert_to_tensor(
              initial_state[..., 0], dtype=self._dtype
          ) + tf.zeros([num_samples], dtype=self._dtype)
          current_vol = tf.convert_to_tensor(
              initial_state[..., 1], dtype=self._dtype
          ) + tf.zeros([num_samples], dtype=self._dtype)
          num_requested_times = tff_utils.get_shape(times)[0]
          if times_grid is None:
              if time_step is None:
                  if num_time_steps is None:
                      raise ValueError(
                          "When `times_grid` is not supplied, either `num_time_steps` "
                          "or `time_step` should be defined."
                      )
                  else:
                      num_time_steps = tf.convert_to_tensor(
                          num_time_steps,
                          dtype=tf.int32,
                          name="num_time_steps",
                      )
                      time_step = times[-1] / tf.cast(
                          num_time_steps, dtype=self._dtype
                      )
              else:
                  if num_time_steps is not None:
                      raise ValueError(
                          "Both `time_step` and `num_time_steps` can not be `None` "
                          "simultaneously when calling sample_paths of HestonModel."
                      )
                  time_step = tf.convert_to_tensor(
                      time_step, dtype=self._dtype, name="time_step"
                  )
          else:
              times_grid = tf.convert_to_tensor(
                  times_grid, dtype=self._dtype, name="times_grid"
              )
          times, keep_mask = _prepare_grid(
              times,
              time_step,
              times.dtype,
              self._mean_reversion,
              self._theta,
              self._volvol,
              self._rho,
              num_time_steps=num_time_steps,
              times_grid=times_grid,
          )
          return self._sample_paths(
              times=times,
              num_requested_times=num_requested_times,
              current_log_spot=current_log_spot,
              current_vol=current_vol,
              num_samples=num_samples,
              random_type=random_type,
              keep_mask=keep_mask,
              seed=seed,
              skip=skip,
              tolerance=tolerance,
              precompute_normal_draws=precompute_normal_draws,
              normal_draws=normal_draws,
          )
  
file_path: tf-quant-finance/tf_quant_finance/models/heston/heston_model.py
imports: from typing import Union, Callable, Optional
  import numpy
  import tensorflow.compat.v2
  from tf_quant_finance import types
  from tf_quant_finance import utils
  from tf_quant_finance.math import piecewise
  from tf_quant_finance.math import random_ops
  from tf_quant_finance.models import generic_ito_process
  from tf_quant_finance.models import utils
label_desc: Use image node_id 2 for calling the HestonModel obj's underlying member method code with example usage: obj.sample_paths(times, initial_state, num_samples, random_type, seed, time_step, skip, tolerance, num_time_steps, precompute_normal_draws, times_grid, normal_draws, name) and returns: self