Wrappers for additional optimizers
nloptwrap.Rd
Wrappers to allow use of alternative optimizers, from the NLopt
library (via nloptr) or elsewhere, for the nonlinear optimization stage.
Arguments
- par
starting parameter vector
- fn
objective function
- lower, upper
numeric vector of lower and upper bounds.
- control
list
of control parameters, corresponding tooptCtrl = *
, e.g., inlmerControl()
. Fornloptwrap
, seedefaultControl
in ‘Details’.- ...
additional arguments to be passed to objective function
Value
- par
estimated parameters
- fval
objective function value at minimum
- feval
number of function evaluations
- conv
convergence code (0 if no error)
- message
convergence message
Details
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 tonlminb()
's defaults, see there.nloptwrap
:environment(nloptwrap)$defaultControl
contains the defaults, notablyalgorithm = "NLOPT_LN_BOBYQA"
.nloptr::nloptr.print.options()
shows and explains the many possible algorithm and options.
Examples
library(lme4)
ls.str(environment(nloptwrap)) # 'defaultControl' algorithm "NLOPT_LN_BOBYQA"
#> defaultControl : List of 4
#> $ algorithm: chr "NLOPT_LN_BOBYQA"
#> $ xtol_abs : num 1e-08
#> $ ftol_abs : num 1e-08
#> $ maxeval : num 1e+05
## 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
#> 'log Lik.' 0 (df=6)
c(logLik(fm1C) - logLik(fm1)) ## no difference in LL
#> [1] 0
## 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")
}
#> Likelihood difference (typically zero): 0