diff --git a/README.md b/README.md index 86374faa9..1ea945e5b 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ NIMBLE. Journal of Computational and Graphical Statistics 26:403-413. [https://d 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, W. Zhang, S. Paganin, and P. van Dam-Bates. 2024. NIMBLE: MCMC, Particle Filtering, and Programmable Hierarchical Modeling. doi: 10.5281/zenodo.1211190. R package version 1.4.1, https://cran.r-project.org/package=nimble. +de Valpine, P., C. Paciorek, D. Turek, N. Michaud, C. Anderson-Bergman, F. Obermeyer, C. Wehrhahn Cortes, A. Rodriguez, D. Temple Lang, W. Zhang, S. Paganin, and P. van Dam-Bates. 2024. NIMBLE: MCMC, Particle Filtering, and Programmable Hierarchical Modeling. doi: 10.5281/zenodo.1211190. R package version 1.4.2, 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. diff --git a/packages/nimble/DESCRIPTION b/packages/nimble/DESCRIPTION index 5ca30c937..8c9d46484 100644 --- a/packages/nimble/DESCRIPTION +++ b/packages/nimble/DESCRIPTION @@ -15,8 +15,8 @@ Description: A system for writing hierarchical statistical models largely of MCMC as the main goal of the 'BUGS'/'JAGS' language for writing models, one can use 'NIMBLE' for writing arbitrary other kinds of model-generic algorithms as well. A full User Manual is available at . -Version: 1.4.2 -Date: 2026-04-01 +Version: 1.4.3 +Date: 2026-05-01 Maintainer: Christopher Paciorek Authors@R: c( person("Perry", "de Valpine", role = "aut"), diff --git a/packages/nimble/R/BUGS_model.R b/packages/nimble/R/BUGS_model.R index 2cf6e609b..27c9083cd 100644 --- a/packages/nimble/R/BUGS_model.R +++ b/packages/nimble/R/BUGS_model.R @@ -959,7 +959,9 @@ Details: The upward search for dependent nodes propagates through deterministic if(self) { # The C++ call does *not* return self nodes nodeFunIDs <- unique(modelDef$maps$vertexID_2_nodeID[ nodeIDs ]) parentIDs <- sort(c(parentIDs, nodeFunIDs)) - } + } else parentIDs <- setdiff(parentIDs, nodeIDs) + + if(!includeRHSonly) parentIDs <- parentIDs[modelDef$maps$types[parentIDs] != 'RHSonly'] if(determOnly) parentIDs <- parentIDs[modelDef$maps$types[parentIDs] == 'determ'] if(stochOnly) parentIDs <- parentIDs[modelDef$maps$types[parentIDs] == 'stoch'] diff --git a/packages/nimble/R/BUGS_nimbleGraph.R b/packages/nimble/R/BUGS_nimbleGraph.R index 39900a585..a3d1d208a 100644 --- a/packages/nimble/R/BUGS_nimbleGraph.R +++ b/packages/nimble/R/BUGS_nimbleGraph.R @@ -194,7 +194,7 @@ getConditionallyIndependentSets <- function(model, if(!missing(nodes)) { if(missing(givenNodes)) - givenNodesIDs <- setdiff(givenNodeIDs, nodeIDs) + givenNodeIDs <- setdiff(givenNodeIDs, nodeIDs) } if(!missing(givenNodes)) { nodeIDs <- setdiff(nodeIDs, givenNodeIDs) diff --git a/packages/nimble/R/MCMC_WAIC.R b/packages/nimble/R/MCMC_WAIC.R index 5e3f9b378..c62618815 100644 --- a/packages/nimble/R/MCMC_WAIC.R +++ b/packages/nimble/R/MCMC_WAIC.R @@ -288,7 +288,7 @@ buildWAIC <- nimbleFunction( if(mcmcIter > 1) { badpWAIC <- length(which( sspWAICmat[lengthConvCheck, ] / (mcmcIter-1) > 0.4 )) if(badpWAIC) { - cat(" [Warning] There are ", badpWAIC, " individual pWAIC values that are greater than 0.4. This may indicate that the WAIC estimate is unstable (Vehtari et al., 2017), at least in cases without grouping of data nodes or multivariate data nodes.\n" ) + cat(" [Warning] There are ", badpWAIC, " individual pWAIC values that are greater than 0.4. This may indicate that the WAIC estimate is unstable (Vehtari et al., 2017), at least in cases without grouping of data nodes or multivariate data nodes. To see the individual pWAIC values, use the `getWAICdetails` method of the compiled MCMC object, with argument `returnElements = TRUE`.\n" ) } } output <- waicNimbleList$new() diff --git a/packages/nimble/R/setupMargNodes.R b/packages/nimble/R/setupMargNodes.R index ecb92c536..b8696d560 100644 --- a/packages/nimble/R/setupMargNodes.R +++ b/packages/nimble/R/setupMargNodes.R @@ -283,7 +283,7 @@ setupMargNodes <- function(model, paramNodes, randomEffectsNodes, calcNodes, tempDataNodesDefault <- model$getNodeNames(dataOnly = TRUE) if(paramsHandled) tempDataNodesDefault <- setdiff(tempDataNodesDefault, paramNodes) - tempDataNodesDefaultParents <- model$getParents(tempDataNodesDefault, upstream = TRUE, stochOnly = TRUE) + tempDataNodesDefaultParents <- model$getParents(tempDataNodesDefault, upstream = TRUE, stochOnly = TRUE, self = TRUE) # See comment above about why this is necessary: tempDataNodesDefaultParents <- setdiff(tempDataNodesDefaultParents, tempDataNodesDefault) reNodesDefault <- intersect(reNodesDefault, tempDataNodesDefaultParents) @@ -292,12 +292,12 @@ setupMargNodes <- function(model, paramNodes, randomEffectsNodes, calcNodes, if(paramsHandled) { # This means reProvided OR paramsProvided. Including parents allows checking # of potentially missing REs. reNodesDefault <- intersect(reNodesDefault, - model$getParents(calcNodes, upstream=TRUE, stochOnly = TRUE)) + model$getParents(calcNodes, upstream=TRUE, stochOnly = TRUE, self = TRUE)) } else { # This means !paramsHandled and hence !reProvided AND !paramsProvided reNodesDefault <- intersect(reNodesDefault, calcNodes) reNodesDefault <- intersect(reNodesDefault, - model$getParents(calcNodes, upstream=TRUE, stochOnly = TRUE)) + model$getParents(calcNodes, upstream=TRUE, stochOnly = TRUE, self = TRUE)) } } } diff --git a/packages/nimble/tests/testthat/test-getDependencies.R b/packages/nimble/tests/testthat/test-getDependencies.R index 028a5c545..acd75a7bf 100644 --- a/packages/nimble/tests/testthat/test-getDependencies.R +++ b/packages/nimble/tests/testthat/test-getDependencies.R @@ -154,12 +154,12 @@ test_that("getParents works in model with no criss-crossing dependencies", { expect_identical(m1$getParents("f1"), c("a1", "a2", "c2", "c4", "c3")) expect_identical(m1$getParents("f1", immediateOnly = TRUE), c("c4", "c3")) - expect_identical(m1$getParents(c("f1", "g1"), stochOnly = TRUE), c("a1", "a2", "f1")) - expect_identical(m1$getParents(c("f1", "g1"), immediateOnly = TRUE), c("c4", "c3", "f1")) - expect_identical(m1$getParents(c("g1", "f1"), stochOnly = TRUE), c("a1", "a2", "f1")) + expect_identical(m1$getParents(c("f1", "g1"), stochOnly = TRUE), c("a1", "a2")) + expect_identical(m1$getParents(c("f1", "g1"), immediateOnly = TRUE), c("c4", "c3")) + expect_identical(m1$getParents(c("g1", "f1"), stochOnly = TRUE), c("a1", "a2")) expect_identical(m1$getParents(c("f1", "g1"), stochOnly = TRUE, self = TRUE), c("a1", "a2", "f1", "g1")) - expect_identical(m1$getParents(c("c3", "c2", "e1"), stochOnly = FALSE), c("a1", "c2", "c3")) - expect_identical(m1$getParents(c("c3", "c2", "e1"), immediateOnly = TRUE, stochOnly = FALSE), c("a1", "c2", "c3")) + expect_identical(m1$getParents(c("c3", "c2", "e1"), stochOnly = FALSE), c("a1")) + expect_identical(m1$getParents(c("c3", "c2", "e1"), immediateOnly = TRUE, stochOnly = FALSE), c("a1")) expect_identical(m1$getParents("h1", includeRHSonly = TRUE, stochOnly = FALSE), c("lho")) })