diff --git a/NEWS.md b/NEWS.md index 2bc593fe..6ae61cce 100644 --- a/NEWS.md +++ b/NEWS.md @@ -13,6 +13,10 @@ ## New features and improvements + * Conditions that are always true because they depend on fixed parameters are + replaced by a `TRUE` value to speed up their evaluation. This speed-up is only + measurable with very large and complicated parameter space. + * The options `src` and `target` of `ablation()` (or `--src` and `--target` of the command-line `ablation` tool) now accept a character string that points to a file containing a configuration that will be read with diff --git a/R/parameters.R b/R/parameters.R index bff87997..fb3b7fce 100644 --- a/R/parameters.R +++ b/R/parameters.R @@ -337,6 +337,16 @@ ParameterSpace <- R6::R6Class("ParameterSpace", cloneable = TRUE, lock_class = T self$forbidden <- sapply(forbidden, compile_forbidden) } + # Optimize always TRUE conditions. + cond_names <- names(which(!unlist(lapply(self$conditions, is.logical)))) + for (p in cond_names) { + deps <- self$depends[[p]] + # p depends on deps and they are both fixed and always active. + if (all(self$isFixed[deps]) && all(sapply(self$conditions[deps], isTRUE, USE.NAMES=FALSE))) { + self$conditions[[p]] <- eval(self$conditions[[p]], envir = self$domains[deps], enclos = NULL) + } + } + # Print the hierarchy vector: if (verbose >= 1L) { cat ("# --- Parameters Hierarchy ---\n") diff --git a/tests/testthat/test-readParameters.R b/tests/testthat/test-readParameters.R index bdf2d490..9b77dc09 100644 --- a/tests/testthat/test-readParameters.R +++ b/tests/testthat/test-readParameters.R @@ -1,5 +1,22 @@ withr::with_output_sink("test-readParameters.Rout", { + test_that("optimize conditions", { + p <- readParameters(text=' +ROOT "" c ("S") +ROOT_T "" c ("FIC") | ROOT %in% c("S") +ROOT_T_FIC.sum "" r (-50.0, 50.0) | ROOT_T %in% c("FIC") +ROOT_T.FFI "" c ("true") | ROOT_T == "FIC" +ROOT_T.im "" c ("FFI", "FIC") | ROOT == "S" & ROOT_T.FFI == "true" +ROOT_E.FFI "" c ("false") | ROOT_T_FIC.sum < 0 +ROOT_E.FIC "" i (0,100) | ROOT_E.FFI == "false" +') + expect_identical(p$conditions, + list(ROOT=TRUE, ROOT_T=TRUE, ROOT_T_FIC.sum=TRUE, + ROOT_T.FFI=TRUE, ROOT_T.im=TRUE, + ROOT_E.FFI=expression(ROOT_T_FIC.sum < 0), + ROOT_E.FIC=expression(ROOT_E.FFI == "false"))) + }) + test_that("error checking", { ref <- parametersNew(param_real(name = "tmp", lower = 0, upper=1,