diff --git a/DESCRIPTION b/DESCRIPTION index ffc831b7..48499663 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -84,6 +84,7 @@ Collate: 'AcqFunctionEI.R' 'AcqFunctionEIPS.R' 'AcqFunctionMean.R' + 'AcqFunctionMulti.R' 'AcqFunctionPI.R' 'AcqFunctionSD.R' 'AcqFunctionSmsEgo.R' diff --git a/NAMESPACE b/NAMESPACE index 1a02acdc..9b8e3b96 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -12,6 +12,7 @@ export(AcqFunctionEHVIGH) export(AcqFunctionEI) export(AcqFunctionEIPS) export(AcqFunctionMean) +export(AcqFunctionMulti) export(AcqFunctionPI) export(AcqFunctionSD) export(AcqFunctionSmsEgo) @@ -25,6 +26,7 @@ export(SurrogateLearner) export(SurrogateLearnerCollection) export(TunerMbo) export(acqf) +export(acqfs) export(acqo) export(bayesopt_ego) export(bayesopt_emo) diff --git a/R/AcqFunctionMulti.R b/R/AcqFunctionMulti.R index 148b7264..7bdb66ae 100644 --- a/R/AcqFunctionMulti.R +++ b/R/AcqFunctionMulti.R @@ -1,22 +1,84 @@ +#' @title Acquisition Function Wrapping Multiple Acquisition Functions +#' +#' @include AcqFunction.R +#' @name mlr_acqfunctions_multi +#' +#' @templateVar id multi +#' @template section_dictionary_acqfunctions +#' +#' @description +#' Wrapping multiple [AcqFunction]s resulting in a multi-objective acquisition function composed of the individual ones. +#' Note that the optimization direction of each wrapped acquisition function is corrected for maximization. +#' +#' @family Acquisition Function +#' @export +#' @examples +#' if (requireNamespace("mlr3learners") & +#' requireNamespace("DiceKriging") & +#' requireNamespace("rgenoud")) { +#' library(bbotk) +#' library(paradox) +#' library(mlr3learners) +#' library(data.table) +#' +#' fun = function(xs) { +#' list(y = xs$x ^ 2) +#' } +#' domain = ps(x = p_dbl(lower = -10, upper = 10)) +#' codomain = ps(y = p_dbl(tags = "minimize")) +#' objective = ObjectiveRFun$new(fun = fun, domain = domain, codomain = codomain) +#' +#' instance = OptimInstanceBatchSingleCrit$new( +#' objective = objective, +#' terminator = trm("evals", n_evals = 5)) +#' +#' instance$eval_batch(data.table(x = c(-6, -5, 3, 9))) +#' +#' learner = default_gp() +#' +#' surrogate = srlrn(learner, archive = instance$archive) +#' +#' acq_function = acqf("multi", +#' acq_functions = acqfs(c("ei", "pi", "cb")), +#' surrogate = surrogate +#' ) +#' +#' acq_function$surrogate$update() +#' acq_function$update() +#' acq_function$eval_dt(data.table(x = c(-1, 0, 1))) +#' } AcqFunctionMulti = R6Class("AcqFunctionMulti", inherit = AcqFunction, public = list( - initialize = function(acq_functions) { + #' @description + #' Creates a new instance of this [R6][R6::R6Class] class. + #' + #' @param acq_functions (list of [AcqFunction]s). + #' @param surrogate (`NULL` | [Surrogate]). + initialize = function(acq_functions, surrogate = NULL) { assert_list(acq_functions, "AcqFunction", min.len = 2L) + acq_function_ids = map_chr(acq_functions, function(acq_function) acq_function$id) + assert_character(acq_function_ids, unique = TRUE) + acq_functions = setNames(acq_functions, nm = acq_function_ids) + acq_function_directions = map_chr(acq_functions, function(acq_function) acq_function$direction) private$.acq_functions = acq_functions - # FIXME: check for unique ids - id = paste0(c("acq", map_chr(acq_functions, function(acq_function) gsub("acq_", replacement = "", x = acq_function$id))), collapse = "_") + private$.acq_function_ids = acq_function_ids + private$.acq_function_directions = acq_function_directions + id = paste0(c("acq", map_chr(acq_function_ids, function(id) gsub("acq_", replacement = "", x = id))), collapse = "_") label = paste0("Multi Acquisition Function of ", paste0(map_chr(acq_functions, function(acq_function) acq_function$label), collapse = ", ")) - # FIXME: constant ids must be prefixed by acqf_id - constants = do.call(c, map(acq_functions, function(acq_function) acq_function$constants)) + constants = ps() domains = map(acq_functions, function(acq_function) acq_function$domain) assert_true(all(map_lgl(domains[-1L], function(domain) all.equal(domains[[1L]]$data, domain$data)))) - # FIXME: surrogates could be the same or different, how to handle this with $update() of the surrogate? - surrogates = map(acq_functions, function(acq_function) acq_function$surrogate) - assert_true(length(unique(map_chr(surrogates, function(surrogate) address(surrogate)))) == 1L) - surrogate = surrogates[[1L]] + if (is.null(surrogate)) { + surrogates = map(acq_functions, function(acq_function) acq_function$surrogate) + assert_list(surrogates, types = c("Surrogate", "NULL")) + if (length(unique(map_chr(surrogates, function(surrogate) address(surrogate)))) > 1L) { + stop("Acquisition functions must rely on the same surrogate model.") + } + surrogate = surrogates[[1L]] + } requires_predict_type_se = any(map_lgl(acq_functions, function(acq_function) acq_function$requires_predict_type_se)) packages = unique(unlist(map(acq_functions, function(acq_function) acq_function$packages))) properties = character() @@ -25,7 +87,7 @@ AcqFunctionMulti = R6Class("AcqFunctionMulti", private$.requires_predict_type_se = requires_predict_type_se private$.packages = packages - self$direction = "minimize" + self$direction = "maximize" if (is.null(surrogate)) { domain = ParamSet$new() codomain = ParamSet$new() @@ -34,7 +96,10 @@ AcqFunctionMulti = R6Class("AcqFunctionMulti", stopf("Acquisition function '%s' requires the surrogate to have `\"se\"` as `$predict_type`.", sprintf("<%s:%s>", "AcqFunction", id)) } private$.surrogate = surrogate - private$.archive = assert_r6(surrogate$archive, classes = "Archive") + private$.archive = assert_archive(surrogate$archive) + for (acq_function in private$.acq_functions) { + acq_function$surrogate = surrogate + } codomain = generate_acq_multi_codomain(surrogate, acq_functions = acq_functions) self$surrogate_max_to_min = surrogate_mult_max_to_min(surrogate) domain = generate_acq_domain(surrogate) @@ -59,7 +124,10 @@ AcqFunctionMulti = R6Class("AcqFunctionMulti", #' @description #' Update each of the wrapped acquisition functions. update = function() { - for (acq_function in private$.acq_functions) { + if (length(unique(map_chr(self$acq_functions, function(acq_function) address(acq_function$surrogate)))) > 1L) { + stop("Acquisition functions must rely on the same surrogate model.") + } + for (acq_function in self$acq_functions) { acq_function$update() } } @@ -72,75 +140,71 @@ AcqFunctionMulti = R6Class("AcqFunctionMulti", if (missing(rhs)) { private$.surrogate } else { - # FIXME: assign surrogate to all acqfs? assert_r6(rhs, classes = "Surrogate") if (self$requires_predict_type_se && rhs$predict_type != "se") { stopf("Acquisition function '%s' requires the surrogate to have `\"se\"` as `$predict_type`.", format(self)) } private$.surrogate = rhs private$.archive = assert_archive(rhs$archive) - codomain = generate_acq_multi_codomain(surrogate, acq_functions = acq_functions) + for (acq_function in self$acq_functions) { + acq_function$surrogate = rhs + } + codomain = generate_acq_multi_codomain(rhs, acq_functions = self$acq_functions) self$surrogate_max_to_min = surrogate_mult_max_to_min(rhs) domain = generate_acq_domain(rhs) # lazy initialization requires this: self$codomain = Codomain$new(get0("domains", codomain, ifnotfound = codomain$params)) # get0 for old paradox self$domain = domain } + }, + + #' @field acq_functions (list of [AcqFunction])\cr + #' Points to the list of the individual acqusition functions. + acq_functions = function(rhs) { + if (!missing(rhs) && !identical(rhs, private$.acq_functions)) { + stop("$acq_functions is read-only.") + } + private$.acq_functions + }, + + #' @field acq_function_ids (character())\cr + #' Points to the ids of the individual acqusition functions. + acq_function_ids = function(rhs) { + if (!missing(rhs) && !identical(rhs, private$.acq_function_ids)) { + stop("$acq_function_ids is read-only.") + } + private$.acq_function_ids } ), private = list( .acq_functions = NULL, - .fun = function(xdt, ...) { - constants = list(...) - # FIXME: prefixed constants matching; needed at all? - values = map_dtc(private$.acq_functions, function(acq_function) acq_function$eval_dt(xdt)) - ids = map_chr(private$.acq_functions, function(acq_function) acq_function$id) - directions = map_chr(private$.acq_functions, function(acq_function) acq_function$direction) + .acq_function_ids = NULL, + + .acq_function_directions = NULL, + + # NOTE: this is currently slower than it could be because when each acquisition functions is evaluated, + # the mean and se prediction for each point is computed again using the surrogate of that acquisition function, + # however, as acquisition functions must share the same surrogate, this is redundant. + # It might be sensible to have a customized eval function for acquisition functions where directly the mean and se + # predictions are passed (along xdt) so that one can save computing the mean and se predictions over and over again. + # This also would, however, depend on learners being fully deterministic. + .fun = function(xdt) { + values = map_dtc(self$acq_functions, function(acq_function) acq_function$eval_dt(xdt)) + ids = private$.acq_function_ids + directions = private$.acq_function_directions if (any(directions == "same")) { directions[directions == "same"] = self$surrogate$archive$codomain$tags[[1L]] } - change_sign = ids[directions == "maximize"] + change_sign = ids[directions == "minimize"] for (j in change_sign) { set(values, j = j, value = - values[[j]]) } - # FIXME: standardize column ranges to [0, 1] values } ) ) -# FIXME: test with multi objective also? -# FIXME: currently there is overhead because each acqf predicts with the surrogate -# but if the surrogate is always the same and shared, can we save time by predicting for xdt -# and having for each acqf a variant of fun that directly uses mean and se - -if (FALSE) { - fun = function(xs) { - list(y = xs$x ^ 2) - } - domain = ps(x = p_dbl(lower = -10, upper = 10)) - codomain = ps(y = p_dbl(tags = "minimize")) - objective = ObjectiveRFun$new(fun = fun, domain = domain, codomain = codomain) - - instance = OptimInstanceBatchSingleCrit$new( - objective = objective, - terminator = trm("evals", n_evals = 5)) - - instance$eval_batch(data.table(x = c(-6, -5, 3, 9))) - - learner = default_gp() - - surrogate = srlrn(learner, archive = instance$archive) - - ei = acqf("ei", surrogate = surrogate) - lcb = acqf("cb", surrogate = surrogate) - pi = acqf("pi", surrogate = surrogate) - - acqf = AcqFunctionMulti$new(list(ei, lcb, pi)) - acqf$surrogate$update() - acqf$update() - acqf$eval_dt(data.table(x = c(-1, 0, 1))) -} +mlr_acqfunctions$add("multi", AcqFunctionMulti) diff --git a/R/AcqOptimizer.R b/R/AcqOptimizer.R index f9f0f5d6..7c895940 100644 --- a/R/AcqOptimizer.R +++ b/R/AcqOptimizer.R @@ -141,23 +141,29 @@ AcqOptimizer = R6Class("AcqOptimizer", #' #' @return [data.table::data.table()] with 1 row per optimum and x as columns. optimize = function() { - # FIXME: currently only supports singlecrit acquisition functions - if (self$acq_function$codomain$length > 1L) { - stop("Multi-objective acquisition functions are currently not supported.") - } + is_multi_acq_function = self$acq_function$codomain$length > 1L logger = lgr::get_logger("bbotk") old_threshold = logger$threshold logger$set_threshold(self$param_set$values$logging_level) on.exit(logger$set_threshold(old_threshold)) - instance = OptimInstanceBatchSingleCrit$new(objective = self$acq_function, search_space = self$acq_function$domain, terminator = self$terminator, check_values = FALSE, callbacks = self$callbacks) + if (is_multi_acq_function) { + instance = OptimInstanceBatchMultiCrit$new(objective = self$acq_function, search_space = self$acq_function$domain, terminator = self$terminator, check_values = FALSE, callbacks = self$callbacks) + } else { + instance = OptimInstanceBatchSingleCrit$new(objective = self$acq_function, search_space = self$acq_function$domain, terminator = self$terminator, check_values = FALSE, callbacks = self$callbacks) + } # warmstart if (self$param_set$values$warmstart) { warmstart_size = if (isTRUE(self$param_set$values$warmstart_size == "all")) Inf else self$param_set$values$warmstart_size %??% 1L # default is 1L n_select = min(nrow(self$acq_function$archive$data), warmstart_size) - instance$eval_batch(self$acq_function$archive$best(n_select = n_select)[, instance$search_space$ids(), with = FALSE]) + warmstart_xdt = if (is_multi_acq_function) { + self$acq_function$archive$nds_selection(n_select = n_select)[, instance$search_space$ids(), with = FALSE] + } else { + self$acq_function$archive$best(n_select = n_select)[, instance$search_space$ids(), with = FALSE] + } + instance$eval_batch(warmstart_xdt) } # acquisition function optimization @@ -166,7 +172,7 @@ AcqOptimizer = R6Class("AcqOptimizer", tryCatch( { self$optimizer$optimize(instance) - get_best_not_evaluated(instance, evaluated = self$acq_function$archive$data, n_select = self$param_set$values$n_candidates) + get_best(instance, is_multi_acq_function = is_multi_acq_function, evaluated = self$acq_function$archive$data, n_select = self$param_set$values$n_candidates, not_already_evaluated = TRUE) }, error = function(error_condition) { lg$warn(error_condition$message) stop(set_class(list(message = error_condition$message, call = NULL), @@ -175,14 +181,14 @@ AcqOptimizer = R6Class("AcqOptimizer", ) } else { self$optimizer$optimize(instance) - get_best_not_evaluated(instance, evaluated = self$acq_function$archive$data, n_select = self$param_set$values$n_candidates) + get_best(instance, is_multi_acq_function = is_multi_acq_function, evaluated = self$acq_function$archive$data, n_select = self$param_set$values$n_candidates, not_already_evaluated = TRUE) } } else { if (self$param_set$values$catch_errors) { tryCatch( { self$optimizer$optimize(instance) - instance$archive$best(n_select = self$param_set$values$n_candidates) + get_best(instance, is_multi_acq_function = is_multi_acq_function, evaluated = self$acq_function$archive$data, n_select = self$param_set$values$n_candidates, not_already_evaluated = FALSE) }, error = function(error_condition) { lg$warn(error_condition$message) stop(set_class(list(message = error_condition$message, call = NULL), @@ -191,9 +197,16 @@ AcqOptimizer = R6Class("AcqOptimizer", ) } else { self$optimizer$optimize(instance) - instance$archive$best(n_select = self$param_set$values$n_candidates) + get_best(instance, is_multi_acq_function = is_multi_acq_function, evaluated = self$acq_function$archive$data, n_select = self$param_set$values$n_candidates, not_already_evaluated = FALSE) } } + #if (is_multi_acq_function) { + # set(xdt, j = instance$objective$id, value = apply(xdt[, instance$objective$acq_function_ids, with = FALSE], MARGIN = 1L, FUN = c, simplify = FALSE)) + # for (acq_function_id in instance$objective$acq_function_ids) { + # set(xdt, j = acq_function_id, value = NULL) + # } + # setcolorder(xdt, c(instance$archive$cols_x, "x_domain", instance$objective$id)) + #} xdt } ), diff --git a/R/helper.R b/R/helper.R index b12eb1fc..78eecfc8 100644 --- a/R/helper.R +++ b/R/helper.R @@ -14,11 +14,12 @@ generate_acq_codomain = function(surrogate, id, direction = "same") { } generate_acq_multi_codomain = function(surrogate, acq_functions) { + acq_functions = unname(acq_functions) # needed for c of ParamSets to keep original ids codomain = do.call(c, map(acq_functions, function(acq_function) acq_function$codomain)) if (any(codomain$tags == "same")) { assert(surrogate$archive$codomain$length == 1L) } - codomain$tags = structure(as.list(rep("minimize", length(acq_functions))), names = map_chr(acq_functions, function(acq_function) acq_function$id)) + codomain$tags = structure(as.list(rep("maximize", length(acq_functions))), names = map_chr(acq_functions, function(acq_function) acq_function$id)) codomain } @@ -92,23 +93,25 @@ mult_max_to_min = function(codomain) { } # used in AcqOptimizer -# FIXME: currently only supports singlecrit acquisition functions -get_best_not_evaluated = function(instance, evaluated, n_select) { +get_best= function(instance, is_multi_acq_function, evaluated, n_select, not_already_evaluated = TRUE) { data = copy(instance$archive$data[, c(instance$archive$cols_x, "x_domain", instance$archive$cols_y), with = FALSE]) evaluated = copy(evaluated) already_evaluated_id = ".already_evaluated" - while (already_evaluated_id %in% c(instance$archive$cols_x, "x_domain", instance$archive$cols_y)) { - already_evaluated_id = paste0(".", already_evaluated_id) + set(data, j = already_evaluated_id, value = FALSE) + data[evaluated, eval(already_evaluated_id) := TRUE, on = instance$archive$cols_x] + set(instance$archive$data, j = already_evaluated_id, value = data[[already_evaluated_id]]) + if (not_already_evaluated) { + not_already_evaluated = which(data[[already_evaluated_id]] == FALSE) + if (length(not_already_evaluated) < n_select) { + stopf("Less then `n_select` (%i) candidate points found during acquisition function optimization were not already evaluated.", n_select) + } + instance$archive$data = instance$archive$data[not_already_evaluated, ] } - data[, eval(already_evaluated_id) := FALSE][evaluated, eval(already_evaluated_id) := TRUE, on = instance$archive$cols_x] - candidates = data[get(already_evaluated_id) == FALSE] - if (nrow(candidates) < n_select) { - stopf("Less then `n_select` (%i) candidate points found during acquisition function optimization were not already evaluated.", n_select) + if (is_multi_acq_function) { + instance$archive$nds_selection(n_select = n_select) + } else { + instance$archive$best(n_select = n_select) } - candidates[[instance$archive$cols_y]] = candidates[[instance$archive$cols_y]] * instance$objective_multiplicator[instance$archive$cols_y] - xdt = setorderv(candidates, cols = instance$archive$cols_y) - xdt[[instance$archive$cols_y]] = xdt[[instance$archive$cols_y]] * instance$objective_multiplicator[instance$archive$cols_y] - xdt[seq_len(n_select), ] } catn = function(..., file = "") { @@ -145,7 +148,6 @@ check_learner_surrogate = function(learner) { return(TRUE) } } - "Must inherit from class 'Learner' or be a list of elements inheriting from class 'Learner'" } @@ -155,10 +157,11 @@ assert_loop_function = function(x, .var.name = vname(x)) { } # NOTE: this is buggy in checkmate; assert should always return x invisible not TRUE as is the case here assert(check_class(x, classes = "loop_function"), - check_function(x, args = c("instance", "surrogate", "acq_function", "acq_optimizer")), - check_attributes(x, attribute_names = c("id", "label", "instance", "man")), - check_instance_attribute(x), - combine = "and", .var.name = .var.name) + check_function(x, args = c("instance", "surrogate", "acq_function", "acq_optimizer")), + check_attributes(x, attribute_names = c("id", "label", "instance", "man")), + check_instance_attribute(x), + combine = "and", .var.name = .var.name + ) x } diff --git a/R/mbo_defaults.R b/R/mbo_defaults.R index 932bac4f..69c9664d 100644 --- a/R/mbo_defaults.R +++ b/R/mbo_defaults.R @@ -230,7 +230,8 @@ default_acqfunction = function(instance) { #' @export default_acqoptimizer = function(acq_function) { assert_r6(acq_function, classes = "AcqFunction") - AcqOptimizer$new(optimizer = opt("random_search", batch_size = 1000L), terminator = trm("evals", n_evals = 10000L)) # FIXME: what do we use + AcqOptimizer$new(optimizer = opt("random_search", batch_size = 1000L), terminator = trm("evals", n_evals = 10000L)) # FIXME: what do we use? + # NOTE: adjust for single-objective vs. multi-objective acquisition function } #' @title Default Result Assigner diff --git a/R/mlr_acqfunctions.R b/R/mlr_acqfunctions.R index 85f4a7a9..b2981203 100644 --- a/R/mlr_acqfunctions.R +++ b/R/mlr_acqfunctions.R @@ -7,7 +7,7 @@ #' A simple [mlr3misc::Dictionary] storing objects of class [AcqFunction]. #' Each acquisition function has an associated help page, see `mlr_acqfunctions_[id]`. #' -#' For a more convenient way to retrieve and construct an acquisition function, see [acqf()]. +#' For a more convenient way to retrieve and construct an acquisition function, see [acqf()] and [acqfs()]. #' #' @section Methods: #' See [mlr3misc::Dictionary]. @@ -15,7 +15,7 @@ #' @family Dictionary #' @family Acquisition Function #' @seealso -#' Sugar function: [acqf()] +#' Sugar functions: [acqf()], [acqfs()] #' @export #' @examples #' library(data.table) @@ -28,11 +28,22 @@ as.data.table.DictionaryAcqFunction = function(x, ..., objects = FALSE) { assert_flag(objects) setkeyv(map_dtr(x$keys(), function(key) { - acqf = withCallingHandlers(x$get(key), packageNotFoundWarning = function(w) invokeRestart("muffleWarning")) - insert_named( - list(key = key, label = acqf$label, man = acqf$man), - if (objects) list(object = list(acqf)) - ) + # NOTE: special handling of AcqFunctionMulti due to acq_functions being required as an argument during construction + if (key == "multi") { + acq_function1 = AcqFunctionMean$new() + acq_function2 = AcqFunctionSD$new() + acqf = withCallingHandlers(x$get(key, acq_functions = list(acq_function1, acq_function2)), packageNotFoundWarning = function(w) invokeRestart("muffleWarning")) + insert_named( + list(key = key, label = "Acquisition Function Wrapping Multiple Acquisition Functions", man = acqf$man), + if (objects) list(object = list(acqf)) + ) + } else { + acqf = withCallingHandlers(x$get(key), packageNotFoundWarning = function(w) invokeRestart("muffleWarning")) + insert_named( + list(key = key, label = acqf$label, man = acqf$man), + if (objects) list(object = list(acqf)) + ) + } }, .fill = TRUE), "key")[] } diff --git a/R/sugar.R b/R/sugar.R index 69c6a8b0..0cc43de3 100644 --- a/R/sugar.R +++ b/R/sugar.R @@ -78,6 +78,31 @@ acqf = function(.key, ...) { dictionary_sugar_get(mlr_acqfunctions, .key, ...) } +#' @title Syntactic Sugar Acquisition Functions Construction +#' +#' @description +#' This function complements [mlr_acqfunctions] with functions in the spirit +#' of `mlr_sugar` from \CRANpkg{mlr3}. +#' +#' @param .keys (`character()`)\cr +#' Keys passed to the respective [dictionary][mlr3misc::Dictionary] to retrieve +#' multiple objects. +#' @param ... (named `list()`)\cr +#' Named arguments passed to the constructor, to be set as parameters in the +#' [paradox::ParamSet], or to be set as public field. See +#' [mlr3misc::dictionary_sugar_get()] for more details. +#' +#' @return List of [AcqFunction]s +#' +#' @export +#' @examples +#' acqfs(c("ei", "pi", "cb")) +#' @export +acqfs = function(.keys, ...) { + dictionary_sugar_mget(dict = mlr_acqfunctions, .keys, ...) +} + + #' @title Syntactic Sugar Acquisition Function Optimizer Construction #' #' @description diff --git a/man/AcqFunction.Rd b/man/AcqFunction.Rd index 48fd7926..31f16e42 100644 --- a/man/AcqFunction.Rd +++ b/man/AcqFunction.Rd @@ -18,6 +18,7 @@ Other Acquisition Function: \code{\link{mlr_acqfunctions_ei}}, \code{\link{mlr_acqfunctions_eips}}, \code{\link{mlr_acqfunctions_mean}}, +\code{\link{mlr_acqfunctions_multi}}, \code{\link{mlr_acqfunctions_pi}}, \code{\link{mlr_acqfunctions_sd}}, \code{\link{mlr_acqfunctions_smsego}} diff --git a/man/acqfs.Rd b/man/acqfs.Rd new file mode 100644 index 00000000..16d23d82 --- /dev/null +++ b/man/acqfs.Rd @@ -0,0 +1,28 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/sugar.R +\name{acqfs} +\alias{acqfs} +\title{Syntactic Sugar Acquisition Functions Construction} +\usage{ +acqfs(.keys, ...) +} +\arguments{ +\item{.keys}{(\code{character()})\cr +Keys passed to the respective \link[mlr3misc:Dictionary]{dictionary} to retrieve +multiple objects.} + +\item{...}{(named \code{list()})\cr +Named arguments passed to the constructor, to be set as parameters in the +\link[paradox:ParamSet]{paradox::ParamSet}, or to be set as public field. See +\code{\link[mlr3misc:dictionary_sugar_get]{mlr3misc::dictionary_sugar_get()}} for more details.} +} +\value{ +List of \link{AcqFunction}s +} +\description{ +This function complements \link{mlr_acqfunctions} with functions in the spirit +of \code{mlr_sugar} from \CRANpkg{mlr3}. +} +\examples{ +acqfs(c("ei", "pi", "cb")) +} diff --git a/man/mlr_acqfunctions.Rd b/man/mlr_acqfunctions.Rd index 1cb921ac..b9d222c5 100644 --- a/man/mlr_acqfunctions.Rd +++ b/man/mlr_acqfunctions.Rd @@ -11,7 +11,7 @@ A simple \link[mlr3misc:Dictionary]{mlr3misc::Dictionary} storing objects of class \link{AcqFunction}. Each acquisition function has an associated help page, see \code{mlr_acqfunctions_[id]}. -For a more convenient way to retrieve and construct an acquisition function, see \code{\link[=acqf]{acqf()}}. +For a more convenient way to retrieve and construct an acquisition function, see \code{\link[=acqf]{acqf()}} and \code{\link[=acqfs]{acqfs()}}. } \section{Methods}{ @@ -24,7 +24,7 @@ as.data.table(mlr_acqfunctions) acqf("ei") } \seealso{ -Sugar function: \code{\link[=acqf]{acqf()}} +Sugar functions: \code{\link[=acqf]{acqf()}}, \code{\link[=acqfs]{acqfs()}} Other Dictionary: \code{\link{mlr_loop_functions}}, @@ -39,6 +39,7 @@ Other Acquisition Function: \code{\link{mlr_acqfunctions_ei}}, \code{\link{mlr_acqfunctions_eips}}, \code{\link{mlr_acqfunctions_mean}}, +\code{\link{mlr_acqfunctions_multi}}, \code{\link{mlr_acqfunctions_pi}}, \code{\link{mlr_acqfunctions_sd}}, \code{\link{mlr_acqfunctions_smsego}} diff --git a/man/mlr_acqfunctions_aei.Rd b/man/mlr_acqfunctions_aei.Rd index 6d8554eb..5ce6d5c9 100644 --- a/man/mlr_acqfunctions_aei.Rd +++ b/man/mlr_acqfunctions_aei.Rd @@ -86,6 +86,7 @@ Other Acquisition Function: \code{\link{mlr_acqfunctions_ei}}, \code{\link{mlr_acqfunctions_eips}}, \code{\link{mlr_acqfunctions_mean}}, +\code{\link{mlr_acqfunctions_multi}}, \code{\link{mlr_acqfunctions_pi}}, \code{\link{mlr_acqfunctions_sd}}, \code{\link{mlr_acqfunctions_smsego}} @@ -150,7 +151,7 @@ Creates a new instance of this \link[R6:R6Class]{R6} class. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-AcqFunctionAEI-update}{}}} \subsection{Method \code{update()}}{ -Updates acquisition function and sets \code{y_effective_best} and \code{noise_var}. +Update the acquisition function and set \code{y_effective_best} and \code{noise_var}. \subsection{Usage}{ \if{html}{\out{