In the past, I was able to speed up computation by vectorizing operations such as the density calculation for iid Bernoulli random variables:
dBernoulliVector <- nimbleFunction(
run = function(x = double(1),
prob = double(1),
log = integer(0, default = 0)) { ## default should be zero
returnType(double(0))
logProb <- sum(dbinom(x, size = 1, prob = prob, log = TRUE))
if(log) return(logProb) else return(exp(logProb))
}
)
dtpois <- nimbleFunction(
run = function(x = integer(), lambda = double(),
log = logical(0, default = 0)) {
returnType(double())
## First handle non-zero data
if(x==0){
if(log){
return(-Inf)
}else{
return(0)
}
}else{
if (log){
return(dpois(x, lambda, log = TRUE) - log(1-exp(-lambda)))
}else{
return(dpois(x, lambda, log = FALSE)/(1-exp(-lambda)))
}
}
})
rtpois <- nimbleFunction(
run = function(n = integer(), lambda = double()) {
returnType(integer())
return(rpois(1, lambda)+1) # This was a lazy fix. I just added this component for completeness. I do not intend to sample from this distribution.
})
registerDistributions(list(
dtpois = list(
BUGSdist = "dtpois(lambda)",
discrete = TRUE,
range = c(0, Inf),
types = c('value = integer()', 'lambda = double()')
)))
dTruncPoissonVector <- nimbleFunction(
run = function(x = double(1),
lambda = double(1),
log = integer(0, default = 0)) { ## default should be zero
returnType(double(0))
logProb <- sum(dtpois(x, lambda = lambda, log = TRUE))
if(log) return(logProb) else return(exp(logProb))
}
)