Defining an arbitrary (unnormalized) density function and sample from it?

Suppose I have a custom probability density function defined up to some constant. For example, it can come from a Gibbs distribution with some manually defined potential.

def unnormalized_pdf(x):
    return torch.exp(-x**2)

Can I use HMC to sample from this distribution? The whole point is not to define the distribution via sampling and conditioning, but define it analytically.

The HMC/NUTS samplers take in potential_fn arg, and you should be able to use that directly. e.g.

import torch
from pyro.infer import MCMC, NUTS


def unnormalized_pdf(x):
    return torch.exp(-x['u']**2)


nuts = NUTS(potential_fn=lambda x: -torch.log(unnormalized_pdf(x)))
mcmc = MCMC(nuts, num_samples=100, initial_params={'u': torch.tensor(0.)})
mcmc.run()
print(mcmc.get_samples())
4 Likes

Oh that’s neat. Thanks very much!

@neerajprad Thanks for your code. I am new to the pyro. I can not find the related document of the intial_params parts. Are there any conventions of args passed to MCMC and potential_fn args?

@qinsheng In Pyro, potential_fn input is a dictionary of name -> value pairs.

@fehiepsi Thanks for your reply. But does it means, args passed to the initial_params will be passed to the input of potential_fn?

Yes, you are right.

Is there a way to generate this distribution with bounded support? say x \in [0, +\infty).

1 Like