R/moo.computeHV.R

Defines functions computeHV computeHVContribution

#' @title
#' Functions for the calculation of the dominated hypervolume (contribution).
#'
#' @description
#' The function \code{computeHV} computes the dominated hypervolume of a set of
#' points given a reference set whereby \code{computeHVContribution} computes the
#' hypervolume contribution of each point.
# FIXME: more details, references to literature.
#'
#' If no reference point is given the nadir point of the set \code{x} is
#' determined and a positive offset with default 1 is added. This is to ensure
#' that the reference point dominates all of the points in the reference set.
#'
#' @note: Keep in mind that this function assumes all objectives to be minimized.
#' In case at least one objective is to be maximized the matrix \code{x} needs
#' to be transformed accordingly in advance.
#FIXME: pointer to control$adaptY()
#'
#' @param x [\code{matrix}]\cr
#'   Matrix of points (column-wise).
#' @param ref.point [\code{numeric} | \code{NULL}]\cr
#'   Reference point.
#'   Set to the maximum in each dimension by default if not provided.
#' @param offset [\code{numeric(1)}]\cr
#'   Offset to be added to each component of the reference point only in the case
#'   where no reference is provided and one is calculated automatically.
#' @param ... [any]\cr
#'   Not used at the moment.
#' @return [\code{numeric(1)}] Dominated hypervolume in the case of
#'  \code{computeHV} and the dominated hypervolume contributions
#'  for each point in the case of \code{computeHVContr}.
#' @rdname dominated_hypervolume
#' @export
computeHV = function(x, ref.point = NULL, ...) {
  # sanity checks
  checkmate::assertMatrix(x, mode = "numeric", any.missing = FALSE, all.missing = FALSE)

  if (is.null(ref.point)) {
    ref.point = apply(x, 1L, max)
  }

  if (any(is.infinite(x))) {
    BBmisc::warningf("[ecr3] computeHV: set of points contains %i infinite values.
      Returning NaN.", sum(is.infinite(x)))
    return(NaN)
  }

  if (length(ref.point) != nrow(x)) {
    BBmisc::stopf("[ecr3] computeHV: set of points and reference point need to have the same dimension, but
      set of points has dimension %i and reference point has dimension %i.", nrow(x), length(ref.point))
  }

  if (any(is.infinite(ref.point))) {
    BBmisc::warningf("[ecr3] computeHV: reference point contains %i infinite values.
      Returning NaN.", sum(is.infinite(ref.point)))
    return(NaN)
  }

  return(.Call("computeHVC", x, ref.point))
}

#' @export
#' @rdname dominated_hypervolume
computeHVContribution = function(x, ref.point = NULL, offset = 1) {
  if (ncol(x) == 1L)
    BBmisc::stopf("[ecr3] computeHVContribution: computation requires at least 2 points in x.")
  if (is.null(ref.point)) {
    ref.point = approximateNadirPoint(x) + offset
  }
  checkmate::assertMatrix(x, mode = "numeric", any.missing = FALSE)
  checkmate::assertNumeric(ref.point, any.missing = FALSE)
  checkmate::assertNumber(offset, finite = TRUE, lower = 0)

  #NOTE: we pass a copy of x here. Otherwise x is modified by computeHVContributionC
  return(.Call("computeHVContributionC", x[, , drop = FALSE], ref.point))
}
jakobbossek/ecr3 documentation built on Nov. 14, 2019, 7:47 p.m.