Quresh, thanks for writing, and your continued use of nimble. Let me give a few comments, which might help get us thinking about the right path.
I looked at the
earlier code you linked. To the best of my knowledge, nimble has never provided (out-of-the-box) the deterministic model functions that you seem to be using here, for example the logdensity.beta, logdensity.gamma, and logdensity.negbin functions. Are you able to confirm what version of nimble you were using for that analysis? Or, did you manually define these functions? (which I don't think is the case, since you also said you have not written any nimble functions before). In any case, this surprised me, since I don't believe these functions were ever provided, and therefore were never deprecated.
If you want to get that approach running again, I've included a short example below, which shows implementations of logdens.beta and logdens.gamma functions, uses these in a model, and also verifies that the log-densities are correct. I also added another approach in the code below, which directly monitors internal variables of the model (logProb_x and logProby). This approach might seem the most straightforward, but it might also become less clear when either 'x' or 'y' are non-scalars (for example, they represent arrays or matrices). Let me know if you have questions about understanding or adapting this code. This is one approach you could take, which most closely mimics the original code you referenced.
If you don't want to do this node-by-node in the model (which may be a lot of coding), it would actually be easier to do this for the entire model at once (to record the (sum) model log-density (the sum of the log-density of all stochastic nodes in the model). This approach could also be adapted to only sum the log-densities of whatever subset of the (stochastic) model nodes you'd like to. Adapting this code, to only record the (sum) log-density of the predictive data nodes in your posterior predictive checks might be the easiest way to go. Here is an example of doing that:
Let me know when you've had time to look at these, and if you give it a try. In any case, I'm sure we can find a path to get this working for you. And the example code for calculating (and saving) model log-densities on a node-by-node basis if directly below.
Cheers,
Daniel
library(nimble)
code <- nimbleCode({
a ~ dunif(0, 10)
b ~ dunif(0, 10)
x ~ dbeta(a, b)
xdens <- logdens.beta(x, a, b)
y ~ dgamma(a, b)
ydens <- logdens.gamma(y, a, b)
})
constants <- list()
data <- list(x = 0.3, y = 0.5)
inits <- list(a = 1, b = 1)
logdens.beta <- nimbleFunction(
run = function(x = double(), a = double(), b = double()) {
lp <- dbeta(x, a, b, log = TRUE)
returnType(double())
return(lp)
}
)
logdens.gamma <- nimbleFunction(
run = function(x = double(), a = double(), b = double()) {
lp <- dgamma(x, a, b, log = TRUE)
returnType(double())
return(lp)
}
)
Rmodel <- nimbleModel(code, constants, data, inits)
conf <- configureMCMC(Rmodel)
conf$addMonitors(c('xdens', 'ydens'))
conf$addMonitors(c('logProb_x', 'logProb_y'))
Rmcmc <- buildMCMC(conf)
Cmodel <- compileNimble(Rmodel)
Cmcmc <- compileNimble(Rmcmc, project = Rmodel)
set.seed(0)
samples <- runMCMC(Cmcmc, 100)
dbeta (data$x, samples[,'a'], samples[,'b'], log = TRUE) - samples[, 'xdens']
samples[, 'logProb_x'] - samples[, 'xdens']
dgamma(data$y, samples[,'a'], samples[,'b'], log = TRUE) - samples[, 'ydens']
samples[, 'logProb_y'] - samples[, 'ydens']