Repository navigation
Expand file tree
/
Copy pathage_pattern.py
More file actions
55 lines (41 loc) · 2.32 KB
/
Copy pathage_pattern.py
File metadata and controls
55 lines (41 loc) · 2.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
""" Several rate models"""
import pylab as pl
import pymc as mc
def spline(name, ages, knots, smoothing, interpolation_method='linear'):
""" Generate PyMC objects for a piecewise constant Gaussian process (PCGP) model
Parameters
----------
name : str
knots : array, locations of the discontinuities in the piecewise constant function
ages : array, points to interpolate to
smoothing : pymc.Node, smoothness parameter for smoothing spline
interpolation_method : str, optional, one of 'linear', 'nearest', 'zero', 'slinear', 'quadratic, 'cubic'
Results
-------
Returns dict of PyMC objects, including 'gamma' and 'mu_age'
the observed stochastic likelihood and data predicted stochastic
"""
assert pl.all(pl.diff(knots) > 0), 'Spline knots must be strictly increasing'
gamma = [mc.Normal('gamma_%s_%d'%(name,k), 0., 10.**-2, value=-10.) for k in knots]
#gamma = [mc.Uniform('gamma_%s_%d'%(name,k), -20., 20., value=-10.) for k in knots]
# TODO: fix AdaptiveMetropolis so that this is not necessary
flat_gamma = mc.Lambda('flat_gamma_%s'%name, lambda gamma=gamma: pl.array([x for x in pl.flatten(gamma)]))
import scipy.interpolate
@mc.deterministic(name='mu_age_%s'%name)
def mu_age(gamma=flat_gamma, knots=knots, ages=ages):
mu = scipy.interpolate.interp1d(knots, pl.exp(gamma), kind=interpolation_method, bounds_error=False, fill_value=0.)
return mu(ages)
vars = dict(gamma=gamma, mu_age=mu_age, ages=ages, knots=knots)
if (smoothing > 0) and (not pl.isinf(smoothing)):
print 'adding smoothing of', smoothing
@mc.potential(name='smooth_mu_%s'%name)
def smooth_gamma(gamma=flat_gamma, knots=knots, tau=smoothing**-2):
# the following is to include a "noise floor" so that level value
# zero prior does not exert undue influence on age pattern
# smoothing
gamma = gamma.clip(pl.log(pl.exp(gamma).mean()/10.), pl.inf) # only include smoothing on values within 10x of mean
return mc.normal_like(pl.sqrt(pl.sum(pl.diff(gamma)**2 / pl.diff(knots))), 0, tau)
vars['smooth_gamma'] = smooth_gamma
return vars
# TODO: change old code to use new name, remove this legacy function name
age_pattern = spline