class_docstr: A fully Bayesian single-task GP model with the SAAS prior.
  
  This model assumes that the inputs have been normalized to [0, 1]^d and that
  the output has been standardized to have zero mean and unit variance. You can
  either normalize and standardize the data before constructing the model or use
  an `input_transform` and `outcome_transform`. The SAAS model [Eriksson2021saasbo]_
  with a Matern-5/2 kernel is used by default.
  
  You are expected to use `fit_fully_bayesian_model_nuts` to fit this model as it
  isn't compatible with `fit_gpytorch_model`.
  
  Example:
      >>> saas_gp = SaasFullyBayesianSingleTaskGP(train_X, train_Y)
      >>> fit_fully_bayesian_model_nuts(saas_gp)
      >>> posterior = saas_gp.posterior(test_X)
class_docstr_tok: ["A","fully","Bayesian","single-task","GP","model","with","the","SAAS","prior",".","This","model","assumes","that","the","inputs","have","been","normalized","to","[","0",",","1","]","^d","and","that","the","output","has","been","standardized","to","have","zero","mean","and","unit","variance",".","You","can","either","normalize","and","standardize","the","data","before","constructing","the","model","or","use","an","`","input_transform","`","and","`","outcome_transform","`",".","The","SAAS","model","[","Eriksson2021saasbo","]","_","with","a","Matern-5\/2","kernel","is","used","by","default",".","You","are","expected","to","use","`","fit_fully_bayesian_model_nuts","`","to","fit","this","model","as","it","is","n't","compatible","with","`","fit_gpytorch_model","`",".","Example",":",">",">",">","saas_gp","=","SaasFullyBayesianSingleTaskGP","(","train_X",",","train_Y",")",">",">",">","fit_fully_bayesian_model_nuts","(","saas_gp",")",">",">",">","posterior","=","saas_gp.posterior","(","test_X",")"]
docstr: Initialize the fully Bayesian single-task GP model.
  
  Args:
      train_X: Training inputs (n x d)
      train_Y: Training targets (n x 1)
      train_Yvar: Observed noise variance (n x 1). Inferred if None.
      outcome_transform: An outcome transform that is applied to the
          training data during instantiation and to the posterior during
          inference (that is, the `Posterior` obtained by calling
          `.posterior` on the model will be on the original scale).
      input_transform: An input transform that is applied in the model's
          forward pass.
      pyro_model: Optional `PyroModel`, defaults to `SaasPyroModel`.
docstr_tok: ["Initialize","the","fully","Bayesian","single-task","GP","model",".","Args",":","train_X",":","Training","inputs","(","n","x","d",")","train_Y",":","Training","targets","(","n","x","1",")","train_Yvar",":","Observed","noise","variance","(","n","x","1",")",".","Inferred","if","None",".","outcome_transform",":","An","outcome","transform","that","is","applied","to","the","training","data","during","instantiation","and","to","the","posterior","during","inference","(","that","is",",","the","`","Posterior","`","obtained","by","calling","`",".posterior","`","on","the","model","will","be","on","the","original","scale",")",".","input_transform",":","An","input","transform","that","is","applied","in","the","model's","forward","pass",".","pyro_model",":","Optional","`","PyroModel","`",",","defaults","to","`","SaasPyroModel","`","."]
code: def __init__(
      self,
      train_X: Tensor,
      train_Y: Tensor,
      train_Yvar: Optional[Tensor] = None,
      outcome_transform: Optional[OutcomeTransform] = None,
      input_transform: Optional[InputTransform] = None,
      pyro_model: Optional[PyroModel] = None,
  ) -> None:
      r"""Initialize the fully Bayesian single-task GP model.
  
      Args:
          train_X: Training inputs (n x d)
          train_Y: Training targets (n x 1)
          train_Yvar: Observed noise variance (n x 1). Inferred if None.
          outcome_transform: An outcome transform that is applied to the
              training data during instantiation and to the posterior during
              inference (that is, the `Posterior` obtained by calling
              `.posterior` on the model will be on the original scale).
          input_transform: An input transform that is applied in the model's
              forward pass.
          pyro_model: Optional `PyroModel`, defaults to `SaasPyroModel`.
      """
      if not (
          train_X.ndim == train_Y.ndim == 2
          and len(train_X) == len(train_Y)
          and train_Y.shape[-1] == 1
      ):
          raise ValueError(
              "Expected train_X to have shape n x d and train_Y to have shape n x 1"
          )
      if train_Yvar is not None:
          if train_Y.shape != train_Yvar.shape:
              raise ValueError(
                  "Expected train_Yvar to be None or have the same shape as train_Y"
              )
      with torch.no_grad():
          transformed_X = self.transform_inputs(
              X=train_X, input_transform=input_transform
          )
      if outcome_transform is not None:
          train_Y, train_Yvar = outcome_transform(train_Y, train_Yvar)
      self._validate_tensor_args(X=transformed_X, Y=train_Y)
      validate_input_scaling(
          train_X=transformed_X, train_Y=train_Y, train_Yvar=train_Yvar
      )
      self._num_outputs = train_Y.shape[-1]
      self._input_batch_shape = train_X.shape[:-2]
      if train_Yvar is not None:  # Clamp after transforming
          train_Yvar = train_Yvar.clamp(MIN_INFERRED_NOISE_LEVEL)
  
      X_tf, Y_tf, _ = self._transform_tensor_args(X=train_X, Y=train_Y)
      super().__init__(
          train_inputs=X_tf,
          train_targets=Y_tf,
          likelihood=GaussianLikelihood(),
      )
      self.mean_module = None
      self.covar_module = None
      self.likelihood = None
      if pyro_model is None:
          pyro_model = SaasPyroModel()
      pyro_model.set_inputs(
          train_X=transformed_X, train_Y=train_Y, train_Yvar=train_Yvar
      )
      self.pyro_model = pyro_model
      if outcome_transform is not None:
          self.outcome_transform = outcome_transform
      if input_transform is not None:
          self.input_transform = input_transform
  
imports: import math
  from abc import abstractmethod
  from typing import Any, Dict, List, Mapping, Optional, Tuple
  import pyro
  import torch
  from botorch.acquisition.objective import PosteriorTransform
  from botorch.models.gpytorch import BatchedMultiOutputGPyTorchModel
  from botorch.models.transforms.input import InputTransform
  from botorch.models.transforms.outcome import OutcomeTransform
  from botorch.models.utils import validate_input_scaling
  from botorch.models.utils.gpytorch_modules import MIN_INFERRED_NOISE_LEVEL
  from botorch.posteriors.fully_bayesian import GaussianMixturePosterior, MCMC_DIM
  from gpytorch.constraints import GreaterThan
  from gpytorch.distributions.multivariate_normal import MultivariateNormal
  from gpytorch.kernels import MaternKernel, ScaleKernel
  from gpytorch.kernels.kernel import dist, Kernel
  from gpytorch.likelihoods.gaussian_likelihood import FixedNoiseGaussianLikelihood, GaussianLikelihood
  from gpytorch.likelihoods.likelihood import Likelihood
  from gpytorch.means.constant_mean import ConstantMean
  from gpytorch.means.mean import Mean
  from gpytorch.models.exact_gp import ExactGP
  from pyro.ops.integrator import register_exception_handler
  from torch import Tensor
label_desc: Use image node_id 1 to create a new SaasFullyBayesianSingleTaskGP object from inherited base classes: ExactGP, BatchedMultiOutputGPyTorchModel with example: obj = SaasFullyBayesianSingleTaskGP(train_X, train_Y, train_Yvar, outcome_transform, input_transform, pyro_model)