class_docstr: Multi-task GP with Kronecker structure, using an ICM kernel.
  
  This model assumes the "block design" case, i.e., it requires that all tasks
  are observed at all data points.
  
  For posterior sampling, this model uses Matheron's rule [Doucet2010sampl] to compute
  the posterior over all tasks as in [Maddox2021bohdo] by exploiting Kronecker
  structure.
  
  When a multi-fidelity model has Kronecker structure, this means there is one
  covariance kernel over the fidelity features (call it `K_f`) and another over
  the rest of the input parameters (call it `K_i`), and the resulting covariance
  across inputs and fidelities is given by the Kronecker product of the two
  covariance matrices. This is equivalent to saying the covariance between
  two input and feature pairs is given by
  
  K((parameter_1, fidelity_1), (parameter_2, fidelity_2))
      = K_f(fidelity_1, fidelity_2) * K_i(parameter_1, parameter_2).
  
  Then the covariance matrix of `n_i` parameters and `n_f` fidelities can be
  codified as a Kronecker product of an `n_i x n_i` matrix and an
  `n_f x n_f` matrix, which is far more parsimonious than specifying the
  whole `(n_i * n_f) x (n_i * n_f)` covariance matrix.
  
  Example:
      >>> train_X = torch.rand(10, 2)
      >>> train_Y = torch.cat([f_1(X), f_2(X)], dim=-1)
      >>> model = KroneckerMultiTaskGP(train_X, train_Y)
class_docstr_tok: ["Multi-task","GP","with","Kronecker","structure",",","using","an","ICM","kernel",".","This","model","assumes","the","``","block","design","''","case",",","i.e.",",","it","requires","that","all","tasks","are","observed","at","all","data","points",".","For","posterior","sampling",",","this","model","uses","Matheron","'s","rule","[","Doucet2010sampl","]","to","compute","the","posterior","over","all","tasks","as","in","[","Maddox2021bohdo","]","by","exploiting","Kronecker","structure",".","When","a","multi-fidelity","model","has","Kronecker","structure",",","this","means","there","is","one","covariance","kernel","over","the","fidelity","features","(","call","it","`","K_f","`",")","and","another","over","the","rest","of","the","input","parameters","(","call","it","`","K_i","`",")",",","and","the","resulting","covariance","across","inputs","and","fidelities","is","given","by","the","Kronecker","product","of","the","two","covariance","matrices",".","This","is","equivalent","to","saying","the","covariance","between","two","input","and","feature","pairs","is","given","by","K","(","(","parameter_1",",","fidelity_1",")",",","(","parameter_2",",","fidelity_2",")",")","=","K_f","(","fidelity_1",",","fidelity_2",")","*","K_i","(","parameter_1",",","parameter_2",")",".","Then","the","covariance","matrix","of","`","n_i","`","parameters","and","`","n_f","`","fidelities","can","be","codified","as","a","Kronecker","product","of","an","`","n_i","x","n_i","`","matrix","and","an","`","n_f","x","n_f","`","matrix",",","which","is","far","more","parsimonious","than","specifying","the","whole","`","(","n_i","*","n_f",")","x","(","n_i","*","n_f",")","`","covariance","matrix",".","Example",":",">",">",">","train_X","=","torch.rand","(","10",",","2",")",">",">",">","train_Y","=","torch.cat","(","[","f_1","(","X",")",",","f_2","(","X",")","]",",","dim=-1",")",">",">",">","model","=","KroneckerMultiTaskGP","(","train_X",",","train_Y",")"]
code: def predictive_mean_cache(self):
      train_x = self.transform_inputs(self.train_inputs[0])
      train_noise = self.likelihood._shaped_noise_covar(train_x.shape)
      if detach_test_caches.on():
          train_noise = train_noise.detach()
  
      train_diff = self.train_targets - self.mean_module(train_x)
      train_solve = (self.train_full_covar + train_noise).solve(
          train_diff.reshape(*train_diff.shape[:-2], -1)
      )
      if detach_test_caches.on():
          train_solve = train_solve.detach()
  
      return train_solve
  
imports: from __future__ import annotations
  import math
  import warnings
  from typing import Any, Dict, List, Optional, Tuple, Union
  import torch
  from botorch.acquisition.objective import PosteriorTransform
  from botorch.models.gpytorch import GPyTorchModel, MultiTaskGPyTorchModel
  from botorch.models.model import FantasizeMixin
  from botorch.models.transforms.input import InputTransform
  from botorch.models.transforms.outcome import OutcomeTransform
  from botorch.models.utils.gpytorch_modules import get_matern_kernel_with_gamma_prior, MIN_INFERRED_NOISE_LEVEL
  from botorch.posteriors.multitask import MultitaskGPPosterior
  from botorch.utils.datasets import MultiTaskDataset, SupervisedDataset
  from gpytorch.constraints import GreaterThan
  from gpytorch.distributions.multitask_multivariate_normal import MultitaskMultivariateNormal
  from gpytorch.distributions.multivariate_normal import MultivariateNormal
  from gpytorch.kernels.index_kernel import IndexKernel
  from gpytorch.kernels.matern_kernel import MaternKernel
  from gpytorch.kernels.multitask_kernel import MultitaskKernel
  from gpytorch.likelihoods.gaussian_likelihood import FixedNoiseGaussianLikelihood, GaussianLikelihood
  from gpytorch.likelihoods.likelihood import Likelihood
  from gpytorch.likelihoods.multitask_gaussian_likelihood import MultitaskGaussianLikelihood
  from gpytorch.means import MultitaskMean
  from gpytorch.means.constant_mean import ConstantMean
  from gpytorch.models.exact_gp import ExactGP
  from gpytorch.module import Module
  from gpytorch.priors.lkj_prior import LKJCovariancePrior
  from gpytorch.priors.prior import Prior
  from gpytorch.priors.smoothed_box_prior import SmoothedBoxPrior
  from gpytorch.priors.torch_priors import GammaPrior
  from gpytorch.settings import detach_test_caches
  from gpytorch.utils.errors import CachingError
  from gpytorch.utils.memoize import cached, pop_from_cache
  from linear_operator.operators import BatchRepeatLinearOperator, CatLinearOperator, DiagLinearOperator, KroneckerProductDiagLinearOperator, KroneckerProductLinearOperator, RootLinearOperator, to_linear_operator
  from torch import Tensor
label_desc: Use image node_id 5 for calling the KroneckerMultiTaskGP obj's underlying member method code with example usage: obj.predictive_mean_cache() and returns: train_solve