class_docstr: Structured interpolation to approximate a large matrix.
  
  This implements a component of the Structured Kernel Interpolation [1]
  algorithm. We approximate the pairwise `kernel` values for two inputs `x1`,
  `x2` with the following product:
  
  ```none
  k(x1, x2) = r(x1) @ k(u, u) @ r(x2)^T
  ```
  
  where `u` is a set of points regularly spaced on grid and `r` is an
  interpolation matrix. In short, instead of evaluating `kernel` on `x1` and
  `x2`, we evaluate it on `u`, which is chosen to contain fewer points than `x1`
  and `x2` and the interpolate using the interpolation matrix.
  
  This construction lets us compute matrix products efficiently. If `x1`/`x2`
  are of shape `O(n)` and `u` is of shape `O(m)`, this reduces the compute cost
  and memory to `O(n + m^2)` from `O(n^2)`.
  
  In practice, the interpolation matrix is implicitly defined using `interp_fn`,
  of which `tfp.math.batch_interp_regular_nd_grid` linear interpolation is a
  prototypical example. When `x1 == x2` we can relatively cheaply compute the
  diagonal of that matrix exactly, to preserve positive-semi-definiteness.
  
  Since we rely on a dense grid `u`, this method works best when the the kernel
  inputs are low dimensional (2 or 3).
  
  #### References
  
  [1]: Wilson, A. G., & Nickisch, H. Kernel Interpolation for Scalable
       Structured Gaussian Processes (KISS-GP). 2005. arXiv.
       http://arxiv.org/abs/1503.01057
class_docstr_tok: ["Structured","interpolation","to","approximate","a","large","matrix",".","This","implements","a","component","of","the","Structured","Kernel","Interpolation","[","1","]","algorithm",".","We","approximate","the","pairwise","`","kernel","`","values","for","two","inputs","`","x1","`",",","`","x2","`","with","the","following","product",":","``","`","none","k","(","x1",",","x2",")","=","r","(","x1",")","@","k","(","u",",","u",")","@","r","(","x2",")","^T","``","`","where","`","u","`","is","a","set","of","points","regularly","spaced","on","grid","and","`","r","`","is","an","interpolation","matrix",".","In","short",",","instead","of","evaluating","`","kernel","`","on","`","x1","`","and","`","x2","`",",","we","evaluate","it","on","`","u","`",",","which","is","chosen","to","contain","fewer","points","than","`","x1","`","and","`","x2","`","and","the","interpolate","using","the","interpolation","matrix",".","This","construction","lets","us","compute","matrix","products","efficiently",".","If","`","x1","`","\/","`","x2","`","are","of","shape","`","O","(","n",")","`","and","`","u","`","is","of","shape","`","O","(","m",")","`",",","this","reduces","the","compute","cost","and","memory","to","`","O","(","n","+","m^2",")","`","from","`","O","(","n^2",")","`",".","In","practice",",","the","interpolation","matrix","is","implicitly","defined","using","`","interp_fn","`",",","of","which","`","tfp.math.batch_interp_regular_nd_grid","`","linear","interpolation","is","a","prototypical","example",".","When","`","x1","==","x2","`","we","can","relatively","cheaply","compute","the","diagonal","of","that","matrix","exactly",",","to","preserve","positive-semi-definiteness",".","Since","we","rely","on","a","dense","grid","`","u","`",",","this","method","works","best","when","the","the","kernel","inputs","are","low","dimensional","(","2","or","3",")",".","#","#","#","#","References","[","1","]",":","Wilson",",","A.","G.",",","&","Nickisch",",","H.","Kernel","Interpolation","for","Scalable","Structured","Gaussian","Processes","(","KISS-GP",")",".","2005.","arXiv",".","http",":","\/\/arxiv.org\/abs\/1503.01057"]
docstr: Initializes the linear operator.
  
  `x1`, `kernel`, `x2` and `diag_shift` must broadcast to a shared batch
  dimension
  `[B]`. The overall shape of the operator will be `[B] + [R, C]`, given `x1`
  and `x2` with shapes `[B, R, D]` and `[B, C, D]` respectively.
  
  Args:
    kernel: Instance of `tfp.math.psd_kernels.PositiveSemidefiniteKernel'.
      Must have `feature_ndims == 1`.
    bounds_min: Floating point `Tensor`. Minimum bounds of the interpolation
      grid. Shape: [D]
    bounds_max: Floating point `Tensor`. Maximum bounds of the interpolation
      grid. Shape: [D]
    num_interpolation_points: Python integer. Number of inducing points per
      dimension.
    x1: Floating point `Tensor`. First input to the kernel. Shape: [B, R, D]
    x2: Optional floating point `Tensor`. Second input to the kernel. Shape:
      [B, C, D] Omit this argument to statically indicate that this operator
      is square, self-adjoint, positive definite and non-singular.
    interp_fn: Interpolation function with an API same as
      `tfp.math.batch_interp_regular_nd_grid`. This must implicitly define a
      matrix as in the class docstring, i.e. it must be linear in the value of
      the `y_ref` argument.
    diag_shift: Optional floating point `Tensor`. A diagonal offset to add to
      the resultant matrix. Must be `None` if the operator is not square and
      self-adjoint. Shape: [B]
    is_non_singular:  Expect that this operator is non-singular.
    is_self_adjoint:  Expect that this operator is equal to its hermitian
      transpose.  If `dtype` is real, this is equivalent to being symmetric.
    is_positive_definite:  Expect that this operator is positive definite,
      meaning the quadratic form `x^H A x` has positive real part for all
      nonzero `x`.
    is_square:  Expect that this operator acts like square [B] matrices.
    name: Name of the operator. Default: LinearOperatorInterpolatedPSDKernel
docstr_tok: ["Initializes","the","linear","operator",".","`","x1","`",",","`","kernel","`",",","`","x2","`","and","`","diag_shift","`","must","broadcast","to","a","shared","batch","dimension","`","[","B","]","`",".","The","overall","shape","of","the","operator","will","be","`","[","B","]","+","[","R",",","C","]","`",",","given","`","x1","`","and","`","x2","`","with","shapes","`","[","B",",","R",",","D","]","`","and","`","[","B",",","C",",","D","]","`","respectively",".","Args",":","kernel",":","Instance","of","`","tfp.math.psd_kernels.PositiveSemidefiniteKernel","'",".","Must","have","`","feature_ndims","==","1","`",".","bounds_min",":","Floating","point","`","Tensor","`",".","Minimum","bounds","of","the","interpolation","grid",".","Shape",":","[","D","]","bounds_max",":","Floating","point","`","Tensor","`",".","Maximum","bounds","of","the","interpolation","grid",".","Shape",":","[","D","]","num_interpolation_points",":","Python","integer",".","Number","of","inducing","points","per","dimension",".","x1",":","Floating","point","`","Tensor","`",".","First","input","to","the","kernel",".","Shape",":","[","B",",","R",",","D","]","x2",":","Optional","floating","point","`","Tensor","`",".","Second","input","to","the","kernel",".","Shape",":","[","B",",","C",",","D","]","Omit","this","argument","to","statically","indicate","that","this","operator","is","square",",","self-adjoint",",","positive","definite","and","non-singular",".","interp_fn",":","Interpolation","function","with","an","API","same","as","`","tfp.math.batch_interp_regular_nd_grid","`",".","This","must","implicitly","define","a","matrix","as","in","the","class","docstring",",","i.e",".","it","must","be","linear","in","the","value","of","the","`","y_ref","`","argument",".","diag_shift",":","Optional","floating","point","`","Tensor","`",".","A","diagonal","offset","to","add","to","the","resultant","matrix",".","Must","be","`","None","`","if","the","operator","is","not","square","and","self-adjoint",".","Shape",":","[","B","]","is_non_singular",":","Expect","that","this","operator","is","non-singular",".","is_self_adjoint",":","Expect","that","this","operator","is","equal","to","its","hermitian","transpose",".","If","`","dtype","`","is","real",",","this","is","equivalent","to","being","symmetric",".","is_positive_definite",":","Expect","that","this","operator","is","positive","definite",",","meaning","the","quadratic","form","`","x^H","A","x","`","has","positive","real","part","for","all","nonzero","`","x","`",".","is_square",":","Expect","that","this","operator","acts","like","square","[","B","]","matrices",".","name",":","Name","of","the","operator",".","Default",":","LinearOperatorInterpolatedPSDKernel"]
code: def __init__(
      self,
      kernel,
      bounds_min,
      bounds_max,
      num_interpolation_points,
      x1,
      x2=None,
      interp_fn=interpolation.batch_interp_regular_nd_grid,
      diag_shift=None,
      is_non_singular=None,
      is_self_adjoint=None,
      is_positive_definite=None,
      is_square=None,
      name=None,
  ):
      """Initializes the linear operator.
  
      `x1`, `kernel`, `x2` and `diag_shift` must broadcast to a shared batch
      dimension
      `[B]`. The overall shape of the operator will be `[B] + [R, C]`, given `x1`
      and `x2` with shapes `[B, R, D]` and `[B, C, D]` respectively.
  
      Args:
        kernel: Instance of `tfp.math.psd_kernels.PositiveSemidefiniteKernel'.
          Must have `feature_ndims == 1`.
        bounds_min: Floating point `Tensor`. Minimum bounds of the interpolation
          grid. Shape: [D]
        bounds_max: Floating point `Tensor`. Maximum bounds of the interpolation
          grid. Shape: [D]
        num_interpolation_points: Python integer. Number of inducing points per
          dimension.
        x1: Floating point `Tensor`. First input to the kernel. Shape: [B, R, D]
        x2: Optional floating point `Tensor`. Second input to the kernel. Shape:
          [B, C, D] Omit this argument to statically indicate that this operator
          is square, self-adjoint, positive definite and non-singular.
        interp_fn: Interpolation function with an API same as
          `tfp.math.batch_interp_regular_nd_grid`. This must implicitly define a
          matrix as in the class docstring, i.e. it must be linear in the value of
          the `y_ref` argument.
        diag_shift: Optional floating point `Tensor`. A diagonal offset to add to
          the resultant matrix. Must be `None` if the operator is not square and
          self-adjoint. Shape: [B]
        is_non_singular:  Expect that this operator is non-singular.
        is_self_adjoint:  Expect that this operator is equal to its hermitian
          transpose.  If `dtype` is real, this is equivalent to being symmetric.
        is_positive_definite:  Expect that this operator is positive definite,
          meaning the quadratic form `x^H A x` has positive real part for all
          nonzero `x`.
        is_square:  Expect that this operator acts like square [B] matrices.
        name: Name of the operator. Default: LinearOperatorInterpolatedPSDKernel
      """
      dtype = dtype_util.common_dtype(
          [kernel, x1, x2, bounds_min, bounds_max, diag_shift],
          dtype_hint=tf.float32,
      )
  
      if kernel.feature_ndims != 1:
          raise NotImplementedError(
              "`kernel.feature_ndims` must be 1, saw: "
              f"{kernel.feature_ndims}"
          )
  
      if x2 is None:
          if is_non_singular is not None and not is_non_singular:
              raise ValueError(
                  "Operator is non-singular with a single set of index points."
              )
          is_non_singular = True
          if is_self_adjoint is not None and not is_self_adjoint:
              raise ValueError(
                  "Operator is self-adjoint with a single set of index points."
              )
          is_self_adjoint = True
          if (
              is_positive_definite is not None
              and not is_positive_definite
          ):
              raise ValueError(
                  "Operator is positive-definite with a single set of index points."
              )
          is_positive_definite = True
          if is_square is not None and not is_square:
              raise ValueError(
                  "Operator is square with a single set of index points."
              )
          is_square = True
      if not is_self_adjoint:
          if diag_shift is not None:
              raise NotImplementedError(
                  "Adding diag_shift is not implemented when operator is not "
                  "self-adjoint."
              )
  
      self._x1 = tensor_util.convert_nonref_to_tensor(x1, dtype=dtype)
      self._x2 = tensor_util.convert_nonref_to_tensor(x2, dtype=dtype)
      self._num_interpolation_points = num_interpolation_points
      self._bounds_min = tensor_util.convert_nonref_to_tensor(
          bounds_min, dtype=dtype
      )
      self._bounds_max = tensor_util.convert_nonref_to_tensor(
          bounds_max, dtype=dtype
      )
      self._diag_shift = tensor_util.convert_nonref_to_tensor(
          diag_shift, dtype=dtype
      )
      self._kernel = kernel
      self._interp_fn = interp_fn
  
      super().__init__(
          dtype,
          is_non_singular=is_non_singular,
          is_self_adjoint=is_self_adjoint,
          is_positive_definite=is_positive_definite,
          is_square=is_square,
          name=name or "LinearOperatorInterpolatedPSDKernel",
      )
  
imports: import functools
  import numpy
  import tensorflow.compat.v2
  from tensorflow_probability.python.internal import distribution_util
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import tensor_util
  from tensorflow_probability.python.math import gradient
  from tensorflow_probability.python.math import interpolation
label_desc: Use image node_id 1 to create a new LinearOperatorInterpolatedPSDKernel object from inherited base classes: tf.linalg with example: obj = LinearOperatorInterpolatedPSDKernel(kernel, bounds_min, bounds_max, num_interpolation_points, x1, x2, interp_fn, diag_shift, is_non_singular, is__adjoint, is_positive_definite, is_square, name)