hi Daniel,
Since yesterday, I have made progress in my understanding of the problem I have. At the root, my problem is that for a certain code in the capture history, the event step must be absent. I opted for metaprogramming the code, replacing the for loop over occasions and individuals by a long list of statements where I could skip the ones corresponding to the specific code. That apparently was a very bad idea. Yesterday, I made trials with the pump example in the manual.
I compared the performance of the original code :
pumpCode <- nimbleCode({
for (i in 1:N) {
theta[i] ~ dgamma(alpha,beta)
lambda[i] <- theta[i]*t[i]
x[i] ~ dpois(lambda[i])
}
alpha ~ dexp(1.0)
beta ~ dgamma(0.1,1.0)
})
with the equivalent code without the for loop :
pumpCodebis <- nimbleCode({
theta[1] ~ dgamma(alpha,beta)
lambda[1] <- theta[1]*t[1]
x[1] ~ dpois(lambda[1])
theta[2] ~ dgamma(alpha,beta)
lambda[2] <- theta[2]*t[2]
x[2] ~ dpois(lambda[2])
theta[3] ~ dgamma(alpha,beta)
lambda[3] <- theta[3]*t[3]
x[3] ~ dpois(lambda[3])
theta[4] ~ dgamma(alpha,beta)
lambda[4] <- theta[4]*t[4]
x[4] ~ dpois(lambda[4])
theta[5] ~ dgamma(alpha,beta)
lambda[5] <- theta[5]*t[5]
x[5] ~ dpois(lambda[5])
theta[6] ~ dgamma(alpha,beta)
lambda[6] <- theta[6]*t[6]
x[6] ~ dpois(lambda[6])
theta[7] ~ dgamma(alpha,beta)
lambda[7] <- theta[7]*t[7]
x[7] ~ dpois(lambda[7])
theta[8] ~ dgamma(alpha,beta)
lambda[8] <- theta[8]*t[8]
x[8] ~ dpois(lambda[8])
theta[9] ~ dgamma(alpha,beta)
lambda[9] <- theta[9]*t[9]
x[9] ~ dpois(lambda[9])
theta[10] ~ dgamma(alpha,beta)
lambda[10] <- theta[10]*t[10]
x[10] ~ dpois(lambda[10])
alpha ~ dexp(1.0)
beta ~ dgamma(0.1,1.0)
})
With the same constants, data, and inits (those in the manual), I then compared the time it took to build the model.
start.time <- Sys.time()
for (i in 1:20) {
pump <- nimbleModel(code = pumpCode, name = "pump", constants = pumpConsts,
data = pumpData, inits = pumpInits)
}
end.time <- Sys.time()
difftime(end.time,start.time, units = "mins")
vs.
start.time <- Sys.time()
for (i in 1:20) {
pump <- nimbleModel(code = pumpCodebis, name = "pump", constants = pumpConsts,
data = pumpData, inits = pumpInits)
}
end.time <- Sys.time()
difftime(end.time,start.time, units = "mins")
The code with the for loop builds faster : 0.44 mins vs 2.68 mins. Does this make sense to you?
I also noticed that there was apparently a slowing down over the 20 iterations and repeated the test 2 more times with the original pumpCode code to check this impression.
After the 0.44 mins of the first test, the second test was down to 0.75 mins, and the third to 0.81 mins. Could that be due to some cluttering of memory or disk space?
Would you recommend keeping a for loop in the code?
In this case, I imagine that I could use a nested index. Say, I want to skip 3 in the for loop in pumpCode. I would construct a vector of indices without 3, pass it as data or constant, and loop from 1 to N-1 like this:
pumpCode <- nimbleCode({
for (i in 1:length(index)) {
theta[
index[i]] ~ dgamma(alpha,beta)
lambda[
index[i]
] <- theta[
index[i]
]*t[
index[i]
]
x[
index[i]
] ~ dpois(lambda[
index[i]
])
}
alpha ~ dexp(1.0)
beta ~ dgamma(0.1,1.0)
})
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),
index = c(1, 2, 4, 5, 6, 7, 8, 9, 10))
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))
Do you believe this is a good approach? Can you suggest another one?
Cheers
Roger