gridSearch: Grid Search

View source: R/gridSearch.R

gridSearchR Documentation

Grid Search

Description

Evaluate a function for a given list of arguments.

Usage

gridSearch(fun, levels, ..., lower, upper, npar = 1L, n = 5L,
           printDetail = TRUE,
           method = NULL,
           mc.control = list(), cl = NULL,
           keepNames = FALSE, asList = FALSE)

Arguments

fun

a function of the form fun(x, ...), with x being a numeric vector or a list

levels

a list of levels for the arguments (see Examples)

...

objects passed to fun

lower

a numeric vector. Ignored if levels are explicitly specified.

upper

a numeric vector. Ignored if levels are explicitly specified.

npar

the number of parameters. Must be supplied if lower and upper are to be expanded; see Details. Ignored when levels are explicitly specified, or when lower/upper are used and at least one has length greater than one. See Examples.

n

the number of levels. Default is 5. Ignored if levels are explicitly specified.

printDetail

print information on the number of objective function evaluations

method

can be loop (the default), multicore or snow. See Details.

mc.control

a list containing settings that will be passed to mclapply if method is multicore. Must be a list of named elements; see the documentation of mclapply in parallel.

cl

default is NULL. If method snow is used, this must be a cluster object or an integer (the number of cores).

keepNames

logical: should the names of levels be kept?

asList

does fun expect a list? Default is FALSE.

Details

A grid search can be used to find ‘good’ parameter values for a function. In principle, a grid search has an obvious deficiency: as the length of x (the first argument to fun) increases, the number of necessary function evaluations grows exponentially. Note that gridSearch will not warn about an unreasonable number of function evaluations, but if printDetail is TRUE it will print the required number of function evaluations.

In practice, grid search is often better than its reputation. If a function takes only a few parameters, it is often a reasonable approach to find ‘good’ parameter values.

The function uses the mechanism of expand.grid to create the list of parameter combinations for which fun is evaluated; it calls lapply to evaluate fun if method == "loop" (the default).

If method is multicore, then function mclapply from package parallel is used. Further settings for mclapply can be passed through the list mc.control. If multicore is chosen but the functionality is not available, then method will be set to loop and a warning is issued. If method == "snow", the function clusterApply from package parallel is used. In this case, the argument cl must either be a cluster object (see the documentation of clusterApply) or an integer. If an integer, a cluster will be set up via makeCluster(c(rep("localhost", cl)), type = "SOCK") (and stopCluster is called when the function is exited). If snow is chosen but not available or cl is not specified, then method will be set to loop and a warning is issued.

Value

A list.

minfun

the minimum of fun.

minlevels

the levels that give this minimum.

values

a list. All the function values of fun.

levels

a list. All the levels for which fun was evaluated.

Author(s)

Enrico Schumann

References

Gilli, M., Maringer, D. and Schumann, E. (2019) Numerical Methods and Optimization in Finance. 2nd edition. Elsevier. \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1016/C2017-0-01621-X")}

Schumann, E. (2023) Financial Optimisation with R (NMOF Manual). http://enricoschumann.net/NMOF.htm#NMOFmanual

Examples

testFun <- function(x)
    x[1L] + x[2L]^2

sol <- gridSearch(fun = testFun, levels = list(1:2, c(2, 3, 5)))
sol$minfun
sol$minlevels

## specify all levels
levels <- list(a = 1:2, b = 1:3)
res <- gridSearch(testFun, levels)
res$minfun
sol$minlevels

## specify lower, upper and npar
lower <- 1; upper <- 3; npar <- 2
res <- gridSearch(testFun, lower = lower, upper = upper, npar = npar)
res$minfun
sol$minlevels

## specify lower, upper, npar and n
lower <- 1; upper <- 3; npar <- 2; n <- 4
res <- gridSearch(testFun, lower = lower, upper = upper, npar = npar, n = n)
res$minfun
sol$minlevels

## specify lower, upper and n
lower <- c(1,1); upper <- c(3,3); n <- 4
res <- gridSearch(testFun, lower = lower, upper = upper, n = n)
res$minfun
sol$minlevels

## specify lower, upper (auto-expanded) and n
lower <- c(1,1); upper <- 3; n <- 4
res <- gridSearch(testFun, lower = lower, upper = upper, n = n)
res$minfun
sol$minlevels



## non-numeric inputs
test_fun <- function(x) {
    -(length(x$S) + x$N1 + x$N2)
}

ans <- gridSearch(test_fun,
                  levels = list(S  = list("a", c("a", "b"), c("a", "b", "c")),
                                N1 = 1:5,
                                N2 = 101:105),
                  asList = TRUE, keepNames = TRUE)
ans$minlevels
## $S
## [1] "a" "b" "c"
##
## $N1
## [1] 5
##
## $N2
## [1] 105


NMOF documentation built on Oct. 20, 2023, 9:07 a.m.