Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding the maxit argument of optim() in R

Tags:

In the following call to optim() I would expect one evaluation of fn() and one of gr(), because maxit=1. However, fn() and gr() are evaluated 7 times each.

optim(par=1000, fn=function(x) x^2, gr=function(x) 2*x,
      method="L-BFGS-B", control=list(maxit=1))$counts
function gradient 
       7        7 

Why is this? Is it a bug? Or why does optim() do 7 evaluations for one iteration?


More detailed output:

optim(par=1000,
      fn=function(x) { cat("f(", x, ")", sep="", fill=TRUE); x^2 },
      gr=function(x) { cat("g(", x, ")", sep="", fill=TRUE); 2*x },
      method="L-BFGS-B", control=list(maxit=1))$counts
f(1000)
g(1000)
f(999)
g(999)
f(995)
g(995)
f(979)
g(979)
f(915)
g(915)
f(659)
g(659)
f(1.136868e-13)
g(1.136868e-13)
function gradient 
       7        7 

(Tested with R version 3.5.0.)

like image 389
Nairolf Avatar asked Dec 05 '18 20:12

Nairolf


2 Answers

An iteration is one iteration of the optimization algorithm. A function evaluation is a single call to the objective function. How many function evaluations are required for each iteration will depend on:

  • what algorithm is being used (e.g. Nelder-Mead vs BFGS vs. ...)
  • how one iteration step works
    • e.g. for Nelder-Mead an iteration comprises (1) reflection; (2) [maybe] expansion; (3) [maybe] contraction; (4) [maybe] shrinkage; there's always one evaluation (reflection), but the other steps are conditional on what happens in the first sub-step
    • for L-BFGS-B I think a line search is involved ...
  • whether derivatives need to be computed by finite differences

For what it's worth,nlminb allows separate control of max iterations and max evaluations:

‘eval.max’ Maximum number of evaluations of the objective function allowed. Defaults to 200.
‘iter.max’ Maximum number of iterations allowed. Defaults to 150.

like image 191
Ben Bolker Avatar answered Oct 16 '22 19:10

Ben Bolker


Docs:

See https://stat.ethz.ch/R-manual/R-devel/library/stats/html/optim.html for more info on how you can tell:

convergence 
An integer code. 0 indicates successful completion (which is always the case for "SANN" and "Brent"). Possible error codes are

1      indicates that the iteration limit maxit had been reached.

Running your code (but looking at convergence instead of counts), I get:

> optim(par=1000,
+       fn=function(x) { cat("f(", x, ")", sep="", fill=TRUE); x^2 },
+       gr=function(x) { cat("g(", x, ")", sep="", fill=TRUE); 2*x },
+       method="L-BFGS-B", control=list(maxit=1))$convergence
f(1000)
g(1000)
f(999)
g(999)
f(995)
g(995)
f(979)
g(979)
f(915)
g(915)
f(659)
g(659)
f(1.136868e-13)
g(1.136868e-13)
[1] 1

So it ran one iteration and stopped, returning convergence = 1. Another key is in the counts description, which says:

counts  
A two-element integer vector giving the number of calls to fn and gr respectively. 
This excludes those calls needed to compute the Hessian, if requested, and any calls 
to fn to compute a finite-difference approximation to the gradient.

Implying it calls it a bunch of times to figure out what's happening. You can look in the c code to figure out how many times each method will call your function.

like image 39
twedl Avatar answered Oct 16 '22 20:10

twedl