code: def gen_loo_cv_folds(
      train_X: Tensor,
      train_Y: Tensor,
      train_Yvar: Optional[Tensor] = None,
  ) -> CVFolds:
      r"""Generate LOO CV folds w.r.t. to `n`.
  
      Args:
          train_X: A `n x d` or `batch_shape x n x d` (batch mode) tensor of training
              features.
          train_Y: A `n x (m)` or `batch_shape x n x (m)` (batch mode) tensor of
              training observations.
          train_Yvar: A `batch_shape x n x (m)` or `batch_shape x n x (m)`
              (batch mode) tensor of observed measurement noise.
  
      Returns:
          CVFolds tuple with the following fields
  
          - train_X: A `n x (n-1) x d` or `batch_shape x n x (n-1) x d` tensor of
            training features.
          - test_X: A `n x 1 x d` or `batch_shape x n x 1 x d` tensor of test features.
          - train_Y: A `n x (n-1) x m` or `batch_shape x n x (n-1) x m` tensor of
            training observations.
          - test_Y: A `n x 1 x m` or `batch_shape x n x 1 x m` tensor of test
            observations.
          - train_Yvar: A `n x (n-1) x m` or `batch_shape x n x (n-1) x m` tensor
            of observed measurement noise.
          - test_Yvar: A `n x 1 x m` or `batch_shape x n x 1 x m` tensor of observed
            measurement noise.
  
      Example:
          >>> train_X = torch.rand(10, 1)
          >>> train_Y = torch.sin(6 * train_X) + 0.2 * torch.rand_like(train_X)
          >>> cv_folds = gen_loo_cv_folds(train_X, train_Y)
      """
      masks = torch.eye(
          train_X.shape[-2], dtype=torch.uint8, device=train_X.device
      )
      masks = masks.to(dtype=torch.bool)
      if train_Y.dim() < train_X.dim():
          # add output dimension
          train_Y = train_Y.unsqueeze(-1)
          if train_Yvar is not None:
              train_Yvar = train_Yvar.unsqueeze(-1)
      train_X_cv = torch.cat(
          [train_X[..., ~m, :].unsqueeze(dim=-3) for m in masks], dim=-3
      )
      test_X_cv = torch.cat(
          [train_X[..., m, :].unsqueeze(dim=-3) for m in masks], dim=-3
      )
      train_Y_cv = torch.cat(
          [train_Y[..., ~m, :].unsqueeze(dim=-3) for m in masks], dim=-3
      )
      test_Y_cv = torch.cat(
          [train_Y[..., m, :].unsqueeze(dim=-3) for m in masks], dim=-3
      )
      if train_Yvar is None:
          train_Yvar_cv = None
          test_Yvar_cv = None
      else:
          train_Yvar_cv = torch.cat(
              [train_Yvar[..., ~m, :].unsqueeze(dim=-3) for m in masks],
              dim=-3,
          )
          test_Yvar_cv = torch.cat(
              [train_Yvar[..., m, :].unsqueeze(dim=-3) for m in masks],
              dim=-3,
          )
      return CVFolds(
          train_X=train_X_cv,
          test_X=test_X_cv,
          train_Y=train_Y_cv,
          test_Y=test_Y_cv,
          train_Yvar=train_Yvar_cv,
          test_Yvar=test_Yvar_cv,
      )
  
file_path: botorch/botorch/cross_validation.py
imports: from __future__ import annotations
  from typing import Any, Dict, NamedTuple, Optional, Type
  import torch
  from botorch.fit import fit_gpytorch_mll
  from botorch.models.gpytorch import GPyTorchModel
  from botorch.optim.utils import _filter_kwargs
  from botorch.posteriors.gpytorch import GPyTorchPosterior
  from gpytorch.mlls.marginal_log_likelihood import MarginalLogLikelihood
  from torch import Tensor
label_desc: Use image node_id 1 for calling a global function with example usage: gen_loo_cv_folds(train_X, train_Y, train_Yvar) and returns: CVFolds