Florian Gerber
2019-May-02 19:35 UTC
[Rd] R optim(method="L-BFGS-B"): unexpected behavior when working with parent environments
Dear all,
when using optim() for a function that uses the parent environment, I
see the following unexpected behavior:
makeFn <- function(){
??? xx <- ret <- NA
??? fn <- function(x){
?????? if(!is.na(xx) && x==xx){
?????????? cat("x=", xx, ", ret=", ret, "
(memory)", fill=TRUE, sep="")
?????????? return(ret)
?????? }
?????? xx <<- x; ret <<- sum(x^2)
?????? cat("x=", xx, ", ret=", ret, "
(calculate)", fill=TRUE, sep="")
?????? ret
??? }
??? fn
}
fn <- makeFn()
optim(par=10, fn=fn, method="L-BFGS-B")
# x=10, ret=100 (calculate)
# x=10.001, ret=100.02 (calculate)
# x=9.999, ret=100.02 (memory)
# $par
# [1] 10
#
# $value
# [1] 100
# (...)
I would expect that optim() does more than 3 function evaluations and
that the optimization converges to 0.
Same problem with optim(par=10, fn=fn, method="BFGS").
Any ideas?
See also my related post:
https://stackoverflow.com/questions/53826521/r-optim-unexpected-behavior-when-working-with-parent-environments
???
platform?????? x86_64-pc-linux-gnu????????
arch?????????? x86_64?????????????????????
os???????????? linux-gnu??????????????????
system???????? x86_64, linux-gnu??????????
status????????????????????????????????????
major????????? 3??????????????????????????
minor????????? 6.0????????????????????????
year?????????? 2019???????????????????????
month????????? 04?????????????????????????
day??????????? 26?????????????????????????
svn rev??????? 76424??????????????????????
language?????? R??????????????????????????
version.string R version 3.6.0 (2019-04-26)
nickname?????? Planting of a Tree?????????
Best,
Florian
Serguei Sokol
2019-May-03 08:31 UTC
[Rd] R optim(method="L-BFGS-B"): unexpected behavior when working with parent environments
On 02/05/2019 21:35, Florian Gerber wrote:> Dear all, > > when using optim() for a function that uses the parent environment, I > see the following unexpected behavior: > > makeFn <- function(){ > ??? xx <- ret <- NA > ??? fn <- function(x){ > ?????? if(!is.na(xx) && x==xx){ > ?????????? cat("x=", xx, ", ret=", ret, " (memory)", fill=TRUE, sep="") > ?????????? return(ret) > ?????? } > ?????? xx <<- x; ret <<- sum(x^2) > ?????? cat("x=", xx, ", ret=", ret, " (calculate)", fill=TRUE, sep="") > ?????? ret > ??? } > ??? fn > } > fn <- makeFn() > optim(par=10, fn=fn, method="L-BFGS-B") > # x=10, ret=100 (calculate) > # x=10.001, ret=100.02 (calculate) > # x=9.999, ret=100.02 (memory) > # $par > # [1] 10 > # > # $value > # [1] 100 > # (...) > > I would expect that optim() does more than 3 function evaluations and > that the optimization converges to 0. > > Same problem with optim(par=10, fn=fn, method="BFGS"). > > Any ideas?I don't have an answer but may be an insight. For some mysterious reason xx is getting changed when in should not. Consider: > fn=local({n=0; xx=ret=NA; function(x) {n <<- n+1; cat(n, "in x,xx,ret=", x, xx, ret, "\n"); if (!is.na(xx) && x==xx) ret else {xx <<- x; ret <<- x**2; cat("out x,xx,ret=", x, xx, ret, "\n"); ret}}}) > optim(par=10, fn=fn, method="L-BFGS-B") 1 in x,xx,ret= 10 NA NA out x,xx,ret= 10 10 100 2 in x,xx,ret= 10.001 10 100 out x,xx,ret= 10.001 10.001 100.02 3 in x,xx,ret= 9.999 9.999 100.02 $par [1] 10 $value [1] 100 $counts function gradient ?????? 1??????? 1 $convergence [1] 0 $message [1] "CONVERGENCE: NORM OF PROJECTED GRADIENT <= PGTOL" At the third call, xx has value 9.999 while it should have kept the value 10.001. Serguei.
Serguei Sokol
2019-May-03 08:41 UTC
[Rd] R optim(method="L-BFGS-B"): unexpected behavior when working with parent environments
On 03/05/2019 10:31, Serguei Sokol wrote:> On 02/05/2019 21:35, Florian Gerber wrote: >> Dear all, >> >> when using optim() for a function that uses the parent environment, I >> see the following unexpected behavior: >> >> makeFn <- function(){ >> ???? xx <- ret <- NA >> ???? fn <- function(x){ >> ??????? if(!is.na(xx) && x==xx){ >> ??????????? cat("x=", xx, ", ret=", ret, " (memory)", fill=TRUE, sep="") >> ??????????? return(ret) >> ??????? } >> ??????? xx <<- x; ret <<- sum(x^2) >> ??????? cat("x=", xx, ", ret=", ret, " (calculate)", fill=TRUE, sep="") >> ??????? ret >> ???? } >> ???? fn >> } >> fn <- makeFn() >> optim(par=10, fn=fn, method="L-BFGS-B") >> # x=10, ret=100 (calculate) >> # x=10.001, ret=100.02 (calculate) >> # x=9.999, ret=100.02 (memory) >> # $par >> # [1] 10 >> # >> # $value >> # [1] 100 >> # (...) >> >> I would expect that optim() does more than 3 function evaluations and >> that the optimization converges to 0. >> >> Same problem with optim(par=10, fn=fn, method="BFGS"). >> >> Any ideas? > I don't have an answer but may be an insight. For some mysterious > reason xx is getting changed when in should not. Consider: > > fn=local({n=0; xx=ret=NA; function(x) {n <<- n+1; cat(n, "in > x,xx,ret=", x, xx, ret, "\n"); if (!is.na(xx) && x==xx) ret else {xx > <<- x; ret <<- x**2; cat("out x,xx,ret=", x, xx, ret, "\n"); ret}}}) > > optim(par=10, fn=fn, method="L-BFGS-B") > 1 in x,xx,ret= 10 NA NA > out x,xx,ret= 10 10 100 > 2 in x,xx,ret= 10.001 10 100 > out x,xx,ret= 10.001 10.001 100.02 > 3 in x,xx,ret= 9.999 9.999 100.02 > $par > [1] 10 > > $value > [1] 100 > > $counts > function gradient > ?????? 1??????? 1 > > $convergence > [1] 0 > > $message > [1] "CONVERGENCE: NORM OF PROJECTED GRADIENT <= PGTOL" > > At the third call, xx has value 9.999 while it should have kept the > value 10.001. >A little follow-up: if you untie the link between xx and x by replacing the expression "xx <<- x" by "xx <<- x+0" it works as expected: > fn=local({n=0; xx=ret=NA; function(x) {n <<- n+1; cat(n, "in x,xx,ret=", x, xx, ret, "\n"); if (!is.na(xx) && x==xx) ret else {xx <<- x+0; ret <<- x**2; cat("out x,xx,ret=", x, xx, ret, "\n"); ret}}}) > optim(par=10, fn=fn, method="L-BFGS-B") 1 in x,xx,ret= 10 NA NA out x,xx,ret= 10 10 100 2 in x,xx,ret= 10.001 10 100 out x,xx,ret= 10.001 10.001 100.02 3 in x,xx,ret= 9.999 10.001 100.02 out x,xx,ret= 9.999 9.999 99.98 4 in x,xx,ret= 9 9.999 99.98 out x,xx,ret= 9 9 81 5 in x,xx,ret= 9.001 9 81 out x,xx,ret= 9.001 9.001 81.018 6 in x,xx,ret= 8.999 9.001 81.018 out x,xx,ret= 8.999 8.999 80.982 7 in x,xx,ret= 1.776357e-11 8.999 80.982 out x,xx,ret= 1.776357e-11 1.776357e-11 3.155444e-22 8 in x,xx,ret= 0.001 1.776357e-11 3.155444e-22 out x,xx,ret= 0.001 0.001 1e-06 9 in x,xx,ret= -0.001 0.001 1e-06 out x,xx,ret= -0.001 -0.001 1e-06 10 in x,xx,ret= -1.334475e-23 -0.001 1e-06 out x,xx,ret= -1.334475e-23 -1.334475e-23 1.780823e-46 11 in x,xx,ret= 0.001 -1.334475e-23 1.780823e-46 out x,xx,ret= 0.001 0.001 1e-06 12 in x,xx,ret= -0.001 0.001 1e-06 out x,xx,ret= -0.001 -0.001 1e-06 $par [1] -1.334475e-23 $value [1] 1.780823e-46 $counts function gradient ?????? 4??????? 4 $convergence [1] 0 $message [1] "CONVERGENCE: NORM OF PROJECTED GRADIENT <= PGTOL" Serguei.
Apparently Analagous Threads
- R optim(method="L-BFGS-B"): unexpected behavior when working with parent environments
- R optim(method="L-BFGS-B"): unexpected behavior when working with parent environments
- R optim(method="L-BFGS-B"): unexpected behavior when working with parent environments
- R optim(method="L-BFGS-B"): unexpected behavior when working with parent environments
- R optim(method="L-BFGS-B"): unexpected behavior when working with parent environments