Author: Paul M. Hargarten
Date: 2026-02-22

# 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.

## References

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