docstr: Computes the posterior predictive covariance of a GP
  
  :param ~linear_operator.operators.LinearOperator test_train_covar:
      Covariance matrix between test and train inputs
  :param ~linear_operator.operators.LinearOperator test_test_covar: Covariance matrix between test inputs
  :return: A LinearOperator representing the predictive posterior covariance of the test points
docstr_tok: ["Computes","the","posterior","predictive","covariance","of","a","GP",":","param","~linear_operator.operators.LinearOperator","test_train_covar",":","Covariance","matrix","between","test","and","train","inputs",":","param","~linear_operator.operators.LinearOperator","test_test_covar",":","Covariance","matrix","between","test","inputs",":","return",":","A","LinearOperator","representing","the","predictive","posterior","covariance","of","the","test","points"]
code: def exact_predictive_covar(
      self,
      test_test_covar: LinearOperator,
      test_train_covar: LinearOperator,
  ) -> LinearOperator:
      """
      Computes the posterior predictive covariance of a GP
  
      :param ~linear_operator.operators.LinearOperator test_train_covar:
          Covariance matrix between test and train inputs
      :param ~linear_operator.operators.LinearOperator test_test_covar: Covariance matrix between test inputs
      :return: A LinearOperator representing the predictive posterior covariance of the test points
      """
      if settings.fast_pred_var.on():
          self._last_test_train_covar = test_train_covar
  
      if settings.skip_posterior_variances.on():
          return ZeroLinearOperator(*test_test_covar.size())
  
      if settings.fast_pred_var.off():
          dist = self.train_prior_dist.__class__(
              torch.zeros_like(self.train_prior_dist.mean),
              self.train_prior_dist.lazy_covariance_matrix,
          )
          if settings.detach_test_caches.on():
              train_train_covar = self.likelihood(
                  dist, self.train_inputs
              ).lazy_covariance_matrix.detach()
          else:
              train_train_covar = self.likelihood(
                  dist, self.train_inputs
              ).lazy_covariance_matrix
  
          test_train_covar = to_dense(test_train_covar)
          train_test_covar = test_train_covar.transpose(-1, -2)
          covar_correction_rhs = train_train_covar.solve(
              train_test_covar
          )
          # For efficiency
          if torch.is_tensor(test_test_covar):
              # We can use addmm in the 2d case
              if test_test_covar.dim() == 2:
                  return to_linear_operator(
                      torch.addmm(
                          test_test_covar,
                          test_train_covar,
                          covar_correction_rhs,
                          beta=1,
                          alpha=-1,
                      )
                  )
              else:
                  return to_linear_operator(
                      test_test_covar
                      + test_train_covar @ covar_correction_rhs.mul(-1)
                  )
          # In other cases - we'll use the standard infrastructure
          else:
              return test_test_covar + MatmulLinearOperator(
                  test_train_covar, covar_correction_rhs.mul(-1)
              )
  
      precomputed_cache = self.covar_cache
      covar_inv_quad_form_root = (
          self._exact_predictive_covar_inv_quad_form_root(
              precomputed_cache, test_train_covar
          )
      )
      if torch.is_tensor(test_test_covar):
          return to_linear_operator(
              torch.add(
                  test_test_covar,
                  covar_inv_quad_form_root
                  @ covar_inv_quad_form_root.transpose(-1, -2),
                  alpha=-1,
              )
          )
      else:
          return test_test_covar + MatmulLinearOperator(
              covar_inv_quad_form_root,
              covar_inv_quad_form_root.transpose(-1, -2).mul(-1),
          )
  
imports: import functools
  import string
  import warnings
  import torch
  from linear_operator import to_dense, to_linear_operator
  from linear_operator.operators import AddedDiagLinearOperator, BatchRepeatLinearOperator, ConstantMulLinearOperator, DenseLinearOperator, InterpolatedLinearOperator, LinearOperator, LowRankRootAddedDiagLinearOperator, MaskedLinearOperator, MatmulLinearOperator, RootLinearOperator, ZeroLinearOperator
  from linear_operator.utils.cholesky import psd_safe_cholesky
  from linear_operator.utils.interpolation import left_interp, left_t_interp
  from torch import Tensor
  from ..None import settings
  from ..distributions import MultitaskMultivariateNormal
  from ..lazy import LazyEvaluatedKernelTensor
  from ..utils.memoize import add_to_cache, cached, clear_cache_hook, pop_from_cache
label_desc: Use image node_id 13 for calling the DefaultPredictionStrategy obj's underlying member method code with example usage: obj.exact_predictive_covar(test_test_covar, test_train_covar) and returns: ZeroLinearOperator, to_linear_operator, unknown, unknown, to_linear_operator, to_linear_operator