code: def _apply_mixed_term_explicitly(
      values_with_boundaries,
      mixed_term,
      delta_t,
      dim1,
      dim2,
      has_default_lower_boundary,
      has_default_upper_boundary,
      n_dims,
  ):
      """Applies mixed term explicitly."""
      (
          mixed_term_pp,
          mixed_term_pm,
          mixed_term_mp,
          mixed_term_mm,
      ) = mixed_term
  
      batch_rank = values_with_boundaries.shape.rank - n_dims
  
      # Below we multiply the mixed terms by inner value grid "shifted" diagonally.
      # With Robin boundary conditions, this shift is done by restoring the
      # boundaries (values_with_boundaries already have them restored) and then
      # slicing. E.g. in 2D, values_inner = values_with_boundaries[1:-1, 1:-1],
      # and an example of a diagonally-shifted slice is
      # values_with_boundaries[:-2, 2:], which gets multiplied by mixed_term_mp.
      # However, with default boundaries, there's no boundary to restore, and the
      # diagonal shift go out of bounds. Since the mixed terms on the default
      # boundaries are zero, the "out-of-bounds" values are irrelevant. However, to
      # avoid going out of bounds and get the shapes right, we need to pad these
      # boundaries.
      paddings = batch_rank * [[0, 0]]
      for dim in range(n_dims):
          lower = 1 if has_default_lower_boundary[dim] else 0
          upper = 1 if has_default_upper_boundary[dim] else 0
          paddings += [[lower, upper]]
  
      # Pad default boundaries with zeros
      values_with_boundaries = tf.pad(
          values_with_boundaries, paddings=paddings
      )
  
      def create_trimming_shifts(dim1_shift, dim2_shift):
          # See _trim_boundaries. We need to apply shifts to dimensions dim1 and dim2.
          shifts = [0] * n_dims
          shifts[dim1] = dim1_shift
          shifts[dim2] = dim2_shift
          return shifts
  
      values_pp = _trim_boundaries(
          values_with_boundaries,
          from_dim=batch_rank,
          shifts=create_trimming_shifts(1, 1),
      )
      values_mm = _trim_boundaries(
          values_with_boundaries,
          from_dim=batch_rank,
          shifts=create_trimming_shifts(-1, -1),
      )
      values_pm = _trim_boundaries(
          values_with_boundaries,
          from_dim=batch_rank,
          shifts=create_trimming_shifts(1, -1),
      )
      values_mp = _trim_boundaries(
          values_with_boundaries,
          from_dim=batch_rank,
          shifts=create_trimming_shifts(-1, 1),
      )
  
      return (
          mixed_term_mm * values_mm
          + mixed_term_mp * values_mp
          + mixed_term_pm * values_pm
          + mixed_term_pp * values_pp
      ) * delta_t
  
file_path: tf-quant-finance/tf_quant_finance/math/pde/steppers/douglas_adi.py
imports: import numpy
  import tensorflow.compat.v2
  from tf_quant_finance.math.pde.steppers.multidim_parabolic_equation_stepper import multidim_parabolic_equation_step
label_desc: Use image node_id 3 for calling a global function with example usage: _apply_mixed_term_explicitly(values_with_boundaries, mixed_term, delta_t, dim1, dim2, has_default_lower_boundary, has_default_upper_boundary, n_dims) and returns: unknown, shifts