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.)
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:
L-BFGS-B
I think a line search is involved ...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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With