Skip to content

Commit

Permalink
tests pass with new paradox (#208)
Browse files Browse the repository at this point in the history
* tests pass with new paradox

* passes with old paradox

* document

* check with both paradox versions

* NEWS update

* try to check with paradox in a different way

* try again

* adapt documentation

* adapt merged stuff to new paradox

* dev cmd check with paradox mater

---------

Co-authored-by: be-marc <[email protected]>
  • Loading branch information
mb706 and be-marc authored Feb 29, 2024
1 parent 0cf1f34 commit 7448f84
Show file tree
Hide file tree
Showing 22 changed files with 258 additions and 133 deletions.
45 changes: 45 additions & 0 deletions .github/workflows/dev-cmd-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# dev cmd check workflow of the mlr3 ecosystem v0.1.0
# https://github.com/mlr-org/actions
on:
workflow_dispatch:
push:
branches:
- main
pull_request:
branches:
- main

name: dev-check

jobs:
check-package:
runs-on: ${{ matrix.config.os }}

name: ${{ matrix.config.dev-package }}

env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}

strategy:
fail-fast: false
matrix:
config:
- {os: ubuntu-latest, r: 'release', dev-package: 'mlr-org/paradox'}

steps:
- uses: actions/checkout@v3

- uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.config.r }}

- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::rcmdcheck
needs: check

- name: Install dev versions
run: pak::pkg_install('${{ matrix.config.dev-package }}')
shell: Rscript {0}

- uses: r-lib/actions/check-r-package@v2
3 changes: 0 additions & 3 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,6 @@ import(mlr3misc)
import(paradox)
importFrom(R6,R6Class)
importFrom(methods,formalArgs)
importFrom(mlr3misc,clbk)
importFrom(mlr3misc,clbks)
importFrom(mlr3misc,mlr_callbacks)
importFrom(utils,bibentry)
importFrom(utils,capture.output)
importFrom(utils,head)
Expand Down
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

* fix: `OptimizerIrace` failed with logical parameters and dependencies.
* refactor: Optimize the runtime of `archive$best()` method with partial sorting.
* compatibility: Work with new paradox version 1.0.0

# bbotk 0.7.3

Expand Down
5 changes: 4 additions & 1 deletion R/Archive.R
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ Archive = R6Class("Archive",
#' Search space that is logged into archive.
initialize = function(search_space, codomain, check_values = TRUE) {
self$search_space = assert_param_set(search_space)
self$codomain = Codomain$new(assert_param_set(codomain)$params)
assert_param_set(codomain)
# get "codomain" element if present (new paradox) or default to $params (old paradox)
params = get0("domains", codomain, ifnotfound = codomain$params)
self$codomain = Codomain$new(params)
self$check_values = assert_flag(check_values)
self$data = data.table()
},
Expand Down
61 changes: 33 additions & 28 deletions R/Codomain.R
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#' @title Codomain of Function
#'
#' @description
#' A set of [Param] objects defining the codomain of a function. The parameter
#' A [ParamSet] defining the codomain of a function. The parameter
#' set must contain at least one target parameter tagged with `"minimize"` or
#' `"maximize"`. The codomain may contain extra parameters which are ignored
#' when calling the [Archive] methods `$best()`, `$nds_selection()` and
#' `$cols_y`. This class is usually constructed internally from a
#' [paradox::ParamSet] when [Objective] is initialized.
#' [ParamSet] when [Objective] is initialized.
#'
#' @export
#' @examples
Expand Down Expand Up @@ -42,55 +42,60 @@ Codomain = R6Class("Codomain", inherit = paradox::ParamSet,
#' Creates a new instance of this [R6][R6::R6Class] class.
#'
#' @param params (`list()`)\cr
#' List of [Param], named with their respective ID.
#' Parameters are cloned.
initialize = function(params = named_list()) {
# assert parameters
for (param in params) {
# only check for codomain parameters tagged with minimize or maximize
if (any(c("minimize", "maximize") %in% param$tags)) {
# all numeric
if (!param$is_number) {
stopf("%s in codomain is not numeric", param$id)
}
#' Named list with which to initialize the codomain.
#' This argument is analogous to [ParamSet]'s `$initialize()` `params` argument.
initialize = function(params) {

# every parameter's tags contain at most one of 'minimize' or 'maximize'
if (sum(param$tags %in% c("minimize", "maximize")) > 1) {
stopf("%s in codomain contains a 'minimize' and 'maximize' tag", param$id)
}
assert_list(params)

super$initialize(params)

# only check for codomain parameters tagged with minimize or maximize
for (id in self$target_ids) {
# all numeric
if (!self$is_number[id]) {
stopf("%s in codomain is not numeric", id)
}
# every parameter's tags contain at most one of 'minimize' or 'maximize'
if (sum(self$tags[[id]] %in% c("minimize", "maximize")) > 1) {
stopf("%s in codomain contains a 'minimize' and 'maximize' tag", id)
}
}
super$initialize(params)

# assert at least one target parameter
if (!any(self$is_target) && length(params)) stop("Codomain contains no parameter tagged with 'minimize' or 'maximize'")
# assert at least one target eter
if (!any(self$is_target) && self$length) stop("Codomain contains no parameter tagged with 'minimize' or 'maximize'")
}
),

active = list(

#' @field is_target (named `logical()`)\cr
#' Position is `TRUE` for target [Param]s.
#' Position is `TRUE` for target parameters.
is_target = function() {
map_lgl(self$tags, has_element, "minimize") | map_lgl(self$tags, has_element, "maximize")
self$ids() %in% self$target_ids
},

#' @field target_length (`integer()`)\cr
#' Returns number of target [Param]s.
#' Returns number of target parameters.
target_length = function() {
sum(self$is_target)
length(self$target_ids)
},

#' @field target_ids (`character()`)\cr
#' Number of contained target [Param]s.
#' IDs of contained target parameters.
target_ids = function() {
self$ids()[self$is_target]
if ("any_tags" %in% names(formals(self$ids))) {
self$ids(any_tags = c("minimize", "maximize"))
} else {
# old paradox
self$ids()[map_lgl(self$tags, function(x) any(c("minimize", "maximize") %in% x))]
}
},

#' @field target_tags (named `list()` of `character()`)\cr
#' Tags of target [Param]s.
#' Tags of target parameters.
target_tags = function() {
self$tags[self$is_target]
self$tags[self$target_ids]
},

#' @field maximization_to_minimization (`integer()`)\cr
Expand Down
5 changes: 4 additions & 1 deletion R/Objective.R
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ Objective = R6Class("Objective",
constants = ps(), check_values = TRUE) {
self$id = assert_string(id)
self$domain = assert_param_set(domain)
self$codomain = Codomain$new(assert_param_set(codomain)$params)
assert_param_set(codomain)
# get "codomain" element if present (new paradox) or default to $params (old paradox)
params = get0("domains", codomain, ifnotfound = codomain$params)
self$codomain = Codomain$new(params)
assert_names(self$domain$ids(), disjunct.from = self$codomain$ids())
assert_names(self$domain$ids(), disjunct.from = c("x_domain", "timestamp", "batch_nr"))
assert_names(self$codomain$ids(), disjunct.from = c("x_domain", "timestamp", "batch_nr"))
Expand Down
6 changes: 2 additions & 4 deletions R/Optimizer.R
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ Optimizer = R6Class("Optimizer",
#' Creates a new instance of this [R6][R6::R6Class] class.
#'
#' @param param_classes (`character()`)\cr
#' Supported parameter classes that the optimizer can optimize.
#' Subclasses of [paradox::Param].
#' Supported parameter classes that the optimizer can optimize, as given in the [`paradox::ParamSet`] `$class` field.
#'
#' @param properties (`character()`)\cr
#' Set of properties of the optimizer.
Expand Down Expand Up @@ -103,8 +102,7 @@ Optimizer = R6Class("Optimizer",
},

#' @field param_classes (`character()`)\cr
#' Supported parameter classes that the optimizer can optimize.
#' Subclasses of [paradox::Param].
#' Supported parameter classes that the optimizer can optimize, as given in the [`paradox::ParamSet`] `$class` field.
param_classes = function(rhs) {
if (!missing(rhs) && !identical(rhs, private$.param_classes)) {
stop("$param_classes is read-only.")
Expand Down
4 changes: 3 additions & 1 deletion R/OptimizerCmaes.R
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,11 @@ OptimizerCmaes = R6Class("OptimizerCmaes",
initialize = function() {
param_set = ps(
sigma = p_dbl(default = 0.5),
start_values = p_fct(default = "random", levels = c("random", "center"))
start_values = p_fct(levels = c("random", "center"), tags = "required")
)
# old paradox; new paradox can use 'init = "random"'
param_set$values$start_values = "random"

super$initialize(
id = "cmaes",
param_set = param_set,
Expand Down
Loading

0 comments on commit 7448f84

Please sign in to comment.