class_docstr: Max-value entropy search.
  
  Args:
      cost_intercept: The cost intercept for the affine cost of the form
          `cost_intercept + n`, where `n` is the number of generated points.
          Only used for multi-fidelity optimzation (i.e., if fidelity_features
          are present).
      linear_truncated: If `False`, use an alternate downsampling + exponential
          decay Kernel instead of the default `LinearTruncatedFidelityKernel`
          (only relevant for multi-fidelity optimization).
      kwargs: Model-specific kwargs.
code: def gen(
      self,
      n: int,
      search_space_digest: SearchSpaceDigest,
      torch_opt_config: TorchOptConfig,
  ) -> TorchGenResults:
      if (
          torch_opt_config.linear_constraints is not None
          or torch_opt_config.outcome_constraints is not None
      ):
          raise UnsupportedError(
              "Constraints are not yet supported by max-value entropy search!"
          )
  
      if len(torch_opt_config.objective_weights) > 1:
          raise UnsupportedError(
              "Models with multiple outcomes are not yet supported by MES!"
          )
  
      options = torch_opt_config.model_gen_options or {}
      acf_options = options.get("acquisition_function_kwargs", {})
      optimizer_options = options.get("optimizer_kwargs", {})
  
      X_pending, X_observed = _get_X_pending_and_observed(
          Xs=self.Xs,
          objective_weights=torch_opt_config.objective_weights,
          bounds=search_space_digest.bounds,
          pending_observations=torch_opt_config.pending_observations,
          outcome_constraints=torch_opt_config.outcome_constraints,
          linear_constraints=torch_opt_config.linear_constraints,
          fixed_features=torch_opt_config.fixed_features,
      )
  
      model = self.model
  
      # subset model only to the outcomes we need for the optimization
      if options.get("subset_model", True):
          subset_model_results = subset_model(
              model=model,
              objective_weights=torch_opt_config.objective_weights,
              outcome_constraints=torch_opt_config.outcome_constraints,
          )
          model = subset_model_results.model
          objective_weights = subset_model_results.objective_weights
      else:
          objective_weights = torch_opt_config.objective_weights
  
      # get the acquisition function
      num_fantasies = acf_options.get("num_fantasies", 16)
      num_mv_samples = acf_options.get("num_mv_samples", 10)
      num_y_samples = acf_options.get("num_y_samples", 128)
      candidate_size = acf_options.get("candidate_size", 1000)
      num_restarts = optimizer_options.get("num_restarts", 40)
      raw_samples = optimizer_options.get("raw_samples", 1024)
  
      # generate the discrete points in the design space to sample max values
      bounds_ = torch.tensor(
          search_space_digest.bounds,
          dtype=self.dtype,
          device=self.device,
      )
      bounds_ = bounds_.transpose(0, 1)
  
      candidate_set = torch.rand(
          candidate_size, bounds_.size(1), device=self.device
      )
      candidate_set = (
          bounds_[0] + (bounds_[1] - bounds_[0]) * candidate_set
      )
  
      target_fidelities = {
          k: v
          for k, v in search_space_digest.target_values.items()
          if k in search_space_digest.fidelity_features
      }
      acq_function = _instantiate_MES(
          model=model,
          candidate_set=candidate_set,
          num_fantasies=num_fantasies,
          num_trace_observations=options.get(
              "num_trace_observations", 0
          ),
          num_mv_samples=num_mv_samples,
          num_y_samples=num_y_samples,
          X_pending=X_pending,
          maximize=True if objective_weights[0] == 1 else False,
          target_fidelities=target_fidelities,
          fidelity_weights=options.get("fidelity_weights"),
          cost_intercept=self.cost_intercept,
      )
  
      # optimize and get new points
      botorch_rounding_func = get_rounding_func(
          torch_opt_config.rounding_func
      )
      opt_options: Dict[str, Union[bool, float, int, str]] = {
          "batch_limit": 8,
          "maxiter": 200,
          "method": "L-BFGS-B",
          "nonnegative": False,
      }
      opt_options.update(optimizer_options.get("options", {}))
      candidates, _ = optimize_acqf(
          acq_function=acq_function,
          bounds=bounds_,
          q=n,
          inequality_constraints=None,
          fixed_features=torch_opt_config.fixed_features,
          post_processing_func=botorch_rounding_func,
          num_restarts=num_restarts,
          raw_samples=raw_samples,
          options=opt_options,
          sequential=True,
      )
      return TorchGenResults(
          points=candidates.detach().cpu(),
          weights=torch.ones(n, dtype=self.dtype),
      )
  
imports: from typing import Any, Dict, List, Optional, Tuple, Union
  import torch
  from ax.core.search_space import SearchSpaceDigest
  from ax.models.torch.botorch import BotorchModel, get_rounding_func
  from ax.models.torch.botorch_defaults import recommend_best_out_of_sample_point
  from ax.models.torch.utils import _get_X_pending_and_observed, get_out_of_sample_best_point_acqf
  from ax.models.torch_base import TorchGenResults, TorchModel, TorchOptConfig
  from ax.utils.common.docutils import copy_doc
  from ax.utils.common.typeutils import not_none
  from botorch.acquisition.acquisition import AcquisitionFunction
  from botorch.acquisition.cost_aware import InverseCostWeightedUtility
  from botorch.acquisition.max_value_entropy_search import qMaxValueEntropy, qMultiFidelityMaxValueEntropy
  from botorch.acquisition.utils import expand_trace_observations, project_to_target_fidelity
  from botorch.exceptions.errors import UnsupportedError
  from botorch.models.cost import AffineFidelityCostModel
  from botorch.models.model import Model
  from botorch.optim.optimize import optimize_acqf
  from torch import Tensor
  from .utils import subset_model
label_desc: Use image node_id 2 for calling the MaxValueEntropySearch obj's underlying member method code with example usage: obj.gen(n, search_space_digest, torch_opt_config) and returns: TorchGenResults