1 import math
2 import random
3 import numpy
4
5 import mcmc
6 import mcmc_indexclass as IC
10 """Sample from the probability distribution.
11 @return: the sample
12 @rtype: C{float}
13 """
14 raise RuntimeError, "Virtual function"
15
17 """Return the log(density) of the probability distribution at x.
18 @param x: the position where the density should be evaluated.
19 @type x: C{float}
20 @return: C{log(density)}
21 @rtype: C{float}
22 @raise mcmc.NotGoodPosition: when the density is not defined at C{x}.
23 """
24 raise RuntimeError, "Virtual function"
25
26
27 -class Fixed(probdist_c):
28 """This is essentially a delta-function probability distribution.
29 Use this for fixed parameters.
30 @note: Software that uses this should ignore C{logdens}.
31 """
32
35
38
39 logdens = None
40
41 @property
43 return "Fixed value %s" % str(self.v)
44
46 """Weibull distribution"""
48 if not ( shape >= 0.0 and scale>=0.0):
49 raise ValueError, "Weibull: shape=%s; scale=%s" % (str(shape), str(scale))
50 self.shape = shape
51 self.scale = scale
52
54 return random.weibullvariate(self.scale, self.shape)
55
57 assert x >= 0.0
58 x /= self.scale
59 return -x**self.shape + math.log(x)*(self.shape-1) + math.log(self.shape/self.scale)
60
61 @property
63 return "Weibull(%g,%s)" % (self.scale, self.shape)
64
65
66 -class Expo(probdist_c):
67 """Exponential distribution"""
68
70 """@type lmbda: float
71 @param lmbda: M{1/the_mean} (also M{1/the_standard_deviation} )
72 @except ValueError: Bad parameters for the distribution.
73 """
74 if not (lmbda > 0.0):
75 raise ValueError, "Expo: lmbda=%s" % str(lmbda)
76 self.lmbda = lmbda
77
79 return random.expovariate(self.lmbda)
80
85
86 @property
88 return "Exponential(%g)" % self.lmbda
89
92 """Normal distribution"""
93
95 if sigma <= 0.0:
96 raise mcmc.NotGoodPosition, "Normal: sigma=%s" % str(sigma)
97 self.mu = mu
98 self.sigma = sigma
99
101 return random.normalvariate(self.mu, self.sigma)
102
104 return -(((x-self.mu)/self.sigma)**2)/2.0 - math.log(math.sqrt(2*math.pi)*self.sigma)
105
106 @property
108 return "Normal(%g+-%g)" % (self.mu, self.sigma)
109
133
136 """Lognormal distribution
137 """
139 """
140 @param sigma: The standard deviation of the log of the resulting distribution.
141 @param mu: The median of the resulting distribution, I{not} the log of the median.
142 @type mu: float
143 @type sigma: float
144 @except ValueError: Bad parameters for the distribution.
145 """
146 if sigma <= 0.0 or not (mu != 0.0):
147 raise ValueError, "LogNormal: sigma=%s, mu=%s" % (str(sigma), str(mu))
148 self.mu = mu
149 self.sigma = sigma
150
152 return self.mu*math.exp(random.normalvariate(0.0, self.sigma))
153
155 if (x>0.0) != (self.mu>0.0) or not (x != 0.0):
156 raise mcmc.NotGoodPosition, "LogNormal: x=%s, mu=%s" % (str(x), str(self.mu))
157 x = math.log(x/self.mu)
158 return -((x/self.sigma)**2)/2.0 - math.log(math.sqrt(2*math.pi)*self.sigma)
159
160 @property
162 return "Lognormal(%g+-%g)" % (self.mu, self.sigma)
163
168 """
169 @type guess_prob_dist: list((str, probdist_c))
170 @type x: newstem2.indexclass.index_base
171 @rtype: float
172 @return: the log of the prior probability.
173 @except L{mcmc.NotGoodPosition}: When raised by any of the underlying probability distributions.
174 """
175 lp = 0.0
176 gpd = IC.PriorProbDist(guess_prob_dist)
177 for key in x.map.keys():
178 v = x.p(*key)
179
180 vv = None
181 fkey = x._fmt(key)
182 vv = gpd[fkey]
183 try:
184 logp = vv.logdens(v)
185 except mcmc.NotGoodPosition, ex:
186 raise ex.add_args("fkey=%s" % fkey, "v=%s" % str(v), "doc=%s" % vv.__doc__)
187 lp += logp
188 return lp
189
197
198
201
202
203 - def plot(self, idxr, arg, pylab, inum):
204 raise RuntimeError, "Virtual Function"
205
206
208 raise RuntimeError, "Virtual Function"
209
210
212 assert self.idxr is not None, "You need to call self.set_idxr()."
213 if self.ckey is not None and numpy.equal(self.ckey, x).all():
214 return self.cached
215 self.idxr.clear()
216 self.idxr.set_prms(x)
217 prob, constraint, logprior = self.logp_guts(self.idxr)
218 self.cached = prob - constraint + logprior
219 self.ckey = numpy.array(self.idxr.get_prms(), copy=True)
220 return self.cached
221
222
224 """Only define this if you can compute the actual probability
225 density for the data given model & parameters,
226 not just something proportional to it!
227 To do this
228 function, you need to be able to do the full multidimensional
229 integral over the probability distribution!
230
231 NOTE that x is an indexer!
232 NOTE that this is not the full logp function: it doesn't contain the prior!
233 """
234 prob, constraint, logprior = self.logp_guts(x)
235 return prob
236
237
239 assert self.idxr is not None, "You need to call self.set_idxr()."
240
241
242 self.idxr.set_prms(x)
243 prob, constraint, logprior = self.logp_guts(self.idxr)
244
245 self.cached = prob - constraint + logprior
246 self.ckey = numpy.array(self.idxr.get_prms(), copy=True)
247
248 return self.ckey
249
250
253
254 PriorProbDist = None
255
257 raise RuntimeError, "Virtual method"
258