# About set of Multivariate Normal Distributions

Let’s say we have a matrix:

and a matrix:

where each row of a matrix is supposed to be a mean vector of some m-dimensional Multivariate Normal Distribution with Covariance matrix .

And we need to define Multivariate Normal Distributions with different mean vectors but with the same covariance matrix inside of a Model. How to achieve this without explicit "for loop" which is a quite performance overhead?

A rough code:

with pm.Model():
Sigma = pm.Deterministic(...)
M = pm.Deterministic(...)

# unoptimal solution
for i in xrange(n):
_Y = pm.MvNormal('_Y_' + str(i), mu=mu_[:, i], cov=sd_, shape=(m, ))

# Is it possible to vectorize last lines using pm.MvNormal or pm.MatrixNormal ??


Thanks,
Best Regards
Alex

1 Like

If the MvNormal is a latent variable, it is much more straightforward to reparameterized it as Y = mu + L.dot(s) with s ~ Normal(0, 1)

n, m = 100, 5
Mean = np.random.randn(m, n)*5

with pm.Model() as model:
sd_dist = pm.HalfNormal.dist(2.5)
packed_chol = pm.LKJCholeskyCov('chol', n=m, eta=2, sd_dist=sd_dist)
# compute the covariance matrix
L = pm.expand_packed_triangular(m, packed_chol, lower=True)
mu = pm.Normal('mu', 0., 1., shape=(m, n))
Mv = pm.Deterministic('Mv', L.dot(mu) + Mean)


Using MvNormal directly is fine too:

n, m = 100, 5
Mean = np.random.randn(m, n)*5
with pm.Model() as model:
sd_dist = pm.HalfNormal.dist(2.5)
packed_chol = pm.LKJCholeskyCov('chol', n=m, eta=2, sd_dist=sd_dist)
# compute the covariance matrix
L = pm.expand_packed_triangular(m, packed_chol, lower=True)
Mv = pm.MvNormal('Mv', Mean.T, chol=L, shape=(n, m))


Note that the shape from MvNormal is different compare to above where you use dot product.

3 Likes

Thanks! The second solution is exactly what I need.

Best Regards
Alex