class_docstr: Core class to calculate the hypervolme value of a set of points.
  As introduced in the original paper, "the indicator is a measure of
  the region which is simultaneously dominated by a set of points P,
  and bounded by a reference point r = `self.reference_bounds`. It is
  a union of axis-aligned hyper-rectangles with one common vertex, r."
  
  To calculate the hypervolume indicator, initialize an instance of the
  HypervolumeIndicator; the hypervolume of a set of points P is calculated
  by HypervolumeIndicator.compute(points = P) method.
  
  For the algorithm, refer to the section III and Algorithms 2, 3 of the
  paper `An Improved Dimension-Sweep Algorithm for the Hypervolume Indicator`
  by C.M. Fonseca et all, IEEE Congress on Evolutionary Computation, 2006.
class_docstr_tok: ["Core","class","to","calculate","the","hypervolme","value","of","a","set","of","points",".","As","introduced","in","the","original","paper",",","``","the","indicator","is","a","measure","of","the","region","which","is","simultaneously","dominated","by","a","set","of","points","P",",","and","bounded","by","a","reference","point","r","=","`","self.reference_bounds","`",".","It","is","a","union","of","axis-aligned","hyper-rectangles","with","one","common","vertex",",","r.","''","To","calculate","the","hypervolume","indicator",",","initialize","an","instance","of","the","HypervolumeIndicator",";","the","hypervolume","of","a","set","of","points","P","is","calculated","by","HypervolumeIndicator.compute","(","points","=","P",")","method",".","For","the","algorithm",",","refer","to","the","section","III","and","Algorithms","2",",","3","of","the","paper","`","An","Improved","Dimension-Sweep","Algorithm","for","the","Hypervolume","Indicator","`","by","C.M",".","Fonseca","et","all",",","IEEE","Congress","on","Evolutionary","Computation",",","2006","."]
docstr: Recursive hypervolume computation. The algorithm is provided by Algorithm 3.
  of the original paper.
docstr_tok: ["Recursive","hypervolume","computation",".","The","algorithm","is","provided","by","Algorithm","3.","of","the","original","paper","."]
code: def recursive_hypervolume(self, dimension: int) -> float:
      """Recursive hypervolume computation. The algorithm is provided by Algorithm 3.
      of the original paper."""
      if self.multilist.chain_length(dimension - 1) == 0:
          return 0
      assert self.multilist is not None
      if dimension == 0:
          return -float(self.multilist.sentinel.next[0].coordinates[0])
  
      if dimension == 1:
          return self.plane_hypervolume()
  
      # Line 4
      for node in self.multilist.reverse_iterate(dimension):
          assert node is not None
          if node.dominated_flag < dimension:
              node.dominated_flag = 0
      # Line 5
      hypervolume = 0.0
      # Line 6
      current_node = self.multilist.sentinel.prev[dimension]
      # Lines 7 to 12
      for node in self.multilist.reverse_iterate(
          dimension, start=current_node
      ):
          assert node is not None
          current_node = node
          if self.multilist.chain_length(dimension - 1) > 1 and (
              node.coordinates[dimension]
              > self.reference_bounds[dimension]
              or node.prev[dimension].coordinates[dimension]
              >= self.reference_bounds[dimension]
          ):
              # Line 9
              self.reference_bounds = (
                  self.multilist.update_coordinate_bounds(
                      self.reference_bounds, node, dimension
                  )
              )  # type: ignore
              # Line 10
              self.multilist.pop(node, dimension)
              # Line 11
              # front_size -= 1
          else:
              break
  
      # Line 13
      if self.multilist.chain_length(dimension - 1) > 1:
          # Line 14
          hypervolume = current_node.prev[dimension].volume[dimension]
          hypervolume += current_node.prev[dimension].area[
              dimension
          ] * (
              current_node.coordinates[dimension]
              - current_node.prev[dimension].coordinates[dimension]
          )
      else:
          current_node.configure_area(dimension)
  
      # Line 15
      current_node.volume[dimension] = hypervolume
      # Line 16
      self.skip_dominated_points(current_node, dimension)
  
      # Line 17
      for node in self.multilist.iterate(
          dimension, start=current_node.next[dimension]
      ):
          assert node is not None
          # Line 18
          hypervolume += node.prev[dimension].area[dimension] * (
              node.coordinates[dimension]
              - node.prev[dimension].coordinates[dimension]
          )
          # Line 19
          self.reference_bounds[dimension] = node.coordinates[dimension]
          # Line 20
          self.reference_bounds = (
              self.multilist.update_coordinate_bounds(
                  self.reference_bounds, node, dimension
              )
          )  # type: ignore
          # Line 21
          self.multilist.reinsert(node, dimension)
          # Line 22
          # front_size += 1
          # Line 25
          node.volume[dimension] = hypervolume
          # Line 26
          self.skip_dominated_points(node, dimension)
  
      # Line 27
      last_node = self.multilist.sentinel.prev[dimension]
      hypervolume -= (
          last_node.area[dimension] * last_node.coordinates[dimension]
      )
      return hypervolume
  
imports: import typing
  import numpy
label_desc: Use image node_id 5 for calling the HypervolumeIndicator obj's underlying member method code with example usage: obj.recursive_hypervolume(dimension) and returns: hypervolume, int, unknown, self