code: def optimize_objective(
      model: Model,
      bounds: Tensor,
      q: int,
      objective: Optional[MCAcquisitionObjective] = None,
      posterior_transform: Optional[PosteriorTransform] = None,
      linear_constraints: Optional[Tuple[Tensor, Tensor]] = None,
      fixed_features: Optional[Dict[int, float]] = None,
      qmc: bool = True,
      mc_samples: int = 512,
      seed_inner: Optional[int] = None,
      optimizer_options: Optional[Dict[str, Any]] = None,
      post_processing_func: Optional[Callable[[Tensor], Tensor]] = None,
      batch_initial_conditions: Optional[Tensor] = None,
      sequential: bool = False,
  ) -> Tuple[Tensor, Tensor]:
      r"""Optimize an objective under the given model.
  
      Args:
          model: The model to be used in the objective.
          bounds: A `2 x d` tensor of lower and upper bounds for each column of `X`.
          q: The cardinality of input sets on which the objective is to be evaluated.
          objective: The objective to optimize.
          posterior_transform: The posterior transform to be used in the
              acquisition function.
          linear_constraints: A tuple of (A, b). Given `k` linear constraints on a
              `d`-dimensional space, `A` is `k x d` and `b` is `k x 1` such that
              `A x <= b`. (Not used by single task models).
          fixed_features: A dictionary of feature assignments `{feature_index: value}` to
              hold fixed during generation.
          qmc: Toggle for enabling (qmc=1) or disabling (qmc=0) use of Quasi Monte Carlo.
          mc_samples: Integer number of samples used to estimate Monte Carlo objectives.
          seed_inner: Integer seed used to initialize the sampler passed to MCObjective.
          optimizer_options: Table used to lookup keyword arguments for the optimizer.
          post_processing_func: A function that post-processes an optimization
              result appropriately (i.e. according to `round-trip` transformations).
          batch_initial_conditions: A Tensor of initial values for the optimizer.
          sequential: If False, uses joint optimization, otherwise uses sequential
              optimization.
  
      Returns:
          A tuple containing the best input locations and corresponding objective values.
      """
      if optimizer_options is None:
          optimizer_options = {}
  
      if objective is not None:
          sampler_cls = (
              SobolQMCNormalSampler if qmc else IIDNormalSampler
          )
          acq_function = qSimpleRegret(
              model=model,
              objective=objective,
              posterior_transform=posterior_transform,
              sampler=sampler_cls(
                  sample_shape=torch.Size([mc_samples]), seed=seed_inner
              ),
          )
      else:
          acq_function = PosteriorMean(
              model=model, posterior_transform=posterior_transform
          )
  
      if fixed_features:
          acq_function = FixedFeatureAcquisitionFunction(
              acq_function=acq_function,
              d=bounds.shape[-1],
              columns=list(fixed_features.keys()),
              values=list(fixed_features.values()),
          )
          free_feature_dims = list(
              range(len(bounds)) - fixed_features.keys()
          )
          free_feature_bounds = bounds[
              :, free_feature_dims
          ]  # (2, d' <= d)
      else:
          free_feature_bounds = bounds
  
      if linear_constraints is None:
          inequality_constraints = None
      else:
          A, b = linear_constraints
          inequality_constraints = []
          k, d = A.shape
          for i in range(k):
              indices = A[i, :].nonzero(as_tuple=False).squeeze()
              coefficients = -A[i, indices]
              rhs = -b[i, 0]
              inequality_constraints.append(
                  (indices, coefficients, rhs)
              )
  
      return optimize_acqf(
          acq_function=acq_function,
          bounds=free_feature_bounds,
          q=q,
          num_restarts=optimizer_options.get("num_restarts", 60),
          raw_samples=optimizer_options.get("raw_samples", 1024),
          options={
              "batch_limit": optimizer_options.get("batch_limit", 8),
              "maxiter": optimizer_options.get("maxiter", 200),
              "nonnegative": optimizer_options.get(
                  "nonnegative", False
              ),
              "method": optimizer_options.get("method", "L-BFGS-B"),
          },
          inequality_constraints=inequality_constraints,
          fixed_features=None,  # handled inside the acquisition function
          post_processing_func=post_processing_func,
          batch_initial_conditions=batch_initial_conditions,
          return_best_only=True,
          sequential=sequential,
      )
  
imports: from __future__ import annotations
  import inspect
  from typing import Any, Callable, Dict, Hashable, Iterable, List, Optional, Sequence, Tuple, Type, TypeVar, Union
  import torch
  from botorch.acquisition.acquisition import AcquisitionFunction
  from botorch.acquisition.analytic import ConstrainedExpectedImprovement, ExpectedImprovement, LogConstrainedExpectedImprovement, LogExpectedImprovement, LogNoisyExpectedImprovement, LogProbabilityOfImprovement, NoisyExpectedImprovement, PosteriorMean, ProbabilityOfImprovement, UpperConfidenceBound
  from botorch.acquisition.cost_aware import InverseCostWeightedUtility
  from botorch.acquisition.fixed_feature import FixedFeatureAcquisitionFunction
  from botorch.acquisition.joint_entropy_search import qJointEntropySearch
  from botorch.acquisition.knowledge_gradient import qKnowledgeGradient, qMultiFidelityKnowledgeGradient
  from botorch.acquisition.logei import qLogExpectedImprovement, qLogNoisyExpectedImprovement, TAU_MAX, TAU_RELU
  from botorch.acquisition.max_value_entropy_search import qMaxValueEntropy, qMultiFidelityMaxValueEntropy
  from botorch.acquisition.monte_carlo import qExpectedImprovement, qNoisyExpectedImprovement, qProbabilityOfImprovement, qSimpleRegret, qUpperConfidenceBound
  from botorch.acquisition.multi_objective import ExpectedHypervolumeImprovement, MCMultiOutputObjective, qExpectedHypervolumeImprovement, qNoisyExpectedHypervolumeImprovement
  from botorch.acquisition.multi_objective.logei import qLogNoisyExpectedHypervolumeImprovement
  from botorch.acquisition.multi_objective.objective import AnalyticMultiOutputObjective, IdentityAnalyticMultiOutputObjective, IdentityMCMultiOutputObjective
  from botorch.acquisition.multi_objective.utils import get_default_partitioning_alpha
  from botorch.acquisition.objective import ConstrainedMCObjective, IdentityMCObjective, MCAcquisitionObjective, PosteriorTransform
  from botorch.acquisition.preference import AnalyticExpectedUtilityOfBestOption
  from botorch.acquisition.risk_measures import RiskMeasureMCObjective
  from botorch.acquisition.utils import compute_best_feasible_objective, expand_trace_observations, get_infeasible_cost, get_optimal_samples, project_to_target_fidelity
  from botorch.exceptions.errors import UnsupportedError
  from botorch.models.cost import AffineFidelityCostModel
  from botorch.models.deterministic import FixedSingleSampleModel
  from botorch.models.gpytorch import GPyTorchModel
  from botorch.models.model import Model
  from botorch.optim.optimize import optimize_acqf
  from botorch.sampling.base import MCSampler
  from botorch.sampling.normal import IIDNormalSampler, SobolQMCNormalSampler
  from botorch.utils.containers import BotorchContainer
  from botorch.utils.datasets import SupervisedDataset
  from botorch.utils.multi_objective.box_decompositions.non_dominated import FastNondominatedPartitioning, NondominatedPartitioning
  from torch import Tensor
label_desc: Use image node_id 32 for calling a global function with example usage: optimize_objective(model, bounds, q, objective, posterior_transform, linear_constraints, fixed_features, qmc, mc_samples, seed_inner, optimizer_options, post_processing_func, batch_initial_conditions, sequential) and returns: optimize_acqf