Skip to content

Commit

Permalink
Minor fix to adaptive Gibbs sampler for clusters with zero factors. M…
Browse files Browse the repository at this point in the history
…inor documentation & examples edits re: the "truncated" argument. Prepared CRAN release.
  • Loading branch information
Keefe-Murphy committed Dec 20, 2022
1 parent 07c2c34 commit 0a7447a
Show file tree
Hide file tree
Showing 13 changed files with 27 additions and 24 deletions.
6 changes: 3 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Package: IMIFA
Type: Package
Date: 2022-08-12
Date: 2022-12-19
Title: Infinite Mixtures of Infinite Factor Analysers and Related Models
Version: 2.1.9
Version: 2.1.10
Authors@R: c(person("Keefe", "Murphy", email = "keefe.murphy@mu.ie", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-7709-3159")),
person("Cinzia", "Viroli", email = "cinzia.viroli@unibo.it", role = "ctb", comment = c(ORCID = "0000-0002-3278-5266")),
person("Isobel Claire", "Gormley", email = "claire.gormley@ucd.ie", role = "ctb", comment = c(ORCID = "0000-0001-7713-681X")))
Expand All @@ -26,7 +26,7 @@ Suggests:
mcclust,
rmarkdown,
Rmpfr
RoxygenNote: 7.2.2
RoxygenNote: 7.2.3
VignetteBuilder: knitr
Collate:
'MainFunction.R'
Expand Down
12 changes: 6 additions & 6 deletions R/FullConditionals.R
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@
#' @param phi.shape,phi.rate The shape and rate hyperparameters for the gamma prior on the local shrinkage parameters. Not necessary for checking if the cumulative shrinkage property holds, but worth supplying \emph{both} if the actual \emph{a priori} expected shrinkage factors are of interest. The default value(s) depends on the value of \code{inverse}, but are chosen in such a way that the local shrinkage has no effect on the expectation unless both are supplied. Cannot be incorporated into the expectation if \code{phi.shape < 1} and \code{isTRUE(inverse)}.
#' @param sigma.shape,sigma.rate The shape and rate hyperparameters for the gamma prior on the cluster shrinkage parameters. Not necessary for checking if the cumulative shrinkage property holds, but worth supplying \emph{both} if the actual \emph{a priori} expected shrinkage factors are of interest. The default value(s) depends on the value of \code{inverse}, but are chosen in such a way that the cluster shrinkage has no effect on the expectation unless both are supplied. Cannot be incorporated into the expectation if \code{sigma.shape < 1} and \code{isTRUE(inverse)}.
#' @param bd1,bd2 Rate hyperparameters for \eqn{\delta_1}{delta_1} and \eqn{\delta_k \forall k\ge 2}{delta_k for all k >= 2}, respectively. Both default to \code{1}.
#' @param truncated A logical value indicating whether the version of the MGP prior based on left-truncated gamma distributions is invoked (see \code{\link{ltrgamma}} and the Zhang et al. reference below). Defaults to \code{FALSE}. Note that, when \code{TRUE}, only the shrinkage parameters for the first loadings column are affected and the conditions needed to pass this check are much less strict. Moreover, more desirable shrinkage properties are easily obtained.
#' @param truncated A logical value indicating whether the version of the MGP prior based on left-truncated gamma distributions is invoked (see \code{\link{ltrgamma}} and the Zhang et al. reference below). Defaults to \code{FALSE}. Note that, when \code{TRUE}, the expected shrinkage factors for the first loadings column are not affected and the conditions needed to pass this check for the parameters associated with subsequent columns are much less strict. Moreover, more desirable shrinkage properties are easily obtained.
#' @param inverse Logical indicator for whether the cumulative shrinkage property is assessed against the induced Inverse Gamma prior, the default, or in terms of the Gamma prior (which is incorrect). This is always \code{TRUE} when used inside \code{\link{mcmc_IMIFA}}: the \code{FALSE} option exists only for demonstration purposes.
#'
#' @details This is called inside \code{\link{mcmc_IMIFA}} for the \code{"IFA"}, \code{"MIFA"}, \code{"OMIFA"} and \code{"IMIFA"} methods. This function is vectorised with respect to the arguments \code{ad1}, \code{ad2}, \code{phi.shape}, \code{phi.rate}, \code{sigma.shape}, \code{sigma.rate}, \code{bd1} and \code{bd2}.
Expand Down Expand Up @@ -564,7 +564,7 @@
#' (shrink <- MGP_check(ad1=1.5, ad2=2.8, Q=10, phi.shape=2, phi.rate=0.5, inverse=TRUE))
#'
#' # Check previously invalid parameterisation again using truncated version of the MGP prior
#' MGP_check(ad1=1.5, ad2=1.8, Q=10, phi.shape=3, truncated=FALSE)$valid # TRUE
#' MGP_check(ad1=1.5, ad2=1.8, Q=10, phi.shape=3, truncated=TRUE)$valid #TRUE
MGP_check <- function(ad1, ad2, Q = 3L, phi.shape = NULL, phi.rate = NULL, sigma.shape = NULL, sigma.rate = NULL, bd1 = 1, bd2 = 1, truncated = FALSE, inverse = TRUE) {
if(length(truncated) != 1 ||
!is.logical(truncated)) stop("'truncated' must be a single logical indicator", call.=FALSE)
Expand Down Expand Up @@ -605,7 +605,7 @@
if(any(c(ad1, ad2) < 1)) stop("All column shrinkage shape hyperparameter values must be at least 1", call.=FALSE)
if(any(c(bd1, bd2) <= 0)) stop("All column shrinkage rate hyperparameter values must be strictly positive", call.=FALSE)
if(any(WX <- ad1 >= ad2 &
!truncated)) warning("'ad2' should be moderately large relative to 'ad1' to encourage loadings column removal\n", call.=FALSE, immediate.=TRUE)
isFALSE(truncated))) warning("'ad2' should be moderately large relative to 'ad1' to encourage loadings column removal\n", call.=FALSE, immediate.=TRUE)

Qseq <- seq_len(Q) - 1L
ML <- seq_len(max.len)
Expand Down Expand Up @@ -1828,7 +1828,7 @@
#' @param adapt A logical value indicating whether adaptation of the number of cluster-specific factors is to take place when the MGP prior is employed. Defaults to \code{TRUE}. Specifying \code{FALSE} and supplying \code{range.Q} within \code{\link{mcmc_IMIFA}} provides a means to either approximate the infinite factor model with a fixed high truncation level, or to use the MGP prior in a finite factor context, however this is NOT recommended for the \code{"OMIFA"} and \code{"IMIFA"} methods.
#' @param forceQg A logical indicating whether the upper limit on the number of cluster-specific factors \code{Q} is also cluster-specific. Defaults to \code{FALSE}: when \code{TRUE}, the number of factors in each cluster is kept below the number of observations in each cluster, in addition to the bound defined by \code{range.Q}. Only relevant for the \code{"IMIFA"}, \code{"OMIFA"}, and \code{"MIFA"} methods, and only invoked when \code{adapt} is \code{TRUE}. May be useful for low-dimensional data sets for which identifiable solutions are desired.
#' @param cluster.shrink A logical value indicating whether to place the prior specified by \code{sigma.hyper} on the cluster shrinkage parameters. Defaults to \code{TRUE}. Specifying \code{FALSE} is equivalent to fixing all cluster shrinkage parameters to 1. Only relevant for the \code{"IMIFA"}, \code{"OMIFA"}, and \code{"MIFA"} methods. If invoked, the posterior mean cluster shrinkage factors will be reported.
#' @param truncated A logical value indicating whether the version of the MGP prior based on left-truncated gamma distributions is invoked (see Zhang et al. reference below and additional relevant documentation in \code{\link{ltrgamma}} and \code{\link{MGP_check}}). Defaults to \code{FALSE}. Note that, when \code{TRUE}, only the shrinkage parameters for the first loadings column are affected and the conditions needed to pass \code{\link{MGP_check}} are much less strict. Moreover, more desirable shrinkage properties are easily obtained, at the expense of slightly longer run times.
#' @param truncated A logical value indicating whether the version of the MGP prior based on left-truncated gamma distributions is invoked (see Zhang et al. reference below and additional relevant documentation in \code{\link{ltrgamma}} and \code{\link{MGP_check}}). Defaults to \code{FALSE}. Note that, when \code{TRUE}, the expected shrinkage factors for the first loadings column are not affected and the conditions needed to pass \code{\link{MGP_check}} for the parameters associated with subsequent columns are much less strict. Moreover, more desirable shrinkage properties are easily obtained, at the expense of slightly longer run times.
#' @param b0,b1 Intercept & slope parameters for the exponentially decaying adaptation probability:
#'
#' \code{p(iter) = 1/exp(b0 + b1 * (iter - start.AGS))}.
Expand Down Expand Up @@ -2110,7 +2110,7 @@
#' \deqn{f(x|\alpha, \beta) = \frac{\beta^\alpha}{(\Gamma(\alpha)-\Gamma(\alpha, \tau\beta))}x^{\alpha-1}e^{-x\beta}}
#' for \eqn{0\le\tau\le x}, and \eqn{\min(\tau,\beta) > 0}{min(tau, beta) > 0}, where \eqn{\alpha}{alpha} and \eqn{\beta}{beta} are the \code{shape} and \code{rate} parameters, respectively, \eqn{\tau}{tau} is the cutoff point at which \code{trunc}ation occurs, and \eqn{\Gamma(\alpha, \tau\beta)} is the upper incomplete gamma function.
#'
#' @note \code{rltrgamma} is invoked internally for the \code{"IFA"}, \code{"MIFA"}, \code{"OMIFA"}, and \code{"IMIFA"} models to draw column shrinkage parameters for all but the first loadings column under the MGP prior when \code{truncated=TRUE} (which is \strong{not} the default) is supplied to \code{mgpControl}, at the expense of slightly longer run times. \code{exp_ltrgamma} is used within \code{MGP_check} to check the validity of the MGP hyperparameters when \code{truncated=TRUE} (which is again, \strong{not} the default). Both functions always assume \code{trunc=1} for these internal usages.
#' @note \code{rltrgamma} is invoked internally for the \code{"IFA"}, \code{"MIFA"}, \code{"OMIFA"}, and \code{"IMIFA"} models to draw column shrinkage parameters for all but the first loadings column under the MGP prior when \code{truncated=TRUE} (which is \strong{not} the default) is supplied to \code{\link{mgpControl}}, at the expense of slightly longer run times. \code{exp_ltrgamma} is used within \code{\link{MGP_check}} to check the validity of the MGP hyperparameters when \code{truncated=TRUE} (which is again, \strong{not} the default). Both functions always assume \code{trunc=1} for these internal usages.
#'
#' Note also that no arguments are recycled, i.e. all arguments must be of length \code{1}.
#' @return For \code{rltrgamma}, a vector of length \code{n} giving draws from the left-truncated gamma distribution with the specified \code{shape} and \code{rate} parameters, and truncation point \code{trunc}.
Expand Down Expand Up @@ -2559,7 +2559,7 @@
dat <- as.matrix(dat)
N <- nrow(dat)
P <- ncol(dat)
inv.cov <- (beta0 + N/2L) * chol2inv(chol(diag(beta0, P) + 0.5 * crossprod(.scale2(dat)))) * tcrossprod(1/colVars(dat, std=TRUE))
inv.cov <- (beta0 + N/2L) * chol2inv(chol(diag(beta0, P) + 0.5 * crossprod(.scale2(dat))))/tcrossprod(colVars(dat, std=TRUE))
error <- diag(P) - (stats::cov(dat) %*% inv.cov)
switch(EXPR=match.arg(type), diag=sum(diag(error)^2)/P, mean(error^2))
}
Expand Down
4 changes: 2 additions & 2 deletions R/Gibbs_IFA.R
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
# Adaptation
if(adapt && all(iter >= start.AGS, iter < stop.AGS)) {
if(stats::runif(1) < ifelse(iter < AGS.burn, 0.5, exp(-b0 - b1 * (iter - start.AGS)))) {
colvec <- (if(Q0) colSums(abs(lmat) < epsilon) / P else stats::runif(1)) >= prop
colvec <- if(Q0) (colSums2(abs(lmat) < epsilon) / P) >= prop else stats::runif(1) <= prop
numred <- sum(colvec)
if(numred == 0) {
Q <- Q + 1L
Expand All @@ -95,7 +95,7 @@
tau <- cumprod(delta)
lmat <- cbind(lmat, stats::rnorm(n=P, mean=0, sd=1/sqrt(phi[,Q] * tau[Q])))
}
} else if(Q > 0) {
} else if(Q0) {
nonred <- colvec == 0
Q <- max(0L, Q - numred)
phi <- phi[,nonred, drop=FALSE]
Expand Down
2 changes: 1 addition & 1 deletion R/Gibbs_IMIFA.R
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@
# Adaptation
if(adapt && all(iter >= start.AGS, iter < stop.AGS)) {
if(stats::runif(1) < ifelse(iter < AGS.burn, 0.5, exp(-b0 - b1 * (iter - start.AGS)))) {
colvec <- lapply(nn.ind, function(g) (if(Q0[g]) colSums(abs(lmat[[g]]) < epsilon)/P else stats::runif(1)) >= prop)
colvec <- lapply(nn.ind, function(g) if(Q0[g]) (colSums2(abs(lmat[[g]]) < epsilon)/P) >= prop else stats::runif(1) <= prop)
nonred <- lapply(colvec, .which0)
numred <- lengths(colvec) - lengths(nonred)
notred <- numred == 0
Expand Down
2 changes: 1 addition & 1 deletion R/Gibbs_MIFA.R
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@
# Adaptation
if(adapt && all(iter >= start.AGS, iter < stop.AGS)) {
if(stats::runif(1) < ifelse(iter < AGS.burn, 0.5, exp(-b0 - b1 * (iter - start.AGS)))) {
colvec <- lapply(nn.ind, function(g) (if(Q0[g]) colSums(abs(lmat[[g]]) < epsilon)/P else stats::runif(1)) >= prop)
colvec <- lapply(nn.ind, function(g) if(Q0[g]) (colSums2(abs(lmat[[g]]) < epsilon)/P) >= prop else stats::runif(1) <= prop)
nonred <- lapply(colvec, .which0)
numred <- lengths(colvec) - lengths(nonred)
notred <- numred == 0
Expand Down
2 changes: 1 addition & 1 deletion R/Gibbs_OMIFA.R
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
# Adaptation
if(adapt && all(iter >= start.AGS, iter < stop.AGS)) {
if(stats::runif(1) < ifelse(iter < AGS.burn, 0.5, exp(-b0 - b1 * (iter - start.AGS)))) {
colvec <- lapply(nn.ind, function(g) (if(Q0[g]) colSums(abs(lmat[[g]]) < epsilon)/P else stats::runif(1)) >= prop)
colvec <- lapply(nn.ind, function(g) if(Q0[g]) (colSums2(abs(lmat[[g]]) < epsilon)/P) >= prop else stats::runif(1) <= prop)
nonred <- lapply(colvec, .which0)
numred <- lengths(colvec) - lengths(nonred)
notred <- numred == 0
Expand Down
4 changes: 2 additions & 2 deletions R/IMIFA.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#' \itemize{
#' \item{Type: }{Package}
#' \item{Package: }{IMIFA}
#' \item{Version: }{2.1.9}
#' \item{Date: }{2022-08-12 (this version), 2017-02-02 (original release)}
#' \item{Version: }{2.1.10}
#' \item{Date: }{2022-12-19 (this version), 2017-02-02 (original release)}
#' \item{Licence: }{GPL (>=2)}
#' }
#'
Expand Down
5 changes: 4 additions & 1 deletion inst/NEWS.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
__Infinite Mixtures of Infinite Factor Analysers__
==================================================

## IMIFA v2.1.10 - (_17<sup>th</sup> release [patch update]: 2022-12-19_)
### Improvements, Bug Fixes, & Miscellaneous Edits
* Minor fix to adaptive Gibbs sampler for clusters with zero factors.
* Minor speed-ups to `Procrustes` when `translate` &/or `dilate` are `TRUE`.
* Minor speed-ups to internal Cholesky decompositions in rare failure cases.
* Cosmetic changes to `param="alpha"` or `"discount"` plots.
* Cosmetic changes to `param="alpha"` & `param="discount"` plots.
* Minor speed-ups, documentation clarifications, & examples edits.

## IMIFA v2.1.9 - (_16<sup>th</sup> release [patch update]: 2022-08-12_)
### Improvements, Bug Fixes, & Miscellaneous Edits
Expand Down
4 changes: 2 additions & 2 deletions man/IMIFA-package.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/MGP_check.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/ltrgamma.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 0a7447a

Please sign in to comment.