Ответ 1
Проблема возникает из-за того, что адрес памяти x
не обновляется, когда он изменяется на третьей итерации алгоритма оптимизации в соответствии с методом "BFGS" или "L-BFGS-B", как и должно быть.
Вместо этого адрес памяти x
сохраняется на том же уровне, что и адрес памяти xx
на третьей итерации, и это приводит к тому, что xx
обновляется до значения x
до того, как функция fn
запускается в третий раз, таким образом заставляя функцию возвращать " Память "значение ret
.
Вы можете проверить это самостоятельно, запустив следующий код, который извлекает адреса памяти x
и xx
fn()
с помощью функции address()
пакета envnames или data.table:
library(envnames)
makeFn <- function(){
xx <- ret <- NA
fn <- function(x){
cat("\nAddress of x and xx at start of fn:\n")
cat("address(x):", address(x), "\n")
cat("address(xx):", address(xx), "\n")
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()
# Run the optimization process
optim(par=0.1, fn=fn, method="L-BFGS-B")
чей частичный вывод (при условии, что перед запуском этого фрагмента кода не было выполнено ни одного прогона оптимизации) будет аналогичен следующему:
Address of x and xx at start of fn:
address(x): 0000000013C89DA8
address(xx): 00000000192182D0
x=0.1, ret=0.010201 (calculate)
Address of x and xx at start of fn:
address(x): 0000000013C8A160
address(xx): 00000000192182D0
x=0.101, ret=0.010201 (calculate)
Address of x and xx at start of fn:
address(x): 0000000013C8A160
address(xx): 0000000013C8A160
x=0.099, ret=0.010201 (memory)
Эта проблема не возникает с другими методами оптимизации, доступными в optim()
, такими как метод по умолчанию.
Примечание. Как уже упоминалось, пакет data.table
также можно использовать для получения адреса памяти объектов, но здесь я пользуюсь возможностью для продвижения моих недавно выпущенных имен пакетов (которые, кроме получения адреса памяти объекта, также извлекают определяемые пользователем имена среды из их адреса памяти --among, другие вещи)