# QInfer/python-qinfer

Fetching contributors…
Cannot retrieve contributors at this time
92 lines (68 sloc) 3.13 KB
.. currentmodule:: qinfer



## Representing Probability Distributions

### Introduction

Probability distributions such as prior distributions over model parameters are reprented in QInfer by objects of type :class:Distribution that are responsible for producing samples according to those distributions. This is especially useful, for instance, when drawing initial particles for use with an :class:~qinfer.smc.SMCUpdater.

The approach to representing distributions taken by QInfer is somewhat different to that taken by, for example, :mod:scipy.stats, in that a QInfer :class:Distribution is a class that produces samples according to that distribution. This means that QInfer :class:Distribution objects provide much less information than do those represented by objects in :mod:scipy.stats, but that they are much easier to write and combine.

QInfer comes along with several distributions, listed in :ref:specific_distributions. Each of these is a subclass of :class:Distribution, and hence has a method :meth:~Distribution.sample that produces an array of samples.

>>> from qinfer import NormalDistribution
>>> dist = NormalDistribution(0, 1)
>>> samples = dist.sample(n=5)
>>> samples.shape == (5, 1)
True

### Combining Distributions

Distribution objects can be combined using other distribution objects. For instance, if a \sim \mathcal{N}(0, 1) and b \sim \text{Uni}(0, 1), then the product distribution on (a,b) can be produced by using :class:ProductDistribution:

>>> from qinfer import UniformDistribution, ProductDistribution
>>> a = NormalDistribution(0, 1)
>>> b = UniformDistribution([0, 1])
>>> ab = ProductDistribution(a, b)
>>> samples = ab.sample(n=5)
>>> samples.shape == (5, 2)
True

### Making Custom Distributions

To make a custom distribution, one need only implement :meth:~Distribution.sample and set the property :attr:~Distribution.n_rvs to indicate how many random variables the new distribution class represents.

For example, to implement a distribution over x and y such that \sqrt{x^2 + y^2} \sim \mathcal{N}(1, 0.1) and such that the angle between x and y is drawn from \text{Uni}(0, 2 \pi):

from qinfer import Distribution

class RingDistribution(Distribution):
@property
def n_rvs(self):
return 2

def sample(self, n=1):
r = np.random.randn(n, 1) * 0.1 + 1
th = np.random.random((n, 1)) * 2 * np.pi

x = r * np.cos(th)
y = r * np.sin(th)

return np.concatenate([x, y], axis=1)