class_docstr: The acquisition function for the multi-objective Max-value Entropy Search,
  where the batches `q > 1` are supported through the lower bound formulation.
  
  This acquisition function computes the mutual information between the observation
  at a candidate point `X` and the Pareto optimal outputs.
  
  See [Tu2022]_ for a discussion on the estimation procedure.
  
  NOTES:
  (i) The estimated acquisition value could be negative.
  
  (ii) The lower bound batch acquisition function might not be monotone in the
  sense that adding more elements to the batch does not necessarily increase the
  acquisition value. Specifically, the acquisition value can become smaller when
  more inputs are added.
class_docstr_tok: ["The","acquisition","function","for","the","multi-objective","Max-value","Entropy","Search",",","where","the","batches","`","q",">","1","`","are","supported","through","the","lower","bound","formulation",".","This","acquisition","function","computes","the","mutual","information","between","the","observation","at","a","candidate","point","`","X","`","and","the","Pareto","optimal","outputs",".","See","[","Tu2022","]","_","for","a","discussion","on","the","estimation","procedure",".","NOTES",":","(","i",")","The","estimated","acquisition","value","could","be","negative",".","(","ii",")","The","lower","bound","batch","acquisition","function","might","not","be","monotone","in","the","sense","that","adding","more","elements","to","the","batch","does","not","necessarily","increase","the","acquisition","value",".","Specifically",",","the","acquisition","value","can","become","smaller","when","more","inputs","are","added","."]
docstr: Compute the samples and log-probability associated with a posterior
  distribution.
  
  Args:
      posterior: The posterior distribution, which includes the observation
          noise.
  
  Returns:
      A two-element tuple containing
  
      - samples: A `num_mc_samples x batch_shape x num_pareto_samples x q x 1
          x M`-dim Tensor containing the Monte Carlo samples.
      - samples_log_prob: A `num_mc_samples x batch_shape x num_pareto_samples
          x q`-dim Tensor containing the log-probabilities of the Monte Carlo
          samples.
docstr_tok: ["Compute","the","samples","and","log-probability","associated","with","a","posterior","distribution",".","Args",":","posterior",":","The","posterior","distribution",",","which","includes","the","observation","noise",".","Returns",":","A","two-element","tuple","containing","-","samples",":","A","`","num_mc_samples","x","batch_shape","x","num_pareto_samples","x","q","x","1","x","M","`","-dim","Tensor","containing","the","Monte","Carlo","samples",".","-","samples_log_prob",":","A","`","num_mc_samples","x","batch_shape","x","num_pareto_samples","x","q","`","-dim","Tensor","containing","the","log-probabilities","of","the","Monte","Carlo","samples","."]
code: def _compute_monte_carlo_variables(
      self, posterior: GPyTorchPosterior
  ) -> Tuple[Tensor, Tensor]:
      r"""Compute the samples and log-probability associated with a posterior
      distribution.
  
      Args:
          posterior: The posterior distribution, which includes the observation
              noise.
  
      Returns:
          A two-element tuple containing
  
          - samples: A `num_mc_samples x batch_shape x num_pareto_samples x q x 1
              x M`-dim Tensor containing the Monte Carlo samples.
          - samples_log_prob: A `num_mc_samples x batch_shape x num_pareto_samples
              x q`-dim Tensor containing the log-probabilities of the Monte Carlo
              samples.
      """
  
      # `num_mc_samples x batch_shape x q x 1 x M`
      samples = self.get_posterior_samples(posterior)
  
      # `num_mc_samples x batch_shape x q`
      if self.model.num_outputs == 1:
          samples_log_prob = posterior.mvn.log_prob(samples.squeeze(-1))
      else:
          samples_log_prob = posterior.mvn.log_prob(samples)
  
      # Expand shape to `num_mc_samples x batch_shape x num_pareto_samples x
      # q x 1 x M`
      new_shape = (
          samples.shape[:-3]
          + torch.Size([self.num_pareto_samples])
          + samples.shape[-3:]
      )
      samples = samples.unsqueeze(-4).expand(new_shape)
  
      # Expand shape to `num_mc_samples x batch_shape x num_pareto_samples x q`
      new_shape = (
          samples_log_prob.shape[:-1]
          + torch.Size([self.num_pareto_samples])
          + samples_log_prob.shape[-1:]
      )
      samples_log_prob = samples_log_prob.unsqueeze(-2).expand(
          new_shape
      )
  
      return samples, samples_log_prob
  
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 qLowerBoundMultiObjectiveMaxValueEntropySearch obj's underlying member method code with example usage: obj._compute_monte_carlo_variables(posterior) and returns: samples,  samples_log_prob