class_docstr: MC-based batch Log Noisy Expected Improvement.
  
  This function does not assume a `best_f` is known (which would require
  noiseless observations). Instead, it uses samples from the joint posterior
  over the `q` test points and previously observed points. A smooth approximation
  to the canonical improvement over previously observed points is computed
  for each sample and the logarithm of the average is returned.
  
  See [Ament2023logei]_ for details. Formally,
  
  `qLogNEI(X) ~ log(qNEI(X)) = Log E(max(max Y - max Y_baseline, 0))`,
  
  where `(Y, Y_baseline) ~ f((X, X_baseline)), X = (x_1,...,x_q)`.
  
  Example:
      >>> model = SingleTaskGP(train_X, train_Y)
      >>> sampler = SobolQMCNormalSampler(1024)
      >>> qLogNEI = qLogNoisyExpectedImprovement(model, train_X, sampler)
      >>> acqval = qLogNEI(test_X)
class_docstr_tok: ["MC-based","batch","Log","Noisy","Expected","Improvement",".","This","function","does","not","assume","a","`","best_f","`","is","known","(","which","would","require","noiseless","observations",")",".","Instead",",","it","uses","samples","from","the","joint","posterior","over","the","`","q","`","test","points","and","previously","observed","points",".","A","smooth","approximation","to","the","canonical","improvement","over","previously","observed","points","is","computed","for","each","sample","and","the","logarithm","of","the","average","is","returned",".","See","[","Ament2023logei","]","_","for","details",".","Formally",",","`","qLogNEI","(","X",")","~","log","(","qNEI","(","X",")",")","=","Log","E","(","max","(","max","Y","-","max","Y_baseline",",","0",")",")","`",",","where","`","(","Y",",","Y_baseline",")","~","f","(","(","X",",","X_baseline",")",")",",","X","=","(","x_1",",","...",",","x_q",")","`",".","Example",":",">",">",">","model","=","SingleTaskGP","(","train_X",",","train_Y",")",">",">",">","sampler","=","SobolQMCNormalSampler","(","1024",")",">",">",">","qLogNEI","=","qLogNoisyExpectedImprovement","(","model",",","train_X",",","sampler",")",">",">",">","acqval","=","qLogNEI","(","test_X",")"]
docstr: Evaluate qLogNoisyExpectedImprovement per sample on the candidate set `X`.
  
  Args:
      obj: `mc_shape x batch_shape x q`-dim Tensor of MC objective values.
  
  Returns:
      A `sample_shape x batch_shape x q`-dim Tensor of log noisy expected smoothed
      improvement values.
docstr_tok: ["Evaluate","qLogNoisyExpectedImprovement","per","sample","on","the","candidate","set","`","X","`",".","Args",":","obj",":","`","mc_shape","x","batch_shape","x","q","`","-dim","Tensor","of","MC","objective","values",".","Returns",":","A","`","sample_shape","x","batch_shape","x","q","`","-dim","Tensor","of","log","noisy","expected","smoothed","improvement","values","."]
code: def _sample_forward(self, obj: Tensor) -> Tensor:
      r"""Evaluate qLogNoisyExpectedImprovement per sample on the candidate set `X`.
  
      Args:
          obj: `mc_shape x batch_shape x q`-dim Tensor of MC objective values.
  
      Returns:
          A `sample_shape x batch_shape x q`-dim Tensor of log noisy expected smoothed
          improvement values.
      """
      return _log_improvement(
          Y=obj,
          best_f=self.compute_best_f(obj),
          tau=self.tau_relu,
          fat=self._fat,
      )
  
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 qLogNoisyExpectedImprovement obj's underlying member method code with example usage: obj._sample_forward(obj) and returns: _log_improvement