class_docstr: Orthogonal Additive Kernels (OAKs) were introduced in [Lu2022additive]_, though
  only for the case of Gaussian base kernels with a Gaussian input data distribution.
  
  The implementation here generalizes OAKs to arbitrary base kernels by using a
  Gauss-Legendre quadrature approximation to the required one-dimensional integrals
  involving the base kernels.
  
  .. [Lu2022additive]
      X. Lu, A. Boukouvalas, and J. Hensman. Additive Gaussian processes revisited.
      Proceedings of the 39th International Conference on Machine Learning. Jul 2022.
class_docstr_tok: ["Orthogonal","Additive","Kernels","(","OAKs",")","were","introduced","in","[","Lu2022additive","]","_",",","though","only","for","the","case","of","Gaussian","base","kernels","with","a","Gaussian","input","data","distribution",".","The","implementation","here","generalizes","OAKs","to","arbitrary","base","kernels","by","using","a","Gauss-Legendre","quadrature","approximation","to","the","required","one-dimensional","integrals","involving","the","base","kernels",".","..","[","Lu2022additive","]","X.","Lu",",","A.","Boukouvalas",",","and","J.","Hensman",".","Additive","Gaussian","processes","revisited",".","Proceedings","of","the","39th","International","Conference","on","Machine","Learning",".","Jul","2022","."]
docstr: Args:
      base_kernel: The kernel which to orthogonalize and evaluate in `forward`.
      dim: Input dimensionality of the kernel.
      quad_deg: Number of integration nodes for orthogonalization.
      second_order: Toggles second order interactions. If true, both the time and
          space complexity of evaluating the kernel are quadratic in `dim`.
      batch_shape: Optional batch shape for the kernel and its parameters.
      dtype: Initialization dtype for required Tensors.
      device: Initialization device for required Tensors.
      coeff_constraint: Constraint on the coefficients of the additive kernel.
docstr_tok: ["Args",":","base_kernel",":","The","kernel","which","to","orthogonalize","and","evaluate","in","`","forward","`",".","dim",":","Input","dimensionality","of","the","kernel",".","quad_deg",":","Number","of","integration","nodes","for","orthogonalization",".","second_order",":","Toggles","second","order","interactions",".","If","true",",","both","the","time","and","space","complexity","of","evaluating","the","kernel","are","quadratic","in","`","dim","`",".","batch_shape",":","Optional","batch","shape","for","the","kernel","and","its","parameters",".","dtype",":","Initialization","dtype","for","required","Tensors",".","device",":","Initialization","device","for","required","Tensors",".","coeff_constraint",":","Constraint","on","the","coefficients","of","the","additive","kernel","."]
code: def __init__(
      self,
      base_kernel: Kernel,
      dim: int,
      quad_deg: int = 32,
      second_order: bool = False,
      batch_shape: Optional[torch.Size] = None,
      dtype: Optional[torch.dtype] = None,
      device: Optional[torch.device] = None,
      coeff_constraint: Interval = _positivity_constraint,
  ):
      """
      Args:
          base_kernel: The kernel which to orthogonalize and evaluate in `forward`.
          dim: Input dimensionality of the kernel.
          quad_deg: Number of integration nodes for orthogonalization.
          second_order: Toggles second order interactions. If true, both the time and
              space complexity of evaluating the kernel are quadratic in `dim`.
          batch_shape: Optional batch shape for the kernel and its parameters.
          dtype: Initialization dtype for required Tensors.
          device: Initialization device for required Tensors.
          coeff_constraint: Constraint on the coefficients of the additive kernel.
      """
      super().__init__(batch_shape=batch_shape)
      self.base_kernel = base_kernel
      # integration nodes, weights for [0, 1]
      tkwargs = {"dtype": dtype, "device": device}
      z, w = leggauss(deg=quad_deg, a=0, b=1, **tkwargs)
      self.z = z.unsqueeze(-1).expand(quad_deg, dim)  # deg x dim
      self.w = w.unsqueeze(-1)
      self.register_parameter(
          name="raw_offset",
          parameter=nn.Parameter(
              torch.zeros(self.batch_shape, **tkwargs)
          ),
      )
      log_d = math.log(dim)
      self.register_parameter(
          name="raw_coeffs_1",
          parameter=nn.Parameter(
              torch.zeros(*self.batch_shape, dim, **tkwargs) - log_d
          ),
      )
      self.register_parameter(
          name="raw_coeffs_2",
          parameter=nn.Parameter(
              torch.zeros(
                  *self.batch_shape, int(dim * (dim - 1) / 2), **tkwargs
              )
              - 2 * log_d
          )
          if second_order
          else None,
      )
      if second_order:
          self._rev_triu_indices = torch.tensor(
              _reverse_triu_indices(dim),
              device=device,
              dtype=int,
          )
          # zero tensor for construction of upper-triangular coefficient matrix
          self._quad_zero = torch.zeros(
              tuple(1 for _ in range(len(batch_shape) + 1)), **tkwargs
          ).expand(*batch_shape, 1)
      self.coeff_constraint = coeff_constraint
      self.dim = dim
  
imports: import math
  from typing import List, Optional, Tuple
  import numpy
  import torch
  from botorch.exceptions.errors import UnsupportedError
  from gpytorch.constraints import Interval, Positive
  from gpytorch.kernels import Kernel
  from torch import nn, Tensor
label_desc: Use image node_id 1 to create a new OrthogonalAdditiveKernel object from inherited base classes: Kernel with example: obj = OrthogonalAdditiveKernel(base_kernel, dim, quad_deg, second_order, batch_shape, dtype, device, coeff_constraint)