test_that("Nop object can be initialized", { ackley <- Nop$new(f = f_ackley, npar = 2) expect_s3_class(ackley, c("Nop", "R6"), exact = TRUE) expect_error( Nop$new(), "specify argument" ) expect_error( Nop$new(f = 1), "is not a" ) expect_error( Nop$new(f = f_ackley), "specify argument" ) expect_error( Nop$new(f = f_ackley, npar = 0), "must be a single, positive" ) expect_identical(ackley$f, f_ackley) expect_identical(ackley$npar, 2L) expect_error( { ackley$f <- function(x) x }, "is read only" ) expect_error( { ackley$npar <- 1 }, "is read only" ) expect_error( Nop$new(f = function() 1, npar = 0), "should have at least one argument" ) }) test_that("Nop object can be printed", { ackley <- Nop$new(f = f_ackley, npar = 2) expect_snapshot(print(ackley)) expect_snapshot(ackley$print()) }) test_that("Parameters for Nop object can be set", { tpm <- matrix(c(0.8, 0.1, 0.2, 0.9), nrow = 2) mu <- c(-2, 2) sigma <- c(0.5, 1) theta <- c(log(tpm[row(tpm) != col(tpm)]), mu, log(sigma)) data <- sim_hmm(Tp = 100, N = 2, theta = theta) hmm <- Nop$new(f = f_ll_hmm, npar = 6, data = data) expect_s3_class(hmm, c("Nop", "R6"), exact = TRUE) expect_error( hmm$set_argument(data), "Please name argument 1." ) expect_error( hmm$set_argument("data" = data), "already exists" ) expect_snapshot(print(hmm)) }) test_that("Parameters for Nop object can be get", { tpm <- matrix(c(0.8, 0.1, 0.2, 0.9), nrow = 2) mu <- c(-2, 2) sigma <- c(0.5, 1) theta <- c(log(tpm[row(tpm) != col(tpm)]), mu, log(sigma)) data <- sim_hmm(Tp = 100, N = 2, theta = theta) hmm <- Nop$new(f = f_ll_hmm, npar = 6, data = data, test_arg = 6) expect_error( hmm$get_argument(), "Please specify" ) expect_equal(hmm$get_argument("test_arg"), 6) expect_error( hmm$get_argument("does_not_exist"), "is not yet specified" ) expect_error( hmm$get_argument(1), "must be a single" ) }) test_that("Parameters for Nop object can be removed", { tpm <- matrix(c(0.8, 0.1, 0.2, 0.9), nrow = 2) mu <- c(-2, 2) sigma <- c(0.5, 1) theta <- c(log(tpm[row(tpm) != col(tpm)]), mu, log(sigma)) data <- sim_hmm(Tp = 100, N = 2, theta = theta) hmm <- Nop$new(f = f_ll_hmm, npar = 6, data = data) expect_error( hmm$remove_argument("arg_does_not_exist"), "is not yet specified" ) expect_s3_class(hmm$remove_argument("data"), "Nop") expect_error( hmm$remove_argument(), "Please specify" ) expect_error( hmm$remove_argument(argument_name = 1:2), "must be a" ) }) test_that("optimizer can be set", { ackley <- Nop$new(f = f_ackley, npar = 2) expect_error( ackley$set_optimizer(), "Please specify argument" ) expect_error( ackley$set_optimizer( "not_an_optimizer_object" ), "must be an" ) expect_error( ackley$set_optimizer(optimizer_nlm(), label = 1), "must be a" ) ackley$set_optimizer(optimizer_nlm(), label = "nlm") expect_snapshot(ackley) expect_error( ackley$set_optimizer(optimizer_nlm(), label = "nlm"), "already exists, please choose another one" ) ackley$set_optimizer(optimizer_optim()) expect_snapshot(ackley) }) test_that("optimizer can be removed", { ackley <- Nop$new(f = f_ackley, npar = 2) ackley$set_optimizer(optimizer_nlm(), label = "A") ackley$set_optimizer(optimizer_nlm(), label = "B") ackley$set_optimizer(optimizer_nlm(), label = "C") ackley$set_optimizer(optimizer_nlm()) expect_snapshot(ackley) expect_error( ackley$remove_optimizer(), "Please specify" ) ackley2 <- ackley$clone() ackley2$remove_optimizer("all") expect_snapshot(ackley2) ackley$remove_optimizer(2) expect_warning( ackley$remove_optimizer(2), "has already been removed" ) expect_snapshot(ackley) ackley$remove_optimizer(c("stats::nlm", "A")) expect_snapshot(ackley) expect_warning( ackley$remove_optimizer("does_not_exist"), "No optimizer selected." ) }) test_that("ackley function can be evaluated", { ackley <- Nop$new(f = f_ackley, npar = 2) expect_error( ackley$evaluate(1), "must be of length 2" ) expect_equal(ackley$evaluate(c(0, 1)), f_ackley(c(0, 1))) }) test_that("long function evaluations can be interrupted", { skip_if_not(.Platform$OS.type == "windows") expect_warning( long_f <- Nop$new(f = function(x) { for (i in 1:7) Sys.sleep(0.1) x }, npar = 1), "is unnamed" ) expect_equal( long_f$evaluate(at = 1, time_limit = 0.5), "time limit reached" ) expect_equal( long_f$evaluate(at = 1, time_limit = 1), 1 ) }) test_that("warnings in function evaluation can be hidden", { expect_warning( warning_f <- Nop$new(f = function(x) { warning("huhu") x }, npar = 1), "is unnamed" ) expect_warning( warning_f$evaluate(at = 1), "huhu" ) expect_warning( warning_f$evaluate(at = 1, hide_warnings = TRUE), regexp = NA ) }) test_that("errors in function evaluation can be returned", { expect_warning( error_f <- Nop$new(f = function(x) { stop("shit") x }, npar = 1), "is unnamed" ) expect_equal( error_f$evaluate(at = 1), "shit" ) }) test_that("HMM likelihood function can be evaluated", { tpm <- matrix(c(0.8, 0.1, 0.2, 0.9), nrow = 2) mu <- c(-2, 2) sigma <- c(0.5, 1) theta <- c(log(tpm[row(tpm) != col(tpm)]), mu, log(sigma)) data <- sim_hmm(Tp = 100, N = 2, theta = theta) hmm <- Nop$new(f = f_ll_hmm, npar = 6, "data" = data) at <- rnorm(6) expect_error( hmm$evaluate(), "is not yet specified" ) hmm$set_argument("N" = 2, "neg" = TRUE) expect_equal( hmm$evaluate(at = at), f_ll_hmm(theta = at, data = data, N = 2, neg = TRUE) ) hmm$remove_argument("neg") expect_equal( hmm$evaluate(at = at), f_ll_hmm(theta = at, data = data, N = 2) ) }) test_that("ackley function can be optimized", { ackley <- Nop$new(f = f_ackley, npar = 2)$ set_optimizer(optimizer_nlm())$ set_optimizer(optimizer_optim()) expect_error( ackley$optimize(runs = -1), "must be a single, positive" ) expect_error( ackley$optimize(verbose = "yes"), "must be" ) expect_error( ackley$optimize(hide_warnings = "bad"), "must be" ) ackley$optimize(runs = 5) ackley$optimize(runs = 1, initial = runif(2)) ackley$optimize(runs = 3, initial = function() runif(2), seed = 1) ackley$optimize(initial = c(0, 0)) ackley$optimize(initial = list(1:2, 2:3, 3:4)) expect_snapshot(ackley) expect_error( ackley$optimize(save_results = "TRUE"), "must be" ) expect_error( ackley$optimize(return_results = "TRUE"), "must be" ) expect_error( ackley$optimize(return_results = TRUE, simplify = "TRUE"), "must be" ) out <- ackley$optimize(runs = 5, return_results = TRUE, save_results = FALSE) expect_type(out, "list") expect_length(out, 5) expect_true(all(sapply(out, length) == 2)) ackley$remove_optimizer(2) out <- ackley$optimize( runs = 1, return_results = TRUE, save_results = FALSE ) expect_type(out, "list") out <- ackley$optimize( runs = 1, return_results = TRUE, save_results = FALSE, simplify = FALSE ) expect_type(out, "list") ackley }) test_that("parallel optimization works", { ackley <- Nop$new(f = f_ackley, npar = 2)$ set_optimizer(optimizer_nlm())$ set_optimizer(optimizer_optim()) expect_error( ackley$optimize(ncores = 1.4), "must be a single, positive" ) skip_on_cran() ackley$optimize( runs = 40, ncores = 2, save_results = FALSE ) }) test_that("Nop object can be tested", { ackley <- Nop$new(f = f_ackley, npar = 2) expect_error( ackley$test(at = 1), "must be of length 2" ) expect_warning( ackley$test(), "No optimizer specified, testing optimizer is skipped." ) ackley$set_optimizer(optimizer_nlm()) expect_true(ackley$test(verbose = FALSE)) }) test_that("standardization works", { tpm <- matrix(c(0.8, 0.1, 0.2, 0.9), nrow = 2) mu <- c(-2, 2) sigma <- c(0.5, 1) theta <- c(log(tpm[row(tpm) != col(tpm)]), mu, log(sigma)) data <- sim_hmm(Tp = 100, N = 2, theta = theta) hmm <- Nop$new( f = f_ll_hmm, npar = 6, "data" = data, "N" = 2, "neg" = TRUE ) expect_error( hmm$standardize(), "Please specify" ) expect_error( hmm$standardize(1), "must be a single" ) expect_s3_class(hmm$standardize("data"), c("Nop", "R6"), exact = TRUE) }) test_that("reduction works", { tpm <- matrix(c(0.8, 0.1, 0.2, 0.9), nrow = 2) mu <- c(-2, 2) sigma <- c(0.5, 1) theta <- c(log(tpm[row(tpm) != col(tpm)]), mu, log(sigma)) data <- sim_hmm(Tp = 100, N = 2, theta = theta) hmm <- Nop$new( f = f_ll_hmm, npar = 6, "data" = data, "N" = 2, "neg" = TRUE ) expect_error( hmm$reduce(), "Please specify" ) expect_error( hmm$reduce(1), "must be a single" ) expect_s3_class(hmm$reduce("data"), c("Nop", "R6"), exact = TRUE) }) test_that("argument can be reset", { tpm <- matrix(c(0.8, 0.1, 0.2, 0.9), nrow = 2) mu <- c(-2, 2) sigma <- c(0.5, 1) theta <- c(log(tpm[row(tpm) != col(tpm)]), mu, log(sigma)) data <- sim_hmm(Tp = 100, N = 2, theta = theta) hmm <- Nop$new( f = f_ll_hmm, npar = 6, "data" = data, "N" = 2, "neg" = TRUE ) hmm$standardize("data") expect_error( hmm$reset_argument(), "Please specify" ) hmm$reset_argument("data") expect_equal(data, hmm$get_argument("data")) hmm$reduce("data") hmm$reset_argument("data") expect_equal(data, hmm$get_argument("data")) }) test_that("continue optimization works", { tpm <- matrix(c(0.8, 0.1, 0.2, 0.9), nrow = 2) mu <- c(-2, 2) sigma <- c(0.5, 1) theta <- c(log(tpm[row(tpm) != col(tpm)]), mu, log(sigma)) data <- sim_hmm(Tp = 100, N = 2, theta = theta) hmm <- Nop$new( f = f_ll_hmm, npar = 6, "data" = data, "N" = 2, "neg" = TRUE )$set_optimizer(optimizer_nlm())$ standardize("data")$ optimize(runs = 2)$ reset_argument("data")$ continue() expect_s3_class(hmm, "Nop") }) test_that("results can be accessed", { runs <- 10 ackley <- Nop$new(f = f_ackley, npar = 2)$ set_optimizer(optimizer_nlm())$ set_optimizer(optimizer_optim())$ optimize(runs = runs, save_results = TRUE, return_results = FALSE) results <- ackley$results() expect_type(results, "list") expect_length(results, runs) }) test_that("number of results can be accessed", { runs <- 10 ackley <- Nop$new(f = f_ackley, npar = 2)$ set_optimizer(optimizer_nlm())$ set_optimizer(optimizer_optim())$ optimize(runs = runs, save_results = TRUE, return_results = FALSE) expect_equal(ackley$number_runs(), runs) }) test_that("overview of available elements can be created", { ackley <- Nop$new(f = f_ackley, npar = 2)$ set_optimizer(optimizer_nlm()) expect_warning( ackley$elements_available(), "No optimization results saved yet" ) ackley$optimize(runs = 10) expect_equal( ackley$elements_available(), list("stats::nlm" = c( "value", "parameter", "seconds", "initial", "gradient", "code", "iterations", "label", "run", "optimizer", "comparable" )) ) }) test_that("results can be cleared", { ackley <- Nop$new(f = f_ackley, npar = 2)$ set_optimizer(optimizer_nlm()) expect_warning( ackley$clear(which_run = 1), "No optimization results saved yet" ) ackley$optimize(runs = 10) ackley$clear(which_run = 1) }) test_that("results can be summarized", { ackley <- Nop$new(f = f_ackley, npar = 2)$ set_optimizer(optimizer_nlm())$ set_optimizer(optimizer_optim()) expect_warning( ackley$summary(), "No optimization results saved yet." ) }) test_that("overview of optima works", { ackley <- Nop$new(f = f_ackley, npar = 2)$ set_optimizer(optimizer_nlm())$ set_optimizer(optimizer_optim()) expect_warning( ackley$optima(), "No optimization results saved yet." ) ackley$optimize(runs = 10) expect_true(is.data.frame(ackley$optima())) expect_error( ackley$optima(sort_by = "bad_input"), "must be" ) }) test_that("optimization times and values can be plotted", { ackley <- Nop$new(f = f_ackley, npar = 2)$ set_optimizer(optimizer_nlm())$ set_optimizer(optimizer_optim())$ optimize(runs = 100, label = "1")$ optimize(runs = 100, label = "2") combinations <- expand.grid( which_element = c("seconds", "value"), by = list("label", "optimizer", NULL), relative = c(TRUE, FALSE), which_run = "all", which_optimizer = "all", only_comparable = c(TRUE, FALSE), stringsAsFactors = FALSE ) for (i in 1:nrow(combinations)) { which_element <- combinations[i, "which_element"] by <- combinations[[i, "by"]] relative <- combinations[i, "relative"] which_run <- combinations[i, "which_run"] which_optimizer <- combinations[i, "which_optimizer"] only_comparable <- combinations[i, "only_comparable"] expect_s3_class( ackley$plot( which_element = which_element, by = by, relative = relative, which_run = which_run, which_optimizer = which_optimizer, only_comparable = only_comparable ), "ggplot" ) } }) test_that("optimization trace can be extracted", { ackley <- Nop$new(f = f_ackley, npar = 2) expect_s3_class(ackley$trace(), "data.frame") }) test_that("best value can be extracted", { ackley <- Nop$new(f = f_ackley, npar = 2)$ set_optimizer(optimizer_nlm())$ set_optimizer(optimizer_optim()) expect_warning( expect_null(ackley$best_value()), "No optimization results saved yet." ) ackley$optimize(runs = 10) expect_length( ackley$best_value(), 1 ) }) test_that("best parameter can be extracted", { ackley <- Nop$new(f = f_ackley, npar = 2)$ set_optimizer(optimizer_nlm())$ set_optimizer(optimizer_optim()) expect_warning( expect_null(ackley$best_parameter()), "No optimization results saved yet." ) ackley$optimize(runs = 10) expect_length( ackley$best_parameter(), 2 ) }) test_that("closest parameter can be extracted", { ackley <- Nop$new(f = f_ackley, npar = 2)$ set_optimizer(optimizer_nlm())$ set_optimizer(optimizer_optim())$ optimize(runs = 10) expect_length( ackley$closest_parameter(0), 2 ) }) test_that("existence of additional argument can be checked", { tpm <- matrix(c(0.8, 0.1, 0.2, 0.9), nrow = 2) mu <- c(-2, 2) sigma <- c(0.5, 1) theta <- c(log(tpm[row(tpm) != col(tpm)]), mu, log(sigma)) data <- sim_hmm(Tp = 100, N = 2, theta = theta) hmm <- Nop$new(f = f_ll_hmm, npar = 6) private <- hmm$.__enclos_env__$private expect_error( private$.check_additional_argument_exists("data"), "is not yet specified" ) hmm$set_argument("data" = data) }) test_that("run ids can be extracted", { ackley <- Nop$new(f = f_ackley, npar = 2)$ set_optimizer(optimizer_nlm(), "nlm")$ optimize(runs = 10, label = "label") private <- ackley$.__enclos_env__$private expect_equal(private$.get_run_ids(which_run = "label"), 1:10) expect_warning( private$.get_run_ids(which_run = "label_does_not_exist"), "Please check argument" ) }) test_that("optimizer ids can be extracted", { ackley <- Nop$new(f = f_ackley, npar = 2) ackley$set_optimizer(optimizer_nlm(), "nlm") ackley$set_optimizer(optimizer_optim(), "optim") ackley$remove_optimizer("optim") private <- ackley$.__enclos_env__$private expect_equal(private$.get_optimizer_ids(which_optimizer = "removed"), 2) expect_error( private$.get_optimizer_ids(which_optimizer = list()), "is misspecified" ) }) test_that("f can be extracted", { hmm <- Nop$new(f = f_ll_hmm, npar = 6) expect_equal(hmm$f, f_ll_hmm) expect_error( { hmm$f <- "function" }, "read only" ) }) test_that("f_name can be extracted and set", { hmm <- Nop$new(f = f_ll_hmm, npar = 6) expect_equal(hmm$f_name, "f_ll_hmm") hmm$f_name <- "name" expect_equal(hmm$f_name, "name") expect_error( { hmm$f_name <- 1 }, "must be a single" ) }) test_that("f_target can be extracted", { hmm <- Nop$new(f = f_ll_hmm, npar = 6) expect_equal(hmm$f_target, "theta") expect_error( { hmm$f_target <- "par" }, "read only" ) }) test_that("npar can be extracted", { hmm <- Nop$new(f = f_ll_hmm, npar = 6) expect_equal(hmm$npar, 6) expect_error( { hmm$npar <- 5 }, "read only" ) }) test_that("arguments can be extracted", { tpm <- matrix(c(0.8, 0.1, 0.2, 0.9), nrow = 2) mu <- c(-2, 2) sigma <- c(0.5, 1) theta <- c(log(tpm[row(tpm) != col(tpm)]), mu, log(sigma)) data <- sim_hmm(Tp = 100, N = 2, theta = theta) hmm <- Nop$new(f = f_ll_hmm, npar = 6) expect_warning( hmm$arguments, "No function arguments have been specified yet" ) hmm$set_argument("data" = data) expect_equal( hmm$arguments, list(data = data) ) expect_error( { hmm$arguments <- "argument" }, "read only" ) }) test_that("true value can be extracted and modified", { ackley <- Nop$new(f = f_ackley, npar = 2) expect_null(ackley$true_value) expect_error( { ackley$true_value <- 1:2 }, "must be a single" ) ackley$true_value <- 0 expect_equal(ackley$true_value, 0) ackley$true_value <- NULL expect_null(ackley$true_value) }) test_that("true parameter can be extracted and modified", { ackley <- Nop$new(f = f_ackley, npar = 2) expect_null(ackley$true_parameter) expect_error( { ackley$true_parameter <- 1:4 }, "must be of length 2" ) ackley$true_parameter <- c(0, 0) expect_equal(ackley$true_value, 0) expect_equal(ackley$true_value, 0) expect_error( { ackley$true_value <- 2 }, "Please update" ) ackley$true_parameter <- NULL expect_null(ackley$true_parameter) }) test_that("show minimum can be extracted and modified", { ackley <- Nop$new(f = f_ackley, npar = 2) expect_true(ackley$minimized) ackley$minimized <- FALSE expect_false(ackley$minimized) expect_error( { ackley$minimized <- "TRUE" }, "must be" ) }) test_that("optimizer can be extracted", { ackley <- Nop$new(f = f_ackley, npar = 2) expect_warning( ackley$optimizer, "No optimizer specified yet" ) ackley$ set_optimizer(optimizer_nlm())$ set_optimizer(optimizer_optim()) expect_type(ackley$optimizer, "list") expect_length(ackley$optimizer, 2) expect_error( { ackley$optimizer <- "optimizer" }, "read only" ) }) test_that("new label can be generated", { ackley <- Nop$new(f = f_ackley, npar = 2)$ set_optimizer(optimizer_nlm()) label <- ackley$new_label expect_true(is_name(label)) ackley$optimize() label_new <- ackley$new_label expect_false(identical(label, label_new)) expect_error( { ackley$new_label <- "label" }, "read only" ) })