class_docstr: Cox–Ingersoll–Ross model.
  
  Represents the Ito process:
  
  ```None
    dX_i(t) = (a - k*X_i(t)) * dt +  sigma * sqrt(X_i(t)) * dW_i(t)
  ```
  where
    a / k: Corresponds to the long term mean.
    k: Corresponds to the speed of reversion.
    sigma: Corresponds to the instantaneous volatility.
  
  See [1] for details.
  
  #### References:
    [1]: A. Alfonsi. Affine Diffusions and Related Processes: Simulation,
      Theory and Applications
class_docstr_tok: ["Cox\u2013Ingersoll\u2013Ross","model",".","Represents","the","Ito","process",":","``","`","None","dX_i","(","t",")","=","(","a","-","k","*","X_i","(","t",")",")","*","dt","+","sigma","*","sqrt","(","X_i","(","t",")",")","*","dW_i","(","t",")","``","`","where","a","\/","k",":","Corresponds","to","the","long","term","mean",".","k",":","Corresponds","to","the","speed","of","reversion",".","sigma",":","Corresponds","to","the","instantaneous","volatility",".","See","[","1","]","for","details",".","#","#","#","#","References",":","[","1","]",":","A.","Alfonsi",".","Affine","Diffusions","and","Related","Processes",":","Simulation",",","Theory","and","Applications"]
docstr: Returns a sample of paths from the process.
docstr_tok: ["Returns","a","sample","of","paths","from","the","process","."]
code: def _sample_paths(
      self,
      theta,
      mean_reversion,
      sigma,
      element_shape,
      times,
      num_requested_times,
      initial_state,
      num_samples,
      random_type,
      seed,
  ):
      """Returns a sample of paths from the process."""
      times = tf.concat([[0], times], -1)
      # Time increments
      # Shape [num_requested_times, 1, 1]
      dts = tf.expand_dims(
          tf.expand_dims(times[1:] - times[:-1], axis=-1), axis=-1
      )
      (
          poisson_fn,
          gamma_fn,
          poisson_seed_fn,
          gamma_seed_fn,
      ) = self._get_distributions(random_type)
  
      def _sample_at_time(i, update_idx, current_x, samples):
          dt = dts[i]
          # Shape batch_shape + [num_samples, dim]
          zeta = tf.where(
              tf.math.equal(
                  mean_reversion, tf.zeros_like(mean_reversion)
              ),
              dt,
              (1 - tf.math.exp(-mean_reversion * dt)) / mean_reversion,
          )
          c = tf.math.divide_no_nan(
              tf.constant(4, dtype=self._dtype), sigma**2 * zeta
          )
          d = c * tf.math.exp(-mean_reversion * dt)
  
          poisson_rv = poisson_fn(
              shape=element_shape,
              lam=d * current_x / 2,
              seed=poisson_seed_fn(seed, i),
              dtype=self._dtype,
          )
  
          gamma_param_alpha = poisson_rv + 2 * theta / (sigma**2)
          gamma_param_beta = c / 2
  
          new_x = gamma_fn(
              shape=element_shape,
              alpha=gamma_param_alpha,
              beta=gamma_param_beta,
              seed=gamma_seed_fn(seed, i),
              dtype=self._dtype,
          )
          # `gamma_fn` outputs infinity when `c==0`
          new_x = tf.where(c > 0, new_x, current_x)
  
          samples = samples.write(i, new_x)
          return (i + 1, update_idx, new_x, samples)
  
      cond_fn = lambda i, *args: i < num_requested_times
      samples = tf.TensorArray(
          dtype=self._dtype,
          size=num_requested_times,
          element_shape=element_shape,
          clear_after_read=False,
      )
      _, _, _, samples = tf.while_loop(
          cond_fn,
          _sample_at_time,
          (0, 0, initial_state, samples),
          maximum_iterations=num_requested_times,
      )
  
      # Shape [num_requested_times, batch_shape..., num_samples, 1]
      samples = samples.stack()
      samples_rank = len(tff_utils.get_shape(samples))
      perm = [batch_idx for batch_idx in range(1, samples_rank - 2)] + [
          samples_rank - 2,
          0,
          samples_rank - 1,
      ]
      # Shape batch_shape + [num_samples, num_requested_times, 1]
      return tf.transpose(samples, perm=perm)
  
file_path: tf-quant-finance/tf_quant_finance/models/cir/cir_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.models import generic_ito_process
label_desc: Use image node_id 3 for calling the CirModel obj's underlying member method code with example usage: obj._sample_paths(theta, mean_reversion, sigma, element_shape, times, num_requested_times, initial_state, num_samples, random_type, seed) and returns: tf, unknown,  update_idx,  new_x,  samples