class_docstr: Additive Kernel.
  
  This kernel has the following form
  ```none
  k(x, y) = sum k_add_i(x, y)
  k_add_n(x, y) = a_n**2 sum_{1<=i1<i2<...in} prod k_i(x[i], y[i])
  ```
  Where $k_i$ is the one-dimensional base kernel for the `i`th dimension.
  
  In other words, this computes sums of elementary symmetric polynomials
  over `k_i(x[i], y[i])`.
  
  This kernel is very related to the ANOVA kernel defined as:
  `k_{ANOVA}(x, y) = prod (1 + k_i(x[i], x[i])`. `k_{ANOVA}` is
  equivalent to a special case of this kernel where the `amplitudes` are
  all one, along with a constant shift by 1.
  
  #### References
  
  [1] D. Duvenaud, H. Nickish, C. E. Rasmussen, Additive Gaussian Process.
  https://hannes.nickisch.org/papers/conferences/duvenaud11gpadditive.pdf
  
  [2] M. Stitson, A. Gammerman, V. Vapnik, V. Vovk, et al.
      Support Vector Regression with ANOVA Decomposition Kernels
      http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.34.7818&rep=rep1&type=pdf
class_docstr_tok: ["Additive","Kernel",".","This","kernel","has","the","following","form","``","`","none","k","(","x",",","y",")","=","sum","k_add_i","(","x",",","y",")","k_add_n","(","x",",","y",")","=","a_n","*","*","2","sum_","{","1","<","=i1","<","i2","<","...","in","}","prod","k_i","(","x","[","i","]",",","y","[","i","]",")","``","`","Where","$","k_i","$","is","the","one-dimensional","base","kernel","for","the","`","i","`","th","dimension",".","In","other","words",",","this","computes","sums","of","elementary","symmetric","polynomials","over","`","k_i","(","x","[","i","]",",","y","[","i","]",")","`",".","This","kernel","is","very","related","to","the","ANOVA","kernel","defined","as",":","`","k_","{","ANOVA","}","(","x",",","y",")","=","prod","(","1","+","k_i","(","x","[","i","]",",","x","[","i","]",")","`",".","`","k_","{","ANOVA","}","`","is","equivalent","to","a","special","case","of","this","kernel","where","the","`","amplitudes","`","are","all","one",",","along","with","a","constant","shift","by","1",".","#","#","#","#","References","[","1","]","D.","Duvenaud",",","H.","Nickish",",","C.","E.","Rasmussen",",","Additive","Gaussian","Process",".","https",":","\/\/hannes.nickisch.org\/papers\/conferences\/duvenaud11gpadditive.pdf","[","2","]","M.","Stitson",",","A.","Gammerman",",","V.","Vapnik",",","V.","Vovk",",","et","al",".","Support","Vector","Regression","with","ANOVA","Decomposition","Kernels","http",":","\/\/citeseerx.ist.psu.edu\/viewdoc\/download","?","doi=10.1.1.34.7818","&","rep=rep1","&","type=pdf"]
code: def _apply(self, x1, x2, example_ndims=0):
      @tf.recompute_grad
      def _inner_apply(x1, x2):
          order = ps.shape(self.amplitudes)[-1]
  
          def scan_fn(esp, i):
              s = self.kernel[..., i].apply(
                  x1[..., i][..., tf.newaxis],
                  x2[..., i][..., tf.newaxis],
                  example_ndims=example_ndims,
              )
              next_esp = (
                  esp[..., 1:] + s[..., tf.newaxis] * esp[..., :-1]
              )
              # Add the zero-th polynomial.
              next_esp = tf.concat(
                  [
                      tf.ones_like(esp[..., 0][..., tf.newaxis]),
                      next_esp,
                  ],
                  axis=-1,
              )
              return next_esp
  
          batch_shape = ps.broadcast_shape(
              ps.shape(x1)[: -self.kernel.feature_ndims],
              ps.shape(x2)[: -self.kernel.feature_ndims],
          )
  
          batch_shape = ps.broadcast_shape(
              batch_shape,
              ps.concat(
                  [self.batch_shape_tensor(), [1] * example_ndims],
                  axis=0,
              ),
          )
  
          initializer = tf.concat(
              [
                  tf.ones(
                      ps.concat([batch_shape, [1]], axis=0),
                      dtype=self.dtype,
                  ),
                  tf.zeros(
                      ps.concat([batch_shape, [order]], axis=0),
                      dtype=self.dtype,
                  ),
              ],
              axis=-1,
          )
  
          esps = tf.scan(
              scan_fn,
              elems=ps.range(0, ps.shape(x1)[-1], dtype=tf.int32),
              parallel_iterations=32,
              initializer=initializer,
          )[-1, ..., 1:]
          amplitudes = util.pad_shape_with_ones(
              self.amplitudes, ndims=example_ndims, start=-2
          )
          return tf.reduce_sum(
              esps * tf.math.square(amplitudes), axis=-1
          )
  
      return _inner_apply(x1, x2)
  
file_path: probability/tensorflow_probability/python/experimental/psd_kernels/additive_kernel.py
imports: import tensorflow.compat.v2
  from tensorflow_probability.python.internal import dtype_util
  from tensorflow_probability.python.internal import parameter_properties
  from tensorflow_probability.python.internal import prefer_static
  from tensorflow_probability.python.internal import tensor_util
  from tensorflow_probability.python.math.psd_kernels import positive_semidefinite_kernel
  from tensorflow_probability.python.math.psd_kernels.internal import util
label_desc: Use image node_id 5 for calling the AdditiveKernel obj's underlying member method code with example usage: obj._apply(x1, x2, example_ndims) and returns: _inner_apply, tf, next_esp