Search code examples
pymcpymc3

sampling multivariate uniform in PyMC3


I would like to use sample from a custom distribution with uniform prior using DensityDist. Something in spirit of:

import theano.tensor as T
from pymc3 import DensityDist, Uniform, Model

with Model() as model:
    lim = 3
    x0 = Uniform('x0', -lim, lim)
    x1 = Uniform('x1', -lim, lim)

    x = T.concatenate([x0,x1])
    # Create custom densities
    star = DensityDist('star', lambda x: star(x[:,0],x[:,1]))

Where star is an function mapping a 2D cartesian point to an un-normalized log-likelihood function. It is the function I want to sample from using Metropolis-Hastings.

I tried a number of variations but none worked. The current code fails with:

ValueError: The index list is longer (size 2) than the number of dimensions of the tensor(namely 0). You are asking for a dimension of the tensor that does not exist! You might need to use dimshuffle to add extra dimension to your tensor.

Any help appreciated!


Solution

  • The index to x is wrong. It is only one dimensional, so indexing along two dimensions can't really work.

    import theano.tensor as tt
    from pymc3 import DensityDist, Uniform, Model
    
    def star(x):
        return -0.5 * tt.exp(-tt.sum(x ** 2))
        # or if you need the components individually
        #return -0.5 * tt.exp(-x[0] ** 2 - x[1] ** 2)
    
    with Model() as model:
        lim = 3
        x0 = Uniform('x0', -lim, lim)
        x1 = Uniform('x1', -lim, lim)
    
        x = T.stack([x0,x1])
        # Create custom densities
        star = DensityDist('star', star)