1
2
3 """
4 Module implementing MCMC samplers
5
6 """
7
8 __author__="fccoelho"
9 __date__ ="$09/12/2009 10:44:11$"
10 __docformat__ = "restructuredtext en"
11
12
14 """
15 Metropolis Hastings sampler class
16 """
17 - def __init__(self, proposal_dist,likfun):
18 self.salt_band = 0.05
19 pass
21 """generates proposals"""
22 pvar = self.proposal_variance*self.adaptscalefactor
23 theta = [self.theta_dists[dist]() for dist in self.q1theta.dtype.names]
24 prop = self.model(*theta)
25 if t == 1:
26 prop=[(v,) for v in prop]
27 return theta,prop
29 """
30 Does the actual sampling loop for
31 n steps
32 """
33 ptheta = recarray((self.K),formats=['f8']*self.ntheta, names = self.post_theta.dtype.names)
34 i=0;j=0;rej=0
35 last_lik = None
36 liklist = []
37 while j < n:
38 theta,prop = self.propose()
39
40 lik=0
41 for k in xrange(self.nphi):
42 if self.q2phi.dtype.names[k] not in data:
43 continue
44 obs = data[self.q2phi.dtype.names[k]]
45 for p in xrange(t):
46 lik += likfun(obs[p],prop[p][k],1./variance)
47
48 if last_lik == None:
49 last_lik = lik
50 continue
51
52 if not (lik-last_lik) > numpy.log(1):
53 if not numpy.log(random())< lik-last_lik:
54 rej +=1
55 i +=1
56
57 continue
58 if i >= burnin:
59 self.phi[j] = prop[0] if t==1 else [tuple(point) for point in prop]
60 ptheta[j] = tuple(theta)
61 liklist.append(lik)
62 j += 1
63 last_lik = lik
64 i+=1
65
66 self.post_theta = self.imp_sample(self.L,ptheta,liklist)
67 ar = (i-rej)/float(i)
68 if ar > 0.9:
69 if self.salt_band < 0:
70 self.salt_band = 0.05
71 elif self.salt_band < 30:
72 self.salt_band *= 10
73 if ar < 0.4:
74 self.salt_band = 0.001
75 print "Total steps(i): ",i,"rej:",rej, "j:",j
76 print ">>> Salt-Band: %s"%self.salt_band
77 print ">>> Acceptance rate: %s"%ar
78
79 return 1
81 """
82 Tune the proposal distribtion variance
83 in the case of using a Normal proposal distribution
84 """
85 if self.proposal_dist == "prior":
86 return
87 if ar<0.05:
88 self.adaptscalefactor *= 0.5
89 elif ar <0.2:
90 self.adaptscalefactor *= 0.9
91 elif ar >0.9:
92 self.adaptscalefactor *= 10
93 elif ar >0.75:
94 self.adaptscalefactor *= 2
95 elif ar >0.5:
96 self.adaptscalefactor *= 1.1
98 """
99 Adds a few extra uniformly distributed data
100 points beyond the dataset range.
101 This is done by adding from a uniform dist.
102
103 :Parameters:
104 - `dataset`: vector of data
105 - `band`: Fraction of range to extend: [0,1[
106
107 :Returns:
108 Salted dataset.
109 """
110 dmax = max(dataset)
111 dmin = min(dataset)
112 drange = dmax-dmin
113 hb = drange*band/2.
114 d = numpy.concatenate((dataset,stats.uniform(dmin-hb,dmax-dmin+hb).rvs(self.K*.05)))
115 return d
116
117 if __name__ == "__main__":
118 pass
119