Wrappers for additional optimizers
Wrappers to allow use of alternative optimizers, from the NLopt
library (via nloptr) or elsewhere, for the nonlinear optimization stage.
nloptwrap (par, fn, lower, upper, control = list(), ...) nlminbwrap(par, fn, lower, upper, control = list(), ...)
par |
starting parameter vector |
fn |
objective function |
lower, upper |
numeric vector of lower and upper bounds. |
control |
|
... |
additional arguments to be passed to objective function |
Using alternative optimizers is an important trouble-shooting
tool for mixed models. These wrappers provide convenient access to
the optimizers provided by Steven Johnson's NLopt library
(via the nloptr R package), and to the nlminb
optimizer from base R. nlminb is also available via the
optimx package; this wrapper provides access to nlminb()
without the need to install/link the package, and without the additional
post-fitting checks that are implemented by optimx (see examples
below).
One important difference between the nloptr-provided
implementation of BOBYQA and the minqa-provided version
accessible via optimizer="bobyqa" is that it provides simpler
access to optimization tolerances. bobyqa provides
only the rhoend parameter (“[t]he smallest value of the
trust region radius that is allowed”), while nloptr provides a more
standard set of tolerances for relative or absolute change in the
objective function or the parameter values (ftol_rel,
ftol_abs, xtol_rel, xtol_abs).
The default (empty) control list corresponds to the following settings:
nlminbwrap:control exactly corresponds to
nlminb()'s defaults, see there.
nloptwrap:environment(nloptwrap)$defaultControl
contains the defaults, notably algorithm = "NLOPT_LN_BOBYQA".
nloptr::nloptr.print.options() shows and explains the many
possible algorithm and options.
par |
estimated parameters |
fval |
objective function value at minimum |
feval |
number of function evaluations |
conv |
convergence code (0 if no error) |
message |
convergence message |
Gabor Grothendieck (nlminbwrap)
library(lme4)
ls.str(environment(nloptwrap)) # 'defaultControl' algorithm "NLOPT_LN_BOBYQA"
## Note that 'optimizer = "nloptwrap"' is now the default for lmer() :
fm1 <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy)
## tighten tolerances
fm1B <- update(fm1, control= lmerControl(optCtrl = list(xtol_abs=1e-8, ftol_abs=1e-8)))
## run for longer (no effect in this case)
fm1C <- update(fm1,control = lmerControl(optCtrl = list(maxeval=10000)))
logLik(fm1B) - logLik(fm1) ## small difference in log likelihood
c(logLik(fm1C) - logLik(fm1)) ## no difference in LL
## Nelder-Mead
fm1_nloptr_NM <- update(fm1, control=
lmerControl(optimizer = "nloptwrap",
optCtrl = list(algorithm = "NLOPT_LN_NELDERMEAD")))
## other nlOpt algorithm options include NLOPT_LN_COBYLA, NLOPT_LN_SBPLX, see
if(interactive())
nloptr::nloptr.print.options()
fm1_nlminb <- update(fm1, control=lmerControl(optimizer = "nlminbwrap"))
if (require(optimx)) { ## the 'optimx'-based nlminb :
fm1_nlminb2 <- update(fm1, control=
lmerControl(optimizer = "optimx",
optCtrl = list(method="nlminb", kkt=FALSE)))
cat("Likelihood difference (typically zero): ",
c(logLik(fm1_nlminb) - logLik(fm1_nlminb2)), "\n")
}Please choose more modern alternatives, such as Google Chrome or Mozilla Firefox.