code: def _interpolate_bilinear_impl(
      grid: types.TensorLike,
      query_points: types.TensorLike,
      indexing: str,
      name: Optional[str],
  ) -> tf.Tensor:
      """tf.function implementation of interpolate_bilinear."""
      with tf.name_scope(name or "interpolate_bilinear"):
          grid_shape = tf.shape(grid)
          query_shape = tf.shape(query_points)
  
          batch_size, height, width, channels = (
              grid_shape[0],
              grid_shape[1],
              grid_shape[2],
              grid_shape[3],
          )
  
          num_queries = query_shape[1]
  
          query_type = query_points.dtype
          grid_type = grid.dtype
  
          alphas = []
          floors = []
          ceils = []
          index_order = [0, 1] if indexing == "ij" else [1, 0]
          unstacked_query_points = tf.unstack(
              query_points, axis=2, num=2
          )
  
          for i, dim in enumerate(index_order):
              with tf.name_scope("dim-" + str(dim)):
                  queries = unstacked_query_points[dim]
  
                  size_in_indexing_dimension = grid_shape[i + 1]
  
                  # max_floor is size_in_indexing_dimension - 2 so that max_floor + 1
                  # is still a valid index into the grid.
                  max_floor = tf.cast(
                      size_in_indexing_dimension - 2, query_type
                  )
                  min_floor = tf.constant(0.0, dtype=query_type)
                  floor = tf.math.minimum(
                      tf.math.maximum(
                          min_floor, tf.math.floor(queries)
                      ),
                      max_floor,
                  )
                  int_floor = tf.cast(floor, tf.dtypes.int32)
                  floors.append(int_floor)
                  ceil = int_floor + 1
                  ceils.append(ceil)
  
                  # alpha has the same type as the grid, as we will directly use alpha
                  # when taking linear combinations of pixel values from the image.
                  alpha = tf.cast(queries - floor, grid_type)
                  min_alpha = tf.constant(0.0, dtype=grid_type)
                  max_alpha = tf.constant(1.0, dtype=grid_type)
                  alpha = tf.math.minimum(
                      tf.math.maximum(min_alpha, alpha), max_alpha
                  )
  
                  # Expand alpha to [b, n, 1] so we can use broadcasting
                  # (since the alpha values don't depend on the channel).
                  alpha = tf.expand_dims(alpha, 2)
                  alphas.append(alpha)
  
              flattened_grid = tf.reshape(
                  grid, [batch_size * height * width, channels]
              )
              batch_offsets = tf.reshape(
                  tf.range(batch_size) * height * width, [batch_size, 1]
              )
  
          # This wraps tf.gather. We reshape the image data such that the
          # batch, y, and x coordinates are pulled into the first dimension.
          # Then we gather. Finally, we reshape the output back. It's possible this
          # code would be made simpler by using tf.gather_nd.
          def gather(y_coords, x_coords, name):
              with tf.name_scope("gather-" + name):
                  linear_coordinates = (
                      batch_offsets + y_coords * width + x_coords
                  )
                  gathered_values = tf.gather(
                      flattened_grid, linear_coordinates
                  )
                  return tf.reshape(
                      gathered_values,
                      [batch_size, num_queries, channels],
                  )
  
          # grab the pixel values in the 4 corners around each query point
          top_left = gather(floors[0], floors[1], "top_left")
          top_right = gather(floors[0], ceils[1], "top_right")
          bottom_left = gather(ceils[0], floors[1], "bottom_left")
          bottom_right = gather(ceils[0], ceils[1], "bottom_right")
  
          # now, do the actual interpolation
          with tf.name_scope("interpolate"):
              interp_top = alphas[1] * (top_right - top_left) + top_left
              interp_bottom = (
                  alphas[1] * (bottom_right - bottom_left) + bottom_left
              )
              interp = (
                  alphas[0] * (interp_bottom - interp_top) + interp_top
              )
  
          return interp
  
file_path: addons/tensorflow_addons/image/dense_image_warp.py
imports: import tensorflow
  from tensorflow_addons.utils import types
  from typing import Optional
label_desc: Use image node_id 3 for calling a global function with example usage: _interpolate_bilinear_impl(grid, query_points, indexing, name) and returns: interp, tf