Package csb :: Package statistics :: Package samplers :: Package mc :: Module singlechain
[frames] | no frames]

Source Code for Module csb.statistics.samplers.mc.singlechain

  1  """ 
  2  Various Monte Carlo equilibrium sampling algorithms, which simulate only one Markov chain. 
  3   
  4  Here is how to sample from a PDF using the L{HMCSampler} class. In the following 
  5  snippet we draw 5000 samples from a 1D normal distribution and plot them: 
  6   
  7   
  8      >>> import numpy 
  9      >>> from csb.io.plots import Chart 
 10      >>> from csb.statistics.pdf import Normal 
 11      >>> from csb.statistics.samplers import State 
 12      >>> from csb.statistics.samplers.mc.singlechain import HMCSampler 
 13       
 14      >>> initial_state = State(numpy.array([1.])) 
 15      >>> grad = lambda q, t: q 
 16      >>> timestep = 1.5 
 17      >>> nsteps = 30 
 18      >>> nsamples = 5000 
 19       
 20      >>> sampler = HMCSampler(Normal(), initial_state, grad, timestep, nsteps) 
 21       
 22      >>> states = [] 
 23      >>> for i in range(nsamples): 
 24              sampler.sample() 
 25              states.append(sampler.state) 
 26       
 27      >>> print('acceptance rate:', sampler.acceptance_rate) 
 28      0.8 
 29       
 30      >>> states = [state.position[0]for state in states] 
 31      >>> chart = Chart() 
 32      >>> chart.plot.hist([numpy.random.normal(size=5000), states], bins=20, normed=True) 
 33      >>> chart.plot.legend(['numpy.random.normal', 'HMC']) 
 34      >>> chart.show() 
 35   
 36   
 37  First, several things which are being needed are imported. 
 38  As every sampler in this module implements a Markov Chain, an initial state has to be 
 39  chosen. In the following lines, several parameters are set: 
 40      - the gradient of the negative log-probability of the PDF under consideration 
 41      - the integration timestep 
 42      - the number of integration steps to be performed in each iteration, that is, the HMC 
 43        trajectory length 
 44      - the number of samples to be drawn 
 45   
 46  The empty list states is initialized. It will serve to store the samples drawn. 
 47  In the loop, C{sampler.sample()} is repeatedly called. After each call of C{sampler.sample()}, 
 48  the current state of the Markov Chain is stored in sampler.state and this state is appended 
 49  to the sample storage list. 
 50   
 51  Then the acceptance rate is printed, the numeric values are being extracted from the 
 52  L{State} objects in states, a histogram is created and finally plotted. 
 53  """ 
 54   
 55  import numpy 
 56  import csb.numeric 
 57   
 58  from csb.statistics.samplers import State 
 59  from csb.statistics.samplers.mc import AbstractSingleChainMC 
 60  from csb.statistics.samplers.mc import SimpleProposalCommunicator 
 61  from csb.statistics.samplers.mc.propagators import MDPropagator 
 62  from csb.numeric.integrators import FastLeapFrog 
63 64 65 -class HMCSampler(AbstractSingleChainMC):
66 """ 67 Hamilton Monte Carlo (HMC, also called Hybrid Monte Carlo by the inventors, 68 Duane, Kennedy, Pendleton, Duncan 1987). 69 70 @param pdf: Probability density function to be sampled from 71 @type pdf: L{csb.statistics.pdf.AbstractDensity} 72 73 @param state: Inital state 74 @type state: L{State} 75 76 @param gradient: Gradient of the negative log-probability 77 @type gradient: L{AbstractGradient} 78 79 @param timestep: Timestep used for integration 80 @type timestep: float 81 82 @param nsteps: Number of integration steps to be performed in 83 each iteration 84 @type nsteps: int 85 86 @param integrator: Subclass of L{AbstractIntegrator} to be used for 87 integrating Hamiltionian equations of motion 88 @type integrator: type 89 90 @param temperature: Pseudo-temperature of the Boltzmann ensemble 91 M{p(x) = 1/N * exp(-1/T * E(x))} with the 92 pseudo-energy defined as M{E(x) = -log(p(x))} 93 where M{p(x)} is the PDF under consideration 94 @type temperature: float 95 """ 96
97 - def __init__(self, pdf, state, gradient, timestep, nsteps, integrator=FastLeapFrog, temperature=1.):
98 99 super(HMCSampler, self).__init__(pdf, state, temperature) 100 101 self._timestep = None 102 self.timestep = timestep 103 self._nsteps = None 104 self.nsteps = nsteps 105 self._integrator = integrator 106 self._gradient = gradient
107
108 - def _propose(self):
109 110 gen = MDPropagator(self._gradient, self._timestep, self._integrator) 111 momenta = numpy.random.normal(size=self.state.position.shape, scale=numpy.sqrt(self._temperature)) 112 self.state = State(self.state.position, momenta) 113 proposal = gen.generate(self.state, self._nsteps).final 114 115 return SimpleProposalCommunicator(proposal)
116
117 - def _calc_pacc(self, proposal_communicator):
118 119 proposal = proposal_communicator.proposal 120 E = lambda x:-self._pdf.log_prob(x) 121 122 pacc = csb.numeric.exp((-0.5 * sum(proposal.momentum ** 2) - E(proposal.position) 123 + 0.5 * sum(self.state.momentum ** 2) + E(self.state.position)) / self.temperature) 124 125 return pacc
126 127 @property
128 - def timestep(self):
129 return self._timestep
130 131 @timestep.setter
132 - def timestep(self, value):
133 self._timestep = float(value)
134 135 @property
136 - def nsteps(self):
137 return self._nsteps
138 139 @nsteps.setter
140 - def nsteps(self, value):
141 self._nsteps = int(value)
142
143 -class RWMCSampler(AbstractSingleChainMC):
144 """ 145 Random Walk Metropolis Monte Carlo implementation 146 (Metropolis, Rosenbluth, Teller, Teller 1953; Hastings, 1970). 147 148 @param pdf: Probability density function to be sampled from 149 @type pdf: L{csb.statistics.pdf.AbstractDensity} 150 151 @param state: Inital state 152 @type state: L{State} 153 154 @param stepsize: Serves to set the step size in 155 proposal_density, e.g. for automatic acceptance 156 rate adaption 157 @type stepsize: float 158 159 @param proposal_density: The proposal density as a function f(x, s) 160 of the current state x and the stepsize s. 161 By default, the proposal density is uniform, 162 centered around x, and has width s. 163 @type proposal_density: callable 164 165 @param temperature: Pseudo-temperature of the Boltzmann ensemble 166 M{p(x) = 1/N * exp(-1/T * E(x))} with the 167 pseudo-energy defined as M{E(x) = -log(p(x))} 168 where M{p(x)} is the PDF under consideration 169 @type temperature: float 170 """ 171
172 - def __init__(self, pdf, state, stepsize=1., proposal_density=None, temperature=1.):
173 174 super(RWMCSampler, self).__init__(pdf, state, temperature) 175 self._stepsize = None 176 self.stepsize = stepsize 177 if proposal_density == None: 178 self._proposal_density = lambda x, s: x.position + s * numpy.random.uniform(size=x.position.shape, low=-1., high=1.) 179 else: 180 self._proposal_density = proposal_density
181
182 - def _propose(self):
183 184 return SimpleProposalCommunicator(State(self._proposal_density(self._state, self.stepsize)))
185
186 - def _calc_pacc(self, proposal_communicator):
187 188 proposal = proposal_communicator.proposal 189 E = lambda x:-self._pdf.log_prob(x) 190 191 pacc = csb.numeric.exp((-(E(proposal.position) - E(self.state.position))) / self.temperature) 192 return pacc
193 194 @property
195 - def stepsize(self):
196 return self._stepsize
197 198 @stepsize.setter
199 - def stepsize(self, value):
200 self._stepsize = float(value)
201