code: def get_polytope_samples(
      n: int,
      bounds: Tensor,
      inequality_constraints: Optional[
          List[Tuple[Tensor, Tensor, float]]
      ] = None,
      equality_constraints: Optional[
          List[Tuple[Tensor, Tensor, float]]
      ] = None,
      seed: Optional[int] = None,
      thinning: int = 32,
      n_burnin: int = 10_000,
  ) -> Tensor:
      r"""Sample from polytope defined by box bounds and (in)equality constraints.
  
      This uses a hit-and-run Markov chain sampler.
  
      TODO: make this method return the sampler object, to avoid doing burn-in
      every time we draw samples.
  
      Args:
          n: The number of samples.
          bounds: A `2 x d`-dim tensor containing the box bounds.
          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`.
          seed: The random seed.
          thinning: The amount of thinning.
          n_burnin: The number of burn-in samples for the Markov chain sampler.
  
      Returns:
          A `n x d`-dim tensor of samples.
      """
      # create tensors representing linear inequality constraints
      # of the form Ax >= b.
      if inequality_constraints:
          # normalize_linear_constraints is called to solve this issue:
          # https://github.com/pytorch/botorch/issues/1225
          constraints = normalize_linear_constraints(
              bounds, inequality_constraints
          )
  
          A, b = sparse_to_dense_constraints(
              d=bounds.shape[-1],
              constraints=constraints,
          )
          # Note the inequality constraints are of the form Ax >= b,
          # but PolytopeSampler expects inequality constraints of the
          # form Ax <= b, so we multiply by -1 below.
          dense_inequality_constraints = -A, -b
      else:
          dense_inequality_constraints = None
      if equality_constraints:
          constraints = normalize_linear_constraints(
              bounds, equality_constraints
          )
          dense_equality_constraints = sparse_to_dense_constraints(
              d=bounds.shape[-1], constraints=constraints
          )
      else:
          dense_equality_constraints = None
      normalized_bounds = torch.zeros_like(bounds)
      normalized_bounds[1, :] = 1.0
      polytope_sampler = HitAndRunPolytopeSampler(
          bounds=normalized_bounds,
          inequality_constraints=dense_inequality_constraints,
          equality_constraints=dense_equality_constraints,
          n_burnin=n_burnin,
      )
      samples = polytope_sampler.draw(n=n * thinning, seed=seed)[
          ::thinning
      ]
      return bounds[0] + samples * (bounds[1] - bounds[0])
  
imports: from __future__ import annotations
  from abc import ABC, abstractmethod
  from contextlib import contextmanager
  from typing import Any, Generator, Iterable, List, Optional, Tuple, TYPE_CHECKING
  import numpy
  import scipy
  import torch
  from botorch.exceptions.errors import BotorchError
  from botorch.sampling.qmc import NormalQMCEngine
  from botorch.utils.transforms import unnormalize
  from scipy.spatial import Delaunay, HalfspaceIntersection
  from torch import LongTensor, Tensor
  from torch.quasirandom import SobolEngine
label_desc: Use image node_id 11 for calling a global function with example usage: get_polytope_samples(n, bounds, inequality_constraints, equality_constraints, seed, thinning, n_burnin) and returns: unknown