class_docstr: The acquisition function for MESMO.
  
  This acquisition function computes the mutual information of
  Pareto frontier and a candidate point. See [Belakaria2019]_ for
  a detailed discussion.
  
  q > 1 is supported through cyclic optimization and fantasies.
  
  Noisy observations are support by computing information gain with
  observation noise as in Appendix C in [Takeno2020mfmves]_.
  
  Note: this only supports maximization.
  
  Attributes:
      _default_sample_shape: The `sample_shape` for the default sampler.
  
  Example:
      >>> model = SingleTaskGP(train_X, train_Y)
      >>> MESMO = qMultiObjectiveMaxValueEntropy(model, sample_pfs)
      >>> mesmo = MESMO(test_X)
class_docstr_tok: ["The","acquisition","function","for","MESMO",".","This","acquisition","function","computes","the","mutual","information","of","Pareto","frontier","and","a","candidate","point",".","See","[","Belakaria2019","]","_","for","a","detailed","discussion",".","q",">","1","is","supported","through","cyclic","optimization","and","fantasies",".","Noisy","observations","are","support","by","computing","information","gain","with","observation","noise","as","in","Appendix","C","in","[","Takeno2020mfmves","]","_",".","Note",":","this","only","supports","maximization",".","Attributes",":","_default_sample_shape",":","The","`","sample_shape","`","for","the","default","sampler",".","Example",":",">",">",">","model","=","SingleTaskGP","(","train_X",",","train_Y",")",">",">",">","MESMO","=","qMultiObjectiveMaxValueEntropy","(","model",",","sample_pfs",")",">",">",">","mesmo","=","MESMO","(","test_X",")"]
docstr: Sample max values for MC approximation of the expectation in MES
docstr_tok: ["Sample","max","values","for","MC","approximation","of","the","expectation","in","MES"]
code: def _sample_max_values(self) -> None:
      r"""Sample max values for MC approximation of the expectation in MES"""
      with torch.no_grad():
          # num_samples x (num_fantasies) x n_pareto_points x m
          sampled_pfs = self.sample_pareto_frontiers(self.mo_model)
          if sampled_pfs.ndim == 3:
              # add fantasy dim
              sampled_pfs = sampled_pfs.unsqueeze(-3)
          # take component-wise max value
          self.posterior_max_values = sampled_pfs.max(dim=-2).values
  
imports: from __future__ import annotations
  from math import pi
  from typing import Any, Callable, Optional, Tuple, Union
  import torch
  from botorch.acquisition.max_value_entropy_search import qMaxValueEntropy
  from botorch.acquisition.multi_objective.joint_entropy_search import LowerBoundMultiObjectiveEntropySearch
  from botorch.acquisition.multi_objective.monte_carlo import MultiObjectiveMCAcquisitionFunction
  from botorch.models.converter import batched_multi_output_to_single_output, model_list_to_batched
  from botorch.models.model import Model
  from botorch.models.model_list_gp_regression import ModelListGP
  from botorch.posteriors.gpytorch import GPyTorchPosterior
  from botorch.sampling.base import MCSampler
  from botorch.sampling.normal import SobolQMCNormalSampler
  from botorch.utils.transforms import concatenate_pending_points, t_batch_mode_transform
  from torch import Tensor
label_desc: Use image node_id 3 for calling the qMultiObjectiveMaxValueEntropy obj's underlying member method code with example usage: obj._sample_max_values() without return types