Hello,
I am attempting to code a stratified mixture model, where the number of components of the mixture may differ by stratum. Specifically, there may be S strata, for each s = 1, ..., S, there are K[s] mixture components. I cannot seem to get Nimble to allow me to do this no matter if I place the vector K as data or constants.
When I declare K as data, I get the error message:
Defining model
Error in getSymbolicParentNodesRecurse(x, constNames, indexNames, nimbleFunctionNames, :
Dynamic indexing found in a vector of indices, 1:K[l]. Only scalar indices, such as 'idx' in 'x[idx]', can be dynamic. One can instead use dynamic indexing in a vector of indices inside a nimbleFunction.
If I declare K as a constant, I get
Defining model
Error in getSymbolicParentNodesRecurse(x, constNames, indexNames, nimbleFunctionNames, :
getSymbolicParentNodesRecurse: dynamic indexing of constants is not allowed in K[l]. Try adding the dynamically-indexed constant as data instead (using the data argument of nimbleModel).
Below is a reproducible example.
code <- nimbleCode({
for ( l in 1:S ) {
gamma[s, 1:K[l]] ~ ddirch(conc[s, 1:K[l]])
for ( k in 1:K[l] ) {
mu[l,k] ~ dnorm(0, sd = 10)
}
}
for ( i in 1:n ) {
c[i] ~ dcat(gamma[s, 1:K[l]])
y[i] ~ dnorm(mu[s[i], c[i]], 1)
}
})
## putting K in data
nimconst <- list(
n = 100, S = 2
)
nimdata <- list(
y = rnorm(nimconst$n)
, s = c(rep(1, floor(nimconst$n/2) ), rep(2, ceiling(nimconst$n/2) ) )
, K = c(2, 3)
)
mu.init <- matrix(0, nrow = nimconst$S, ncol = max(nimdata$K) )
gamma.init <- matrix(0, nrow = nimconst$S, ncol = max(nimdata$K) )
for ( s in 1:nimconst$S ) {
gamma.init[s, 1:nimdata$K[s]] <- 1/nimdata$K[s]
}
niminit <- list(gamma = gamma.init, mu = mu.init, c = rcat(nimconst$n, c(0.5, 0.5)))
model <- nimbleModel(code, nimconst, nimdata, niminit)
## putting K in constants
nimconst$K = nimdata$K
nimdata <- nimdata[-which(names(nimdata) == 'K')]
model <- nimbleModel(code, nimconst, nimdata, niminit)