class_docstr: A class for partitioning the non-dominated space into hyper-cells.
  
  Note: this assumes maximization. Internally, it multiplies outcomes by -1 and
  performs the decomposition under minimization. TODO: use maximization
  internally as well.
  
  Note: it is only feasible to use this algorithm to compute an exact
  decomposition of the non-dominated space for `m<5` objectives (alpha=0.0).
  
  The alpha parameter can be increased to obtain an approximate partitioning
  faster. The `alpha` is a fraction of the total hypervolume encapsuling the
  entire Pareto set. When a hypercell's volume divided by the total hypervolume
  is less than `alpha`, we discard the hypercell. See Figure 2 in
  [Couckuyt2012]_ for a visual representation.
  
  This PyTorch implementation of the binary partitioning algorithm ([Couckuyt2012]_)
  is adapted from numpy/tensorflow implementation at:
  https://github.com/GPflow/GPflowOpt/blob/master/gpflowopt/pareto.py.
  
  TODO: replace this with a more efficient decomposition. E.g.
  https://link.springer.com/content/pdf/10.1007/s10898-019-00798-7.pdf
docstr: Get the bounds of each hypercell in the decomposition.
  
  Args:
      aug_pareto_Y: A `n_pareto + 2 x m`-dim tensor containing
      the augmented Pareto front.
  
  Returns:
      A `2 x (batch_shape) x num_cells x m`-dim tensor containing the
          lower and upper vertices bounding each hypercell.
docstr_tok: ["Get","the","bounds","of","each","hypercell","in","the","decomposition",".","Args",":","aug_pareto_Y",":","A","`","n_pareto","+","2","x","m","`","-dim","tensor","containing","the","augmented","Pareto","front",".","Returns",":","A","`","2","x","(","batch_shape",")","x","num_cells","x","m","`","-dim","tensor","containing","the","lower","and","upper","vertices","bounding","each","hypercell","."]
code: def _get_hypercell_bounds(self, aug_pareto_Y: Tensor) -> Tensor:
      r"""Get the bounds of each hypercell in the decomposition.
  
      Args:
          aug_pareto_Y: A `n_pareto + 2 x m`-dim tensor containing
          the augmented Pareto front.
  
      Returns:
          A `2 x (batch_shape) x num_cells x m`-dim tensor containing the
              lower and upper vertices bounding each hypercell.
      """
      num_cells = self.hypercells.shape[-2]
      cells_times_outcomes = num_cells * self.num_outcomes
      outcome_idxr = (
          torch.arange(
              self.num_outcomes,
              dtype=torch.long,
              device=self._neg_Y.device,
          )
          .repeat(num_cells)
          .view(
              *(1 for _ in self.hypercells.shape[:-2]),
              cells_times_outcomes,
          )
          .expand(*self.hypercells.shape[:-2], cells_times_outcomes)
      )
  
      # this tensor is 2 x (num_cells * m) x 2
      # the batch dim corresponds to lower/upper bound
      cell_bounds_idxr = torch.stack(
          [
              self.hypercells.view(*self.hypercells.shape[:-2], -1),
              outcome_idxr,
          ],
          dim=-1,
      ).view(2, -1, 2)
      if len(self.batch_shape) > 0:
          # TODO: support multiple batch dimensions here
          batch_idxr = (
              torch.arange(
                  self.batch_shape[0],
                  dtype=torch.long,
                  device=self._neg_Y.device,
              )
              .unsqueeze(1)
              .expand(-1, cells_times_outcomes)
              .reshape(1, -1, 1)
              .expand(2, -1, 1)
          )
          cell_bounds_idxr = torch.cat(
              [batch_idxr, cell_bounds_idxr], dim=-1
          )
  
      cell_bounds_values = aug_pareto_Y[
          cell_bounds_idxr.chunk(cell_bounds_idxr.shape[-1], dim=-1)
      ]
      view_shape = (2, *self.batch_shape, num_cells, self.num_outcomes)
      return cell_bounds_values.view(view_shape)
  
imports: from __future__ import annotations
  from typing import Optional
  import torch
  from botorch.utils.multi_objective.box_decompositions.box_decomposition import BoxDecomposition, FastPartitioning
  from botorch.utils.multi_objective.box_decompositions.utils import _expand_ref_point, compute_non_dominated_hypercell_bounds_2d, get_partition_bounds, update_local_upper_bounds_incremental
  from torch import Tensor
label_desc: Use image node_id 6 for calling the NondominatedPartitioning obj's underlying member method code with example usage: obj._get_hypercell_bounds(aug_pareto_Y) and returns: cell_bounds_values