This repository has been archived by the owner on Jul 29, 2020. It is now read-only.
forked from James-Thorson/2018_FSH556
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added example of overload fn to track REPORT
- Loading branch information
1 parent
3215142
commit f12eff5
Showing
2 changed files
with
122 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
|
||
setwd( "C:/Users/James.Thorson/Desktop/Project_git/2018_FSH556/TMB examples/Track report objects/" ) | ||
|
||
library(TMB) | ||
library(RandomFields) | ||
library(Matrix) | ||
|
||
################### | ||
# Equal distance 2D autoregressive | ||
################### | ||
|
||
Dim = c("n_x"=10, "n_y"=10) | ||
loc_xy = expand.grid("x"=1:Dim['n_x'], "y"=1:Dim['n_y']) | ||
Scale = 5 | ||
Sigma2 = (0.5) ^ 2 | ||
beta0 = 3 | ||
prob_missing = 0.2 | ||
|
||
# Simulate spatial process | ||
RMmodel = RMexp(var=Sigma2, scale=Scale) | ||
epsilon_xy = array(RFsimulate(model=RMmodel, x=loc_xy[,'x'], y=loc_xy[,'y'])@data[,1], dim=Dim) | ||
image( z=epsilon_xy ) | ||
|
||
# SImulate counts | ||
c_xy = array(NA, dim=dim(epsilon_xy)) | ||
for(x in 1:nrow(c_xy)){ | ||
for(y in 1:ncol(c_xy)){ | ||
c_xy[x,y] = rpois(1, exp(beta0 + epsilon_xy[x,y]) ) | ||
if( rbinom(n=1, size=1, prob=prob_missing)==1) c_xy[x,y] = NA | ||
}} | ||
true_abundance = sum( exp(beta0 + epsilon_xy) ) | ||
|
||
# Generate sparse matrices for precision matrix of 2D AR1 process | ||
M0 = as( ifelse(as.matrix(dist(loc_xy,diag=TRUE,upper=TRUE))==0,1,0), "dgTMatrix" ) | ||
M1 = as( ifelse(as.matrix(dist(loc_xy,diag=TRUE,upper=TRUE))==1,1,0), "dgTMatrix" ) | ||
M2 = as( ifelse(as.matrix(dist(loc_xy,diag=TRUE,upper=TRUE))==sqrt(2),1,0), "dgTMatrix" ) | ||
|
||
# Compile | ||
Params = list( "beta0"=0, "ln_sigma2"=0, "logit_rho"=0, "epsilon_xy"=array(rnorm(prod(dim(loc_xy)))-100,dim=dim(epsilon_xy)) ) | ||
compile( "autoregressive_grid.cpp" ) | ||
dyn.load( dynlib("autoregressive_grid") ) | ||
|
||
# Build object | ||
Data = list("c_xy"=c_xy, "M0"=M0, "M1"=M1, "M2"=M2 ) | ||
Obj = MakeADFun( data=Data, parameters=Params, random="epsilon_xy", DLL="autoregressive_grid" ) | ||
|
||
# Overload marginal log-likelihood function | ||
Obj$fn_orig = Obj$fn | ||
Obj$fn = function( par ){ | ||
MargNLL = Obj$fn_orig( par ) | ||
Report = Obj$report() | ||
Total_Abundance = rbind(Total_Abundance, c(nrow(Total_Abundance)+1, Report$Total_Abundance) ) | ||
colnames(Total_Abundance) = c("Function_call","Total_Abundance") | ||
assign( "Total_Abundance", Total_Abundance, pos=.GlobalEnv ) | ||
return( MargNLL ) | ||
} | ||
|
||
# Optimize | ||
Total_Abundance = data.frame() | ||
Opt = TMBhelper::Optimize( obj=Obj, fn=Obj$fn_trace, newtonsteps=1 ) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
|
||
#include <TMB.hpp> | ||
// Function for detecting NAs | ||
template<class Type> | ||
bool isNA(Type x){ | ||
return R_IsNA(asDouble(x)); | ||
} | ||
|
||
// Space time | ||
template<class Type> | ||
Type objective_function<Type>::operator() () | ||
{ | ||
// Data | ||
DATA_MATRIX( c_xy ); | ||
|
||
// Sparse matrices for forming the AR precision matrix (Version #4 below) | ||
// Q = M0*(1+rho^2)^2 + M1*(1+rho^2)*(-rho) + M2*rho^2 | ||
DATA_SPARSE_MATRIX(M0); | ||
DATA_SPARSE_MATRIX(M1); | ||
DATA_SPARSE_MATRIX(M2); | ||
|
||
// Parameters | ||
PARAMETER( beta0 ); | ||
PARAMETER( ln_sigma2 ); | ||
PARAMETER( logit_rho ); | ||
|
||
// Random effects | ||
PARAMETER_ARRAY( epsilon_xy ); | ||
|
||
// Objective funcction | ||
int n_x = c_xy.col(0).size(); | ||
int n_y = c_xy.row(0).size(); | ||
vector<Type> jnll_comp(2); | ||
jnll_comp.setZero(); | ||
Type sigma2 = exp(ln_sigma2); | ||
Type rho = 1 / (1 + exp(-logit_rho)); | ||
|
||
//// Calculate using built-in TMB functions | ||
using namespace density; | ||
Eigen::SparseMatrix<Type> Q_zz = ( M0*pow(1+pow(rho,2),2) + M1*(1+pow(rho,2))*(-rho) + M2*pow(rho,2) ) / sigma2; | ||
jnll_comp(1) += GMRF(Q_zz)( epsilon_xy ); | ||
|
||
// Probability of data conditional on random effects | ||
Type Total_Abundance = 0; | ||
for( int x=0; x<n_x; x++){ | ||
for( int y=0; y<n_y; y++){ | ||
if( !isNA(c_xy(x,y)) ) jnll_comp(0) -= dpois( c_xy(x,y), exp(beta0 + epsilon_xy(x,y)), true ); | ||
Total_Abundance += exp(beta0 + epsilon_xy(x,y)); | ||
}} | ||
|
||
// Reporting | ||
Type jnll = jnll_comp.sum(); | ||
REPORT( jnll_comp ); | ||
REPORT( jnll ); | ||
REPORT( sigma2 ); | ||
REPORT( rho ); | ||
REPORT( Total_Abundance ); | ||
ADREPORT( Total_Abundance ); | ||
|
||
return jnll; | ||
} |