Nothing
##library(knitr) library(RTMB) set.seed(1) formals(MakeADFun)$silent <- TRUE
if(), abs(), round(), min(), max() depending on parameters)library(RTMB) might not work<-[ (see here) etc.c() function, or if you use the diag<- function (which sets the diagonal of a matrix) or the [<- function (which assigns values within a matrix), you need to add e.g. ADoverload("[<-") to the beginning of your functionnumeric(0), not c() or NULL (i.e. x <- c(); x[1] <- 2 throws an error, but x <- numeric(0); x[1] <- 2 does work), see here. In any case it is better practice to preallocate instead of growing vectors, e.g. x <- numeric(1); x[1] <- 2 (see chapter 2 of the R Inferno).Matrix::expm() rather than expm::expm()drop() and as.matrix() to convert matrices with dimension 1 in some direction (or Matrix matrices) back to vectors[[-indexing may be much faster than [-indexing: see here (and later messages in that thread)cat() or print() to print out numeric values, the results may not make sense (you'll see a printout of RTMB's internal representation of autodiff-augmented numbers ...)%*% (as in base R), not * (as in C++) for matrix/matrix and matrix/vector multiplicationfor loops) being very slow relative to vectorized codes. However, vectorized code builds the model object (i.e. runs MakeADFun) much faster. In addition, you can control vectorized RTMB code to use more efficient internal operations e.g. by setting TapeConfig(vectorize="enable").
Comparing natively vectorized code (fastest) to RTMB vectorized or for-loop code (both a bit slower, but not different from each other) to native R for-loops (much slower):library(microbenchmark) set.seed(101) ## Loops *must* be fairly long for the caller overhead to vanish x <- rnorm(1e5) y <- rnorm(1e5) ## Benchmark functions *must* return something, or RTMB will optimize it all away! f1_vect <- function(p) { sum(p*x+y) } f1_forloop <- function(p) { z <- 0 for (i in seq_along(x)) { z = z + p*x[i] + y[i] } z } f1_vect_RTMB <- MakeADFun(f1_vect, c(p=1)) f1_forloop_RTMB <- MakeADFun(f1_forloop, c(p=1)) old <- TapeConfig() TapeConfig(vectorize="enable") f1_vect_RTMB2 <- MakeADFun(f1_vect, c(p=1)) invisible(TapeConfig(old)) ## RTMB *must* be given a new argument for each eval, or it will just return the previous value! if (requireNamespace("microbenchmark")) { mm <- microbenchmark(vect = f1_vect(rnorm(1)), vect_RTMB = f1_vect_RTMB$fn(rnorm(1)), vect_RTMB2 = f1_vect_RTMB2$fn(rnorm(1)), forloop = f1_forloop(rnorm(1)), forloop_RTMB = f1_forloop_RTMB$fn(rnorm(1)), times = 100L) }
if (exists("mm") && requireNamespace("tinyplot")) { par(las=1) mm2 <- transform(as.data.frame(mm), ntime = time/1000, expr = factor(expr, levels = c("vect", "vect_RTMB2", "vect_RTMB", "forloop_RTMB", "forloop"), labels = c("vectorized\nnative R", "TapeConfig\nRTMB", "vectorized\nRTMB", "for loop\nRTMB", "for loop\nnative R")) ) tinyplot::tinyplot(ntime ~ expr, data = mm2, type = "violin", log = "y", trim = TRUE, joint.bw = FALSE, xlab = "", ylab = "time (microseconds)") }
data argument)broom.mixed package does have a rudimentary tidy method for TMB objects (e.g. class(TMBobj) <- c("TMB", class(TMBobj)); broom.mixed::tidy(TMBobj))MakeADFun, you can use assign(..., environment(objective_function)) to make sure that the objective function can see any objects it needs to know about ...Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.