code: def _apply_robin_boundary_conditions(
      value_grid,
      boundary_conditions,
      has_default_lower_boundary,
      has_default_upper_boundary,
      coord_grid,
      coord_grid_deltas,
      diagonal,
      upper_diagonal,
      lower_diagonal,
      t,
  ):
      """Updates space-discretized equation according to boundary conditions."""
      # Without taking into account the boundary conditions, the space-discretized
      # PDE has the form dv/dt = A(t) v(t), where v(t) is V(t, x) discretized by
      # x, and A is the tridiagonal matrix defined by coefficients of the PDE.
      # Boundary conditions change the first and the last row of A and introduce
      # the inhomogeneous term, so the equation becomes dv/dt = A'(t) v(t) + b(t),
      # where A' is the modified matrix, and b is a vector.
      # This function receives A and returns A' and b.
      # We do not update the rows of A where the boundary condition is default
  
      # If both boundaries are default, there is no need to update the
      # space-discretization matrix
      if has_default_lower_boundary and has_default_upper_boundary:
          return (
              diagonal,
              upper_diagonal,
              lower_diagonal,
          ), tf.zeros_like(diagonal)
  
      batch_shape = utils.get_shape(value_grid)[:-1]
      # Retrieve the boundary conditions in the form alpha V + beta V' = gamma.
      if has_default_lower_boundary:
          # No need for the BC as default BC was applied
          alpha_l, beta_l, gamma_l = None, None, None
      else:
          alpha_l, beta_l, gamma_l = boundary_conditions[0][0](
              t, coord_grid
          )
      if has_default_upper_boundary:
          # No need for the BC as default BC was applied
          alpha_u, beta_u, gamma_u = None, None, None
      else:
          alpha_u, beta_u, gamma_u = boundary_conditions[0][1](
              t, coord_grid
          )
  
      alpha_l, beta_l, gamma_l, alpha_u, beta_u, gamma_u = (
          _prepare_boundary_conditions(b, value_grid)
          for b in (alpha_l, beta_l, gamma_l, alpha_u, beta_u, gamma_u)
      )
  
      if beta_l is None and beta_u is None:
          # Dirichlet or default conditions on both boundaries. In this case there are
          # no corrections to the tridiagonal matrix, so we can take a shortcut.
          if has_default_lower_boundary:
              # Inhomogeneous term is zero for default BC
              first_inhomog_element = tf.zeros(
                  batch_shape, dtype=value_grid.dtype
              )
          else:
              first_inhomog_element = (
                  lower_diagonal[..., 0] * gamma_l / alpha_l
              )
          if has_default_upper_boundary:
              # Inhomogeneous term is zero for default BC
              last_inhomog_element = tf.zeros(
                  batch_shape, dtype=value_grid.dtype
              )
          else:
              last_inhomog_element = (
                  upper_diagonal[..., -1] * gamma_u / alpha_u
              )
          inhomog_term = _append_first_and_last(
              first_inhomog_element,
              tf.zeros_like(diagonal[..., 1:-1]),
              last_inhomog_element,
          )
          return (
              diagonal,
              upper_diagonal,
              lower_diagonal,
          ), inhomog_term
  
      # Convert the boundary conditions into the form v0 = xi1 v1 + xi2 v2 + eta,
      # and calculate corrections to the tridiagonal matrix and the inhomogeneous
      # term.
      if has_default_lower_boundary:
          # No update for the default BC
          first_inhomog_element = tf.zeros(
              batch_shape, dtype=value_grid.dtype
          )
          diag_first_correction = 0
          upper_diag_correction = 0
      else:
          # Robin BC case for the lower bound
          xi1, xi2, eta = _discretize_boundary_conditions(
              coord_grid_deltas[..., 0],
              coord_grid_deltas[..., 1],
              alpha_l,
              beta_l,
              gamma_l,
          )
          diag_first_correction = lower_diagonal[..., 0] * xi1
          upper_diag_correction = lower_diagonal[..., 0] * xi2
          first_inhomog_element = lower_diagonal[..., 0] * eta
  
      if has_default_upper_boundary:
          # No update for the default BC
          last_inhomog_element = tf.zeros(
              batch_shape, dtype=value_grid.dtype
          )
          diag_last_correction = 0
          lower_diag_correction = 0
      else:
          # Robin BC case for the upper bound
          xi1, xi2, eta = _discretize_boundary_conditions(
              coord_grid_deltas[..., -1],
              coord_grid_deltas[..., -2],
              alpha_u,
              beta_u,
              gamma_u,
          )
          diag_last_correction = upper_diagonal[..., -1] * xi1
          lower_diag_correction = upper_diagonal[..., -1] * xi2
          last_inhomog_element = upper_diagonal[..., -1] * eta
  
      # Update spatial discretization matrix, where appropriate
      diagonal = _append_first_and_last(
          diagonal[..., 0] + diag_first_correction,
          diagonal[..., 1:-1],
          diagonal[..., -1] + diag_last_correction,
      )
      upper_diagonal = _append_first(
          upper_diagonal[..., 0] + upper_diag_correction,
          upper_diagonal[..., 1:],
      )
      lower_diagonal = _append_last(
          lower_diagonal[..., :-1],
          lower_diagonal[..., -1] + lower_diag_correction,
      )
      inhomog_term = _append_first_and_last(
          first_inhomog_element,
          tf.zeros_like(diagonal[..., 1:-1]),
          last_inhomog_element,
      )
      return (diagonal, upper_diagonal, lower_diagonal), inhomog_term
  
file_path: tf-quant-finance/tf_quant_finance/math/pde/steppers/parabolic_equation_stepper.py
imports: import tensorflow.compat.v2
  from tf_quant_finance import utils
label_desc: Use image node_id 6 for calling a global function with example usage: _apply_robin_boundary_conditions(value_grid, boundary_conditions, has_default_lower_boundary, has_default_upper_boundary, coord_grid, coord_grid_deltas, diagonal, upper_diagonal, lower_diagonal, t) and returns: diagonal,  upper_diagonal,  lower_diagonal,  inhomog_term, diagonal,  upper_diagonal,  lower_diagonal,  tf, diagonal,  upper_diagonal,  lower_diagonal,  inhomog_term