Hi Christopher,
Thanks for your advice. I also exchanged off-list with Daniel and Perry and I have now written my own sampler. I provide it below in case it might be of some use to somebody else. It worked perfectly for me.
# change default categorical samplers for survival state s
# to own samplers of a 2-occasion sliding window of s states
# moving-window categorical sampler
# (see Manual p188 for guidance on writing samplers)
# (this is adapted from the standard categorical sampler code)
MW_cat <- nimbleFunction(
contains = sampler_BASE,
setup = function(model, mvSaved, target, control) {
calcNodes <- model$getDependencies(target)
calcNodesNoSelf <- model$getDependencies(target, self = FALSE)
isStochCalcNodesNoSelf <- model$isStoch(calcNodesNoSelf)
calcNodesNoSelfDeterm <- calcNodesNoSelf[!isStochCalcNodesNoSelf]
calcNodesNoSelfStoch <- calcNodesNoSelf[isStochCalcNodesNoSelf]
# 4 below is specific to current problem; in general this should be ns^window_length
k <- 4
probs <- numeric(k)
logProbs <- numeric(k)
# 'double' required for compilation
validstatepairs <- nimMatrix(c(1,1,2,3,1,2,3,3),nrow = 4,ncol = 2,type = 'double')
},
run = function() {
currentValue <- model[[target]]
if(currentValue[1] == 3 & currentValue[2] ==3) currentCase <- 4 else currentCase <- currentValue[2]
logProbs[currentCase] <<- model$getLogProb(calcNodes)
for (i in 1:k) {
if (i != currentCase) {
model[[target]] <<- validstatepairs[i,1:2]
logProbs[i] <<- model$calculate(calcNodes)
if (is.nan(logProbs[i]))
logProbs[i] <<- -Inf
}
}
logProbs <<- logProbs - max(logProbs)
probs <<- exp(logProbs)
newCase <- rcat(1, probs)
if (newCase != currentCase) {
model[[target]] <<- validstatepairs[newCase,1:2]
model$calculate(calcNodes)
nimCopy(from = model, to = mvSaved, row = 1, nodes = target,
logProb = TRUE)
nimCopy(from = model, to = mvSaved, row = 1, nodes = calcNodesNoSelfDeterm,
logProb = FALSE)
nimCopy(from = model, to = mvSaved, row = 1, nodes = calcNodesNoSelfStoch,
logProbOnly = TRUE)
}
else {
nimCopy(from = mvSaved, to = model, row = 1, nodes = target,
logProb = TRUE)
nimCopy(from = mvSaved, to = model, row = 1, nodes = calcNodesNoSelfDeterm,
logProb = FALSE)
nimCopy(from = mvSaved, to = model, row = 1, nodes = calcNodesNoSelfStoch,
logProbOnly = TRUE)
}
},
methods = list( reset = function () {} )
)
Note that this sampler is specialized to my particular problem as it examines only the relevant combinations of successive states (validstatepairs in code)
Roger