code: def _stdtr_partials(df, t):
      """Return the partial derivatives of `stdtr(df, t)`."""
      dtype = dtype_util.common_dtype([df, t], tf.float32)
      numpy_dtype = dtype_util.as_numpy_dtype(dtype)
      tiny = np.finfo(numpy_dtype).tiny
      eps = np.finfo(numpy_dtype).eps
      half = numpy_dtype(0.5)
      one = numpy_dtype(1.0)
  
      df, t = [
          tf.convert_to_tensor(param, dtype=dtype) for param in (df, t)
      ]
      broadcast_shape = functools.reduce(
          ps.broadcast_shape, [ps.shape(df), ps.shape(t)]
      )
      df, t = [
          tf.broadcast_to(param, broadcast_shape) for param in (df, t)
      ]
  
      # The gradient with respect to t can be computed more accurately and stably
      # using Student's t-distribution probability density function.
  
      stdtr_grad_t = tf.math.exp(log_prob(t, df, numpy_dtype(0.0), one))
  
      # For moderate df and relatively small t**2, or in case of large df, we use
      # automatic differentiation of the procedure _stdtr_asymptotic_expansion to
      # compute the gradient with respect to df.
  
      if numpy_dtype == np.float32:
          use_asymptotic_expansion = (
              (df >= 10.0) & (tf.math.square(t) < (16.0 * df - 5.0))
          ) | (df > 30.0)
      else:
          use_asymptotic_expansion = (
              (df >= 100.0) & (tf.math.square(t) < (0.1 * df - 5.0))
          ) | (df > 1000.0)
  
      abs_t = tf.math.abs(t)
      min_abs_t = half * df * tf.math.pow(tiny, numpy_dtype(0.25))
      t_is_tiny = abs_t < min_abs_t
      df_asymptotic_expansion = tf.where(
          use_asymptotic_expansion, df, one
      )
      t_asymptotic_expansion = tf.where(
          use_asymptotic_expansion,
          # Mask out tiny t so the gradient correctly propagates. When t is tiny,
          # second derivative of log1psquare(t * tf.math.rsqrt(df)) can be NaN.
          tf.where(
              t_is_tiny, tf.where(t < 0.0, -min_abs_t, min_abs_t), t
          ),
          one,
      )
  
      stdtr_grad_df = gradient.value_and_gradient(
          lambda z: _stdtr_asymptotic_expansion(  # pylint: disable=g-long-lambda
              z, t_asymptotic_expansion, numpy_dtype
          ),
          df_asymptotic_expansion,
      )[1]
      # Handle the case (abs_t < min_abs_t): we use a rough linear approximation.
      stdtr_grad_df = tf.where(
          t_is_tiny, stdtr_grad_df * abs_t, stdtr_grad_df
      )
  
      # Otherwise, the gradient with respect to df is evaluated using the partial
      # derivatives of betainc(a, b, x). For t < 0, we have:
      #   stdtr_grad_df = 0.5 * (betainc_grad_a * a_grad_df +
      #                          betainc_grad_x * x_grad_df)
      #                 = 0.5 * (betainc_grad_a * a_grad_df +
      #                          2. * stdtr_grad_t / x_grad_t * x_grad_df)
      #                 = 0.5 * (betainc_grad_a * a_grad_df -
      #                          stdtr_grad_t * t / df) ,
      # where a = 0.5 * df and x = df / (df + t**2). In above equation, the second
      # equality follows from the fact that:
      #   stdtr_grad_t = 0.5 * betainc_grad_x * x_grad_t , for t < 0.
      # To avoid rounding error when t**2 is small compared to df, we compute the
      # ratio df / (df + t**2) in the logarithmic space. If ratio > 0.99, we then
      # use the following symmetry relation:
      #   betainc(a, b, x) = 1 - betainc(b, a, 1 - x) .
  
      min_abs_t_betainc = tf.math.sqrt(
          df * eps * tf.math.reciprocal(one - eps)
      )
      t_is_small = abs_t < min_abs_t_betainc
      # Mask out small t so the gradient correctly propagates. When t is small,
      # ratio == 1 and one_minus_ratio < eps.
      abs_t_betainc = tf.where(t_is_small, min_abs_t_betainc, abs_t)
  
      raw_ratio = abs_t_betainc * tf.math.rsqrt(df)
      ratio = tf.math.exp(-numeric.log1psquare(raw_ratio))
      one_minus_ratio = tf.math.exp(
          -numeric.log1psquare(tf.math.reciprocal(raw_ratio))
      )
  
      # The maximum value for the ratio was set by experimentation.
      use_symmetry_relation = ratio > 0.99
      half_df = half * df
      a = tf.where(use_symmetry_relation, half, half_df)
      b = tf.where(use_symmetry_relation, half_df, half)
      x = tf.where(use_symmetry_relation, one_minus_ratio, ratio)
  
      # Prepare betainc inputs to make the evaluation of its gradients easier.
      use_betainc = ~use_asymptotic_expansion
      a = tf.where(use_betainc, a, half)
      b = tf.where(use_betainc, b, half)
      x = tf.where(use_betainc, x, half)
  
      betainc_grad_a, betainc_grad_b = gradient.value_and_gradient(
          lambda y, z: special.betainc(y, z, x), [a, b]
      )[1]
      betainc_grad_a = tf.where(
          use_symmetry_relation, -betainc_grad_b, betainc_grad_a
      )
  
      stdtr_grad_df_betainc = half * (
          betainc_grad_a * half + stdtr_grad_t * abs_t / df
      )
      # Handle the case (t >= 0).
      stdtr_grad_df_betainc = tf.where(
          t >= 0.0, -stdtr_grad_df_betainc, stdtr_grad_df_betainc
      )
      # Handle the case (abs_t < min_abs_t_betainc): we use again a rough linear
      # approximation.
      stdtr_grad_df_betainc = tf.where(
          t_is_small,
          stdtr_grad_df_betainc * abs_t,
          stdtr_grad_df_betainc,
      )
  
      stdtr_grad_df = tf.where(
          use_asymptotic_expansion, stdtr_grad_df, stdtr_grad_df_betainc
      )
  
      # Determine if df is out of range (should return NaN output).
      stdtr_grad_df, stdtr_grad_t = [
          tf.where(df <= 0.0, numpy_dtype(np.nan), grad)
          for grad in [stdtr_grad_df, stdtr_grad_t]
      ]
  
      return stdtr_grad_df, stdtr_grad_t
  
imports: import functools
  import numpy
  import tensorflow.compat.v2
  from tensorflow_probability.python.bijectors import identity
  from tensorflow_probability.python.bijectors import softplus
  from tensorflow_probability.python.distributions import distribution
  from tensorflow_probability.python.distributions import gamma
  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 generic
  from tensorflow_probability.python.math import gradient
  from tensorflow_probability.python.math import numeric
  from tensorflow_probability.python.math import special
label_desc: Use image node_id 6 for calling a global function with example usage: _stdtr_partials(df, t) and returns: stdtr_grad_df,  stdtr_grad_t