class_docstr: Performs interpolation in a 2-dimensional space.
  
  For input `x_data` in x-direction we assume that values in y-direction are
  given by `y_data` and the corresponding function values by `z_data`.
  For given `x` and `y` along x- and y- direction respectively,
  the interpolated function values are computed on grid `[x, y]`.
  The interpolation is first performed along y-direction for every `x_data`
  point and all `y` using 1-d cubic spline interpolation. Next, for
  each interpolated `y_value` point, the function values are interpolated along
  x-direction for `x` using 1-d cubic spline interpolation.
  Constant extrapolation is used for the linear interpolation and natural
  boundary conditions are used for the cubic spline.
  
  ### Example. Volatility surface interpolation
  
  ```python
  dtype = np.float64
  times = tf.constant([2., 2.5, 3, 4.5], dtype=dtype)
  strikes = tf.constant([16, 22, 35], dtype=dtype)
  
  times_data = tf.constant([1.5, 2.5, 3.5, 4.5, 5.5], dtype=dtype)
  # Corresponding squared volatility values
  sigma_square_data = tf.constant(
      [[0.15, 0.25, 0.35, 0.4, 0.45, 0.4],
       [0.2, 0.35, 0.55, 0.45, 0.4, 0.6],
       [0.3, 0.45, 0.25, 0.4, 0.5, 0.65],
       [0.25, 0.25, 0.45, 0.25, 0.5, 0.55],
       [0.35, 0.35, 0.25, 0.4, 0.55, 0.65]], dtype=dtype)
  # Interpolation is done for the total variance
  total_variance = tf.expand_dims(times_data, -1) * sigma_square_data
  # Corresponding strike values. Notice we need to broadcast to the shape of
  # `sigma_square_data`
  strike_data = tf.broadcast_to(
      tf.constant([15, 25, 35, 40, 50, 55], dtype=dtype), [5, 6])
  # Interpolate total variance on for coordinates `(times, strikes)`
  interpolator = Interpolation2D(times_data, strike_data, total_variance,
                                 dtype=dtype)
  interpolated_values = interpolator.interpolate(times, strikes)
  ```
docstr: Performs 2-D interpolation on a specified set of points.
  
  Args:
    x: Real-valued `Tensor` of shape `batch_shape + [num_points]`.
      Defines the x-coordinates at which the interpolation should be
      performed. Note that `batch_shape` should be the same as in the
      underlying data.
    y: A `Tensor` of the same shape and `dtype` as `x`.
      Defines the y-coordinates at which the interpolation should be
      performed.
    name: Python `str` name prefixed to ops created by this function.
      Default value: `None` which is mapped to the default name
      `interpolate`.
  
  Returns:
    A `Tensor` of the same shape and `dtype` as `x`. Represents the
    interpolated values of the function on for the coordinates
    `(x, y)`.
docstr_tok: ["Performs","2-D","interpolation","on","a","specified","set","of","points",".","Args",":","x",":","Real-valued","`","Tensor","`","of","shape","`","batch_shape","+","[","num_points","]","`",".","Defines","the","x-coordinates","at","which","the","interpolation","should","be","performed",".","Note","that","`","batch_shape","`","should","be","the","same","as","in","the","underlying","data",".","y",":","A","`","Tensor","`","of","the","same","shape","and","`","dtype","`","as","`","x","`",".","Defines","the","y-coordinates","at","which","the","interpolation","should","be","performed",".","name",":","Python","`","str","`","name","prefixed","to","ops","created","by","this","function",".","Default","value",":","`","None","`","which","is","mapped","to","the","default","name","`","interpolate","`",".","Returns",":","A","`","Tensor","`","of","the","same","shape","and","`","dtype","`","as","`","x","`",".","Represents","the","interpolated","values","of","the","function","on","for","the","coordinates","`","(","x",",","y",")","`","."]
code: def interpolate(
      self, x: types.RealTensor, y: types.RealTensor, name: str = None
  ):
      """Performs 2-D interpolation on a specified set of points.
  
      Args:
        x: Real-valued `Tensor` of shape `batch_shape + [num_points]`.
          Defines the x-coordinates at which the interpolation should be
          performed. Note that `batch_shape` should be the same as in the
          underlying data.
        y: A `Tensor` of the same shape and `dtype` as `x`.
          Defines the y-coordinates at which the interpolation should be
          performed.
        name: Python `str` name prefixed to ops created by this function.
          Default value: `None` which is mapped to the default name
          `interpolate`.
  
      Returns:
        A `Tensor` of the same shape and `dtype` as `x`. Represents the
        interpolated values of the function on for the coordinates
        `(x, y)`.
      """
      name = name or self._name + "_interpolate"
      with tf.name_scope(name):
          x = tf.convert_to_tensor(x, dtype=self._dtype, name="x")
          y = tf.convert_to_tensor(y, dtype=self._dtype, name="y")
  
          # Broadcast `y` to the number of `x_data` points
          y = tf.expand_dims(y, axis=-2)
          # For each `x_data` point interpolate values of the function at the
          # y. Shape of `xy` is
          # batch_shape + `[num_x_data_points, num_points]`.
          xy = cubic.interpolate(
              y, self._spline_yz, name="interpolation_in_y_direction"
          )
          # Interpolate the value of the function along x-direction
          # Prepare xy for linear interpolation. Put the batch dims in front
          xy_rank = xy.shape.rank
          perm = [xy_rank - 1] + list(range(xy_rank - 1))
          # Shape [num_points] + batch_shape + [num_x_data_points]
          yx = tf.transpose(xy, perm=perm)
          # Get the permutation to the original shape
          perm_original = list(range(1, xy_rank)) + [0]
          # Reshape to [num_points] + batch_shape + [1]
          x = tf.expand_dims(
              tf.transpose(x, [xy_rank - 2] + list(range(xy_rank - 2))),
              axis=-1,
          )
          # Interpolation takes care of braodcasting
          z_values = linear.interpolate(x, self._xdata, yx)
          return tf.squeeze(
              tf.transpose(z_values, perm=perm_original), axis=-2
          )
  
imports: import tensorflow.compat.v2
  from tf_quant_finance import types
  from tf_quant_finance.math.interpolation import cubic
  from tf_quant_finance.math.interpolation import linear
label_desc: Use image node_id 2 for calling the Interpolation2D obj's underlying member method code with example usage: obj.interpolate(x, y, name) and returns: tf