Skip to contents

Runs one of the fourteen ported Numerics optimizers over an R function. The optimizer's random number generator lives in C++, so a seeded run reproduces exactly, and reproduces identically in corehydropy.

Usage

optim_minimize(
  objective,
  lower = NULL,
  upper = NULL,
  initial = NULL,
  method = c("de", "particle_swarm", "sce", "simulated_annealing", "multi_start", "mlsl",
    "bfgs", "powell", "adam", "gradient_descent", "nelder_mead", "brent",
    "golden_section", "augmented_lagrange"),
  seed = NULL,
  control = list(),
  gradient = NULL,
  constraints = NULL,
  inner = NULL
)

optim_maximize(
  objective,
  lower = NULL,
  upper = NULL,
  initial = NULL,
  method = c("de", "particle_swarm", "sce", "simulated_annealing", "multi_start", "mlsl",
    "bfgs", "powell", "adam", "gradient_descent", "nelder_mead", "brent",
    "golden_section", "augmented_lagrange"),
  seed = NULL,
  control = list(),
  gradient = NULL,
  constraints = NULL,
  inner = NULL
)

Arguments

objective

a function taking a numeric parameter vector and returning a single number.

lower, upper

numeric vectors of parameter bounds, the same length as the parameter vector. Required for every method, including "de", "brent" and "golden_section", which take no initial. "brent" and "golden_section" are one-dimensional: pass a single bound each.

initial

optional numeric vector of starting values, the same length as lower/upper. Required for "bfgs", "powell", "mlsl", "multi_start", "adam", "gradient_descent" and "nelder_mead".

method

one of "de" (differential evolution, the default), "particle_swarm", "sce" (shuffled complex evolution), "simulated_annealing", "multi_start", "mlsl", "bfgs", "powell", "adam", "gradient_descent", "nelder_mead", "brent", "golden_section", or "augmented_lagrange" (the one constrained method, and the one method optim_maximize() rejects – see Details).

seed

optional integer seed for the stochastic methods ("de", "particle_swarm", "sce", "simulated_annealing", "multi_start", "mlsl"); an error for any other method.

control

a named list of optimizer settings. Every method accepts max_iterations, absolute_tolerance and relative_tolerance. Every method except "nelder_mead" and "brent" (the two classes that do not derive from the ported Optimizer base) additionally accepts max_function_evaluations, report_failure (default TRUE, which surfaces a configuration failure as an R error rather than returning a failed status quietly) and compute_hessian. The method-specific settings are population_size ("de", "particle_swarm"); complexes, cce_iterations and tolerance_steps ("sce"); initial_temperature, min_temperature, cooling_rate, update_cycles, temperature_cycles and tolerance_steps ("simulated_annealing"); local_method ("multi_start", "mlsl", one of "bfgs", "nelder_mead", "powell"); local_absolute_tolerance, local_relative_tolerance, polish ("multi_start"); alpha, the step size or learning rate ("adam", "gradient_descent"); and beta1, beta2, the two decay factors ("adam"). Passing a setting a method does not read is an error rather than a silent no-op. compute_hessian DEFAULTS TO TRUE for the Optimizer-base methods (matching the ported C# Optimizer base), so a successful run returns a Hessian, computed by extra objective evaluations, unless the caller passes control = list(compute_hessian = FALSE) to skip it.

gradient

optional function taking the parameter vector and returning one partial derivative per parameter. Accepted only by "adam" and "gradient_descent", an error for every other method. Omitted, both methods differentiate the objective numerically, exactly as the upstream C# classes do with a null gradient.

constraints

a list of optim_constraint() objects. Required by, and accepted only by, method = "augmented_lagrange".

inner

an optional named list describing the inner optimizer the augmented Lagrange method drives, with names method, initial, lower, upper, seed and control. Any vector left out falls back to the top-level one, so list(method = "powell") is enough. Accepted only by method = "augmented_lagrange"; omitted, the inner optimizer is "bfgs" over the top-level initial/lower/upper. The inner method may be any method except "augmented_lagrange" itself and the two standalone classes "nelder_mead"/"brent".

Value

a corehydro_optim list with parameters, value (the objective's own value at the optimum, in its own sign convention – not negated for optim_maximize()), iterations, function_evaluations, status, and hessian (populated by default for every Optimizer-base method; always NULL for "nelder_mead"/"brent", or when compute_hessian was turned off). For "augmented_lagrange" it additionally carries multipliers, a list of the three Lagrange multiplier vectors – equality, less_than and greater_than – each holding one entry per constraint of that type, in the order the constraints were given.

Details

optim_maximize() accepts every method except "augmented_lagrange", which can only minimize: the upstream C# class always drives its inner optimizer through Minimize() over an augmented Lagrangian built from the raw objective, so a maximize request would flip the reported sign without flipping the search direction and hand back the constrained minimum. Negate the objective and call optim_minimize() instead – minimizing -f subject to the same constraints is exactly maximizing f.

Examples

rosenbrock <- function(p) (1 - p[1])^2 + 100 * (p[2] - p[1]^2)^2
fit <- optim_minimize(rosenbrock, lower = c(-5, -5), upper = c(5, 5), seed = 42)
round(fit$parameters, 3)
#> [1] 1 1

# Constrained: minimize the same function on the unit disk.
con <- optim_constraint(function(p) p[1]^2 + p[2]^2, value = 2, type = "le")
fit <- optim_minimize(rosenbrock, initial = c(0, 0), lower = c(-1.5, -1.5),
                      upper = c(1.5, 1.5), method = "augmented_lagrange",
                      constraints = list(con))
round(fit$parameters, 3)
#> [1] 1 1