code: def _sample(
      *,
      dim,
      batch_shape,
      drift_fn,
      volatility_fn,
      times,
      keep_mask,
      num_requested_times,
      num_samples,
      initial_state,
      random_type,
      seed,
      swap_memory,
      skip,
      precompute_normal_draws,
      watch_params,
      time_indices,
      normal_draws,
      dtype,
  ):
      """Returns a sample of paths from the process using Euler method."""
      dt = times[1:] - times[:-1]
      sqrt_dt = tf.sqrt(dt)
      # current_state.shape = batch_shape + [num_samples, dim]
      current_state = initial_state + tf.zeros(
          [num_samples, dim], dtype=dtype
      )
      steps_num = tff_utils.get_shape(dt)[-1]
      wiener_mean = None
      if normal_draws is None:
          # In order to use low-discrepancy random_type we need to generate the
          # sequence of independent random normals upfront. We also precompute random
          # numbers for stateless random type in order to ensure independent samples
          # for multiple function calls with different seeds.
          if precompute_normal_draws or random_type in (
              random.RandomType.SOBOL,
              random.RandomType.HALTON,
              random.RandomType.HALTON_RANDOMIZED,
              random.RandomType.STATELESS,
              random.RandomType.STATELESS_ANTITHETIC,
          ):
              normal_draws = utils.generate_mc_normal_draws(
                  num_normal_draws=dim,
                  num_time_steps=steps_num,
                  num_sample_paths=num_samples,
                  batch_shape=batch_shape,
                  random_type=random_type,
                  dtype=dtype,
                  seed=seed,
                  skip=skip,
              )
              wiener_mean = None
          else:
              # If pseudo or anthithetic sampling is used, proceed with random sampling
              # at each step.
              wiener_mean = tf.zeros(
                  (dim,), dtype=dtype, name="wiener_mean"
              )
              normal_draws = None
      if watch_params is None:
          # Use while_loop if `watch_params` is not passed
          return _while_loop(
              steps_num=steps_num,
              current_state=current_state,
              drift_fn=drift_fn,
              volatility_fn=volatility_fn,
              wiener_mean=wiener_mean,
              num_samples=num_samples,
              times=times,
              dt=dt,
              sqrt_dt=sqrt_dt,
              keep_mask=keep_mask,
              num_requested_times=num_requested_times,
              swap_memory=swap_memory,
              random_type=random_type,
              seed=seed,
              normal_draws=normal_draws,
              dtype=dtype,
          )
      else:
          # Use custom for_loop if `watch_params` is specified
          return _for_loop(
              batch_shape=batch_shape,
              steps_num=steps_num,
              current_state=current_state,
              drift_fn=drift_fn,
              volatility_fn=volatility_fn,
              wiener_mean=wiener_mean,
              num_samples=num_samples,
              times=times,
              dt=dt,
              sqrt_dt=sqrt_dt,
              time_indices=time_indices,
              keep_mask=keep_mask,
              watch_params=watch_params,
              random_type=random_type,
              seed=seed,
              normal_draws=normal_draws,
          )
  
file_path: tf-quant-finance/tf_quant_finance/models/euler_sampling.py
imports: from typing import Callable, List, Optional
  import tensorflow.compat.v2
  from tf_quant_finance import types
  from tf_quant_finance import utils
  from tf_quant_finance.math import custom_loops
  from tf_quant_finance.math import random
  from tf_quant_finance.models import utils
label_desc: Use image node_id 2 for calling a global function with example usage: _sample() and returns: _while_loop, _for_loop