code: def sample_q_batches_from_polytope(
      n: int,
      q: int,
      bounds: Tensor,
      n_burnin: int,
      thinning: int,
      seed: int,
      inequality_constraints: Optional[
          List[Tuple[Tensor, Tensor, float]]
      ] = None,
      equality_constraints: Optional[
          List[Tuple[Tensor, Tensor, float]]
      ] = None,
  ) -> Tensor:
      r"""Samples `n` q-baches from a polytope of dimension `d`.
  
      Args:
          n: Number of q-batches to sample.
          q: Number of samples per q-batch
          bounds: A `2 x d` tensor of lower and upper bounds for each column of `X`.
          n_burnin: The number of burn-in samples for the Markov chain sampler.
              thinning: The amount of thinning (number of steps to take between
              returning samples).
          seed: The random seed.
          inequality_constraints: A list of tuples (indices, coefficients, rhs),
              with each tuple encoding an inequality constraint of the form
              `\sum_i (X[indices[i]] * coefficients[i]) >= rhs`.
          equality_constraints: A list of tuples (indices, coefficients, rhs),
              with each tuple encoding an inequality constraint of the form
              `\sum_i (X[indices[i]] * coefficients[i]) = rhs`.
  
      Returns:
          A `n x q x d`-dim tensor of samples.
      """
  
      # check if inter-point constraints are present
      inter_point = any(
          len(indices.shape) > 1
          for constraints in (
              inequality_constraints or [],
              equality_constraints or [],
          )
          for indices, _, _ in constraints
      )
  
      if inter_point:
          samples = get_polytope_samples(
              n=n,
              bounds=torch.hstack([bounds for _ in range(q)]),
              inequality_constraints=transform_constraints(
                  constraints=inequality_constraints,
                  q=q,
                  d=bounds.shape[1],
              ),
              equality_constraints=transform_constraints(
                  constraints=equality_constraints,
                  q=q,
                  d=bounds.shape[1],
              ),
              seed=seed,
              n_burnin=n_burnin,
              thinning=thinning * q,
          )
      else:
          samples = get_polytope_samples(
              n=n * q,
              bounds=bounds,
              inequality_constraints=inequality_constraints,
              equality_constraints=equality_constraints,
              seed=seed,
              n_burnin=n_burnin,
              thinning=thinning,
          )
      return samples.view(n, q, -1).cpu()
  
imports: from __future__ import annotations
  import warnings
  from math import ceil
  from typing import Callable, Dict, List, Optional, Tuple, Union
  import torch
  from botorch import settings
  from botorch.acquisition import analytic, monte_carlo, multi_objective
  from botorch.acquisition.acquisition import AcquisitionFunction
  from botorch.acquisition.fixed_feature import FixedFeatureAcquisitionFunction
  from botorch.acquisition.knowledge_gradient import _get_value_function, qKnowledgeGradient
  from botorch.acquisition.multi_objective.hypervolume_knowledge_gradient import _get_hv_value_function, qHypervolumeKnowledgeGradient, qMultiFidelityHypervolumeKnowledgeGradient
  from botorch.exceptions.errors import BotorchTensorDimensionError, UnsupportedError
  from botorch.exceptions.warnings import BadInitialCandidatesWarning, BotorchWarning, SamplingWarning
  from botorch.models.model import Model
  from botorch.optim.utils import fix_features, get_X_baseline
  from botorch.utils.multi_objective.pareto import is_non_dominated
  from botorch.utils.sampling import batched_multinomial, draw_sobol_samples, get_polytope_samples, manual_seed
  from botorch.utils.transforms import normalize, standardize, unnormalize
  from torch import Tensor
  from torch.distributions import Normal
  from torch.quasirandom import SobolEngine
label_desc: Use image node_id 4 for calling a global function with example usage: sample_q_batches_from_polytope(n, q, bounds, n_burnin, thinning, seed, inequality_constraints, equality_constraints) and returns: samples