code: def _nc2_cdf_abramowitz_and_stegun(x, df, noncentrality):
      """Computes the CDF of a noncentral chi2 random variable.
  
      Computation is performed according to Eq (26.4.25) in
      Abramowitz, M., Stegun, I. A., & Romer, R. H. (1988).
      Handbook of mathematical functions with formulas, graphs,
      and mathematical tables.
  
      Args:
        x: point at which CDF is to be evaluated.
        df: `tf.Tensor` of the degrees of freedom of the distribution.
        noncentrality: `tf.Tensor` of the noncentrality parameter of the
          distribution.
  
      Returns:
        `tf.Tensor` of the CDF evaluated at x.
      """
  
      dtype = df.dtype
      numpy_dtype = dtype_util.as_numpy_dtype(dtype)
      log_eps_abs = tf.math.log(numpy_dtype(np.finfo(numpy_dtype).eps))
  
      # This can be set to something a bit larger (e.g. twice the type's machine
      # epsilon) if we want to speed up the calculation in the tails,
      # at the cost of potentially quite wrong answers in the far tails.
      # SciPy uses log(1e-300) = -690 on 64 bit precision.
      log_eps_s = -80.0
  
      below_precision_mask = log_eps_abs > _log_cdf_chernoff_bound(
          x, df, noncentrality
      )
  
      # At the end, we will just set the dimensions with very low
      # noncentrality using the CDF of the standard chi2
      small_noncentrality_mask = noncentrality < 1e-10
  
      nc_over_2 = noncentrality / 2.0
      x_over_2 = x / 2.0
  
      # Index of the term with the highest weight in the sum from Eq (26.4.25)
      central_index = tf.math.floor(nc_over_2)
  
      # Bump 0 indices to 1
      central_index = central_index + tf.where(
          tf.math.equal(central_index, 0.0),
          numpy_dtype(1.0),
          numpy_dtype(0.0),
      )
  
      # Calculate the "central" term in the series
      log_central_weight = tf.math.xlogy(central_index, nc_over_2)
      log_central_weight = log_central_weight - nc_over_2
      log_central_weight = log_central_weight - tf.math.lgamma(
          central_index + 1.0
      )
  
      central_weight = tf.math.exp(log_central_weight)
  
      central_df_over_2 = 0.5 * df + central_index
  
      central_index = central_index * tf.ones_like(x)
      central_weight = central_weight * tf.ones_like(x)
  
      # Wilson-Hilferty transform
      # For large values of `df`, the Chi2 CDF of x is very well approximated
      # by the CDF of a Gaussian with mean 1 - 2 / (9 df) and variance 2 / (9 df)
      # evaluated at(x / df)^{1/3}.
      #
      # The rationale of using it here is that for `df`s larger than 1e3 it is
      # more numerically stable and accurate to use the Gaussian WH transform than
      # to evaluate the Chi2 CDF directly
      central_df_var_term = 1.0 / central_df_over_2 / 9.0
  
      wilson_hilferty_x = (x_over_2 / central_df_over_2) ** (1.0 / 3.0)
      wilson_hilferty_x = wilson_hilferty_x - (
          1.0 - central_df_var_term
      )
      wilson_hilferty_x = wilson_hilferty_x / tf.math.sqrt(
          central_df_var_term
      )
  
      # Compute the central chi2 probability
      central_chi2_prob = tf.where(
          central_df_over_2 < 1e3,
          tf.math.igamma(central_df_over_2, x_over_2),
          special_math.ndtr(wilson_hilferty_x),
      )
  
      # Prob will contain the return value of the function
      prob = central_weight * central_chi2_prob
  
      # Calculate adjustment terms to the chi2 probability above.
      # This means that `tf.math.igamma` only needs to be called once, the rest
      # of the CDFs can be calculated using the adjustment.
      log_adjustment_term = tf.math.xlogy(central_df_over_2, x_over_2)
      log_adjustment_term = (
          log_adjustment_term
          - x_over_2
          - tf.math.lgamma(central_df_over_2 + 1.0)
      )
      central_adjustment_term = tf.math.exp(log_adjustment_term)
  
      # Now, sum the series "backwards" from the central term
      def backwards_summation_loop_body(
          index, weight, adj_term, total_adj, prob
      ):
          update_mask = (
              ~below_precision_mask
              & (index > 0.0)
              & (
                  tf.math.log(weight) + tf.math.log(adj_term)
                  > log_eps_s
              )
          )
  
          df_over_2 = 0.5 * df + index
  
          adj_term = adj_term * tf.where(
              update_mask, df_over_2 / x_over_2, 1.0
          )
          total_adj = total_adj + tf.where(update_mask, adj_term, 0.0)
  
          adjusted_prob = central_chi2_prob + total_adj
          weight = weight * tf.where(
              update_mask, index / nc_over_2, 1.0
          )
  
          prob_term = weight * adjusted_prob
          prob = prob + tf.where(update_mask, prob_term, 0.0)
  
          index = index - tf.cast(
              tf.where(update_mask, 1.0, 0.0), dtype
          )
  
          return index, weight, adj_term, total_adj, prob
  
      def backwards_summation_loop_cond(
          index, weight, adj_term, total_adj, prob
      ):
          return tf.reduce_any(
              ~below_precision_mask
              & (index > 0.0)
              & (
                  tf.math.log(weight) + tf.math.log(adj_term)
                  > log_eps_s
              )
          )
  
      _, _, _, _, prob = tf.while_loop(
          cond=backwards_summation_loop_cond,
          body=backwards_summation_loop_body,
          loop_vars=(
              central_index,
              central_weight,
              central_adjustment_term,
              tf.zeros_like(central_adjustment_term),
              prob,
          ),
      )
  
      # Now, sum the series "forwards" from the central term
      def forwards_summation_loop_body(
          index, weight, adj_term, total_adj, prob
      ):
          update_mask = ~below_precision_mask & (
              tf.math.log(weight) + tf.math.log(adj_term) > log_eps_s
          )
  
          weight = weight * tf.where(
              update_mask, nc_over_2 / (index + 1.0), 1.0
          )
          adjusted_prob = central_chi2_prob - total_adj
  
          prob_term = weight * adjusted_prob
          prob = prob + tf.where(update_mask, prob_term, 0.0)
  
          index = tf.where(update_mask, index + 1.0, index)
          df_over_2 = 0.5 * df + index
          adj_term = adj_term * tf.where(
              update_mask, x_over_2 / df_over_2, 1.0
          )
          total_adj = total_adj + tf.where(update_mask, adj_term, 0.0)
  
          return index, weight, adj_term, total_adj, prob
  
      def forwards_summation_loop_cond(
          index, weight, adj_term, total_adj, prob
      ):
          return tf.reduce_any(
              ~below_precision_mask
              & (
                  tf.math.log(weight) + tf.math.log(adj_term)
                  > log_eps_s
              )
          )
  
      _, _, _, _, prob = tf.while_loop(
          cond=forwards_summation_loop_cond,
          body=forwards_summation_loop_body,
          loop_vars=(
              central_index,
              central_weight,
              central_adjustment_term,
              central_adjustment_term,
              prob,
          ),
      )
  
      prob = tf.where(
          small_noncentrality_mask,
          tf.math.igamma(0.5 * df, 0.5 * x),
          prob,
      )
  
      x_above_mean_mask = x > (df + noncentrality)
  
      prob = tf.where(
          below_precision_mask & x_above_mean_mask,
          tf.ones_like(x),
          prob,
      )
  
      prob = tf.where(
          below_precision_mask & ~x_above_mean_mask,
          tf.zeros_like(x),
          prob,
      )
  
      return prob
  
imports: import numpy
  import tensorflow.compat.v2
  from tensorflow_probability.python.bijectors import softplus
  from tensorflow_probability.python.distributions import chi2
  from tensorflow_probability.python.distributions import distribution
  from tensorflow_probability.python.distributions import gamma
  from tensorflow_probability.python.distributions import poisson
  from tensorflow_probability.python.internal import assert_util
  from tensorflow_probability.python.internal import custom_gradient
  from tensorflow_probability.python.internal import distribution_util
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import parameter_properties
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import reparameterization
  from tensorflow_probability.python.internal import samplers
  from tensorflow_probability.python.internal import special_math
  from tensorflow_probability.python.internal import tensor_util
  from tensorflow_probability.python.math import bessel
  from tensorflow_probability.python.math import generic
  from tensorflow_probability.python.math import root_search
  import tensorflow_probability.python.random
label_desc: Use image node_id 2 for calling a global function with example usage: _nc2_cdf_abramowitz_and_stegun(x, df, noncentrality) and returns: prob, index,  weight,  adj_term,  total_adj,  prob, tf, index,  weight,  adj_term,  total_adj,  prob, tf