Source code for binf.pdf.example
"""
Example illustrating the use of the Parameter class
"""
from csb.statistics.pdf import AbstractDensity, ParameterNotFoundError
from csb.statistics.pdf.parameterized import Parameter, ParameterValueError
from csb.core import typedproperty, iterable
from binf.pdf.parameters import FancyGaussian
import numpy as np
import numpy
[docs]class Likelihood(AbstractDensity):
"""
A probability density function with data and parameters.
"""
@typedproperty(np.ndarray)
def data():
pass
[docs]class NormalLikelihood(FancyGaussian):
@typedproperty(numpy.ndarray)
def data():
pass
@property
def mock(self):
mock = L._params.get('mock',0.)
if isinstance(mock,Parameter):
mock = mock.value
return mock
[docs] def log_prob(self):
return super(NormalLikelihood, self).log_prob(self.data-self.mock).sum()
[docs]class LinearModel(Parameter):
def __init__(self, basis, input, value=None):
value = value if value is not None else np.zeros(len(input))
self._basis = basis
self._input = np.array(input)
super(LinearModel, self).__init__(value=value)
self._design_matrix = None
self._update_design_matrix()
@property
def x(self):
return self._input
@property
def y(self):
return self.value
[docs] def _update_design_matrix(self):
self._design_matrix = np.array([f(self.x) for f in self._basis]).T
[docs] def _validate(self, value):
if iterable(value) and len(value) == len(self._input):
return np.array(value)
else:
raise ValueError()
[docs] def _compute(self, base_value):
if not len(base_value) == len(self._basis):
raise ValueError()
return np.inner(self._design_matrix, base_value)
[docs]class Coefficients(Parameter):
def __init__(self, n):
super(Coefficients, self).__init__(np.zeros(n))
def __len__(self):
return len(self._value)
[docs] def _validate(self, value):
try:
return numpy.array(value)
except(ValueError, TypeError):
raise ParameterValueError(self.name, value)
if __name__ == '__main__':
n = 100
## straight-line fitting
basis = (lambda x: 0 * x + 1, lambda x: x)
x = np.linspace(-10., 10., n)
noise = np.random.standard_normal(n)
model = LinearModel(basis, x)
theta = Coefficients(len(basis))
model.set(noise)
model.bind_to(theta)
theta.set([0.,1.])
y = model.value
L = NormalLikelihood()
L.data = y + noise
L._register('mock')
L.set_params(mock=model)
print L.log_prob()
## Monte Carlo
stepsize = 1e-1
p = np.array([5.,5.]) #np.random.random(len(theta))
theta.set(p)
P = L.log_prob()
a = 0
M = 10000
samples = np.zeros((M,len(p)+1))
def energy(x):
theta.set(x)
return -L.log_prob()
for i in range(M):
q = p + stepsize * (np.random.random(len(p))-0.5)
theta.set(q)
Q = L.log_prob()
if np.log(np.random.random()) < Q - P:
p, P = q, Q
a += 1
theta.set(p)
chi2 = np.linalg.norm(L.data - L.mock)**2
L.precision = np.random.gamma(0.5 * n) / (0.5 * chi2)
P = L.log_prob()
samples[i,:2] = p
samples[i,-1] = L.precision