Python – pymc3. Shape variables in DensityDist do not work correctly

pymc3. Shape variables in DensityDist do not work correctly… here is a solution to the problem.

pymc3. Shape variables in DensityDist do not work correctly

I’m trying to pass pymc3. DensityDist() defines a multivariate custom distribution; However, I keep getting the following size mismatch error:

“LinAlgError: The given 0-dimensional array. The array must be two-dimensional”

I’ve seen https://github.com/pymc-devs/pymc3/issues/535 but I can’t find the answer to my question. For clarity, here is my simple example

import numpy as np
import pymc3 as pm

def pdf(x):
    y = 0
    print(x)
    sigma = np.identity(2)
    isigma  = sigma
    mu = np.array([[1,2],[3,4]])
    for i in range(2):
        x0 = x- mu[i,:]
        xsinv = np.linalg.multi_dot([x0,isigma,x0])
        y = y + np.exp(-0.5*xsinv)
    return y

logp = lambda x: np.log(pdf(x))
with pm. Model() as model:
    pm. DensityDist('x',logp, shape=2)
    step = pm. Metropolis(tune=False, S=np.identity(2)) 
    trace = pm.sample(100000, step=step, chain=1, tune=0,progressbar=False)

result = trace['x']

In this simple code, I want to define a denormalized pdf function, which is the sum of two denormalized normal distributions, and extract samples from this pdf by the Metropolis algorithm.

Thanks,

Solution

Try replacing numpy with theano: in the following line

xsinv = tt.dot(tt.dot(x0, isigma), x0)
y = y + tt.exp(-0.5 * xsinv)

As a side note, try using NUTS instead of metropolis and let PyMC3 choose the sampling method for you, and that’s it

trace = pm.sample(1000)

If you have questions, you can also ask here

Related Problems and Solutions