class_docstr: Implements the SABR model defined by the following equations.
  
  ```
    dF_t = v_t * F_t ^ beta * dW_{F,t}
    dv_t = volvol * v_t * dW_{v,t}
    dW_{F,t} * dW_{v,t} = rho * dt
  ```
  
  `F_t` is the forward. `v_t` is volatility. `beta` is the CEV parameter.
  `volvol` is volatility of volatility. `W_{F,t}` and `W_{v,t}` are two
  correlated Wiener processes with instantaneous correlation `rho`.
  
  This model supports time dependent parameters. In other words, `beta`,
  `volvol`, and `rho` can be functions of time. When all of these parameters are
  constants, `beta` != 1, and `enable_unbiased_sampling` is True, the almost
  exact sampling procedure described in Ref [1] will be used. Otherwise it will
  default to Euler sampling.
  
  ### Example. Simple example with time independent params.
  
  ```none
    process = sabr.SabrModel(beta=0.5, volvol=1, rho=0.5, dtype=tf.float32)
    paths = process.sample_paths(
        initial_forward=100,
        initial_volatility=0.05,
        times=[1,2,5],
        time_step=0.01,
        num_samples=10000)
  ```
  
  ### Example 2. Callable volvol and correlation coefficient.
  
  ```none
    volvol_fn = lambda t: tf.where(t < 2, 0.5, 1.0)
    rho_fn = lambda t: tf.where(t < 1, 0., 0.5)
  
    process = sabr.SabrModel(
        beta=0.5, volvol=volvol_fn, rho=rho_fn, dtype=tf.float32)
  
    # Any time where parameters vary drastically (e.g. t=2 above) should be
    # added to `times` to reduce numerical error.
    paths = process.sample_paths(
        initial_forward=100,
        initial_volatility=0.05,
        times=[1,2,5],
        time_step=0.01,
        num_samples=10000)
  ```
  
  ### References:
  [1]: Chen B, Oosterlee CW, Van Der Weide H. Efficient unbiased simulation
  scheme for the SABR stochastic volatility model. 2011
  Link: http://ta.twi.tudelft.nl/mf/users/oosterle/oosterlee/SABRMC.pdf
  [2]: Andersen, Leif B.G., Efficient Simulation of the Heston Stochastic
  Volatility Model (January 23, 2007). Available at SSRN:
  https://ssrn.com/abstract=946405 or http://dx.doi.org/10.2139/ssrn.946405
class_docstr_tok: ["Implements","the","SABR","model","defined","by","the","following","equations",".","``","`","dF_t","=","v_t","*","F_t","^","beta","*","dW_","{","F",",","t","}","dv_t","=","volvol","*","v_t","*","dW_","{","v",",","t","}","dW_","{","F",",","t","}","*","dW_","{","v",",","t","}","=","rho","*","dt","``","`","`","F_t","`","is","the","forward",".","`","v_t","`","is","volatility",".","`","beta","`","is","the","CEV","parameter",".","`","volvol","`","is","volatility","of","volatility",".","`","W_","{","F",",","t","}","`","and","`","W_","{","v",",","t","}","`","are","two","correlated","Wiener","processes","with","instantaneous","correlation","`","rho","`",".","This","model","supports","time","dependent","parameters",".","In","other","words",",","`","beta","`",",","`","volvol","`",",","and","`","rho","`","can","be","functions","of","time",".","When","all","of","these","parameters","are","constants",",","`","beta","`","!","=","1",",","and","`","enable_unbiased_sampling","`","is","True",",","the","almost","exact","sampling","procedure","described","in","Ref","[","1","]","will","be","used",".","Otherwise","it","will","default","to","Euler","sampling",".","#","#","#","Example",".","Simple","example","with","time","independent","params",".","``","`","none","process","=","sabr.SabrModel","(","beta=0.5",",","volvol=1",",","rho=0.5",",","dtype=tf.float32",")","paths","=","process.sample_paths","(","initial_forward=100",",","initial_volatility=0.05",",","times=","[","1,2,5","]",",","time_step=0.01",",","num_samples=10000",")","``","`","#","#","#","Example","2",".","Callable","volvol","and","correlation","coefficient",".","``","`","none","volvol_fn","=","lambda","t",":","tf.where","(","t","<","2",",","0.5",",","1.0",")","rho_fn","=","lambda","t",":","tf.where","(","t","<","1",",","0.",",","0.5",")","process","=","sabr.SabrModel","(","beta=0.5",",","volvol=volvol_fn",",","rho=rho_fn",",","dtype=tf.float32",")","#","Any","time","where","parameters","vary","drastically","(","e.g",".","t=2","above",")","should","be","#","added","to","`","times","`","to","reduce","numerical","error",".","paths","=","process.sample_paths","(","initial_forward=100",",","initial_volatility=0.05",",","times=","[","1,2,5","]",",","time_step=0.01",",","num_samples=10000",")","``","`","#","#","#","References",":","[","1","]",":","Chen","B",",","Oosterlee","CW",",","Van","Der","Weide","H.","Efficient","unbiased","simulation","scheme","for","the","SABR","stochastic","volatility","model",".","2011","Link",":","http",":","\/\/ta.twi.tudelft.nl\/mf\/users\/oosterle\/oosterlee\/SABRMC.pdf","[","2","]",":","Andersen",",","Leif","B.G.",",","Efficient","Simulation","of","the","Heston","Stochastic","Volatility","Model","(","January","23",",","2007",")",".","Available","at","SSRN",":","https",":","\/\/ssrn.com\/abstract=946405","or","http",":","\/\/dx.doi.org\/10.2139\/ssrn.946405"]
docstr: Returns a sample of paths from the process.
  
  Generates samples of paths from the process at the specified time points.
  
  Currently only supports absorbing boundary conditions.
  
  Args:
    initial_forward: Initial value of the forward. A scalar real tensor.
    initial_volatility: Initial value of the volatilities. A scalar real
      tensor.
    times: The times at which the path points are to be evaluated. Rank 1
      `Tensor` of positive real values. This `Tensor` should be sorted in
      ascending order.
    time_step: Positive Python float or a scalar `Tensor `to denote time
      discretization parameter.
    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.
    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.
      Default value: `0`.
    validate_args: Python `bool`. When `True`, input `Tensor's` are checked
      for validity despite possibly degrading runtime performance. The checks
      verify that `times` is strictly increasing. When `False` invalid inputs
      may silently render incorrect outputs. Default value: False.
    precompute_normal_draws: Python bool. Indicates whether the noise
      increments are precomputed upfront (see `models.euler_sampling.sample`).
      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`.
    name: str. The name to give this op. If not supplied, default name of
      `sample_paths` is used.
  
  Returns:
    A `Tensor`s of shape [num_samples, k, 2] where `k` is the size of the
    `times`.  The first values in `Tensor` are the simulated forward `F(t)`,
    whereas the second values in `Tensor` are the simulated volatility
    trajectories `V(t)`.
docstr_tok: ["Returns","a","sample","of","paths","from","the","process",".","Generates","samples","of","paths","from","the","process","at","the","specified","time","points",".","Currently","only","supports","absorbing","boundary","conditions",".","Args",":","initial_forward",":","Initial","value","of","the","forward",".","A","scalar","real","tensor",".","initial_volatility",":","Initial","value","of","the","volatilities",".","A","scalar","real","tensor",".","times",":","The","times","at","which","the","path","points","are","to","be","evaluated",".","Rank","1","`","Tensor","`","of","positive","real","values",".","This","`","Tensor","`","should","be","sorted","in","ascending","order",".","time_step",":","Positive","Python","float","or","a","scalar","`","Tensor","`","to","denote","time","discretization","parameter",".","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",".","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",".","Default","value",":","`","0","`",".","validate_args",":","Python","`","bool","`",".","When","`","True","`",",","input","`","Tensor","'s","`","are","checked","for","validity","despite","possibly","degrading","runtime","performance",".","The","checks","verify","that","`","times","`","is","strictly","increasing",".","When","`","False","`","invalid","inputs","may","silently","render","incorrect","outputs",".","Default","value",":","False",".","precompute_normal_draws",":","Python","bool",".","Indicates","whether","the","noise","increments","are","precomputed","upfront","(","see","`","models.euler_sampling.sample","`",")",".","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","`",".","name",":","str",".","The","name","to","give","this","op",".","If","not","supplied",",","default","name","of","`","sample_paths","`","is","used",".","Returns",":","A","`","Tensor","`","s","of","shape","[","num_samples",",","k",",","2","]","where","`","k","`","is","the","size","of","the","`","times","`",".","The","first","values","in","`","Tensor","`","are","the","simulated","forward","`","F","(","t",")","`",",","whereas","the","second","values","in","`","Tensor","`","are","the","simulated","volatility","trajectories","`","V","(","t",")","`","."]
code: def sample_paths(
      self,
      initial_forward: types.RealTensor,
      initial_volatility: types.RealTensor,
      times: types.RealTensor,
      time_step: types.RealTensor,
      num_samples: types.RealTensor = 1,
      random_type: Optional[random.RandomType] = None,
      seed: Optional[types.IntTensor] = None,
      skip: types.IntTensor = 0,
      validate_args: bool = False,
      precompute_normal_draws: bool = True,
      name: Optional[str] = None,
  ):
      """Returns a sample of paths from the process.
  
      Generates samples of paths from the process at the specified time points.
  
      Currently only supports absorbing boundary conditions.
  
      Args:
        initial_forward: Initial value of the forward. A scalar real tensor.
        initial_volatility: Initial value of the volatilities. A scalar real
          tensor.
        times: The times at which the path points are to be evaluated. Rank 1
          `Tensor` of positive real values. This `Tensor` should be sorted in
          ascending order.
        time_step: Positive Python float or a scalar `Tensor `to denote time
          discretization parameter.
        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.
        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.
          Default value: `0`.
        validate_args: Python `bool`. When `True`, input `Tensor's` are checked
          for validity despite possibly degrading runtime performance. The checks
          verify that `times` is strictly increasing. When `False` invalid inputs
          may silently render incorrect outputs. Default value: False.
        precompute_normal_draws: Python bool. Indicates whether the noise
          increments are precomputed upfront (see `models.euler_sampling.sample`).
          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`.
        name: str. The name to give this op. If not supplied, default name of
          `sample_paths` is used.
  
      Returns:
        A `Tensor`s of shape [num_samples, k, 2] where `k` is the size of the
        `times`.  The first values in `Tensor` are the simulated forward `F(t)`,
        whereas the second values in `Tensor` are the simulated volatility
        trajectories `V(t)`.
      """
      name = name or self._name + "_sample_path"
      with tf.name_scope(name):
          initial_forward = tf.convert_to_tensor(
              initial_forward, self._dtype, name="initial_forward"
          )
          initial_volatility = tf.convert_to_tensor(
              initial_volatility, self._dtype, name="initial_volatility"
          )
          times = tf.convert_to_tensor(times, self._dtype, name="times")
          time_step = tf.convert_to_tensor(
              time_step, self._dtype, name="time_step"
          )
  
          if validate_args:
              self.control_dependencies.append(
                  tf.compat.v1.debugging.Assert(
                      tf.compat.v1.debugging.is_strictly_increasing(
                          times
                      ),
                      [times],
                  )
              )
  
          with tf.compat.v1.control_dependencies(
              self.control_dependencies
          ):
              initial_forward += self._shift
              if self._enable_unbiased_sampling and not (
                  _is_callable(self._beta)
                  or _is_callable(self._volvol)
                  or _is_callable(self._rho)
                  or self._beta == 1
              ):
                  paths = self._sabr_sample_paths(
                      initial_forward,
                      initial_volatility,
                      times,
                      time_step,
                      num_samples,
                      random_type,
                      seed,
                      precompute_normal_draws,
                      skip=skip,
                  )
              else:
                  paths = super(SabrModel, self).sample_paths(
                      times,
                      num_samples,
                      [initial_forward, initial_volatility],
                      random_type,
                      seed,
                      skip=skip,
                      time_step=time_step,
                      precompute_normal_draws=precompute_normal_draws,
                  )
  
              forwards = tf.expand_dims(
                  paths[:, :, 0] - self._shift, axis=-1
              )
              volatilities = tf.expand_dims(paths[:, :, 1], axis=-1)
  
              return tf.concat([forwards, volatilities], axis=-1)
  
file_path: tf-quant-finance/tf_quant_finance/models/sabr/sabr_model.py
imports: from typing import Optional
  import tensorflow.compat.v2
  from tf_quant_finance import types
  from tf_quant_finance import utils
  from tf_quant_finance.math import random_ops
  from tf_quant_finance.math.root_search.newton import root_finder
  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 SabrModel obj's underlying member method code with example usage: obj.sample_paths(initial_forward, initial_volatility, times, time_step, num_samples, random_type, seed, skip, validate_args, precompute_normal_draws, name) and returns: tf