Learn R Programming

nimble (version 1.2.1)

nimOptim: General-purpose Optimization

Description

NIMBLE wrapper around R's builtin optim, with flexibility for additional methods.

Usage

nimOptim(
  par,
  fn,
  gr = "NULL",
  he = "NULL",
  ...,
  method = "Nelder-Mead",
  lower = -Inf,
  upper = Inf,
  control = nimOptimDefaultControl(),
  hessian = FALSE
)

Value

optimResultNimbleList

Arguments

par

Initial values for the parameters to be optimized over.

fn

A function to be minimized (or maximized), with first argument the vector of parameters over which minimization is to take place. It should return a scalar result.

gr

A function to return the gradient for the "BFGS", "CG" and "L-BFGS-B" methods. If not provided, a finite-difference approximation to derivatives will be used.

he

A function to return the Hessian matrix of second derivatives. Used (but not required) in "nlminb" or (optionally) user-provided methods.

...

IGNORED

method

The method to be used. See `Details` section of optim. One of: "Nelder-Mead", "BFGS", "CG", "L-BFGS-B", or "nlminb". Note that the R methods "SANN", "Brent" are not supported. It is also possible to provide a new method; see details.

lower

Vector or scalar of lower bounds for parameters.

upper

Vector or scalar of upper bounds for parameters.

control

A list of control parameters. See Details section of optim. For code in a nimbleFunction to be compiled, this must be an optimControlNimbleList, which has fields for most elements in the control list for R's optim.

hessian

Logical. Should a Hessian matrix be returned?

Details

This function for use in nimbleFunctions for compilation by compileNimble provides capabilities similar to R's optim and nlminb. For the supported methods provided by optim, a compiled nimbleFunction will directly call the C code used by R for these methods.

If optim appears in a nimbleFunction, it will be converted to nimOptim.

Note that if a gradient function (gr) is not provided, optim provides a finite difference approximation for use by optimization methods that need gradients. nimble's compiled version of nimOptim does the same thing, although results might not be completely identical.

For method="nlminb", a compiled nimbleFunction will run R's nlminb directly in R, with fn, gr (if provided) and he (if provided) that call back into compiled code.

An experimental feature is the capability to provide one's own optimization method in R and register it for use by nimOptim. One must write a function that takes arguments par, fn, gr, he, lower, upper, control, and hessian. The function must return a list with elements par, value, convergence, counts, evaluations, message, and hessian (which may be NULL). If hessian=TRUE but the function does not return a matrix in the hessian element of its return list, nimOptim will fill in that element using finite differences of the gradient.

The control list passed from a nimbleFunction to the optimization function will include a minimum of options, including abstol, reltol, maxit, and trace. Other options for a specific method may be set within the custom optimization function but cannot be passed from nimOptim.

The elements parscale and fnscale in control are used in a special way. They are implemented by nimOptim such that for *any* the method is expected to do minimization and nimOptim will arrange for it to minimize fn(par)/fnscale in the parameter space par/parscale.

An optimizer fun may be registered by nimOptimMethod("method_name", fun), and then "method_name" can be used as the method argument to nimOptim to use fun. An optimizer may be found by nimOptimMethod("method_name") and may be removed by nimOptimMethod("method_name", NULL).

Support for method="nlminb" is provided in this way, and can be studied as an example via nimOptimMethod("nlminb").

The system for providing one's own optimizer is not considered stable and is subject to change in future versions.

See Also

Examples

Run this code
if (FALSE) {
objectiveFunction <- nimbleFunction(
    run = function(par = double(1)) {
        return(sum(par) * exp(-sum(par ^ 2) / 2))
        returnType(double(0))
    }
)
optimizer <- nimbleFunction(
    run = function(method = character(0), fnscale = double(0)) {
        control <- optimDefaultControl()
        control$fnscale <- fnscale
        par <- c(0.1, -0.1)
        return(optim(par, objectiveFunction, method = method, control = control))
        returnType(optimResultNimbleList())
    }
)
cOptimizer <- compileNimble(optimizer)
cOptimizer(method = 'BFGS', fnscale = -1)
}

Run the code above in your browser using DataLab