# Package for Multivariate (normal) Conditional Distribution

**URL:** https://discourse.julialang.org/t/package-for-multivariate-normal-conditional-distribution/112765
**Category:** Statistics
**Created:** [April 10, 2024, 11:53am UTC](https://discourse.julialang.org/t/package-for-multivariate-normal-conditional-distribution/112765 "2024-04-10T11:53:38Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![PharmCat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pharmcat/32/6953_2.png) [@PharmCat](https://discourse.julialang.org/u/PharmCat)
#### Post date: [April 10, 2024, 11:53am UTC](https://discourse.julialang.org/t/package-for-multivariate-normal-conditional-distribution/112765/1 "2024-04-10T11:53:38Z")

</div>

Hi! Is any package to get Multivariate (normal) Conditional Distribution?

Something like described [here](https://statproofbook.github.io/P/mvn-cond.html).

---

<div class="post-metadata">

### Author: ![mlanghinrichs](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mlanghinrichs/32/50371_2.png) [@mlanghinrichs](https://discourse.julialang.org/u/mlanghinrichs)
#### Post date: [April 10, 2024, 1:41pm UTC](https://discourse.julialang.org/t/package-for-multivariate-normal-conditional-distribution/112765/2 "2024-04-10T13:41:15Z")

</div>

maybe other people jump in that know more, but this seems related:

> <https://github.com/JuliaStats/Distributions.jl/issues/418>
>
> I'm interested writing a set of functions that condition on a subset of variable…s, and return a new (conditional) distribution. This is \_roughly\_ how I'd imagine doing it for a multivariate normal distribution:
> 
> \`\`\` julia
> \# Given a multivariate distribution p(x), 
> \# returns new distribution p(x | xᵢ=aᵢ), where
> \# "a" is a vector of values to condition on, and
> \# "d2" is a vector of indices providing the
> \# dimensions (subscript i) in increasing order.
> function condition(
> joint::MultivariateDistribution,
> a::Vector{Float64},
> d2::Vector{Int}
> )
> if length(d2) != length(a)
> error("list of conditioned values and dimension indices bet the same length")
> end
> max\_dim = length(joint.μ)
> if minimum(d2) \< 1 || maximum(d2) \> max\_dim
> error("dimension indices must be between 1 and dimension of joint distribution")
> end
> 
> # d1 = remaining dimensions
> # d2 = removed/conditioned dimensions
> d2 = sort(d2)
> d1 = setdiff(1:max\_dim,d2)
> 
> # covariance matrix blocks
> Σ = full(joint.Σ)
> Σ11 = Σ\[d1,d1\]
> Σ12 = Σ\[d1,d2\]
> Σ22inv = inv(Σ\[d2,d2\])
> 
> μ\_new = joint.μ\[d1\] + (Σ12 \* Σ22inv \* (a - joint.μ\[d2\]))
> Σ\_new = Σ11 - (Σ12 \* Σ22inv \* Σ12')
> return MvNormal(μ\_new,Σ\_new)
> end
> \`\`\`
> 
> \*\*Questions:\*\*
> 
> 1) I know this is really inefficient, particularly the step \`Σ = full(joint.Σ)\` to convert a \`PDmat\` to a normal matrix. Any suggestions on how to do this better -- i.e. using the (already computed) Cholesky factorization? I admit I haven't given this much thought at all yet.
> 
> 2) Would a set of functions like this be useful to add to \`Distributions.jl\` or does it not fit within the scope of this package? Where (if anywhere at all) would this live in JuliaStats?
> 
> 3) Is the above approach completely off base, or am I on the right track at least?

in particular, also the last answer therein and reference to the `conditional(P, A, B, xB)` method from GaussianDistributions.jl which should do what you want.

essentially you could “just” calculate \mu\_{1|2} and \Sigma\_{1|2} yourself as described in your link and then sample from `MvNormal`(\mu\_{1|2}, \Sigma\_{1|2}) via Distributions.jl. Advantage of the above references may be a good _numerical_ implementation for computing \mu\_{1|2} and \Sigma\_{1|2}.

---

<div class="post-metadata">

### Author: ![lrnv](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lrnv/32/19373_2.png) [@lrnv](https://discourse.julialang.org/u/lrnv)
#### Post date: [October 22, 2025, 2:23pm UTC](https://discourse.julialang.org/t/package-for-multivariate-normal-conditional-distribution/112765/3 "2025-10-22T14:23:59Z")

</div>

[Shameless propaganda] Just to inform you if you still care that now Copulas.jl does allow conditioning or multivariate random vectors. It has a generic AD-based Implementation, but for Gaussian’s and Student’s dependence structures, it does the smart parametric thing:

```julia
using Copulas, Distributions
rho = 0.7 # could be a full correlation matrix as well.
mu = [0, 1, -2]
sigma = [1, 1, 2]
S = SklarDist(GaussianCopula(3, rho), Normal.(mu, sigma)) # this is now a trivariate gaussian random vector.

D1 = condition(S, 2, 0.3) # gives a bivariate random vector. 
D2 = condition(S, (1,2), (0.3, 0.4)) # gives a Normal() with correct mean and variance. 

```

see the docs there : [Conditioning and Subsetting | Copulas.jl](https://lrnv.github.io/Copulas.jl/dev/manual/conditioning_and_subsetting#Conditioning)
