Title: | Generate Samples from Multivariate Truncated Normal Distributions |
Version: | 0.2.1 |
Maintainer: | Zhenyu Zhang <zhangzhenyusa@gmail.com> |
Description: | Efficient sampling from high-dimensional truncated Gaussian distributions, or multivariate truncated normal (MTN). Techniques include zigzag Hamiltonian Monte Carlo as in Akihiko Nishimura, Zhenyu Zhang and Marc A. Suchard (2024) <doi:10.1080/01621459.2024.2395587>, and harmonic Monte in Ari Pakman and Liam Paninski (2014) <doi:10.1080/10618600.2013.788448>. |
License: | MIT + file LICENSE |
Encoding: | UTF-8 |
RoxygenNote: | 7.3.2.9000 |
Imports: | Rcpp, RcppParallel, RcppXsimd, mgcv, stats, Rdpack |
RdMacros: | Rdpack |
LinkingTo: | Rcpp, RcppEigen, RcppParallel, RcppXsimd |
Suggests: | testthat (≥ 3.0.0) |
Config/testthat/edition: | 3 |
SystemRequirements: | RcppXsimd (>= 1.0.0), CPU with AVX/SSE4.2 (optional for better performance) |
NeedsCompilation: | yes |
Packaged: | 2025-05-20 18:04:04 UTC; zhzhang |
Author: | Zhenyu Zhang [aut, cre], Andrew Chin [aut], Akihiko Nishimura [aut], Marc A. Suchard [aut], John W. Ratcliff et al. [cph, ctb] (authors and copyright holders of see2neon.h under an MIT license) |
Repository: | CRAN |
Date/Publication: | 2025-05-20 21:50:02 UTC |
Efficient Cholesky decomposition
Description
Compute Cholesky decomposition of a matrix.
Usage
cholesky(A)
Arguments
A |
matrix to decompose |
Value
upper triangular matrix R such that A = U'U.
Create a Zigzag-HMC engine object
Description
Create the C++ object to set up SIMD vectorization for speeding up calculations for Zigzag-HMC ("Zigzag-HMC engine").
Usage
createEngine(
dimension,
lowerBounds,
upperBounds,
seed,
mean,
precision,
flags = 128L
)
Arguments
dimension |
the dimension of MTN. |
lowerBounds |
a vector specifying the lower bounds. |
upperBounds |
a vector specifying the upper bounds. |
seed |
random seed. |
mean |
the mean vector. |
precision |
the precision matrix. |
flags |
which SIMD instruction set to use. 128 = SSE, 256 = AVX. |
Value
a list whose only element is the Zigzag-HMC engine object.
Create a Zigzag-NUTS engine object
Description
Create the C++ object to set up SIMD vectorization for speeding up calculations for Zigzag-NUTS ("Zigzag-NUTS engine").
Usage
createNutsEngine(
dimension,
lowerBounds,
upperBounds,
seed,
stepSize,
mean,
precision,
flags = 128L
)
Arguments
dimension |
the dimension of MTN. |
lowerBounds |
a vector specifying the lower bounds. |
upperBounds |
a vector specifying the upper bounds. |
seed |
random seed. |
stepSize |
the base step size for Zigzag-NUTS. |
mean |
the mean vector. |
precision |
the precision matrix. |
flags |
which SIMD instruction set to use. 128 = SSE, 256 = AVX. |
Value
a list whose only element is the Zigzag-NUTS engine object.
Draw a random Laplace momentum
Description
Generate a d-dimensional momentum where the density of each element is proportional to exp(-|pi|).
Usage
drawLaplaceMomentum(d)
Arguments
d |
dimension of the momentum. |
Value
a d-dimensional Laplace-distributed momentum.
Get an eligible initial value for a MTN with given mean and truncations
Description
For a given MTN the function returns an initial vector whose elements are one of:
(1) middle point of the truncation interval if both lower and upper bounds are
finite (2) lower (upper) bound +0.1 (-0.1) if only the lower (upper) bound is finite
(3) the corresponding mean value if lower bound = -Inf
are upper bound = Inf
.
Usage
getInitialPosition(mean, lowerBounds, upperBounds)
Arguments
mean |
a d-dimensional mean vector. |
lowerBounds |
a d-dimensional vector specifying the lower bounds. |
upperBounds |
a d-dimensional vector specifying the lower bounds. |
Value
an eligible d-dimensional initial vector.
Draw one Markovian zigzag sample
Description
Simulate the Markovian zigzag dynamics for a given position over a specified travel time.
Usage
getMarkovianZigzagSample(position, velocity = NULL, engine, travelTime)
Arguments
position |
a d-dimensional position vector. |
velocity |
optional d-dimensional velocity vector. If NULL, it will be generated within the function. |
engine |
an object representing the Markovian zigzag engine, typically containing settings and state required for the simulation. |
travelTime |
the duration for which the dynamics are simulated. |
Value
A list containing the position and velocity after simulating the dynamics.
Draw one MTN sample with Zigzag-HMC or Zigzag-NUTS
Description
Simulate the Zigzag-HMC or Zigzag-NUTS dynamics on a given MTN.
Usage
getZigzagSample(position, momentum = NULL, nutsFlg, engine, stepZZHMC = NULL)
Arguments
position |
a d-dimensional initial position vector. |
momentum |
a d-dimensional initial momentum vector. |
nutsFlg |
logical. If |
engine |
list. Its |
stepZZHMC |
step size for Zigzag-HMC. If |
Value
one MCMC sample from the target MTN.
Note
getZigzagSample
is particularly efficient when the target MTN has a random
mean and covariance/precision where one can reuse the Zigzag-HMC engine object while
updating the mean and covariance. The following example demonstrates such a use.
Examples
set.seed(1)
n <- 1000
d <- 10
samples <- array(0, c(n, d))
# initialize MTN mean and precision
m <- rnorm(d, 0, 1)
prec <- rWishart(n = 1, df = d, Sigma = diag(d))[, , 1]
# call createEngine once
engine <- createEngine(dimension = d, lowerBounds = rep(0, d),
upperBounds = rep(Inf, d), seed = 1, mean = m, precision = prec)
HZZtime <- sqrt(2) / sqrt(min(mgcv::slanczos(
A = prec, k = 1,
kl = 1
)[['values']]))
currentSample <- rep(0.1, d)
for (i in 1:n) {
m <- rnorm(d, 0, 1)
prec <- rWishart(n = 1, df = d, Sigma = diag(d))[,,1]
setMean(sexp = engine$engine, mean = m)
setPrecision(sexp = engine$engine, precision = prec)
currentSample <- getZigzagSample(position = currentSample, nutsFlg = FALSE,
engine = engine, stepZZHMC = HZZtime)
samples[i,] <- currentSample
}
Sample from a truncated Gaussian distribution with the harmonic HMC
Description
Generate MCMC samples from a d-dimensional truncated Gaussian distribution with constraints Fx+g >= 0 using the Harmonic Hamiltonian Monte Carlo sampler (Harmonic-HMC).
Usage
harmonicHMC(
nSample,
burnin = 0,
mean,
choleskyFactor,
constrainDirec,
constrainBound,
init,
time = c(pi/8, pi/2),
precFlg,
seed = NULL,
extraOutputs = c()
)
Arguments
nSample |
number of samples after burn-in. |
burnin |
number of burn-in samples (default = 0). |
mean |
a d-dimensional mean vector. |
choleskyFactor |
upper triangular matrix R from Cholesky decomposition of precision or covariance matrix into R^TR. |
constrainDirec |
the k-by-d F matrix (k is the number of linear constraints). |
constrainBound |
the k-dimensional g vector. |
init |
a d-dimensional vector of the initial value. |
time |
HMC integration time for each iteration. Can either be a scalar value for a fixed time across all samples, or a length 2 vector of a lower and upper bound for uniform distribution from which the time is drawn from for each iteration. |
precFlg |
logical. whether |
seed |
random seed (default = 1). |
extraOutputs |
vector of strings. "numBounces" and/or "bounceDistances" can be requested, with the latter containing the distances in-between bounces for each sample and hence incurring significant computational and memory costs. |
Value
samples
: nSample-by-d matrix of samples
or, if extraOutputs
is non-empty, a list of samples
and the extra outputs.
References
Pakman A, Paninski L (2014). “Exact Hamiltonian Monte Carlo for truncated multivariate Gaussians.” Journal of Computational and Graphical Statistics, 23(2), 518–542.
Examples
set.seed(1)
d <- 10
A <- matrix(runif(d^2)*2 - 1, ncol=d)
Sigma <- t(A) %*% A
R <- cholesky(Sigma)
mu <- rep(0, d)
constrainDirec <- diag(d)
constrainBound <- rep(0,d)
initial <- rep(1, d)
results <- harmonicHMC(1000, 1000, mu, R, constrainDirec, constrainBound, initial, precFlg = FALSE)
Set the mean for the target MTN
Description
Set the mean vector for a given Zigzag-HMC engine object.
Usage
setMean(sexp, mean)
Arguments
sexp |
pointer to a Zigzag-HMC engine object. |
mean |
the mean vector. |
Set the precision matrix for the target MTN
Description
Set the precision matrix for a given Zigzag-HMC engine object.
Usage
setPrecision(sexp, precision)
Arguments
sexp |
pointer to a Zigzag-HMC engine object. |
precision |
the precision matrix. |
Sample from a truncated Gaussian distribution
Description
Generate MCMC samples from a d-dimensional truncated Gaussian distribution with element-wise truncations using the Zigzag Hamiltonian Monte Carlo sampler (Zigzag-HMC).
Usage
zigzagHMC(
nSample,
burnin = 0,
mean,
prec,
lowerBounds,
upperBounds,
init = NULL,
stepsize = NULL,
nutsFlg = FALSE,
precondition = FALSE,
seed = NULL,
diagnosticMode = FALSE
)
Arguments
nSample |
number of samples after burn-in. |
burnin |
number of burn-in samples (default = 0). |
mean |
a d-dimensional mean vector. |
prec |
a d-by-d precision matrix of the Gaussian distribution. |
lowerBounds |
a d-dimensional vector specifying the lower bounds. |
upperBounds |
a d-dimensional vector specifying the upper bounds. |
init |
a d-dimensional vector of the initial value. |
stepsize |
step size for Zigzag-HMC or Zigzag-NUTS (if |
nutsFlg |
logical. If |
precondition |
logical. If |
seed |
random seed (default = 1). |
diagnosticMode |
logical. |
Value
an nSample-by-d matrix of samples. If diagnosticMode
is TRUE
, a list with additional diagnostic information is returned.
References
Nishimura A, Zhang Z, Suchard MA (2024). “Zigzag path connects two Monte Carlo samplers: Hamiltonian counterpart to a piecewise deterministic Markov process.” Journal of the American Statistical Association, 1–13.
Nishimura A, Dunson DB, Lu J (2020). “Discontinuous Hamiltonian Monte Carlo for discrete parameters and discontinuous likelihoods.” Biometrika, 107(2), 365–380.
Examples
set.seed(1)
d <- 10
A <- matrix(runif(d^2)*2-1, ncol=d)
covMat <- t(A) %*% A
precMat <- solve(covMat)
initial <- rep(1, d)
results <- zigzagHMC(nSample = 1000, burnin = 1000, mean = rep(0, d), prec = precMat,
lowerBounds = rep(0, d), upperBounds = rep(Inf, d))