Package BIP :: Package Bayes :: Package Samplers :: Module MCMC
[hide private]
[frames] | no frames]

Source Code for Module BIP.Bayes.Samplers.MCMC

  1  # To change this template, choose Tools | Templates 
  2  # and open the template in the editor. 
  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  #TODO: Finish implementation and test 
13 -class Metropolis(object):
14 """ 15 Metropolis Hastings sampler class 16 """
17 - def __init__(self, proposal_dist,likfun):
18 self.salt_band = 0.05 19 pass
20 - def propose(self):
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
28 - def step(self,n=1):
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 #total samples,accepted samples, rejected proposals 35 last_lik = None 36 liklist = [] 37 while j < n: 38 theta,prop = self.propose() 39 #calculate likelihoods 40 lik=0 41 for k in xrange(self.nphi): #loop on series 42 if self.q2phi.dtype.names[k] not in data: 43 continue#Only calculate liks of series for which we have data 44 obs = data[self.q2phi.dtype.names[k]] 45 for p in xrange(t): #Loop on time 46 lik += likfun(obs[p],prop[p][k],1./variance) 47 #store samples 48 if last_lik == None: #on first sample 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 #adjust rejection counter 55 i +=1 56 #print theta 57 continue 58 if i >= burnin:#store only after burnin samples 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 #update good sample counter 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 #no more expansion 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
80 - def tune(self, ar):
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
97 - def add_salt(self,dataset,band):
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