--- title: "Design and sequential optimization" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Design and sequential optimization} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` Version 0.12.0 of `magp` includes four functions for Bayesian optimization: | Starting point | Function | |---|---| | Candidate rows and a fitted model | `magp_expected_improvement()` | | A fitted model and a need for one new experiment | `magp_next_point()` | | Completed experiments and responses | `magp_bayes_optimize()` | | No completed experiments | `magp_bayes_optimize_from_scratch()` | The examples below show the last two cases. The same objective-function interface can evaluate a computer simulation or retrieve a response that has already been measured outside R. ## Define an objective ```{r objective} library(magp) objective <- function(quantity_1, quantity_2, quantity_3, sequence_1, sequence_2, sequence_3) { quantity <- c(quantity_1, quantity_2, quantity_3) sequence <- c(sequence_1, sequence_2, sequence_3) -sum((quantity - c(0.2, 0.6, 0.8))^2) - 0.01 * sum((sequence - c(1, 3, 2))^2) } ``` The function arguments must match the input column names. The return value must be one finite number, or a list containing one finite number named `Score` or `Value`. ## Start without initial data Use `magp_bayes_optimize_from_scratch()` when no experiments have been run. The function creates an initial design, evaluates the objective at those rows, fits a MaGP model, and selects later rows with expected improvement. ```{r complete-workflow, eval=FALSE} result <- magp_bayes_optimize_from_scratch( FUN = objective, n_initial = 8, q = 3, model = "2d", direction = "maximize", n_iter = 3, seed = 4, design_control = list( sequence_method = "sfta", sequence_maxit = 500, quantity_maxit = 500, alignment_maxit = 500 ), fit_control = list( n_starts = 4, workers = 2 ), acquisition_control = list( n_starts = 5, workers = 2 ), verbose = FALSE ) result$initial_design$design result$initial_response result$best_point result$best_value result$history ``` Use `direction = "minimize"` when a smaller response is better, or `direction = "maximize"` when a larger response is better. `n_initial` is the number of starting experiments. `n_iter` is the maximum number of later experiments. The result records the initial design and responses, the best observed point, every completed evaluation in `history`, and the final fitted model. ## Choose the initial sequence method The `sequence_method` setting affects only the sequence portion of the initial design. Choose `"random"` to sample valid permutations, `"sfta"` to improve a complete sequence design with space-filling threshold accepting, or `"sann"` to use simulated annealing. The default is `"sann"` for compatibility with earlier versions. ```{r compare-sequence-methods, eval=FALSE} random_design <- magp_initial_design( n = 12, q = 4, sequence_method = "random", seed = 4 ) sfta_design <- magp_initial_design( n = 12, q = 4, sequence_method = "sfta", seed = 4, sfta_control = list(nstarts = 5, ncalibrate = 200) ) rbind(random = random_design$criteria, sfta = sfta_design$criteria) sfta_design$sequence_search$sfta ``` With a fixed seed, both calls use the same quantitative Latin hypercube before the final alignment step. SFTA improves the initial sequence design. It does not change the expected-improvement search used to select later experiments. ## Continue from completed experiments Use `magp_bayes_optimize()` when initial inputs and responses already exist. The initial rows are treated as completed experiments and are not evaluated again. ```{r continue-existing, eval=FALSE} design <- magp_initial_design(n = 8, q = 3, seed = 4) X_initial <- design$design y_initial <- apply(X_initial, 1L, function(row) { do.call(objective, as.list(row)) }) result <- magp_bayes_optimize( FUN = objective, X = X_initial, y = y_initial, direction = "maximize", n_iter = 3, seed = 4, verbose = FALSE ) result$best_point result$best_value result$history ``` Each iteration fits a model to all available results, selects one unobserved point, evaluates the objective, and adds the new response. Set `stop_ei` and `stop_patience` to stop after repeated selections with little expected improvement. The control lists are optional. `design_control` changes the initial-design search, `fit_control` changes model fitting, and `acquisition_control` changes the next-point search. The function help pages list every available setting and every returned component.