RTMB has the capabilities to do this (example below) but there are some side effects to be aware of:
* The tape optimizer can do a better job when knowing the data can't change. It's therefore often worth waiting for the tape to be rebuilt with the new data rather than implementing data updates.
* The tape forward loop is only triggered when parameters change compared to previous evaluation. That is, if you change the data, and re-evaluate the likelihood for the same parameters as previous, nothing will happen (see example)!
* DataEval evaluates an R function and is therefore not thread safe. It therefore won't play well with a parallel version of RTMB.
library(RTMB)
mydat <- rivers
f <- function(p) {
getDat <- function(x) {
print("Get data")
.GlobalEnv$mydat
}
## dummy parameter (DataEval expects an argument)
empty <- rep(p$mu, 0)
## Add R function to the AD tape
y <- DataEval(getDat, empty)
-sum(dnorm(y, p$mu, p$sd, log=TRUE))
}
obj <- MakeADFun(f, list(mu=0, sd=1))
obj$fn(obj$par)
obj$fn(obj$par) ## Same parameter as previous - nothing happens!
## Fit with mydat
opt <- nlminb(obj$par, obj$fn, obj$gr)
opt$par
## Refit with new data
mydat <- mydat * .1
opt <- nlminb(obj$par, obj$fn, obj$gr)
opt$par