MultivariateNormal#

The Multivariate Normal on \(\mathbb{R}^d\) with mean \(\mu\) and covariance \(\Sigma\):

\[ f(x \mid \mu, \Sigma) = (2\pi)^{-d/2} |\Sigma|^{-1/2} \exp\!\left(-\tfrac12 (x - \mu)^\top \Sigma^{-1} (x - \mu)\right). \]

It is the Gaussian core of every mixture in this gallery: compounding it with a positive GIG subordinator (via \(X \mid Y \sim \mathcal{N}(\mu + \gamma Y,\; \Sigma Y)\)) produces the GeneralizedHyperbolic family. normix stores the lower Cholesky factor L_Sigma and routes all linear algebra through it — \(\Sigma^{-1}\) is never formed explicitly.

Parametrizations#

Stored attributes: mu \((d,)\) and L_Sigma \((d, d)\) (lower Cholesky of \(\Sigma\)). Exponential family with sufficient statistic \(t(x) = [x,\; \operatorname{vec}(xx^\top)]\):

Parametrization

Value

Classical

mean \(\mu \in \mathbb{R}^d\), covariance \(\Sigma \succ 0\)

Natural \(\theta\)

\([\,\Sigma^{-1}\mu,\; -\tfrac12\operatorname{vec}(\Sigma^{-1})\,]\)

Expectation \(\eta = \nabla\psi\)

\([\,\mu,\; \operatorname{vec}(\Sigma + \mu\mu^\top)\,] = (\mathbb{E}[X],\; \mathbb{E}[XX^\top])\)

Every conversion is analytical — no solver is invoked, and fit_mle is the closed-form sample mean and covariance.

Quick usage#

mu = jnp.array([1.0, -0.5])
Sigma = jnp.array([[1.0, 0.4], [0.4, 2.0]])
mvn = MultivariateNormal.from_classical(mu, Sigma)

print("mean:\n", np.asarray(mvn.mean()))
print("cov:\n", np.asarray(mvn.cov()))
print("log_prob at mean:", float(mvn.log_prob(mu)))

samples = mvn.rvs(5_000, seed=0)           # (n, d)
fitted = MultivariateNormal.fit_mle(samples)
print("fitted mean:", np.asarray(fitted.mean()))
mean:
 [ 1.  -0.5]
cov:
 [[1.  0.4]
 [0.4 2. ]]
log_prob at mean: -2.1427598522197924
fitted mean: [ 0.97894 -0.51671]

See also#