alternative to conditional 'for' loop

38 views
Skip to first unread message

guillaum...@gmail.com

unread,
Jun 2, 2023, 12:55:59 PM6/2/23
to nimble-users
Dear all, 

Coming from Jags/Openbugs, there is a trick that one could use to have and if-like statement to specify likelihood, this being convenient when we know that there is no likelihood in a particular situation.
This can be achieved by  having the following structure:

for (i in 1:Range1){
    for ( j in 1:Range2){
        for(k in 1:Index_if[i,j]) { 
        Y[i,j] ~ gamma(a[i],b[i])
        }
    }
}

when  Index_if[i,j] == 1, the likelihood is specified and when Index_if[i,j] == 0, it isn't.

Is there an alternative in Nimble or do I have to generate vectors/dataframes that only cover cases where the likelihood needs to be specified ?

Thanks 

G


Daniel Turek

unread,
Jun 2, 2023, 4:10:40 PM6/2/23
to guillaum...@gmail.com, nimble-users
I think this will work fine in nimble as well, although you'll get a warning message (which you can safely ignore, so long as all elements of Index_if[] are either 0 or 1).

Nimble actually has facilities for if() statements inside model code, but it appears those do not work with for-loop indexing of the if() statement conditions.

Here's the example I just tried, the same as what you had.  Notice that Index_if is provided in the constants list to nimbleModel().

library(nimble)

code <- nimbleCode({
    for(i in 1:N) {
        for(j in 1:M) {

            for(k in 1:Index_if[i,j]) {
                y[i,j] <- 0
            }
        }
    }
})

Index_if <- matrix(c(1,1,0,0,0, 0,0,0,0,1), nrow=5)
constants <- list(N=5, M=2, Index_if=Index_if)
Rmodel <- nimbleModel(code, constants)

Rmodel$getNodeNames()

## "y[1, 1]" "y[2, 1]" "y[5, 2]"




--
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/650762df-4263-4ed7-923d-cd9681bf414bn%40googlegroups.com.

guillaum...@gmail.com

unread,
Jun 5, 2023, 8:13:06 AM6/5/23
to nimble-users

Hi Daniel,

Awesome, my issue was that i wasn't using the correct syntax to provide the matrix of index!

Now to  code 3 dimensional arrays !

Cheers

G

guillaum...@gmail.com

unread,
Jun 5, 2023, 9:45:52 AM6/5/23
to nimble-users
follow-up:

when assigning a stochastic node

library(nimble)

code <- nimbleCode({
    for(i in 1:N) {
        for(j in 1:M) {
            for(k in 1:Index_if[i,j]) {
                y[i,j] ~ dbeta(1,1)
            }
        }
    }
})


Index_if <- matrix(c(1,1,0,0,0, 0,0,0,0,1), nrow=5)
constants <- list(N=5, M=2, Index_if=Index_if)
Rmodel <- nimbleModel(code, constants)


the following warning message is generated:

Warning message: In genExpandedNodeAndParentNames3(debug = debug) : Multiple definitions for the same node. Did you forget indexing with 'k' on the left-hand side of 'y[i, j] ~ dbeta(shape1 = 1, shape2 = 1, lower_ = 0, upper_ = 1, .mean = 0.5, .sd = 0.28867513459481287)'?

model compiles and running MCMC seems to work too
just reporting this here in case other people run into this message.

Daniel Turek

unread,
Jun 5, 2023, 10:09:10 AM6/5/23
to guillaum...@gmail.com, nimble-users
Yes, this warning is to be expected.  It arises because you have a node declaration (y[i,j] ~ ...) which appears *inside a loop indexed by k*, but the declaration itself (y[i,j] ~ ...) is *not* indexed by k, which is most situations would lead to multiple declarations of y[i,j].

This message is not preventable even using nimbleOptions(verbose = FALSE), but I suspect you could suppress this using R's native suppressWarnings() function. 

In any case, thanks for following up.

Cheers,
Daniel


Reply all
Reply to author
Forward
0 new messages