Git Product home page Git Product logo

nimble's Introduction

NIMBLE

Build Status AppVeyor Build Status CRAN DOI Google Group

Website | Documentation | Examples | Developing | Workshop materials

NIMBLE is an R package for hierarchical statistical modeling (aka graphical modeling). It enables writing general models along with methods such as Markov chain Monte Carlo (MCMC), particle filtering (aka sequential Monte Carlo), and other general methods.

For writing statistical models, NIMBLE adopts and extends the BUGS language, making it largely compatible with BUGS and JAGS. NIMBLE makes BUGS extensible, allowing users to add new functions and new distributions.

For writing algorithms (aka analysis methods), NIMBLE provides a model-generic programming system embedded within R. This provides control over models as generic objects and mathematical manipulation of model variables. In this way, NIMBLE's programming paradigm treats probabilistic graphical models as a basic programming construct.

Both models and algorithms are compiled via generating customized C++ and providing seamless interfaces to compiled C++ from R.

NIMBLE's most developed methods are for MCMC. Users can easily customize sampler configurations from R and write new samplers in NIMBLE's algorithm programming system.

Developers of new computational statistical methods can build them in NIMBLE to gain the benefits of its graphical modeling language, compilation, and distribution via CRAN.

Installation

Install prerequisites

NIMBLE needs a C++ compiler and the GNU make utility. Typically, Mac users can obtain these by installing Xcode, including command line utilities, while Windows users can obtain them by installing Rtools. See the User Manual for more details.

Install NIMBLE

The easiest way to install NIMBLE is via CRAN:

install.packages("nimble")

To install from the NIMBLE website:

library(devtools)
install.packages("nimble", type = "source", repos = "https://r-nimble.org")

Note that NIMBLE's sequential Monte Carlo (SMC; aka particle filtering) methods are now (as of version 0.10.0) in the nimbleSMC package.

Note that MCMCsuite and compareMCMCs have been migrated to the compareMCMCs package, now available on CRAN.

Citation

In published work that uses or mentions NIMBLE, please cite:

de Valpine, P., D. Turek, C.J. Paciorek, C. Anderson-Bergman, D. Temple Lang, and R. Bodik. 2017. Programming with models: writing statistical algorithms for general model structures with NIMBLE. Journal of Computational and Graphical Statistics 26:403-413. https://doi.org/10.1080/10618600.2016.1172487.

In published work that uses NIMBLE, please also cite the package version:

de Valpine, P., C. Paciorek, D. Turek, N. Michaud, C. Anderson-Bergman, F. Obermeyer, C. Wehrhahn Cortes, A. Rodriguez, D. Temple Lang, and S. Paganin. 2024. NIMBLE: MCMC, Particle Filtering, and Programmable Hierarchical Modeling. doi: 10.5281/zenodo.1211190. R package version 1.1.0, https://cran.r-project.org/package=nimble.

To help us track usage to justify funding support for NIMBLE, please include the DOI in the citation.

Licenses

Nimble is released under a mixture of licenses, and depends on additional third-party libraries with compatible licenses.

Acknowledgements

The development of NIMBLE has been funded by:

  • an NSF Advances in Biological Informatics grant (DBI-1147230) to P. de Valpine, C. Paciorek, and D. Temple Lang;
  • an NSF SI2-SSI grant (ACI-1550488) to P. de Valpine, C. Paciorek, and D. Temple Lang;
  • an NSF Collaborative Research grant (DMS-1622444) to P. de Valpine, A. Rodriguez, and C. Paciorek; and
  • an NSF Collaborative Research grant (DMS-2152860) to P. de Valpine, C. Paciorek, and D. Turek.

with additional support provided by postdoctoral funding for D. Turek from the Berkeley Institute for Data Science and Google Summer of Code fellowships for N. Michaud (2015) and C. Lewis-Beck (2017).

nimble's People

Contributors

andrew-primer-e avatar danielturek avatar dlebauer avatar dochvam avatar dtemplelangtest avatar duncantl avatar fritzo avatar jpdunc23 avatar kenkellner avatar macgyver08 avatar nlmichaud avatar paciorek avatar perrydv avatar peterasujan avatar pistacliffcho avatar rpatin avatar salleuska avatar weizhangstats avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nimble's Issues

provide more informative error message when needed constants are missing from BUGS model

Example of current non-informative error msg:

code <- nimbleCode({
alpha[1:K] ~ ddirch(theta[1:K])
})
K <- 5
m <- nimbleModel(code, inits = list(theta = rgamma(K, 3, 1)))
Error in getSymbolicParentNodesRecurse(x, constNames, indexNames, nimbleFunctionNames) :
Error, R function : has non-replaceable node values as arguments. Must be a nimble function.

tidy up MCMC spec related functions

  1. fix help info so that removeSamplers() and getSamplers() indicate that one can pass vectors of node or var names

  2. addSampler help info is missing 'target'. Also my thought is that 'target' should be the first arg, not 'type'

  3. (maybe worth discussion) I think we want getSamplers() to return an R object that contains info about the sampler that a user could then work with programmatically. Perhaps it should just be the (vector of) ref class object as is from samplerSpecs. It could return this invisibly with print=TRUE being the standard functionality or the return could be the main poitn, with print=FALSE the standard functionality.

3a) if getSamplers() returns list of sampler specs, it would be nice to have each element named based on the vertex being sampled

3b) (enhancement for down the road perhaps) we might want to allow a user to modify a spec (i.e., change a value in the control list) without having to create a totally new sampler and delete the old one just to, say, change the adaptation time

norm in R and C differ

norm() in R and C nimble functions differ as the R default seems to be the "1" norm (the 'type' argument) and the C version is the Frobenius

help on isData() is misleading

isData will accept variables rather than node names, but the help info on the nodeNames argument states:

nodeNames: A character vector of node names. This must be
entirely node names, not model variables.

Same issue for the main argument to expandNodeNames().

I would just change the wording, but wanted to run this by Daniel first.

restrictions on column names in data?

Hi nimble-devs,

Haven't quite wrapped my head around the expected format for the data argument to nimbleModel(). For instance, it seems that x is a valid name but not X; I get the error:

variable name not suitable for setData(): X

when using a data.frame with X as a column name (yes, I realize that data expects a list, though a data.frame appears to work, presumably by some automatic coercion. Why the default data format is a list and not a data.frame is another thing that isn't clear to me). I think I may be missing something, but this seems like a somewhat strange restriction. Thanks for the help.

Cheers,
Carl

p.s. greatly enjoying v0.3.0; thanks for the thorough release notes on the syntax changes.

clean up types in distributions_inputlist and in various nimble-provided distributions

current plan:

  • all core C code use doubles and has some checking of inputs
  • interface code is place for more checking
  • only provide types in inputList when dimension > 1, and always use double
  • tell user in user-defined section of manual that we assume double(0) and they should use double and not int

work on handling of NA and NaN in C code for distribution functions

conjugacy checking

  • add tests of conjugacy to testing system
  • have Daniel's run-time checking of numerical values against M-H be optional based on user-provided flag in nimbleOptions

Where is the source code?

I am excited about the release and can't resist the chance to submit issue #1

Here is my bug report:

I want to check out your code but can't find any of the files.

warn user about NAs in RHS only nodes at model building time

Would be nice to do, particularly as the current warning at run time doesn't say what RHS only variable is missing, but I don't see a good way to do this, given the variety of ways that a single variable can contain parameters, data (LHS), and RHS only. Furthermore, part of a variable might never get used in a model so it would be fine to have NAs for that part.

warning is issued from using values(...) <- X assignment

nimbleFunction() issues a warning (from reference class creation) whenever we use the assignment form of values() <-

This can be seen by creating such a NF:

nfdef <- nimbleFunction(
setup = function(model, nodes) {},
run = function(p = double(1)) {
values(model, nodes) <- p
}
)

deal with periods in nimbleFunction arguments

At this point, these propagate to C++ and cause compilation errors as they conflict with C++ OOP.

More generally might deal with cases like a user user 'log' as a function and as a variable/argument.

Also avoid conflict of user variable/arg names with variable names generated when lifting in nimble code.

verbosity and nimbleOption()

We have a bunch of methods related to MCMC that take a print argument.

We might do the following:

  1. have the default value be the result of getNimbleOptions('verbose'), and have the default nimbleOption value for verbose be FALSE. This mimics R's 'verbose' option

  2. change 'print' to 'verbose' and in general in other cases where we want this sort of thing have the arg be 'verbose'

  3. possibly have getNimbleOptions('verbose') default to getOptions('verbose')

Any thoughts? (Daniel, in particular)

work on how nimble handles NA, NaN

Here's an example of something awry:

code <- nimbleCode({
ind <- mu < 0
})
m <- nimbleModel(code)

cm$ind
[1] NA
calculate(cm,'ind')
[1] 0
cm$ind
[1] 0

The issue here is why the NA is not being propagated to 'ind', given that 'mu' is NA at the moment.

expandNodeNames overlaps with getNodeNames?

Should we combined these two functions by allowing getNodeNames to take a 'nodes' argument?

Also, I think the help info on the nodeNames arg to expandNodeNames is not quite right. It says that it takes a vector of nodeNames, but it could also take variable names, right?

work on scoping for nimbleFunctions

(Replacing original post here):

It would be nice to use/imitate R's scoping for nimbleFunctions and models. E.g. it would be nice to write

foo <- function() {

nf1 <- nimbleFunction(...)

nf2 <- nimbleFunction(...)  use nf1 in here

mc <- nimbleCode(...) use nf1 or nf2 in here

m <- nimbleModel(mc)

compiledStuff <- compileNimble(...) compile nf1, nf2, mc, etc. here

compiledStuff

}

This would require several things to work:

  • When we process a model definition (i.e. nimbleModel), we look in the right environments for user-defined nimbleFunctions (or other objects, potentially), i.e. we find them from the environment from which nimbleModel was called.
  • When we compile, we again look in the right environment(s) to find objects.
  • During uncompiled (R) execution, one nimbleFunction calling another finds it via R's scoping rules.

We could accomplish the first two (I got through the first before reaching the conclusion of this note), but R's reference classes make the third apparently impossible. We build models, the nodeFunctions within models, and other nimbleFunctions by generating and evaluating code for new reference class definitions. The member functions in these classes do not use R's scoping, so we're stuck. In other words, we could arrange to build m, but then calculate(m) would attempt to use its nodeFunctions, which are reference class objects, which might contain a call to nf1 but wouldn't find it as one would expect from lexical scoping. Again, this is a limitation of R's reference class system.

As a result, users must define their models and nimbleFunctions in the global environment.

fix nodefunction compilation so that argument matching by name works

Currently, my understanding is that arg matching by name works for standard nimbleFunctions but something is up with how we process nodefunctions such that in a nodefunction, the arg names are ignored.

Perry, I know we chatted briefly about this, but I'm forgetting what was said. If you can point me in the right direction, I'm happy to take this on.

update manual on use of distribution functions in nimbleFunctions

Once keyword processing is dealt with, we should update the manual to reflect the additional flexibility we allow.

Also note at that location in the manual that user defined dist functions can be used. (Note need to deal with keyword processing for user-defined too via matchFunctions analog in nimbleUserNamespace)

attempt to warn/error out when using indexing outside of a loop

The following code provides a non-informative warning message, does not error out, and produces a non-functional model, with a node function for "mu[]"

Note the syntax error that the user forgot to have {} wrap the two lines intended to be part of the for loop.

code = nimbleCode({
for(i in 1:3)
y[i] ~ dnorm(mu[i],1)
mu[i] ~ dnorm(0,1)
})
m = nimbleModel(code)

is getDepencies in devel behaving as discussed Fri May 1 mtg?

Note that when returnScalarComponents = FALSE, we are returning extra "y" nodes.

code <- nimbleCode({
for(i in 1:4) {
y[i] ~ dnorm(mu[i],1)
}
mu[1:2] ~ dmnorm(z[1:2],I[1:2,1:2])
mu[3:4] ~dmnorm(z[1:2],I[1:2,1:2])
})

m <- nimbleModel(code)
m$getDependencies("mu[2:3]")
[1] "mu[1:2]" "mu[3:4]" "y[1]" "y[2]" "y[3]" "y[4]"
m$getDependencies("mu[1]")
[1] "mu[1:2]" "y[1]" "y[2]"
m$getDependencies("mu[1:2]")
[1] "mu[1:2]" "y[1]" "y[2]"
m$getDependencies("mu[2]")
[1] "mu[1:2]" "y[1]" "y[2]"

m$getDependencies("mu[2:3]", returnScalarComponents = TRUE)
[1] "mu[2]" "mu[3]" "y[2]" "y[3]"
m$getDependencies("mu[1]", returnScalarComponents = TRUE)
[1] "mu[1]" "y[1]"
m$getDependencies("mu[1:2]", returnScalarComponents = TRUE)
[1] "mu[1]" "mu[2]" "y[1]" "y[2]"
m$getDependencies("mu[2]", returnScalarComponents = TRUE)
[1] "mu[2]" "y[2]"

provide more informative error msgs for nimbleModel() and compileNimble() when dimension info not sufficient in BUGS code

In a number of cases our error msgs are non-informative when no brackets are provided for non-scalars (see below) (note we are much better when brackets are provided but the indexing is missing). One possibility would be to write a little system to check code based on knowing dimensions of distribution values and parameters and knowing expected dimensions for various DSL functions.

Examples:
code <- nimbleCode({
b[1:2] ~ dmnorm(mn[1:2], I[1:2,1:2])
z <- Z%*%b
})

m <- nimbleModel(code, inits = list(mn = rep(0, 2), I = diag(rep(0,2)), b = c(1,2), Z =matrix(rnorm(4),2)))
Error in parentExprReplaced[[iI + 2]] :
object of type 'symbol' is not subsettable

code <- nimbleCode({
b ~ dmnorm(mn, I)
})

m <- nimbleModel(code, inits = list(mn = rep(0, 2), I = diag(rep(1,2)), b = c(1,2)))
cm <- compileNimble(m)
Error: Error, sizeUnaryCwiseSquare was called with an argument that is not a matrix

code <- nimbleCode({
b ~ dmnorm(mn, I)
z[1:2] <- Z[1:2,1:2]%*%b[1:2]
})

m <- nimbleModel(code, inits = list(mn = rep(0, 2), I = diag(rep(1,2)), b = c(1,2), Z =matrix(rnorm(4),2)))
Error in if (is.numeric(v) && any(v < 0)) { :
missing value where TRUE/FALSE needed

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.