condTruncMVN: Conditional Truncated Multivariate Normal Distribution

Paul M. Hargarten

2026-02-22

The goal of condTruncMVN is to find densities, probabilities, and samples from a conditional truncated multivariate normal distribution. Suppose that Z = (X,Y) is from a fully-joint multivariate normal distribution of dimension n with mean \(\boldsymbol\mu\) and covariance matrix sigma ( \(\Sigma\) ) truncated between lower and upper. Then, Z has the density \[ f_Z(\textbf{z}, \boldsymbol\mu, \Sigma, \textbf{lower}, \textbf{upper})= \frac{exp(-\frac{1}{2}*(\textbf{z}-\boldsymbol\mu)^T \Sigma^{-1} (\textbf{z}-\boldsymbol\mu))} {\int_{\textbf{lower}}^{\textbf{upper}} exp(-\frac{1}{2}*(\textbf{z}-\boldsymbol\mu)^T \Sigma^{-1} (\textbf{z}-\boldsymbol\mu)) d\textbf{z}} \] for all z in [lower, upper] in \(\mathbb{R^{n}}\).

This package computes the conditional truncated multivariate normal distribution of Y|X. The conditional distribution follows a truncated multivariate normal [1]. Specifically, the functions are arranged such that

\[ Y = Z[ , dependent.ind] \] \[ X = Z[ , given.ind] \] \[ Y|X = X.given \sim MVN(mean, sigma, lower, upper) \] The [d,p,r]cmvtnorm() functions create a list of parameters used in truncated conditional normal and then passes the parameters to the source function below.

Function Name Description Source Function Univariate Case Additional Parameters
condtMVN List of parameters used in truncated conditional normal. condMVNorm:: condMVN()
dcmvtnorm Calculates the density f(Y=y| X = X.given) up to a constant. The integral of truncated distribution is not computed. tmvtnorm:: dtmvnorm() truncnorm:: dtruncnorm() y, log
pcmvtnorm Calculates the probability that Y|X is between lowerY and upperY given the parameters. tmvtnorm:: ptmvnorm() truncnorm:: ptruncnorm() lowerY, upperY, maxpts, abseps, releps
rcmvtnorm Generate random sample. tmvmixnorm:: rtmvn() truncnorm:: rtruncnorm() n, init, burn, thin

Installation

You can install the released version of condTruncMVN from CRAN with install.packages("condTruncMVN"). You can load the package by:

> library("condTruncMVN")
#> Loading required package: condMVNorm
#> Loading required package: mvtnorm

And the development version from GitHub with:

Example

Suppose \(X2,X3,X5|X1 = 1,X4 = -1 \sim N_3(1, Sigma, -10, 10)\). The following code finds the parameters of the distribution, calculates the density, probability, and finds random variates from this distribution.

> library(condTruncMVN)
> d <- 5
> rho <- 0.9
> Sigma <- matrix(0, nrow = d, ncol = d)
> Sigma <- rho^abs(row(Sigma) - col(Sigma))
> Sigma
#>        [,1]  [,2] [,3]  [,4]   [,5]
#> [1,] 1.0000 0.900 0.81 0.729 0.6561
#> [2,] 0.9000 1.000 0.90 0.810 0.7290
#> [3,] 0.8100 0.900 1.00 0.900 0.8100
#> [4,] 0.7290 0.810 0.90 1.000 0.9000
#> [5,] 0.6561 0.729 0.81 0.900 1.0000

First, we find the conditional Truncated Normal Parameters.

> condtMVN(mean = rep(1, d), sigma = Sigma, lower = rep(-10, d), upper = rep(10, d), dependent.ind = c(2,
+     3, 5), given.ind = c(1, 4), X.given = c(1, -1))
#> $condMean
#> [1]  0.3430923 -0.3211143 -0.8000000
#> 
#> $condVar
#>            [,1]       [,2]          [,3]
#> [1,] 0.13945095 0.06934025  2.220446e-16
#> [2,] 0.06934025 0.13945095 -1.110223e-16
#> [3,] 0.00000000 0.00000000  1.900000e-01
#> 
#> $condLower
#> [1] -10 -10 -10
#> 
#> $condUpper
#> [1] 10 10 10
#> 
#> $condInit
#> [1] 0 0 0

Find the log-density when X2,X3,X5 all equal \(0\):

> dcmvtruncnorm(rep(0, 3), mean = rep(1, 5), sigma = Sigma, lower = rep(-10, 5), upper = rep(10,
+     d), dependent.ind = c(2, 3, 5), given.ind = c(1, 4), X.given = c(1, -1), log = TRUE)
#> [1] -3.07231

Find \(P( -0.5 < X2,X3,X5 < 0 | X1 = 1,X4 = -1)\):

> pcmvtruncnorm(rep(-0.5, 3), rep(0, 3), mean = rep(1, d), sigma = Sigma, lower = rep(-10, d),
+     upper = rep(10, d), dependent.ind = c(2, 3, 5), given.ind = c(1, 4), X.given = c(1, -1))
#> [1] 0.0130611
#> attr(,"error")
#> [1] 7.177267e-07
#> attr(,"msg")
#> [1] "Normal Completion"

Generate two random numbers from the distribution.

> set.seed(2342)
> rcmvtruncnorm(2, mean = rep(1, d), sigma = Sigma, lower = rep(-10, d), upper = rep(10, d),
+     dependent.ind = c(2, 3, 5), given.ind = c(1, 4), X.given = c(1, -1))
#>            [,1]       [,2]       [,3]
#> [1,] 0.02238382 -0.1426882 -1.7914223
#> [2,] 0.32684386 -0.5239659 -0.1189072

Another Example: To find the probability that \(X1|X2, X3, X4, X5 \sim N(**1**, Sigma, **-10**, **10**)\) is between -0.5 and 0:

> pcmvtruncnorm(-0.5, 0, mean = rep(1, d), sigma = Sigma, lower = rep(-10, d), upper = rep(10,
+     d), dependent.ind = 1, given.ind = 2:5, X.given = c(1, -1, 1, -1))
#> univariate CDF: using truncnorm::ptruncnorm
#> [1] 7.080093e-08

If I want to generate 2 random variates from \(X1|X2, X3, X4, X5 \sim N(**1**, Sigma, **-10**, **10**)\):

> set.seed(2342)
> rcmvtruncnorm(2, mean = rep(1, d), sigma = Sigma, lower = rep(-10, d), upper = rep(10, d),
+     dependent.ind = 1, given.ind = 2:5, X.given = c(1, -1, 1, -1))
#> [1] 1.160074 1.040832

Computational Details

This vignette is successfully processed using the following.

#>  -- Session info ---------------------------------------------------
#>  setting  value
#>  version  R version 4.5.2 (2025-10-31)
#>  os       macOS Tahoe 26.2
#>  system   aarch64, darwin20
#>  ui       X11
#>  language (EN)
#>  collate  C
#>  ctype    en_US.UTF-8
#>  tz       America/New_York
#>  date     2026-02-22
#>  pandoc   3.6.3 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/aarch64/ (via rmarkdown)
#>  quarto   1.8.25 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/quarto
#> --  Packages -------------------------------------------------------
#>  package      * version date (UTC) lib source
#>  condMVNorm   * 2025.1  2025-04-13 [3] CRAN (R 4.5.0)
#>  matrixNormal   0.1.1   2022-09-16 [3] CRAN (R 4.5.0)
#>  tmvmixnorm     1.1.1   2020-09-18 [3] CRAN (R 4.5.0)
#>  tmvtnorm       1.7     2025-09-01 [3] CRAN (R 4.5.0)
#>  truncnorm      1.0-9   2023-03-20 [3] CRAN (R 4.5.0)
#> 
#>  [1] /private/var/folders/xt/b5cmsrmn26j8v9pvsz8_z8v00000gn/T/RtmpNmUXA1/Rinst157862ece250d
#>  [2] /private/var/folders/xt/b5cmsrmn26j8v9pvsz8_z8v00000gn/T/RtmpV9miMD/temp_libpath139c157f4820a
#>  [3] /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/library
#>  * ── Packages attached to the search path.

Final Notes

Please note that the ‘condTruncMVN’ package is released with a . By contributing to this project, you agree to abide by its terms.

CRAN status

References

1.
Horrace, W.C. Some results on the multivariate truncated normal distribution. Journal of Multivariate Analysis 2005, 94, 209–221.