library("nimble")
library("lazyeval")
Can we declare the nimbleCode
parts in sections? Such as defining the model and priors in separate, reusable code blocks? Here’s a “model” block:
model <- nimbleCode({
for (i in 1:N){
theta[i] ~ dgamma(alpha,beta)
lambda[i] <- theta[i]*t[i]
x[i] ~ dpois(lambda[i])
}
})
We may also wish to define the priors separately, and with specified list of hyperparameters for the priors. Perhaps the need to use quote
and to specify each line as a list item, instead of as a block defined with {
, is not ideal, but non-standard evaluation is a bit of a wild west still.
hyperparameters <- list(lambda = 1.0, a = 0.1, b = 1.0)
priors <- nimbleCode({
alpha ~ dexp(lambda)
beta ~ dgamma(a,b)
})
Having done so, we can construct a nimbleCode
block by passing our chosen hyperparameters to the priors and concatenating the model and priors.
P <- as.expression(sapply(priors, lazyeval::interp, .values = hyperparameters)[-1])
pumpCode <- c(model, P)
The result appears to work as a functional nimbleCode
block; though note the resulting expression is not quite identical to the one we would typically write (e.g. without commas):
pumpCode
expression({
for (i in 1:N) {
theta[i] ~ dgamma(alpha, beta)
lambda[i] <- theta[i] * t[i]
x[i] ~ dpois(lambda[i])
}
}, alpha ~ dexp(1), beta ~ dgamma(0.1, 1))
Here we just specify the rest of the model:
pumpConsts <- list(N = 10,
t = c(94.3, 15.7, 62.9, 126, 5.24,
31.4, 1.05, 1.05, 2.1, 10.5))
pumpData <- list(x = c(5, 1, 5, 14, 3, 19, 1, 1, 4, 22))
pumpInits <- list(alpha = 1,
beta = 1,
theta = rep(0.1, pumpConsts$N))
pump <- nimbleModel(code = pumpCode,
name = 'pump',
constants = pumpConsts,
data = pumpData,
inits = pumpInits)
and then verify that it runs.
Cmodel <- compileNimble(pump)
mcmcspec <- configureMCMC(pump, print=FALSE)
mcmc <- buildMCMC(mcmcspec)
Cmcmc <- compileNimble(mcmc, project = Cmodel)
Cmcmc$run(1000)
NULL
samples <- as.data.frame(as.matrix(Cmcmc$mvSamples))
plot(samples[ , 'alpha'], samples[ , 'beta'], xlab = expression(alpha), ylab = expression(beta))
(The plot shows the same correlation issue that arises without using a block sampler that is illustrated in the manual.)