blob: 76dc41699a50fdf3d6f649d39b8d592acc4e2b1b [file] [log] [blame]
Guido van Rossume7b146f2000-02-04 15:28:42 +00001"""Random variable generators.
Guido van Rossumff03b1a1994-03-09 12:55:02 +00002
Tim Petersd7b5e882001-01-25 03:36:26 +00003 integers
4 --------
5 uniform within range
6
7 sequences
8 ---------
9 pick random element
Raymond Hettingerf24eb352002-11-12 17:41:57 +000010 pick random sample
Tim Petersd7b5e882001-01-25 03:36:26 +000011 generate random permutation
12
Guido van Rossume7b146f2000-02-04 15:28:42 +000013 distributions on the real line:
14 ------------------------------
Tim Petersd7b5e882001-01-25 03:36:26 +000015 uniform
Guido van Rossume7b146f2000-02-04 15:28:42 +000016 normal (Gaussian)
17 lognormal
18 negative exponential
19 gamma
20 beta
Raymond Hettinger40f62172002-12-29 23:03:38 +000021 pareto
22 Weibull
Guido van Rossumff03b1a1994-03-09 12:55:02 +000023
Guido van Rossume7b146f2000-02-04 15:28:42 +000024 distributions on the circle (angles 0 to 2pi)
25 ---------------------------------------------
26 circular uniform
27 von Mises
28
Raymond Hettinger40f62172002-12-29 23:03:38 +000029General notes on the underlying Mersenne Twister core generator:
Guido van Rossume7b146f2000-02-04 15:28:42 +000030
Raymond Hettinger40f62172002-12-29 23:03:38 +000031* The period is 2**19937-1.
32* It is one of the most extensively tested generators in existence
33* Without a direct way to compute N steps forward, the
34 semantics of jumpahead(n) are weakened to simply jump
35 to another distant state and rely on the large period
36 to avoid overlapping sequences.
37* The random() method is implemented in C, executes in
38 a single Python step, and is, therefore, threadsafe.
Tim Peterse360d952001-01-26 10:00:39 +000039
Guido van Rossume7b146f2000-02-04 15:28:42 +000040"""
Guido van Rossumd03e1191998-05-29 17:51:31 +000041
Tim Petersd7b5e882001-01-25 03:36:26 +000042from math import log as _log, exp as _exp, pi as _pi, e as _e
43from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
Tim Peters9146f272002-08-16 03:41:39 +000044from math import floor as _floor
Guido van Rossumff03b1a1994-03-09 12:55:02 +000045
Raymond Hettingerf24eb352002-11-12 17:41:57 +000046__all__ = ["Random","seed","random","uniform","randint","choice","sample",
Skip Montanaro0de65802001-02-15 22:15:14 +000047 "randrange","shuffle","normalvariate","lognormvariate",
Raymond Hettingerf8a52d32003-08-05 12:23:19 +000048 "expovariate","vonmisesvariate","gammavariate",
49 "gauss","betavariate","paretovariate","weibullvariate",
Raymond Hettinger40f62172002-12-29 23:03:38 +000050 "getstate","setstate","jumpahead"]
Tim Petersd7b5e882001-01-25 03:36:26 +000051
52NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0)
Tim Petersd7b5e882001-01-25 03:36:26 +000053TWOPI = 2.0*_pi
Tim Petersd7b5e882001-01-25 03:36:26 +000054LOG4 = _log(4.0)
Tim Petersd7b5e882001-01-25 03:36:26 +000055SG_MAGICCONST = 1.0 + _log(4.5)
Tim Petersd7b5e882001-01-25 03:36:26 +000056
57# Translated by Guido van Rossum from C source provided by
Raymond Hettinger40f62172002-12-29 23:03:38 +000058# Adrian Baddeley. Adapted by Raymond Hettinger for use with
59# the Mersenne Twister core generator.
Tim Petersd7b5e882001-01-25 03:36:26 +000060
Raymond Hettinger145a4a02003-01-07 10:25:55 +000061import _random
Raymond Hettinger40f62172002-12-29 23:03:38 +000062
Raymond Hettinger145a4a02003-01-07 10:25:55 +000063class Random(_random.Random):
Raymond Hettingerc32f0332002-05-23 19:44:49 +000064 """Random number generator base class used by bound module functions.
65
66 Used to instantiate instances of Random to get generators that don't
67 share state. Especially useful for multi-threaded programs, creating
68 a different instance of Random for each thread, and using the jumpahead()
69 method to ensure that the generated sequences seen by each thread don't
70 overlap.
71
72 Class Random can also be subclassed if you want to use a different basic
73 generator of your own devising: in that case, override the following
74 methods: random(), seed(), getstate(), setstate() and jumpahead().
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +000075
Raymond Hettingerc32f0332002-05-23 19:44:49 +000076 """
Tim Petersd7b5e882001-01-25 03:36:26 +000077
Raymond Hettinger40f62172002-12-29 23:03:38 +000078 VERSION = 2 # used by getstate/setstate
Tim Petersd7b5e882001-01-25 03:36:26 +000079
80 def __init__(self, x=None):
81 """Initialize an instance.
82
83 Optional argument x controls seeding, as for Random.seed().
84 """
85
86 self.seed(x)
Raymond Hettinger40f62172002-12-29 23:03:38 +000087 self.gauss_next = None
Tim Petersd7b5e882001-01-25 03:36:26 +000088
Tim Peters0de88fc2001-02-01 04:59:18 +000089 def seed(self, a=None):
90 """Initialize internal state from hashable object.
Tim Petersd7b5e882001-01-25 03:36:26 +000091
Tim Peters0de88fc2001-02-01 04:59:18 +000092 None or no argument seeds from current time.
93
Tim Petersbcd725f2001-02-01 10:06:53 +000094 If a is not None or an int or long, hash(a) is used instead.
Tim Petersd7b5e882001-01-25 03:36:26 +000095 """
96
Raymond Hettinger145a4a02003-01-07 10:25:55 +000097 super(Random, self).seed(a)
Tim Peters46c04e12002-05-05 20:40:00 +000098 self.gauss_next = None
99
Tim Peterscd804102001-01-25 20:25:57 +0000100 def getstate(self):
101 """Return internal state; can be passed to setstate() later."""
Raymond Hettinger145a4a02003-01-07 10:25:55 +0000102 return self.VERSION, super(Random, self).getstate(), self.gauss_next
Tim Peterscd804102001-01-25 20:25:57 +0000103
104 def setstate(self, state):
105 """Restore internal state from object returned by getstate()."""
106 version = state[0]
Raymond Hettinger40f62172002-12-29 23:03:38 +0000107 if version == 2:
108 version, internalstate, self.gauss_next = state
Raymond Hettinger145a4a02003-01-07 10:25:55 +0000109 super(Random, self).setstate(internalstate)
Tim Peterscd804102001-01-25 20:25:57 +0000110 else:
111 raise ValueError("state with version %s passed to "
112 "Random.setstate() of version %s" %
113 (version, self.VERSION))
114
Tim Peterscd804102001-01-25 20:25:57 +0000115## ---- Methods below this point do not need to be overridden when
116## ---- subclassing for the purpose of using a different core generator.
117
118## -------------------- pickle support -------------------
119
120 def __getstate__(self): # for pickle
121 return self.getstate()
122
123 def __setstate__(self, state): # for pickle
124 self.setstate(state)
125
Raymond Hettinger5f078ff2003-06-24 20:29:04 +0000126 def __reduce__(self):
127 return self.__class__, (), self.getstate()
128
Tim Peterscd804102001-01-25 20:25:57 +0000129## -------------------- integer methods -------------------
130
Tim Petersd7b5e882001-01-25 03:36:26 +0000131 def randrange(self, start, stop=None, step=1, int=int, default=None):
132 """Choose a random item from range(start, stop[, step]).
133
134 This fixes the problem with randint() which includes the
135 endpoint; in Python this is usually not what you want.
136 Do not supply the 'int' and 'default' arguments.
137 """
138
139 # This code is a bit messy to make it fast for the
Tim Peters9146f272002-08-16 03:41:39 +0000140 # common case while still doing adequate error checking.
Tim Petersd7b5e882001-01-25 03:36:26 +0000141 istart = int(start)
142 if istart != start:
143 raise ValueError, "non-integer arg 1 for randrange()"
144 if stop is default:
145 if istart > 0:
146 return int(self.random() * istart)
147 raise ValueError, "empty range for randrange()"
Tim Peters9146f272002-08-16 03:41:39 +0000148
149 # stop argument supplied.
Tim Petersd7b5e882001-01-25 03:36:26 +0000150 istop = int(stop)
151 if istop != stop:
152 raise ValueError, "non-integer stop for randrange()"
Tim Peters9146f272002-08-16 03:41:39 +0000153 if step == 1 and istart < istop:
Tim Peters76ca1d42003-06-19 03:46:46 +0000154 # Note that
155 # int(istart + self.random()*(istop - istart))
156 # instead would be incorrect. For example, consider istart
157 # = -2 and istop = 0. Then the guts would be in
158 # -2.0 to 0.0 exclusive on both ends (ignoring that random()
159 # might return 0.0), and because int() truncates toward 0, the
160 # final result would be -1 or 0 (instead of -2 or -1).
161 # istart + int(self.random()*(istop - istart))
162 # would also be incorrect, for a subtler reason: the RHS
163 # can return a long, and then randrange() would also return
164 # a long, but we're supposed to return an int (for backward
165 # compatibility).
166 return int(istart + int(self.random()*(istop - istart)))
Tim Petersd7b5e882001-01-25 03:36:26 +0000167 if step == 1:
Tim Petersd7b5e882001-01-25 03:36:26 +0000168 raise ValueError, "empty range for randrange()"
Tim Peters9146f272002-08-16 03:41:39 +0000169
170 # Non-unit step argument supplied.
Tim Petersd7b5e882001-01-25 03:36:26 +0000171 istep = int(step)
172 if istep != step:
173 raise ValueError, "non-integer step for randrange()"
174 if istep > 0:
175 n = (istop - istart + istep - 1) / istep
176 elif istep < 0:
177 n = (istop - istart + istep + 1) / istep
178 else:
179 raise ValueError, "zero step for randrange()"
180
181 if n <= 0:
182 raise ValueError, "empty range for randrange()"
183 return istart + istep*int(self.random() * n)
184
185 def randint(self, a, b):
Tim Peterscd804102001-01-25 20:25:57 +0000186 """Return random integer in range [a, b], including both end points.
Tim Petersd7b5e882001-01-25 03:36:26 +0000187 """
188
189 return self.randrange(a, b+1)
190
Tim Peterscd804102001-01-25 20:25:57 +0000191## -------------------- sequence methods -------------------
192
Tim Petersd7b5e882001-01-25 03:36:26 +0000193 def choice(self, seq):
194 """Choose a random element from a non-empty sequence."""
195 return seq[int(self.random() * len(seq))]
196
197 def shuffle(self, x, random=None, int=int):
198 """x, random=random.random -> shuffle list x in place; return None.
199
200 Optional arg random is a 0-argument function returning a random
201 float in [0.0, 1.0); by default, the standard random.random.
202
203 Note that for even rather small len(x), the total number of
204 permutations of x is larger than the period of most random number
205 generators; this implies that "most" permutations of a long
206 sequence can never be generated.
207 """
208
209 if random is None:
210 random = self.random
211 for i in xrange(len(x)-1, 0, -1):
Tim Peterscd804102001-01-25 20:25:57 +0000212 # pick an element in x[:i+1] with which to exchange x[i]
Tim Petersd7b5e882001-01-25 03:36:26 +0000213 j = int(random() * (i+1))
214 x[i], x[j] = x[j], x[i]
215
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000216 def sample(self, population, k):
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000217 """Chooses k unique random elements from a population sequence.
218
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000219 Returns a new list containing elements from the population while
220 leaving the original population unchanged. The resulting list is
221 in selection order so that all sub-slices will also be valid random
222 samples. This allows raffle winners (the sample) to be partitioned
223 into grand prize and second place winners (the subslices).
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000224
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000225 Members of the population need not be hashable or unique. If the
226 population contains repeats, then each occurrence is a possible
227 selection in the sample.
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000228
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000229 To choose a sample in a range of integers, use xrange as an argument.
230 This is especially fast and space efficient for sampling from a
231 large population: sample(xrange(10000000), 60)
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000232 """
233
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000234 # Sampling without replacement entails tracking either potential
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000235 # selections (the pool) in a list or previous selections in a
236 # dictionary.
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000237
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000238 # When the number of selections is small compared to the population,
239 # then tracking selections is efficient, requiring only a small
240 # dictionary and an occasional reselection. For a larger number of
241 # selections, the pool tracking method is preferred since the list takes
242 # less space than the dictionary and it doesn't suffer from frequent
243 # reselections.
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000244
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000245 n = len(population)
246 if not 0 <= k <= n:
247 raise ValueError, "sample larger than population"
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000248 random = self.random
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000249 _int = int
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000250 result = [None] * k
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000251 if n < 6 * k: # if n len list takes less space than a k len dict
Raymond Hettinger311f4192002-11-18 09:01:24 +0000252 pool = list(population)
253 for i in xrange(k): # invariant: non-selected at [0,n-i)
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000254 j = _int(random() * (n-i))
Raymond Hettinger311f4192002-11-18 09:01:24 +0000255 result[i] = pool[j]
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000256 pool[j] = pool[n-i-1] # move non-selected item into vacancy
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000257 else:
Raymond Hettinger311f4192002-11-18 09:01:24 +0000258 selected = {}
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000259 for i in xrange(k):
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000260 j = _int(random() * n)
Raymond Hettinger311f4192002-11-18 09:01:24 +0000261 while j in selected:
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000262 j = _int(random() * n)
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000263 result[i] = selected[j] = population[j]
Raymond Hettinger311f4192002-11-18 09:01:24 +0000264 return result
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000265
Tim Peterscd804102001-01-25 20:25:57 +0000266## -------------------- real-valued distributions -------------------
267
268## -------------------- uniform distribution -------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000269
270 def uniform(self, a, b):
271 """Get a random number in the range [a, b)."""
272 return a + (b-a) * self.random()
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000273
Tim Peterscd804102001-01-25 20:25:57 +0000274## -------------------- normal distribution --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000275
Tim Petersd7b5e882001-01-25 03:36:26 +0000276 def normalvariate(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000277 """Normal distribution.
278
279 mu is the mean, and sigma is the standard deviation.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000280
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000281 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000282 # mu = mean, sigma = standard deviation
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000283
Tim Petersd7b5e882001-01-25 03:36:26 +0000284 # Uses Kinderman and Monahan method. Reference: Kinderman,
285 # A.J. and Monahan, J.F., "Computer generation of random
286 # variables using the ratio of uniform deviates", ACM Trans
287 # Math Software, 3, (1977), pp257-260.
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000288
Tim Petersd7b5e882001-01-25 03:36:26 +0000289 random = self.random
Raymond Hettinger311f4192002-11-18 09:01:24 +0000290 while True:
Tim Peters0c9886d2001-01-15 01:18:21 +0000291 u1 = random()
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000292 u2 = 1.0 - random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000293 z = NV_MAGICCONST*(u1-0.5)/u2
294 zz = z*z/4.0
295 if zz <= -_log(u2):
296 break
297 return mu + z*sigma
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000298
Tim Peterscd804102001-01-25 20:25:57 +0000299## -------------------- lognormal distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000300
301 def lognormvariate(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000302 """Log normal distribution.
303
304 If you take the natural logarithm of this distribution, you'll get a
305 normal distribution with mean mu and standard deviation sigma.
306 mu can have any value, and sigma must be greater than zero.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000307
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000308 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000309 return _exp(self.normalvariate(mu, sigma))
310
Tim Peterscd804102001-01-25 20:25:57 +0000311## -------------------- exponential distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000312
313 def expovariate(self, lambd):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000314 """Exponential distribution.
315
316 lambd is 1.0 divided by the desired mean. (The parameter would be
317 called "lambda", but that is a reserved word in Python.) Returned
318 values range from 0 to positive infinity.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000319
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000320 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000321 # lambd: rate lambd = 1/mean
322 # ('lambda' is a Python reserved word)
323
324 random = self.random
Tim Peters0c9886d2001-01-15 01:18:21 +0000325 u = random()
326 while u <= 1e-7:
327 u = random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000328 return -_log(u)/lambd
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000329
Tim Peterscd804102001-01-25 20:25:57 +0000330## -------------------- von Mises distribution --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000331
Tim Petersd7b5e882001-01-25 03:36:26 +0000332 def vonmisesvariate(self, mu, kappa):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000333 """Circular data distribution.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000334
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000335 mu is the mean angle, expressed in radians between 0 and 2*pi, and
336 kappa is the concentration parameter, which must be greater than or
337 equal to zero. If kappa is equal to zero, this distribution reduces
338 to a uniform random angle over the range 0 to 2*pi.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000339
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000340 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000341 # mu: mean angle (in radians between 0 and 2*pi)
342 # kappa: concentration parameter kappa (>= 0)
343 # if kappa = 0 generate uniform random angle
344
345 # Based upon an algorithm published in: Fisher, N.I.,
346 # "Statistical Analysis of Circular Data", Cambridge
347 # University Press, 1993.
348
349 # Thanks to Magnus Kessler for a correction to the
350 # implementation of step 4.
351
352 random = self.random
353 if kappa <= 1e-6:
354 return TWOPI * random()
355
356 a = 1.0 + _sqrt(1.0 + 4.0 * kappa * kappa)
357 b = (a - _sqrt(2.0 * a))/(2.0 * kappa)
358 r = (1.0 + b * b)/(2.0 * b)
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000359
Raymond Hettinger311f4192002-11-18 09:01:24 +0000360 while True:
Tim Peters0c9886d2001-01-15 01:18:21 +0000361 u1 = random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000362
363 z = _cos(_pi * u1)
364 f = (1.0 + r * z)/(r + z)
365 c = kappa * (r - f)
366
367 u2 = random()
368
369 if not (u2 >= c * (2.0 - c) and u2 > c * _exp(1.0 - c)):
Tim Peters0c9886d2001-01-15 01:18:21 +0000370 break
Tim Petersd7b5e882001-01-25 03:36:26 +0000371
372 u3 = random()
373 if u3 > 0.5:
374 theta = (mu % TWOPI) + _acos(f)
375 else:
376 theta = (mu % TWOPI) - _acos(f)
377
378 return theta
379
Tim Peterscd804102001-01-25 20:25:57 +0000380## -------------------- gamma distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000381
382 def gammavariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000383 """Gamma distribution. Not the gamma function!
384
385 Conditions on the parameters are alpha > 0 and beta > 0.
386
387 """
Tim Peters8ac14952002-05-23 15:15:30 +0000388
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000389 # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
Tim Peters8ac14952002-05-23 15:15:30 +0000390
Guido van Rossum570764d2002-05-14 14:08:12 +0000391 # Warning: a few older sources define the gamma distribution in terms
392 # of alpha > -1.0
393 if alpha <= 0.0 or beta <= 0.0:
394 raise ValueError, 'gammavariate: alpha and beta must be > 0.0'
Tim Peters8ac14952002-05-23 15:15:30 +0000395
Tim Petersd7b5e882001-01-25 03:36:26 +0000396 random = self.random
Tim Petersd7b5e882001-01-25 03:36:26 +0000397 if alpha > 1.0:
398
399 # Uses R.C.H. Cheng, "The generation of Gamma
400 # variables with non-integral shape parameters",
401 # Applied Statistics, (1977), 26, No. 1, p71-74
402
Raymond Hettingerca6cdc22002-05-13 23:40:14 +0000403 ainv = _sqrt(2.0 * alpha - 1.0)
404 bbb = alpha - LOG4
405 ccc = alpha + ainv
Tim Peters8ac14952002-05-23 15:15:30 +0000406
Raymond Hettinger311f4192002-11-18 09:01:24 +0000407 while True:
Tim Petersd7b5e882001-01-25 03:36:26 +0000408 u1 = random()
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000409 if not 1e-7 < u1 < .9999999:
410 continue
411 u2 = 1.0 - random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000412 v = _log(u1/(1.0-u1))/ainv
413 x = alpha*_exp(v)
414 z = u1*u1*u2
415 r = bbb+ccc*v-x
416 if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z):
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000417 return x * beta
Tim Petersd7b5e882001-01-25 03:36:26 +0000418
419 elif alpha == 1.0:
420 # expovariate(1)
421 u = random()
422 while u <= 1e-7:
423 u = random()
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000424 return -_log(u) * beta
Tim Petersd7b5e882001-01-25 03:36:26 +0000425
426 else: # alpha is between 0 and 1 (exclusive)
427
428 # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
429
Raymond Hettinger311f4192002-11-18 09:01:24 +0000430 while True:
Tim Petersd7b5e882001-01-25 03:36:26 +0000431 u = random()
432 b = (_e + alpha)/_e
433 p = b*u
434 if p <= 1.0:
435 x = pow(p, 1.0/alpha)
436 else:
437 # p > 1
438 x = -_log((b-p)/alpha)
439 u1 = random()
440 if not (((p <= 1.0) and (u1 > _exp(-x))) or
441 ((p > 1) and (u1 > pow(x, alpha - 1.0)))):
442 break
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000443 return x * beta
444
Tim Peterscd804102001-01-25 20:25:57 +0000445## -------------------- Gauss (faster alternative) --------------------
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000446
Tim Petersd7b5e882001-01-25 03:36:26 +0000447 def gauss(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000448 """Gaussian distribution.
449
450 mu is the mean, and sigma is the standard deviation. This is
451 slightly faster than the normalvariate() function.
452
453 Not thread-safe without a lock around calls.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000454
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000455 """
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000456
Tim Petersd7b5e882001-01-25 03:36:26 +0000457 # When x and y are two variables from [0, 1), uniformly
458 # distributed, then
459 #
460 # cos(2*pi*x)*sqrt(-2*log(1-y))
461 # sin(2*pi*x)*sqrt(-2*log(1-y))
462 #
463 # are two *independent* variables with normal distribution
464 # (mu = 0, sigma = 1).
465 # (Lambert Meertens)
466 # (corrected version; bug discovered by Mike Miller, fixed by LM)
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000467
Tim Petersd7b5e882001-01-25 03:36:26 +0000468 # Multithreading note: When two threads call this function
469 # simultaneously, it is possible that they will receive the
470 # same return value. The window is very small though. To
471 # avoid this, you have to use a lock around all calls. (I
472 # didn't want to slow this down in the serial case by using a
473 # lock here.)
Guido van Rossumd03e1191998-05-29 17:51:31 +0000474
Tim Petersd7b5e882001-01-25 03:36:26 +0000475 random = self.random
476 z = self.gauss_next
477 self.gauss_next = None
478 if z is None:
479 x2pi = random() * TWOPI
480 g2rad = _sqrt(-2.0 * _log(1.0 - random()))
481 z = _cos(x2pi) * g2rad
482 self.gauss_next = _sin(x2pi) * g2rad
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000483
Tim Petersd7b5e882001-01-25 03:36:26 +0000484 return mu + z*sigma
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000485
Tim Peterscd804102001-01-25 20:25:57 +0000486## -------------------- beta --------------------
Tim Peters85e2e472001-01-26 06:49:56 +0000487## See
488## http://sourceforge.net/bugs/?func=detailbug&bug_id=130030&group_id=5470
489## for Ivan Frohne's insightful analysis of why the original implementation:
490##
491## def betavariate(self, alpha, beta):
492## # Discrete Event Simulation in C, pp 87-88.
493##
494## y = self.expovariate(alpha)
495## z = self.expovariate(1.0/beta)
496## return z/(y+z)
497##
498## was dead wrong, and how it probably got that way.
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000499
Tim Petersd7b5e882001-01-25 03:36:26 +0000500 def betavariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000501 """Beta distribution.
502
503 Conditions on the parameters are alpha > -1 and beta} > -1.
504 Returned values range between 0 and 1.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000505
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000506 """
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000507
Tim Peters85e2e472001-01-26 06:49:56 +0000508 # This version due to Janne Sinkkonen, and matches all the std
509 # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
510 y = self.gammavariate(alpha, 1.)
511 if y == 0:
512 return 0.0
513 else:
514 return y / (y + self.gammavariate(beta, 1.))
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000515
Tim Peterscd804102001-01-25 20:25:57 +0000516## -------------------- Pareto --------------------
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000517
Tim Petersd7b5e882001-01-25 03:36:26 +0000518 def paretovariate(self, alpha):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000519 """Pareto distribution. alpha is the shape parameter."""
Tim Petersd7b5e882001-01-25 03:36:26 +0000520 # Jain, pg. 495
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000521
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000522 u = 1.0 - self.random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000523 return 1.0 / pow(u, 1.0/alpha)
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000524
Tim Peterscd804102001-01-25 20:25:57 +0000525## -------------------- Weibull --------------------
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000526
Tim Petersd7b5e882001-01-25 03:36:26 +0000527 def weibullvariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000528 """Weibull distribution.
529
530 alpha is the scale parameter and beta is the shape parameter.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000531
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000532 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000533 # Jain, pg. 499; bug fix courtesy Bill Arms
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000534
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000535 u = 1.0 - self.random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000536 return alpha * pow(-_log(u), 1.0/beta)
Guido van Rossum6c395ba1999-08-18 13:53:28 +0000537
Raymond Hettinger40f62172002-12-29 23:03:38 +0000538## -------------------- Wichmann-Hill -------------------
539
540class WichmannHill(Random):
541
542 VERSION = 1 # used by getstate/setstate
543
544 def seed(self, a=None):
545 """Initialize internal state from hashable object.
546
547 None or no argument seeds from current time.
548
549 If a is not None or an int or long, hash(a) is used instead.
550
551 If a is an int or long, a is used directly. Distinct values between
552 0 and 27814431486575L inclusive are guaranteed to yield distinct
553 internal states (this guarantee is specific to the default
554 Wichmann-Hill generator).
555 """
556
557 if a is None:
558 # Initialize from current time
559 import time
560 a = long(time.time() * 256)
561
562 if not isinstance(a, (int, long)):
563 a = hash(a)
564
565 a, x = divmod(a, 30268)
566 a, y = divmod(a, 30306)
567 a, z = divmod(a, 30322)
568 self._seed = int(x)+1, int(y)+1, int(z)+1
569
570 self.gauss_next = None
571
572 def random(self):
573 """Get the next random number in the range [0.0, 1.0)."""
574
575 # Wichman-Hill random number generator.
576 #
577 # Wichmann, B. A. & Hill, I. D. (1982)
578 # Algorithm AS 183:
579 # An efficient and portable pseudo-random number generator
580 # Applied Statistics 31 (1982) 188-190
581 #
582 # see also:
583 # Correction to Algorithm AS 183
584 # Applied Statistics 33 (1984) 123
585 #
586 # McLeod, A. I. (1985)
587 # A remark on Algorithm AS 183
588 # Applied Statistics 34 (1985),198-200
589
590 # This part is thread-unsafe:
591 # BEGIN CRITICAL SECTION
592 x, y, z = self._seed
593 x = (171 * x) % 30269
594 y = (172 * y) % 30307
595 z = (170 * z) % 30323
596 self._seed = x, y, z
597 # END CRITICAL SECTION
598
599 # Note: on a platform using IEEE-754 double arithmetic, this can
600 # never return 0.0 (asserted by Tim; proof too long for a comment).
601 return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0
602
603 def getstate(self):
604 """Return internal state; can be passed to setstate() later."""
605 return self.VERSION, self._seed, self.gauss_next
606
607 def setstate(self, state):
608 """Restore internal state from object returned by getstate()."""
609 version = state[0]
610 if version == 1:
611 version, self._seed, self.gauss_next = state
612 else:
613 raise ValueError("state with version %s passed to "
614 "Random.setstate() of version %s" %
615 (version, self.VERSION))
616
617 def jumpahead(self, n):
618 """Act as if n calls to random() were made, but quickly.
619
620 n is an int, greater than or equal to 0.
621
622 Example use: If you have 2 threads and know that each will
623 consume no more than a million random numbers, create two Random
624 objects r1 and r2, then do
625 r2.setstate(r1.getstate())
626 r2.jumpahead(1000000)
627 Then r1 and r2 will use guaranteed-disjoint segments of the full
628 period.
629 """
630
631 if not n >= 0:
632 raise ValueError("n must be >= 0")
633 x, y, z = self._seed
634 x = int(x * pow(171, n, 30269)) % 30269
635 y = int(y * pow(172, n, 30307)) % 30307
636 z = int(z * pow(170, n, 30323)) % 30323
637 self._seed = x, y, z
638
639 def __whseed(self, x=0, y=0, z=0):
640 """Set the Wichmann-Hill seed from (x, y, z).
641
642 These must be integers in the range [0, 256).
643 """
644
645 if not type(x) == type(y) == type(z) == int:
646 raise TypeError('seeds must be integers')
647 if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256):
648 raise ValueError('seeds must be in range(0, 256)')
649 if 0 == x == y == z:
650 # Initialize from current time
651 import time
652 t = long(time.time() * 256)
653 t = int((t&0xffffff) ^ (t>>24))
654 t, x = divmod(t, 256)
655 t, y = divmod(t, 256)
656 t, z = divmod(t, 256)
657 # Zero is a poor seed, so substitute 1
658 self._seed = (x or 1, y or 1, z or 1)
659
660 self.gauss_next = None
661
662 def whseed(self, a=None):
663 """Seed from hashable object's hash code.
664
665 None or no argument seeds from current time. It is not guaranteed
666 that objects with distinct hash codes lead to distinct internal
667 states.
668
669 This is obsolete, provided for compatibility with the seed routine
670 used prior to Python 2.1. Use the .seed() method instead.
671 """
672
673 if a is None:
674 self.__whseed()
675 return
676 a = hash(a)
677 a, x = divmod(a, 256)
678 a, y = divmod(a, 256)
679 a, z = divmod(a, 256)
680 x = (x + a) % 256 or 1
681 y = (y + a) % 256 or 1
682 z = (z + a) % 256 or 1
683 self.__whseed(x, y, z)
684
Tim Peterscd804102001-01-25 20:25:57 +0000685## -------------------- test program --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000686
Tim Petersd7b5e882001-01-25 03:36:26 +0000687def _test_generator(n, funccall):
Tim Peters0c9886d2001-01-15 01:18:21 +0000688 import time
689 print n, 'times', funccall
690 code = compile(funccall, funccall, 'eval')
Raymond Hettingerb98154e2003-05-24 17:26:02 +0000691 total = 0.0
Tim Peters0c9886d2001-01-15 01:18:21 +0000692 sqsum = 0.0
693 smallest = 1e10
694 largest = -1e10
695 t0 = time.time()
696 for i in range(n):
697 x = eval(code)
Raymond Hettingerb98154e2003-05-24 17:26:02 +0000698 total += x
Tim Peters0c9886d2001-01-15 01:18:21 +0000699 sqsum = sqsum + x*x
700 smallest = min(x, smallest)
701 largest = max(x, largest)
702 t1 = time.time()
703 print round(t1-t0, 3), 'sec,',
Raymond Hettingerb98154e2003-05-24 17:26:02 +0000704 avg = total/n
Tim Petersd7b5e882001-01-25 03:36:26 +0000705 stddev = _sqrt(sqsum/n - avg*avg)
Tim Peters0c9886d2001-01-15 01:18:21 +0000706 print 'avg %g, stddev %g, min %g, max %g' % \
707 (avg, stddev, smallest, largest)
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000708
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000709
710def _test(N=2000):
Tim Petersd7b5e882001-01-25 03:36:26 +0000711 _test_generator(N, 'random()')
712 _test_generator(N, 'normalvariate(0.0, 1.0)')
713 _test_generator(N, 'lognormvariate(0.0, 1.0)')
Tim Petersd7b5e882001-01-25 03:36:26 +0000714 _test_generator(N, 'vonmisesvariate(0.0, 1.0)')
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000715 _test_generator(N, 'gammavariate(0.01, 1.0)')
716 _test_generator(N, 'gammavariate(0.1, 1.0)')
Tim Peters8ac14952002-05-23 15:15:30 +0000717 _test_generator(N, 'gammavariate(0.1, 2.0)')
Tim Petersd7b5e882001-01-25 03:36:26 +0000718 _test_generator(N, 'gammavariate(0.5, 1.0)')
719 _test_generator(N, 'gammavariate(0.9, 1.0)')
720 _test_generator(N, 'gammavariate(1.0, 1.0)')
721 _test_generator(N, 'gammavariate(2.0, 1.0)')
722 _test_generator(N, 'gammavariate(20.0, 1.0)')
723 _test_generator(N, 'gammavariate(200.0, 1.0)')
724 _test_generator(N, 'gauss(0.0, 1.0)')
725 _test_generator(N, 'betavariate(3.0, 3.0)')
Tim Peterscd804102001-01-25 20:25:57 +0000726
Tim Peters715c4c42001-01-26 22:56:56 +0000727# Create one instance, seeded from current time, and export its methods
Raymond Hettinger40f62172002-12-29 23:03:38 +0000728# as module-level functions. The functions share state across all uses
729#(both in the user's code and in the Python libraries), but that's fine
730# for most programs and is easier for the casual user than making them
731# instantiate their own Random() instance.
732
Tim Petersd7b5e882001-01-25 03:36:26 +0000733_inst = Random()
734seed = _inst.seed
735random = _inst.random
736uniform = _inst.uniform
737randint = _inst.randint
738choice = _inst.choice
739randrange = _inst.randrange
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000740sample = _inst.sample
Tim Petersd7b5e882001-01-25 03:36:26 +0000741shuffle = _inst.shuffle
742normalvariate = _inst.normalvariate
743lognormvariate = _inst.lognormvariate
Tim Petersd7b5e882001-01-25 03:36:26 +0000744expovariate = _inst.expovariate
745vonmisesvariate = _inst.vonmisesvariate
746gammavariate = _inst.gammavariate
Tim Petersd7b5e882001-01-25 03:36:26 +0000747gauss = _inst.gauss
748betavariate = _inst.betavariate
749paretovariate = _inst.paretovariate
750weibullvariate = _inst.weibullvariate
751getstate = _inst.getstate
752setstate = _inst.setstate
Tim Petersd52269b2001-01-25 06:23:18 +0000753jumpahead = _inst.jumpahead
Tim Petersd7b5e882001-01-25 03:36:26 +0000754
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000755if __name__ == '__main__':
Tim Petersd7b5e882001-01-25 03:36:26 +0000756 _test()