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.
  
  This class is abstract to support to two applications of Alg 1 from
  [Lacour17]_: 1) partitioning the space that is dominated by the Pareto
  frontier and 2) partitioning the space that is not dominated by the
  Pareto frontier.
  
  :meta private:
docstr: Partition the non-dominated space into disjoint hypercells.
  
  This method supports an arbitrary number of outcomes, but is
  less efficient than `partition_space_2d` for the 2-outcome case.
code: def _partition_space(self):
      r"""Partition the non-dominated space into disjoint hypercells.
  
      This method supports an arbitrary number of outcomes, but is
      less efficient than `partition_space_2d` for the 2-outcome case.
      """
      if len(self.batch_shape) > 0:
          # this could be triggered when m=2 outcomes and
          # BoxDecomposition._partition_space_2d is not overridden.
          raise NotImplementedError(
              "_partition_space does not support batch dimensions."
          )
      # this assumes minimization
      # initialize local upper bounds
      self.register_buffer(
          "_U", self._neg_ref_point.unsqueeze(-2).clone()
      )
      # initialize defining points to be the dummy points \hat{z} that are
      # defined in Sec 2.1 in [Lacour17]_. Note that in [Lacour17]_, outcomes
      # are assumed to be between [0,1], so they used 0 rather than -inf.
      self._Z = torch.zeros(
          1,
          self.num_outcomes,
          self.num_outcomes,
          dtype=self.Y.dtype,
          device=self.Y.device,
      )
      for j in range(self.ref_point.shape[-1]):
          # use ref point for maximization as the ideal point for minimization.
          self._Z[0, j] = float("-inf")
          self._Z[0, j, j] = self._U[0, j]
      # incrementally update local upper bounds and defining points
      # for each new Pareto point
      self._U, self._Z = update_local_upper_bounds_incremental(
          new_pareto_Y=self._neg_pareto_Y,
          U=self._U,
          Z=self._Z,
      )
      self._get_partitioning()
  
imports: from __future__ import annotations
  from abc import ABC, abstractmethod
  from typing import Optional
  import torch
  from botorch.exceptions.errors import BotorchError
  from botorch.utils.multi_objective.box_decompositions.utils import _expand_ref_point, _pad_batch_pareto_frontier, update_local_upper_bounds_incremental
  from botorch.utils.multi_objective.pareto import is_non_dominated
  from torch import Tensor
  from torch.nn import Module
label_desc: Use image node_id 5 for calling the FastPartitioning obj's underlying member method code with example usage: obj._partition_space() without return types