class_docstr: MC-based batch Log Expected Improvement.
  
  This computes qLogEI by
  (1) sampling the joint posterior over q points,
  (2) evaluating the smoothed log improvement over the current best for each sample,
  (3) smoothly maximizing over q, and
  (4) averaging over the samples in log space.
  
  See [Ament2023logei]_ for details. Formally,
  
  `qLogEI(X) ~ log(qEI(X)) = log(E(max(max Y - best_f, 0)))`.
  
  where `Y ~ f(X)`, and `X = (x_1,...,x_q)`, .
  
  Example:
      >>> model = SingleTaskGP(train_X, train_Y)
      >>> best_f = train_Y.max()[0]
      >>> sampler = SobolQMCNormalSampler(1024)
      >>> qLogEI = qLogExpectedImprovement(model, best_f, sampler)
      >>> qei = qLogEI(test_X)
class_docstr_tok: ["MC-based","batch","Log","Expected","Improvement",".","This","computes","qLogEI","by","(","1",")","sampling","the","joint","posterior","over","q","points",",","(","2",")","evaluating","the","smoothed","log","improvement","over","the","current","best","for","each","sample",",","(","3",")","smoothly","maximizing","over","q",",","and","(","4",")","averaging","over","the","samples","in","log","space",".","See","[","Ament2023logei","]","_","for","details",".","Formally",",","`","qLogEI","(","X",")","~","log","(","qEI","(","X",")",")","=","log","(","E","(","max","(","max","Y","-","best_f",",","0",")",")",")","`",".","where","`","Y","~","f","(","X",")","`",",","and","`","X","=","(","x_1",",","...",",","x_q",")","`",",",".","Example",":",">",">",">","model","=","SingleTaskGP","(","train_X",",","train_Y",")",">",">",">","best_f","=","train_Y.max","(",")","[","0","]",">",">",">","sampler","=","SobolQMCNormalSampler","(","1024",")",">",">",">","qLogEI","=","qLogExpectedImprovement","(","model",",","best_f",",","sampler",")",">",">",">","qei","=","qLogEI","(","test_X",")"]
docstr: Evaluate qLogExpectedImprovement on the candidate set `X`.
  
  Args:
      obj: `mc_shape x batch_shape x q`-dim Tensor of MC objective values.
  
  Returns:
      A `mc_shape x batch_shape x q`-dim Tensor of expected improvement values.
docstr_tok: ["Evaluate","qLogExpectedImprovement","on","the","candidate","set","`","X","`",".","Args",":","obj",":","`","mc_shape","x","batch_shape","x","q","`","-dim","Tensor","of","MC","objective","values",".","Returns",":","A","`","mc_shape","x","batch_shape","x","q","`","-dim","Tensor","of","expected","improvement","values","."]
code: def _sample_forward(self, obj: Tensor) -> Tensor:
      r"""Evaluate qLogExpectedImprovement on the candidate set `X`.
  
      Args:
          obj: `mc_shape x batch_shape x q`-dim Tensor of MC objective values.
  
      Returns:
          A `mc_shape x batch_shape x q`-dim Tensor of expected improvement values.
      """
      li = _log_improvement(
          Y=obj,
          best_f=self.best_f,
          tau=self.tau_relu,
          fat=self._fat,
      )
      return li
  
imports: from __future__ import annotations
  from copy import deepcopy
  from functools import partial
  from typing import Any, Callable, List, Optional, Tuple, TypeVar, Union
  import torch
  from botorch.acquisition.cached_cholesky import CachedCholeskyMCSamplerMixin
  from botorch.acquisition.monte_carlo import SampleReducingMCAcquisitionFunction
  from botorch.acquisition.objective import ConstrainedMCObjective, MCAcquisitionObjective, PosteriorTransform
  from botorch.acquisition.utils import compute_best_feasible_objective, prune_inferior_points
  from botorch.exceptions.errors import BotorchError
  from botorch.models.model import Model
  from botorch.sampling.base import MCSampler
  from botorch.utils.safe_math import fatmax, log_fatplus, log_softplus, logmeanexp, smooth_amax
  from botorch.utils.transforms import match_batch_shape
  from torch import Tensor
label_desc: Use image node_id 2 for calling the qLogExpectedImprovement obj's underlying member method code with example usage: obj._sample_forward(obj) and returns: li