Using pm.MvNormal for setting prior distribution

In my model, I aim to set [c,m]~multiGaussian with mu=[2.3,-14.9];
Cov=[[0.0179,-0.0432517],[-0.0432517,0.108137]]. Then, infer c, m from posterior distribution. But I don’t know how to assign two-dimensional Gaussian distribution to [c,m]. I tried the following code,

import numpy as np
import pymc3 as pm
delta=…
growth=…
with pm.Model() as model_a:
mu = [2.3075560664282255,-14.925081358163954]
Cov=np.array([[0.0179,-0.0432517],[-0.0432517,0.108137]])
[c,m] = pm.MvNormal(‘vals’, mu=mu, cov=Cov, shape=(1, 2))#some thing wrong
deltmu=pm.Deterministic(‘deltmu’,c*delta**m)
y=pm.Normal(‘y’,mu=deltmu,sd=0.1,observed=growth)
trace_a=pm.sample(10000,cores=1)

Actually, it is similar to assign ‘c=pm.Normal(‘c’,mu1,var1)’ and ‘m=pm.Normal(‘m’,mu2,var2)’. But c and m is correlated, so I want to use two-dimensional Gaussian distribution.
I know that the error is caused by “[c,m] = pm.MvNormal(‘vals’, mu=mu, cov=cov, shape=(1, 2))”. Could you advice how to make it correctly.

Many thanks for your help.

import numpy as np
import pymc3 as pm
import theano.tensor as tt

with pm.Model() as model_a:
    x = pm.MvNormal('vals', mu=mu, cov=cov, shape=(1, 2))
    c, m = tt.split(x, [1, 1], n_splits=2, axis=1)
    deltmu = pm.Deterministic('deltmu', c*delta**m)
    deltmu = tt.squeeze(deltmu)
    y = pm.Normal('y', mu=deltmu[0], sd=0.1, observed=growth)
    trace_a = pm.sample(10000, cores=1)

Also, the sd parameter has been deprecated. Use sigma instead!

Hi, thanks for your comments. However, when I duplicate your code, Python reports the error: “ValueError: Input dimension mis-match. (input[0].shape[1] = 5, input[1].shape[1] = 1)”

I put my entire code as follows,

import numpy as np
import pymc3 as pm
import theano.tensor as tt
delta=[8.30612523,8.40355324,8.50030771,8.59642241,8.69192957]
growth=[3.20924e-05,3.25786e-05,3.46921e-05,3.34784e-05,4.08747e-05]
with pm.Model() as model_a:
mu = [2.3075560664282255,-14.925081358163954]
Cov=np.array([[0.0179,-0.0432517],[-0.0432517,0.108137]])
x = pm.MvNormal(‘x’, mu=mu, cov=Cov,shape=(1,2))
c,m=tt.split(x,[1,1],n_splits=2,axis=1)
deltmu=pm.Deterministic(‘deltmu’,c*delta**m)
deltmu=tt.squeeze(deltmu)
y=pm.Normal(‘y’,mu=deltmu[0],sigma=0.1,observed=growth)
trace_a=pm.sample(10000,cores=1)

I think this error is caused by shape of tensor. Could you advise how to fix it.

Thanks a lot for your kind help.

Oh, I didn’t notice that delta was a vector. In that case, the below code should work

import numpy as np
import pymc3 as pm
import theano.tensor as tt

delta = np.array([8.30612523,8.40355324,8.50030771,8.59642241,8.69192957])
growth = np.array([3.20924e-05,3.25786e-05,3.46921e-05,3.34784e-05,4.08747e-05])

with pm.Model() as model_a:
    mu = [2.3075560664282255,-14.925081358163954]
    Cov = np.array([[0.0179,-0.0432517],[-0.0432517,0.108137]])

    x = pm.MvNormal('x', mu=mu, cov=Cov, shape=(1,2))
    c, m = tt.split(x, [1, 1], n_splits=2, axis=1)
    c = tt.squeeze(c)
    m = tt.squeeze(m)
    deltmu = pm.Deterministic('deltmu', c[0] * delta ** m[0])
    y = pm.Normal('y', mu=deltmu, sigma=0.1, observed=growth)
    trace_a = pm.sample(10, cores=1)
1 Like

Yes, It works. Thanks a lot.

Hi, Thanks for your solution. When I look back on this solution, I am wondering why we need to use tt.squeenze. Besides, Why we need to use c[0]*delta**m[0]" instead of c*delta**m" in pm.Deterministic function?
Many thanks for your help!

c and m are tensors of shape (1,1). tt.squeeze squeezes the shape of the tensors to (1,). So, we have to index c[0] and m[0] to get the data and avoid shape issues.