class_docstr: A class for partitioning the non-dominated space into hyper-cells.
  
  Note: this assumes maximization. Internally, it multiplies by -1 and performs
  the decomposition under minimization.
  
  This class is far more efficient than NondominatedPartitioning for exact box
  partitionings
  
  This class uses the two-step approach similar to that in [Yang2019]_, where:
      a) first, Alg 1 from [Lacour17]_ is used to find the local lower bounds
          for the maximization problem
      b) second, the local lower bounds are used as the Pareto frontier for the
          minimization problem, and [Lacour17]_ is applied again to partition
          the space dominated by that Pareto frontier.
code: def _compute_hypervolume_if_y_has_data(self) -> Tensor:
      ideal_point = self.pareto_Y.max(dim=-2, keepdim=True).values
      total_volume = (
          (ideal_point.squeeze(-2) - self.ref_point)
          .clamp_min(0.0)
          .prod(dim=-1)
      )
      finite_cell_bounds = torch.min(self.hypercell_bounds, ideal_point)
      non_dom_volume = (
          (finite_cell_bounds[1] - finite_cell_bounds[0])
          .clamp_min(0.0)
          .prod(dim=-1)
          .sum(dim=-1)
      )
      return total_volume - non_dom_volume
  
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 5 for calling the FastNondominatedPartitioning obj's underlying member method code with example usage: obj._compute_hypervolume_if_y_has_data() and returns: unknown