N[1] not allowed in x[1:N[1]] <- r[]

25 views
Skip to first unread message

Keith Lau

unread,
Nov 11, 2023, 8:42:23 AM11/11/23
to nimble-users
Hello,

I ran into a problem in my model that appeared related to expression like x[1:N[1]] <- r[]. So I created a toy example that mimics the problem. See the full code appended. The error is
Error in addMissingIndexingRecurse(code[[i]], dimensionsList) : inconsistent dimensionality provided for node 'N'

I would like to use the expression x[1:N[1]] because my data could have one or more datasets and 'N' length will vary from a scalar to a vector, such as N = 100, N = c(100, 200), and so on. I believe NIMBLE should be able to accommodate the code like "x[1:N[t]] <- r[] " for t = 1, 2, ...

Will NIMBLE accept this expression in the future or do we have a workaround to solve this problem?

Many thanks!




library("nimble")


code <- nimbleCode({
 
  for (n in 1:N[1]){
    r[n] ~ dnorm(mu,sd=sd)
  }
  nu ~ dnorm(0,0.01)
  sd ~ dunif(0.01,5)
 
  x[1:N[1]] <- r[]
 
})

constants <- list(N=100)

data <- list(r=rnorm(n=100))

inits <- list(mu=0,sd=2)

monitors = c("mu","sd")


MODEL <- nimbleModel(code = code, name = "MODEL", constants = constants,data = data, inits = inits)

cmodel <- compileNimble(MODEL)

conf <- configureMCMC(MODEL, monitors = monitors
                      ,useConjugacy=TRUE ,print = FALSE
                      ,enableWAIC=TRUE
                      ,onlySlice=FALSE
)

modelMCMC <- buildMCMC(conf)
cmodelMCMC <- compileNimble(modelMCMC, project = MODEL ,resetFunctions = TRUE)

burnin = 1000
keep = 1000
nchains = 1
rand.seed = 1

niter = burnin + keep

out <- system.time(samples <- runMCMC(cmodelMCMC, niter = niter, nburnin = burnin, nchains=nchains
                                              ,samplesAsCodaMCMC=TRUE
                                              ,samples= TRUE
                                              ,summary=TRUE
                                              ,WAIC = TRUE
                                              ,setSeed = rand.seed))

print(samples$summary)



Keith Lau

unread,
Nov 11, 2023, 12:57:50 PM11/11/23
to nimble-users
I just found a workaround is to set "constants <- list(N=matrix(100))" and in the model set "x[1:N[1,1]] <- r[]".  The 1x1 matrix "N" can be recognized.


Keith Lau 在 2023年11月11日 星期六晚上9:42:23 [UTC+8] 的信中寫道:

Perry de Valpine

unread,
Nov 13, 2023, 11:54:34 AM11/13/23
to Keith Lau, nimble-users
Hi Keith,
Thanks for the question and following up with a workaround.
It does cause some hassles that nimble is strict about dimensionality and in particular distinguishes between scalars and length 1 vectors (or matrices or arrays), whereas in R a scalar is simply a. length 1 vector. So if N is a scalar, you shouldn't be using N[1].
You can look in the manual for if-then-else evaluated at the time of model definition and see if that is helpful for your use case. This is in section 6.1.1.4 of the User Manual. i.e. you could have one version of code if N is a scalar.
HTH
Perry


--
You received this message because you are subscribed to the Google Groups "nimble-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nimble-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/nimble-users/cb66cdd1-5103-495d-90f1-3c05f3c37f70n%40googlegroups.com.

Quresh Latif

unread,
May 30, 2024, 12:14:12 PMMay 30
to nimble-users
I ran into an issue with simulations in which one of my constants could occasionally be a scalar when there was only one simulated count > 0. Thought I'd post my solution here using a conditional statement.

I previously had the following in my model:

...
    for(det in 1:ndet) {
      y_a[det, 1:R] ~ dmulti(pic_a[year.ind[det.ind[det]], bcr.ind[det.ind[det]], 1:R], n[det.ind[det]])
      y_p[det, 1:dmax] ~ dmulti(pic_p[year.ind[det.ind[det]], 1:dmax], n[det.ind[det]])
      }
...

wherein `det.ind` is usually a vector of length `ndet` but could be a scalar if there is only one element in it (i.e., if `ndet` = 1). The following allows for ndet = 1:

...
    for(det in 1:ndet) {
      if(ndet == 1) {
        y_a[det, 1:R] ~ dmulti(pic_a[year.ind[det.ind], bcr.ind[det.ind], 1:R], n[det.ind])
        y_p[det, 1:dmax] ~ dmulti(pic_p[year.ind[det.ind], 1:dmax], n[det.ind])
      }
      if(ndet > 1) {
        y_a[det, 1:R] ~ dmulti(pic_a[year.ind[det.ind[det]], bcr.ind[det.ind[det]], 1:R], n[det.ind[det]])
        y_p[det, 1:dmax] ~ dmulti(pic_p[year.ind[det.ind[det]], 1:dmax], n[det.ind[det]])
      }
      }
...
Reply all
Reply to author
Forward
0 new messages