code: def _hyp2f1_fraction(a, b, c, z):
      """Compute 2F1(a, b, c, z) by using a running fraction."""
      with tf.name_scope("hyp2f1_fraction"):
          dtype = dtype_util.common_dtype([a, b, c, z], tf.float32)
          a = tf.convert_to_tensor(a, dtype=dtype)
          b = tf.convert_to_tensor(b, dtype=dtype)
          c = tf.convert_to_tensor(c, dtype=dtype)
          z = tf.convert_to_tensor(z, dtype=dtype)
          np_finfo = np.finfo(dtype_util.as_numpy_dtype(dtype))
          tolerance = tf.cast(np_finfo.resolution, dtype=dtype)
  
          broadcast_shape = functools.reduce(
              ps.broadcast_shape, [ps.shape(x) for x in [a, b, c, z]]
          )
  
          def hypergeometric_fraction(
              should_stop,
              index,
              numerator_term0,
              numerator_term1,
              denominator,
              fraction,
              previous_fraction,
              two_before_fraction,
          ):
              new_numerator_term0 = (
                  numerator_term0 + numerator_term1
              ) * index
              new_numerator_term1 = (
                  numerator_term1
                  * (a + index - 1.0)
                  * (b + index - 1.0)
                  * z
              ) / (c + index - 1.0)
              new_denominator = denominator * index
  
              largest_term = tf.math.maximum(
                  tf.math.maximum(
                      tf.math.abs(new_numerator_term0),
                      tf.math.abs(new_numerator_term1),
                  ),
                  tf.math.abs(new_denominator),
              )
  
              should_rescale = largest_term > 100
  
              # Rescale to prevent overflow.
              new_numerator_term0 = tf.where(
                  should_rescale,
                  new_numerator_term0 / largest_term,
                  new_numerator_term0,
              )
              new_numerator_term1 = tf.where(
                  should_rescale,
                  new_numerator_term1 / largest_term,
                  new_numerator_term1,
              )
              new_denominator = tf.where(
                  should_rescale,
                  new_denominator / largest_term,
                  new_denominator,
              )
  
              new_fraction = (
                  new_numerator_term0 + new_numerator_term1
              ) / new_denominator
              new_fraction = tf.where(
                  should_stop, fraction, new_fraction
              )
  
              # When a or be is near a negative integer n, it's possibly the term is
              # small because we are computing (a + n) * (b + n) in the numerator.
              # Checking that three consecutive terms are small compared their
              # corresponding sum will let us avoid this error.
              should_stop = (
                  (
                      tf.math.abs(new_fraction - fraction)
                      < tolerance * tf.math.abs(fraction)
                  )
                  & (
                      tf.math.abs(fraction - previous_fraction)
                      < tolerance * tf.math.abs(previous_fraction)
                  )
                  & (
                      tf.math.abs(
                          previous_fraction - two_before_fraction
                      )
                      < tolerance * tf.math.abs(two_before_fraction)
                  )
              )
              return (
                  tf.logical_or(should_stop, index > 1000.0),
                  index + 1.0,
                  new_numerator_term0,
                  new_numerator_term1,
                  new_denominator,
                  new_fraction,
                  fraction,
                  previous_fraction,
              )
  
          (_, _, _, _, _, fraction, _, _) = tf.while_loop(
              cond=lambda stop, *_: tf.reduce_any(~stop),
              body=hypergeometric_fraction,
              loop_vars=(
                  tf.zeros(broadcast_shape, dtype=tf.bool),
                  tf.cast(1.0, dtype=dtype),
                  tf.zeros(broadcast_shape, dtype=dtype),
                  tf.ones(broadcast_shape, dtype=dtype),
                  tf.ones(broadcast_shape, dtype=dtype),
                  # Only the previous term and taylor sum are used for computation.
                  # The rest are used for checking convergence. We can safely set
                  # these to zero.
                  tf.ones(broadcast_shape, dtype=dtype),
                  tf.zeros(broadcast_shape, dtype=dtype),
                  tf.zeros(broadcast_shape, dtype=dtype),
              ),
          )
          return fraction
  
file_path: probability/tensorflow_probability/python/math/hypergeometric.py
imports: import functools
  import numpy
  import tensorflow.compat.v2
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.math import generic
label_desc: Use image node_id 2 for calling a global function with example usage: _hyp2f1_fraction(a, b, c, z) and returns: fraction, tf,  unknown,  new_numerator_term0,  new_numerator_term1,  new_denominator,  new_fraction,  fraction,  previous_fraction