Search code examples
pythonpymc3

The shape variable in pymc3.DensityDist does not work properly


I am trying to define a multivariate custom distribution through pymc3.DensityDist(); however, I keep getting the following error that dimensions do not match:

"LinAlgError: 0-dimensional array given. Array must be two-dimensional"

I have already seen https://github.com/pymc-devs/pymc3/issues/535 but I could not find the answer to my question. Just 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 an unnormilized pdf function, which is sum of two unnormalized normal distributions, and take samples from this pdf through Metropolis algorithm.

Thanks,


Solution

  • Try replacing numpy for theano in the following lines:

    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, just do

    trace = pm.sample(1000)
    

    For future reference you can also ask questions here