code: def _compute_general_continued_fraction(
      max_iterations,
      numerator_denominator_args_list,
      tolerance=None,
      partial_numerator_fn=None,
      partial_denominator_fn=None,
      dtype=tf.float32,
      name=None,
  ):
      """Compute a general continued fraction.
  
      Given at least one of `partial_numerator_fn` and `partial_denominator_fn`,
      compute the continued fraction associated with it via the forward recurrence.
  
      Let `a_i = partial_numerator_fn` and `b_i = partial_denominator_fn`. Then,
      this evaluates the infinite continued fraction:
  
      ```result = a_1 / (b_1 + a_2 / (b_2 + a_3 / (b_3 .....)```.
  
      If `partial_numerator_fn` or `partial_denominator_fn` are not given, then
      `a_i` (respectively `b_i`) are assumed to be 1. However one must be given.
  
      NOTE: Use this with caution. Forward recursion doesn't have numerical
      stability guarantees, compared to backward recursion.
  
  
      Args:
        max_iterations: Integer `Tensor` specifying the maximum number of terms to
          use.
        numerator_denominator_args_list: Arguments to pass in to
          `partial_numerator_fn` and `partial_denominator_fn`.
        tolerance: Float `Tensor` specifying the maximum acceptable tolerance
          between convergents. If unset, convergence is dictated by the number
          of iterations.
          Default value: `None`.
        partial_numerator_fn: Python callable that takes in as its first argument
          the current iteration count (an integer >= 1), and a list of *args, and
          returns a `Tensor`. These are used as partial numerators for the
          continued fraction.
          Default value: `None`.
        partial_denominator_fn: Python callable that takes in as its first argument
          the current iteration count (an integer >= 1), and a list of *args, and
          returns a `Tensor`. These are used as partial denominators for the
          continued fraction.
          Default value: `None`.
        dtype: The default dtype of the continued fraction. Default: `float32`.
        name: A name for the operation (optional).
          Default value: `None` (i.e., 'continued_fraction').
  
      Returns:
        Continued fraction computed to `max_iterations` iterations and/or
        up to absolute error `tolerance`.
  
      #### References
      [1]: Walter Gautschi and Josef Slavik. On the Computation of Modified
           Bessel Function Ratios. http://www.jstor.com/stable/2006491
      """
      with tf.name_scope(name or "continued_fraction"):
          dtype = dtype_util.common_dtype(
              numerator_denominator_args_list, dtype
          )
  
          if (partial_numerator_fn is None) and (
              partial_denominator_fn is None
          ):
              raise ValueError(
                  "Expect one of `partial_numerator_fn` and "
                  "`partial_denominator_fn` to be set."
              )
  
          def _continued_fraction_one_step(
              unused_should_stop,
              numerator,
              previous_numerator,
              denominator,
              previous_denominator,
              iteration_count,
          ):
              partial_denominator = 1.0
              if partial_denominator_fn:
                  partial_denominator = partial_denominator_fn(
                      iteration_count, *numerator_denominator_args_list
                  )
              new_numerator = partial_denominator * numerator
              new_denominator = partial_denominator * denominator
  
              partial_numerator = 1.0
              if partial_numerator_fn:
                  partial_numerator = partial_numerator_fn(
                      iteration_count, *numerator_denominator_args_list
                  )
              new_numerator = (
                  new_numerator + partial_numerator * previous_numerator
              )
              new_denominator = (
                  new_denominator
                  + partial_numerator * previous_denominator
              )
  
              should_stop_next = iteration_count > max_iterations
  
              if tolerance is not None:
                  # We can use a more efficient computation when the partial numerators
                  # are 1.
                  if partial_numerator_fn is None:
                      # We now want to compute to relative error between the fraction at
                      # this iteration, vs. the previous iteration.
                      # Let h_i be the numerator and k_i the denominator, and a_i be the
                      # i-th term.
                      # h_i / k_i - h_{i-1} / k_{i-1} =
                      # (h_i * k_{i - 1} - h_{i - 1} * k_i) / (k_i * k_{i - 1}) =
                      # ((a_i h_{i - 1} + h_{i - 2}) * k_{i - 1} -
                      # (a_i k_{i - 1} + k_{i - 2}) * h_{i - 1}) / (k_i * k_{i - 1}) =
                      # -(h_{i - 1} * k_{i - 2} - h_{i - 2} * k_{i - 1}) / (k_i * k_{i - 1})
                      # This suggests we should prove something about the numerator
                      # inductively, and indeed
                      # (h_i * k_{i - 1} - h_{i - 1} * k_i) = (-1)**i
                      delta = tf.math.reciprocal(
                          new_denominator * denominator
                      )
                  # We actually need to compute the difference of fractions.
                  else:
                      delta = (
                          new_numerator / new_denominator
                          - numerator / denominator
                      )
  
                  converged = tf.math.abs(delta) <= tolerance
                  should_stop_next = (
                      tf.reduce_all(converged) | should_stop_next
                  )
              return (
                  should_stop_next,
                  new_numerator,
                  numerator,
                  new_denominator,
                  denominator,
                  iteration_count + 1.0,
              )
  
          # This is to infer the correct shape of tensors
          if partial_denominator_fn:
              term = partial_denominator_fn(
                  1.0, *numerator_denominator_args_list
              )
          else:
              term = partial_numerator_fn(
                  1.0, *numerator_denominator_args_list
              )
  
          zeroth_numerator = tf.ones_like(term, dtype=dtype)
          zeroth_denominator = tf.zeros_like(term, dtype=dtype)
          first_numerator = tf.zeros_like(term, dtype=dtype)
          first_denominator = tf.ones_like(term, dtype=dtype)
  
          results = tf.while_loop(
              cond=lambda stop, *_: ~stop,
              body=_continued_fraction_one_step,
              loop_vars=(
                  False,
                  first_numerator,
                  zeroth_numerator,
                  first_denominator,
                  zeroth_denominator,
                  tf.cast(1.0, dtype=dtype),
              ),
          )
          return results[1] / results[3]
  
imports: import numpy
  import tensorflow.compat.v2
  from tensorflow_probability.python.internal import custom_gradient
  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: _compute_general_continued_fraction(max_iterations, numerator_denominator_args_list, tolerance, partial_numerator_fn, partial_denominator_fn, dtype, name) and returns: unknown, should_stop_next,  new_numerator,  numerator,  new_denominator,  denominator,  unknown