anders nielsen template model-builder
DESCRIPTION
Advancing Software for Ecological ForecastingTRANSCRIPT
Introduction to Template Model Builder
Kasper Kristensen & Anders Nielsen
What is TMB
� Developered by Kasper Kristensen
� ADMB inspired R-package
� Combines external libraries: CppAD, Eigen, CHOLMOD
� Continuously developed since 2009, < 10000 lines of code
� Implements Laplace approximation for random effects
� C++ Template based
� Automatic sparseness detection
� Parallelism through BLAS
� Parallel user templates
� Parallelism through multicore package
Code
DATA_SECTION
init_int N
init_vector Y(1,N)
init_vector x(1,N)
PARAMETER_SECTION
init_number a
init_number b
init_number logSigma
sdreport_number sigmasq
objective_function_value nll
PROCEDURE_SECTION
sigmasq=exp(2*logSigma);
nll=0.5*(N*log(2*M_PI*sigmasq)+sum(square(Y-(a+b*x)))/sigmasq);
#include <TMB.hpp>
template<class Type>
Type objective_function<Type>::operator() ()
{
DATA_VECTOR(Y);
DATA_VECTOR(x);
PARAMETER(a);
PARAMETER(b);
PARAMETER(logSigma);
ADREPORT(exp(2*logSigma));
Type nll=-sum(dnorm(Y,a+b*x,exp(logSigma),true));
return nll;
}
##################### THEN IN R #####################
library(TMB)
compile("linreg.cpp")
dyn.load("linreg.so")
set.seed(123)
data <- list(Y=rnorm(10)+1:10,x=1:10)
parameters <- list(a=0,b=0,logSigma=0)
obj <- MakeADFun(data,parameters)
obj$hessian <- TRUE
opt <- do.call("optim",obj)
opt
opt$hessian ## <-- FD hessian from optim
obj$he() ## <-- Analytical hessian
sdreport(obj)
Code with random effects#include <TMB.hpp>
/* Parameter transform */
template <class Type>
Type square(Type x){return x*x;}
template<class Type>
Type objective_function<Type>::operator() ()
{
DATA_VECTOR(Y); /* timeSteps x stateDim */
PARAMETER_VECTOR(X); /* State */
PARAMETER(logr0);
PARAMETER(logtheta);
PARAMETER(logK);
PARAMETER(logQ)
PARAMETER(logR)
int timeSteps=Y.size();
using namespace density;
Type ans=0;
for(int i=1;i<timeSteps;i++){
Type var=exp(logQ);
Type m=X[i-1] + exp(logr0) * (1.0 - pow(exp(X[i-1])/exp(logK),exp(logtheta)));
ans+=0.5*(log(2.0*M_PI*var)+square(X[i]-m)/var);
}
for(int i=0;i<timeSteps;i++){
Type var=exp(logR);
ans+=0.5*(log(2.0*M_PI*var)+square(X[i]-Y[i])/var);
}
return ans;
}
####################### THEN IN R #######################
Y<-scan('thetalog.dat', skip=3, quiet=TRUE)
library(TMB)
compile("thetalog.cpp")
dyn.load("thetalog.so")
data <- list(Y=Y)
parameters <- list(
X=data$Y*0,
logr0=0,
logtheta=0,
logK=6,
logQ=0,
logR=0
)
newtonOption(smartsearch=FALSE)
obj <- MakeADFun(data,parameters,random="X",DLL="thetalog")
obj$hessian <- TRUE
#obj$control$reltol<-1e-12
obj$fn()
obj$gr()
system.time(opt <- nlminb(obj$par,obj$fn,obj$gr))
rep <- sdreport(obj)
rep
Timings
Example TMB (est) TMB (sd) ADMB (est) ADMB (sd)
mvrw 0.22 0.09 15.70 12.98
nmix 2.99 0.73 16.49 15.07
orange big 2.76 1.26 179.10 93.47
sdv multi 10.63 2.38 345.99 99.07
spatial 9.08 1.51 8.68 3.26
thetalog 0.27 0.07 4.17 3.61
SAM 2.22 3.37 187.52 52.43
Tabel 1: Timings for each example in seconds, either for estimation alone (est) or the
sdreport phase alone including hessian calculation (sd).