-
Notifications
You must be signed in to change notification settings - Fork 24
Tips for avoiding errors in nimbleFunction programming and compilation (DSL)
Christopher Paciorek edited this page Mar 9, 2019
·
12 revisions
Chapters 11-15 of the NIMBLE manual describe how to program in NIMBLE: how to write nimbleFunctions using the NIMBLE language (NIMBLE DSL).
Writing nimbleFunction run code is similar to programming in R, but because nimbleFunctions are compiled to C++, there are some limitations on what can be done in run code.
Here we document some of the syntax that does NOT work in nimbleFunction run code and work-arounds in each case.
Syntax that doesn't work | Alternative syntax to accomplish this |
---|---|
Use of distribution parameterizations other than those in Section 11.2.4 of the manual | Manually reparameterize to one of the parameterizations in Section 11.2.4 |
Reverse indexing such as 2:1
|
Manually write a loop such as for(i in 1:L) { index[i] <- L+1-i }
|
is.na() and is.nan() are not vectorized |
Write a for loop |
is.na() does not work with logical or integer type NA values passed from R |
Use as.numeric in R to convert to numeric type |
model[[nodes]] and model[[nodes[i]]] do not work when nodes indicates more than one nodes or variables |
Use values(model, nodes) or values(model, nodes[i])
|
node <- nodes[i]; model[[node]] does not work |
Use values(model, nodes) or values(model, nodes[i])
|
node <- nodes[i]; values(model, node) does not work |
Avoid working with temporary variables involving node names; instead establish the node variables in setup code |
model$values(nodes) does not work |
Use values(model, nodes)
|
values(model, nodes)[i] <<- foo does not work |
Use a temporary variable, e.g., tmp <- values(model, nodes); tmp[i] <- foo; values(model, nodes) <<- tmp
|
values(model,node) <<- some_scalar_value does not work because values() expects a vector |
Use values(model, node) <- c(some_scalar_value)
|
Changing the type of a variable within a run function, e.g., a <- 3; a <- numeric(5)
|
Use distinct variable names |
Indexing (e.g., x[1] ) into a length-one vector defined using numeric(1) , integer(1) , or logical(1)
|
Define a length-two vector and only use the first element: x <- numeric(2); x[1]
|
Some additional details to be aware of:
-
values(model, node)
andvalues(model, nodes[i])
returns a vector, not a scalar, even whennode
is a scalar node - matrix operations such as
A %*% b
returns a one-column matrix whenb
is a vector -
nimNumeric(1)
ends up be treated as a scalar in the generated C++ so if you need it as a vector, usenimNumeric(2)
. You can just not use the 2nd element.