code: def _initialize_tps(
      num_control_points,
      input_shape,
      downsample_factor,
      precompute_grid,
  ):
      """
      Initializes the thin plate spline calculation by creating the source
      point array and the inverted L matrix used for calculating the
      transformations as in ref [2]_
  
      :param num_control_points: the number of control points. Must be a
          perfect square. Points will be used to generate an evenly spaced grid.
      :param input_shape: tuple with 4 elements specifying the input shape
      :param downsample_factor: tuple with 2 elements specifying the
          downsample for the height and width, respectively
      :param precompute_grid: boolean specifying whether to precompute the
          grid matrix
      :return:
          right_mat: shape (num_control_points + 3, out_height*out_width) tensor
          L_inv: shape (num_control_points + 3, num_control_points + 3) tensor
          source_points: shape (2, num_control_points) tensor
          out_height: tensor constant specifying the ouptut height
          out_width: tensor constant specifying the output width
  
      """
  
      # break out input_shape
      _, _, height, width = input_shape
  
      # Create source grid
      grid_size = np.sqrt(num_control_points)
      x_control_source, y_control_source = np.meshgrid(
          np.linspace(-1, 1, grid_size), np.linspace(-1, 1, grid_size)
      )
  
      # Create 2 x num_points array of source points
      source_points = np.vstack(
          (x_control_source.flatten(), y_control_source.flatten())
      )
  
      # Convert to floatX
      source_points = source_points.astype(theano.config.floatX)
  
      # Get number of equations
      num_equations = num_control_points + 3
  
      # Initialize L to be num_equations square matrix
      L = np.zeros(
          (num_equations, num_equations), dtype=theano.config.floatX
      )
  
      # Create P matrix components
      L[0, 3:num_equations] = 1.0
      L[1:3, 3:num_equations] = source_points
      L[3:num_equations, 0] = 1.0
      L[3:num_equations, 1:3] = source_points.T
  
      # Loop through each pair of points and create the K matrix
      for point_1 in range(num_control_points):
          for point_2 in range(point_1, num_control_points):
              L[point_1 + 3, point_2 + 3] = _U_func_numpy(
                  source_points[0, point_1],
                  source_points[1, point_1],
                  source_points[0, point_2],
                  source_points[1, point_2],
              )
  
              if point_1 != point_2:
                  L[point_2 + 3, point_1 + 3] = L[
                      point_1 + 3, point_2 + 3
                  ]
  
      # Invert
      L_inv = np.linalg.inv(L)
  
      if precompute_grid:
          # Construct grid
          out_height = np.array(height // downsample_factor[0]).astype(
              "int64"
          )
          out_width = np.array(width // downsample_factor[1]).astype(
              "int64"
          )
          x_t, y_t = np.meshgrid(
              np.linspace(-1, 1, out_width),
              np.linspace(-1, 1, out_height),
          )
          ones = np.ones(np.prod(x_t.shape))
          orig_grid = np.vstack([x_t.flatten(), y_t.flatten(), ones])
          orig_grid = orig_grid[0:2, :]
          orig_grid = orig_grid.astype(theano.config.floatX)
  
          # Construct right mat
  
          # First Calculate the U function for the new point and each source
          # point as in ref [2]
          # The U function is simply U(r) = r^2 * log(r^2), where r^2 is the
          # squared distance
          to_transform = orig_grid[:, :, np.newaxis].transpose(2, 0, 1)
          stacked_transform = np.tile(
              to_transform, (num_control_points, 1, 1)
          )
          stacked_source_points = source_points[
              :, :, np.newaxis
          ].transpose(1, 0, 2)
          r_2 = np.sum(
              (stacked_transform - stacked_source_points) ** 2, axis=1
          )
  
          # Take the product (r^2 * log(r^2)), being careful to avoid NaNs
          log_r_2 = np.log(r_2)
          log_r_2[np.isinf(log_r_2)] = 0.0
          distances = r_2 * log_r_2
  
          # Add in the coefficients for the affine translation (1, x, and y,
          # corresponding to a_1, a_x, and a_y)
          upper_array = np.ones(
              shape=(1, orig_grid.shape[1]), dtype=theano.config.floatX
          )
          upper_array = np.concatenate([upper_array, orig_grid], axis=0)
          right_mat = np.concatenate([upper_array, distances], axis=0)
  
          # Convert to tensors
          out_height = T.as_tensor_variable(out_height)
          out_width = T.as_tensor_variable(out_width)
          right_mat = T.as_tensor_variable(right_mat)
  
      else:
          out_height = None
          out_width = None
          right_mat = None
  
      # Convert to tensors
      L_inv = T.as_tensor_variable(L_inv)
      source_points = T.as_tensor_variable(source_points)
  
      return right_mat, L_inv, source_points, out_height, out_width
  
imports: import theano
  import theano.tensor
  import numpy
  from ..None import init
  from ..None import nonlinearities
  from ..utils import as_tuple, floatX, int_types
  from ..random import get_rng
  from .base import Layer, MergeLayer
  from theano.sandbox.rng_mrg import MRG_RandomStreams
label_desc: Use image node_id 9 for calling a global function with example usage: _initialize_tps(num_control_points, input_shape, downsample_factor, precompute_grid) and returns: right_mat,  L_inv,  source_points,  out_height,  out_width