blob: 2530c39ac76b633b0e1c594f71297eb1d52827cc [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 Hettinger3081d592003-08-09 18:30:57 +000097 if a is None:
98 import time
99 a = long(time.time() * 256) # use fractional seconds
Raymond Hettinger145a4a02003-01-07 10:25:55 +0000100 super(Random, self).seed(a)
Tim Peters46c04e12002-05-05 20:40:00 +0000101 self.gauss_next = None
102
Tim Peterscd804102001-01-25 20:25:57 +0000103 def getstate(self):
104 """Return internal state; can be passed to setstate() later."""
Raymond Hettinger145a4a02003-01-07 10:25:55 +0000105 return self.VERSION, super(Random, self).getstate(), self.gauss_next
Tim Peterscd804102001-01-25 20:25:57 +0000106
107 def setstate(self, state):
108 """Restore internal state from object returned by getstate()."""
109 version = state[0]
Raymond Hettinger40f62172002-12-29 23:03:38 +0000110 if version == 2:
111 version, internalstate, self.gauss_next = state
Raymond Hettinger145a4a02003-01-07 10:25:55 +0000112 super(Random, self).setstate(internalstate)
Tim Peterscd804102001-01-25 20:25:57 +0000113 else:
114 raise ValueError("state with version %s passed to "
115 "Random.setstate() of version %s" %
116 (version, self.VERSION))
117
Tim Peterscd804102001-01-25 20:25:57 +0000118## ---- Methods below this point do not need to be overridden when
119## ---- subclassing for the purpose of using a different core generator.
120
121## -------------------- pickle support -------------------
122
123 def __getstate__(self): # for pickle
124 return self.getstate()
125
126 def __setstate__(self, state): # for pickle
127 self.setstate(state)
128
Raymond Hettinger5f078ff2003-06-24 20:29:04 +0000129 def __reduce__(self):
130 return self.__class__, (), self.getstate()
131
Tim Peterscd804102001-01-25 20:25:57 +0000132## -------------------- integer methods -------------------
133
Tim Petersd7b5e882001-01-25 03:36:26 +0000134 def randrange(self, start, stop=None, step=1, int=int, default=None):
135 """Choose a random item from range(start, stop[, step]).
136
137 This fixes the problem with randint() which includes the
138 endpoint; in Python this is usually not what you want.
139 Do not supply the 'int' and 'default' arguments.
140 """
141
142 # This code is a bit messy to make it fast for the
Tim Peters9146f272002-08-16 03:41:39 +0000143 # common case while still doing adequate error checking.
Tim Petersd7b5e882001-01-25 03:36:26 +0000144 istart = int(start)
145 if istart != start:
146 raise ValueError, "non-integer arg 1 for randrange()"
147 if stop is default:
148 if istart > 0:
149 return int(self.random() * istart)
150 raise ValueError, "empty range for randrange()"
Tim Peters9146f272002-08-16 03:41:39 +0000151
152 # stop argument supplied.
Tim Petersd7b5e882001-01-25 03:36:26 +0000153 istop = int(stop)
154 if istop != stop:
155 raise ValueError, "non-integer stop for randrange()"
Tim Peters9146f272002-08-16 03:41:39 +0000156 if step == 1 and istart < istop:
Tim Peters76ca1d42003-06-19 03:46:46 +0000157 # Note that
158 # int(istart + self.random()*(istop - istart))
159 # instead would be incorrect. For example, consider istart
160 # = -2 and istop = 0. Then the guts would be in
161 # -2.0 to 0.0 exclusive on both ends (ignoring that random()
162 # might return 0.0), and because int() truncates toward 0, the
163 # final result would be -1 or 0 (instead of -2 or -1).
164 # istart + int(self.random()*(istop - istart))
165 # would also be incorrect, for a subtler reason: the RHS
166 # can return a long, and then randrange() would also return
167 # a long, but we're supposed to return an int (for backward
168 # compatibility).
169 return int(istart + int(self.random()*(istop - istart)))
Tim Petersd7b5e882001-01-25 03:36:26 +0000170 if step == 1:
Tim Petersd7b5e882001-01-25 03:36:26 +0000171 raise ValueError, "empty range for randrange()"
Tim Peters9146f272002-08-16 03:41:39 +0000172
173 # Non-unit step argument supplied.
Tim Petersd7b5e882001-01-25 03:36:26 +0000174 istep = int(step)
175 if istep != step:
176 raise ValueError, "non-integer step for randrange()"
177 if istep > 0:
178 n = (istop - istart + istep - 1) / istep
179 elif istep < 0:
180 n = (istop - istart + istep + 1) / istep
181 else:
182 raise ValueError, "zero step for randrange()"
183
184 if n <= 0:
185 raise ValueError, "empty range for randrange()"
186 return istart + istep*int(self.random() * n)
187
188 def randint(self, a, b):
Tim Peterscd804102001-01-25 20:25:57 +0000189 """Return random integer in range [a, b], including both end points.
Tim Petersd7b5e882001-01-25 03:36:26 +0000190 """
191
192 return self.randrange(a, b+1)
193
Tim Peterscd804102001-01-25 20:25:57 +0000194## -------------------- sequence methods -------------------
195
Tim Petersd7b5e882001-01-25 03:36:26 +0000196 def choice(self, seq):
197 """Choose a random element from a non-empty sequence."""
198 return seq[int(self.random() * len(seq))]
199
200 def shuffle(self, x, random=None, int=int):
201 """x, random=random.random -> shuffle list x in place; return None.
202
203 Optional arg random is a 0-argument function returning a random
204 float in [0.0, 1.0); by default, the standard random.random.
205
206 Note that for even rather small len(x), the total number of
207 permutations of x is larger than the period of most random number
208 generators; this implies that "most" permutations of a long
209 sequence can never be generated.
210 """
211
212 if random is None:
213 random = self.random
214 for i in xrange(len(x)-1, 0, -1):
Tim Peterscd804102001-01-25 20:25:57 +0000215 # pick an element in x[:i+1] with which to exchange x[i]
Tim Petersd7b5e882001-01-25 03:36:26 +0000216 j = int(random() * (i+1))
217 x[i], x[j] = x[j], x[i]
218
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000219 def sample(self, population, k):
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000220 """Chooses k unique random elements from a population sequence.
221
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000222 Returns a new list containing elements from the population while
223 leaving the original population unchanged. The resulting list is
224 in selection order so that all sub-slices will also be valid random
225 samples. This allows raffle winners (the sample) to be partitioned
226 into grand prize and second place winners (the subslices).
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000227
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000228 Members of the population need not be hashable or unique. If the
229 population contains repeats, then each occurrence is a possible
230 selection in the sample.
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000231
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000232 To choose a sample in a range of integers, use xrange as an argument.
233 This is especially fast and space efficient for sampling from a
234 large population: sample(xrange(10000000), 60)
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000235 """
236
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000237 # Sampling without replacement entails tracking either potential
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000238 # selections (the pool) in a list or previous selections in a
239 # dictionary.
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000240
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000241 # When the number of selections is small compared to the population,
242 # then tracking selections is efficient, requiring only a small
243 # dictionary and an occasional reselection. For a larger number of
244 # selections, the pool tracking method is preferred since the list takes
245 # less space than the dictionary and it doesn't suffer from frequent
246 # reselections.
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000247
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000248 n = len(population)
249 if not 0 <= k <= n:
250 raise ValueError, "sample larger than population"
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000251 random = self.random
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000252 _int = int
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000253 result = [None] * k
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000254 if n < 6 * k: # if n len list takes less space than a k len dict
Raymond Hettinger311f4192002-11-18 09:01:24 +0000255 pool = list(population)
256 for i in xrange(k): # invariant: non-selected at [0,n-i)
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000257 j = _int(random() * (n-i))
Raymond Hettinger311f4192002-11-18 09:01:24 +0000258 result[i] = pool[j]
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000259 pool[j] = pool[n-i-1] # move non-selected item into vacancy
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000260 else:
Raymond Hettinger66d09f12003-09-06 04:25:54 +0000261 try:
262 n > 0 and (population[0], population[n//2], population[n-1])
263 except (TypeError, KeyError): # handle sets and dictionaries
264 population = tuple(population)
Raymond Hettinger311f4192002-11-18 09:01:24 +0000265 selected = {}
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000266 for i in xrange(k):
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000267 j = _int(random() * n)
Raymond Hettinger311f4192002-11-18 09:01:24 +0000268 while j in selected:
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000269 j = _int(random() * n)
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000270 result[i] = selected[j] = population[j]
Raymond Hettinger311f4192002-11-18 09:01:24 +0000271 return result
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000272
Tim Peterscd804102001-01-25 20:25:57 +0000273## -------------------- real-valued distributions -------------------
274
275## -------------------- uniform distribution -------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000276
277 def uniform(self, a, b):
278 """Get a random number in the range [a, b)."""
279 return a + (b-a) * self.random()
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000280
Tim Peterscd804102001-01-25 20:25:57 +0000281## -------------------- normal distribution --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000282
Tim Petersd7b5e882001-01-25 03:36:26 +0000283 def normalvariate(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000284 """Normal distribution.
285
286 mu is the mean, and sigma is the standard deviation.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000287
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000288 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000289 # mu = mean, sigma = standard deviation
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000290
Tim Petersd7b5e882001-01-25 03:36:26 +0000291 # Uses Kinderman and Monahan method. Reference: Kinderman,
292 # A.J. and Monahan, J.F., "Computer generation of random
293 # variables using the ratio of uniform deviates", ACM Trans
294 # Math Software, 3, (1977), pp257-260.
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000295
Tim Petersd7b5e882001-01-25 03:36:26 +0000296 random = self.random
Raymond Hettinger311f4192002-11-18 09:01:24 +0000297 while True:
Tim Peters0c9886d2001-01-15 01:18:21 +0000298 u1 = random()
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000299 u2 = 1.0 - random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000300 z = NV_MAGICCONST*(u1-0.5)/u2
301 zz = z*z/4.0
302 if zz <= -_log(u2):
303 break
304 return mu + z*sigma
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000305
Tim Peterscd804102001-01-25 20:25:57 +0000306## -------------------- lognormal distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000307
308 def lognormvariate(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000309 """Log normal distribution.
310
311 If you take the natural logarithm of this distribution, you'll get a
312 normal distribution with mean mu and standard deviation sigma.
313 mu can have any value, and sigma must be greater than zero.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000314
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000315 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000316 return _exp(self.normalvariate(mu, sigma))
317
Tim Peterscd804102001-01-25 20:25:57 +0000318## -------------------- exponential distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000319
320 def expovariate(self, lambd):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000321 """Exponential distribution.
322
323 lambd is 1.0 divided by the desired mean. (The parameter would be
324 called "lambda", but that is a reserved word in Python.) Returned
325 values range from 0 to positive infinity.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000326
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000327 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000328 # lambd: rate lambd = 1/mean
329 # ('lambda' is a Python reserved word)
330
331 random = self.random
Tim Peters0c9886d2001-01-15 01:18:21 +0000332 u = random()
333 while u <= 1e-7:
334 u = random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000335 return -_log(u)/lambd
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000336
Tim Peterscd804102001-01-25 20:25:57 +0000337## -------------------- von Mises distribution --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000338
Tim Petersd7b5e882001-01-25 03:36:26 +0000339 def vonmisesvariate(self, mu, kappa):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000340 """Circular data distribution.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000341
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000342 mu is the mean angle, expressed in radians between 0 and 2*pi, and
343 kappa is the concentration parameter, which must be greater than or
344 equal to zero. If kappa is equal to zero, this distribution reduces
345 to a uniform random angle over the range 0 to 2*pi.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000346
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000347 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000348 # mu: mean angle (in radians between 0 and 2*pi)
349 # kappa: concentration parameter kappa (>= 0)
350 # if kappa = 0 generate uniform random angle
351
352 # Based upon an algorithm published in: Fisher, N.I.,
353 # "Statistical Analysis of Circular Data", Cambridge
354 # University Press, 1993.
355
356 # Thanks to Magnus Kessler for a correction to the
357 # implementation of step 4.
358
359 random = self.random
360 if kappa <= 1e-6:
361 return TWOPI * random()
362
363 a = 1.0 + _sqrt(1.0 + 4.0 * kappa * kappa)
364 b = (a - _sqrt(2.0 * a))/(2.0 * kappa)
365 r = (1.0 + b * b)/(2.0 * b)
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000366
Raymond Hettinger311f4192002-11-18 09:01:24 +0000367 while True:
Tim Peters0c9886d2001-01-15 01:18:21 +0000368 u1 = random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000369
370 z = _cos(_pi * u1)
371 f = (1.0 + r * z)/(r + z)
372 c = kappa * (r - f)
373
374 u2 = random()
375
376 if not (u2 >= c * (2.0 - c) and u2 > c * _exp(1.0 - c)):
Tim Peters0c9886d2001-01-15 01:18:21 +0000377 break
Tim Petersd7b5e882001-01-25 03:36:26 +0000378
379 u3 = random()
380 if u3 > 0.5:
381 theta = (mu % TWOPI) + _acos(f)
382 else:
383 theta = (mu % TWOPI) - _acos(f)
384
385 return theta
386
Tim Peterscd804102001-01-25 20:25:57 +0000387## -------------------- gamma distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000388
389 def gammavariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000390 """Gamma distribution. Not the gamma function!
391
392 Conditions on the parameters are alpha > 0 and beta > 0.
393
394 """
Tim Peters8ac14952002-05-23 15:15:30 +0000395
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000396 # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
Tim Peters8ac14952002-05-23 15:15:30 +0000397
Guido van Rossum570764d2002-05-14 14:08:12 +0000398 # Warning: a few older sources define the gamma distribution in terms
399 # of alpha > -1.0
400 if alpha <= 0.0 or beta <= 0.0:
401 raise ValueError, 'gammavariate: alpha and beta must be > 0.0'
Tim Peters8ac14952002-05-23 15:15:30 +0000402
Tim Petersd7b5e882001-01-25 03:36:26 +0000403 random = self.random
Tim Petersd7b5e882001-01-25 03:36:26 +0000404 if alpha > 1.0:
405
406 # Uses R.C.H. Cheng, "The generation of Gamma
407 # variables with non-integral shape parameters",
408 # Applied Statistics, (1977), 26, No. 1, p71-74
409
Raymond Hettingerca6cdc22002-05-13 23:40:14 +0000410 ainv = _sqrt(2.0 * alpha - 1.0)
411 bbb = alpha - LOG4
412 ccc = alpha + ainv
Tim Peters8ac14952002-05-23 15:15:30 +0000413
Raymond Hettinger311f4192002-11-18 09:01:24 +0000414 while True:
Tim Petersd7b5e882001-01-25 03:36:26 +0000415 u1 = random()
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000416 if not 1e-7 < u1 < .9999999:
417 continue
418 u2 = 1.0 - random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000419 v = _log(u1/(1.0-u1))/ainv
420 x = alpha*_exp(v)
421 z = u1*u1*u2
422 r = bbb+ccc*v-x
423 if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z):
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000424 return x * beta
Tim Petersd7b5e882001-01-25 03:36:26 +0000425
426 elif alpha == 1.0:
427 # expovariate(1)
428 u = random()
429 while u <= 1e-7:
430 u = random()
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000431 return -_log(u) * beta
Tim Petersd7b5e882001-01-25 03:36:26 +0000432
433 else: # alpha is between 0 and 1 (exclusive)
434
435 # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
436
Raymond Hettinger311f4192002-11-18 09:01:24 +0000437 while True:
Tim Petersd7b5e882001-01-25 03:36:26 +0000438 u = random()
439 b = (_e + alpha)/_e
440 p = b*u
441 if p <= 1.0:
442 x = pow(p, 1.0/alpha)
443 else:
444 # p > 1
445 x = -_log((b-p)/alpha)
446 u1 = random()
447 if not (((p <= 1.0) and (u1 > _exp(-x))) or
448 ((p > 1) and (u1 > pow(x, alpha - 1.0)))):
449 break
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000450 return x * beta
451
Tim Peterscd804102001-01-25 20:25:57 +0000452## -------------------- Gauss (faster alternative) --------------------
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000453
Tim Petersd7b5e882001-01-25 03:36:26 +0000454 def gauss(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000455 """Gaussian distribution.
456
457 mu is the mean, and sigma is the standard deviation. This is
458 slightly faster than the normalvariate() function.
459
460 Not thread-safe without a lock around calls.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000461
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000462 """
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000463
Tim Petersd7b5e882001-01-25 03:36:26 +0000464 # When x and y are two variables from [0, 1), uniformly
465 # distributed, then
466 #
467 # cos(2*pi*x)*sqrt(-2*log(1-y))
468 # sin(2*pi*x)*sqrt(-2*log(1-y))
469 #
470 # are two *independent* variables with normal distribution
471 # (mu = 0, sigma = 1).
472 # (Lambert Meertens)
473 # (corrected version; bug discovered by Mike Miller, fixed by LM)
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000474
Tim Petersd7b5e882001-01-25 03:36:26 +0000475 # Multithreading note: When two threads call this function
476 # simultaneously, it is possible that they will receive the
477 # same return value. The window is very small though. To
478 # avoid this, you have to use a lock around all calls. (I
479 # didn't want to slow this down in the serial case by using a
480 # lock here.)
Guido van Rossumd03e1191998-05-29 17:51:31 +0000481
Tim Petersd7b5e882001-01-25 03:36:26 +0000482 random = self.random
483 z = self.gauss_next
484 self.gauss_next = None
485 if z is None:
486 x2pi = random() * TWOPI
487 g2rad = _sqrt(-2.0 * _log(1.0 - random()))
488 z = _cos(x2pi) * g2rad
489 self.gauss_next = _sin(x2pi) * g2rad
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000490
Tim Petersd7b5e882001-01-25 03:36:26 +0000491 return mu + z*sigma
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000492
Tim Peterscd804102001-01-25 20:25:57 +0000493## -------------------- beta --------------------
Tim Peters85e2e472001-01-26 06:49:56 +0000494## See
495## http://sourceforge.net/bugs/?func=detailbug&bug_id=130030&group_id=5470
496## for Ivan Frohne's insightful analysis of why the original implementation:
497##
498## def betavariate(self, alpha, beta):
499## # Discrete Event Simulation in C, pp 87-88.
500##
501## y = self.expovariate(alpha)
502## z = self.expovariate(1.0/beta)
503## return z/(y+z)
504##
505## was dead wrong, and how it probably got that way.
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000506
Tim Petersd7b5e882001-01-25 03:36:26 +0000507 def betavariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000508 """Beta distribution.
509
510 Conditions on the parameters are alpha > -1 and beta} > -1.
511 Returned values range between 0 and 1.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000512
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000513 """
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000514
Tim Peters85e2e472001-01-26 06:49:56 +0000515 # This version due to Janne Sinkkonen, and matches all the std
516 # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
517 y = self.gammavariate(alpha, 1.)
518 if y == 0:
519 return 0.0
520 else:
521 return y / (y + self.gammavariate(beta, 1.))
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000522
Tim Peterscd804102001-01-25 20:25:57 +0000523## -------------------- Pareto --------------------
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000524
Tim Petersd7b5e882001-01-25 03:36:26 +0000525 def paretovariate(self, alpha):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000526 """Pareto distribution. alpha is the shape parameter."""
Tim Petersd7b5e882001-01-25 03:36:26 +0000527 # Jain, pg. 495
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000528
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000529 u = 1.0 - self.random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000530 return 1.0 / pow(u, 1.0/alpha)
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000531
Tim Peterscd804102001-01-25 20:25:57 +0000532## -------------------- Weibull --------------------
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000533
Tim Petersd7b5e882001-01-25 03:36:26 +0000534 def weibullvariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000535 """Weibull distribution.
536
537 alpha is the scale parameter and beta is the shape parameter.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000538
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000539 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000540 # Jain, pg. 499; bug fix courtesy Bill Arms
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000541
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000542 u = 1.0 - self.random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000543 return alpha * pow(-_log(u), 1.0/beta)
Guido van Rossum6c395ba1999-08-18 13:53:28 +0000544
Raymond Hettinger40f62172002-12-29 23:03:38 +0000545## -------------------- Wichmann-Hill -------------------
546
547class WichmannHill(Random):
548
549 VERSION = 1 # used by getstate/setstate
550
551 def seed(self, a=None):
552 """Initialize internal state from hashable object.
553
554 None or no argument seeds from current time.
555
556 If a is not None or an int or long, hash(a) is used instead.
557
558 If a is an int or long, a is used directly. Distinct values between
559 0 and 27814431486575L inclusive are guaranteed to yield distinct
560 internal states (this guarantee is specific to the default
561 Wichmann-Hill generator).
562 """
563
564 if a is None:
565 # Initialize from current time
566 import time
567 a = long(time.time() * 256)
568
569 if not isinstance(a, (int, long)):
570 a = hash(a)
571
572 a, x = divmod(a, 30268)
573 a, y = divmod(a, 30306)
574 a, z = divmod(a, 30322)
575 self._seed = int(x)+1, int(y)+1, int(z)+1
576
577 self.gauss_next = None
578
579 def random(self):
580 """Get the next random number in the range [0.0, 1.0)."""
581
582 # Wichman-Hill random number generator.
583 #
584 # Wichmann, B. A. & Hill, I. D. (1982)
585 # Algorithm AS 183:
586 # An efficient and portable pseudo-random number generator
587 # Applied Statistics 31 (1982) 188-190
588 #
589 # see also:
590 # Correction to Algorithm AS 183
591 # Applied Statistics 33 (1984) 123
592 #
593 # McLeod, A. I. (1985)
594 # A remark on Algorithm AS 183
595 # Applied Statistics 34 (1985),198-200
596
597 # This part is thread-unsafe:
598 # BEGIN CRITICAL SECTION
599 x, y, z = self._seed
600 x = (171 * x) % 30269
601 y = (172 * y) % 30307
602 z = (170 * z) % 30323
603 self._seed = x, y, z
604 # END CRITICAL SECTION
605
606 # Note: on a platform using IEEE-754 double arithmetic, this can
607 # never return 0.0 (asserted by Tim; proof too long for a comment).
608 return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0
609
610 def getstate(self):
611 """Return internal state; can be passed to setstate() later."""
612 return self.VERSION, self._seed, self.gauss_next
613
614 def setstate(self, state):
615 """Restore internal state from object returned by getstate()."""
616 version = state[0]
617 if version == 1:
618 version, self._seed, self.gauss_next = state
619 else:
620 raise ValueError("state with version %s passed to "
621 "Random.setstate() of version %s" %
622 (version, self.VERSION))
623
624 def jumpahead(self, n):
625 """Act as if n calls to random() were made, but quickly.
626
627 n is an int, greater than or equal to 0.
628
629 Example use: If you have 2 threads and know that each will
630 consume no more than a million random numbers, create two Random
631 objects r1 and r2, then do
632 r2.setstate(r1.getstate())
633 r2.jumpahead(1000000)
634 Then r1 and r2 will use guaranteed-disjoint segments of the full
635 period.
636 """
637
638 if not n >= 0:
639 raise ValueError("n must be >= 0")
640 x, y, z = self._seed
641 x = int(x * pow(171, n, 30269)) % 30269
642 y = int(y * pow(172, n, 30307)) % 30307
643 z = int(z * pow(170, n, 30323)) % 30323
644 self._seed = x, y, z
645
646 def __whseed(self, x=0, y=0, z=0):
647 """Set the Wichmann-Hill seed from (x, y, z).
648
649 These must be integers in the range [0, 256).
650 """
651
652 if not type(x) == type(y) == type(z) == int:
653 raise TypeError('seeds must be integers')
654 if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256):
655 raise ValueError('seeds must be in range(0, 256)')
656 if 0 == x == y == z:
657 # Initialize from current time
658 import time
659 t = long(time.time() * 256)
660 t = int((t&0xffffff) ^ (t>>24))
661 t, x = divmod(t, 256)
662 t, y = divmod(t, 256)
663 t, z = divmod(t, 256)
664 # Zero is a poor seed, so substitute 1
665 self._seed = (x or 1, y or 1, z or 1)
666
667 self.gauss_next = None
668
669 def whseed(self, a=None):
670 """Seed from hashable object's hash code.
671
672 None or no argument seeds from current time. It is not guaranteed
673 that objects with distinct hash codes lead to distinct internal
674 states.
675
676 This is obsolete, provided for compatibility with the seed routine
677 used prior to Python 2.1. Use the .seed() method instead.
678 """
679
680 if a is None:
681 self.__whseed()
682 return
683 a = hash(a)
684 a, x = divmod(a, 256)
685 a, y = divmod(a, 256)
686 a, z = divmod(a, 256)
687 x = (x + a) % 256 or 1
688 y = (y + a) % 256 or 1
689 z = (z + a) % 256 or 1
690 self.__whseed(x, y, z)
691
Tim Peterscd804102001-01-25 20:25:57 +0000692## -------------------- test program --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000693
Raymond Hettinger62297132003-08-30 01:24:19 +0000694def _test_generator(n, func, args):
Tim Peters0c9886d2001-01-15 01:18:21 +0000695 import time
Raymond Hettinger62297132003-08-30 01:24:19 +0000696 print n, 'times', func.__name__
Raymond Hettingerb98154e2003-05-24 17:26:02 +0000697 total = 0.0
Tim Peters0c9886d2001-01-15 01:18:21 +0000698 sqsum = 0.0
699 smallest = 1e10
700 largest = -1e10
701 t0 = time.time()
702 for i in range(n):
Raymond Hettinger62297132003-08-30 01:24:19 +0000703 x = func(*args)
Raymond Hettingerb98154e2003-05-24 17:26:02 +0000704 total += x
Tim Peters0c9886d2001-01-15 01:18:21 +0000705 sqsum = sqsum + x*x
706 smallest = min(x, smallest)
707 largest = max(x, largest)
708 t1 = time.time()
709 print round(t1-t0, 3), 'sec,',
Raymond Hettingerb98154e2003-05-24 17:26:02 +0000710 avg = total/n
Tim Petersd7b5e882001-01-25 03:36:26 +0000711 stddev = _sqrt(sqsum/n - avg*avg)
Tim Peters0c9886d2001-01-15 01:18:21 +0000712 print 'avg %g, stddev %g, min %g, max %g' % \
713 (avg, stddev, smallest, largest)
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000714
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000715
716def _test(N=2000):
Raymond Hettinger62297132003-08-30 01:24:19 +0000717 _test_generator(N, random, ())
718 _test_generator(N, normalvariate, (0.0, 1.0))
719 _test_generator(N, lognormvariate, (0.0, 1.0))
720 _test_generator(N, vonmisesvariate, (0.0, 1.0))
721 _test_generator(N, gammavariate, (0.01, 1.0))
722 _test_generator(N, gammavariate, (0.1, 1.0))
723 _test_generator(N, gammavariate, (0.1, 2.0))
724 _test_generator(N, gammavariate, (0.5, 1.0))
725 _test_generator(N, gammavariate, (0.9, 1.0))
726 _test_generator(N, gammavariate, (1.0, 1.0))
727 _test_generator(N, gammavariate, (2.0, 1.0))
728 _test_generator(N, gammavariate, (20.0, 1.0))
729 _test_generator(N, gammavariate, (200.0, 1.0))
730 _test_generator(N, gauss, (0.0, 1.0))
731 _test_generator(N, betavariate, (3.0, 3.0))
Tim Peterscd804102001-01-25 20:25:57 +0000732
Tim Peters715c4c42001-01-26 22:56:56 +0000733# Create one instance, seeded from current time, and export its methods
Raymond Hettinger40f62172002-12-29 23:03:38 +0000734# as module-level functions. The functions share state across all uses
735#(both in the user's code and in the Python libraries), but that's fine
736# for most programs and is easier for the casual user than making them
737# instantiate their own Random() instance.
738
Tim Petersd7b5e882001-01-25 03:36:26 +0000739_inst = Random()
740seed = _inst.seed
741random = _inst.random
742uniform = _inst.uniform
743randint = _inst.randint
744choice = _inst.choice
745randrange = _inst.randrange
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000746sample = _inst.sample
Tim Petersd7b5e882001-01-25 03:36:26 +0000747shuffle = _inst.shuffle
748normalvariate = _inst.normalvariate
749lognormvariate = _inst.lognormvariate
Tim Petersd7b5e882001-01-25 03:36:26 +0000750expovariate = _inst.expovariate
751vonmisesvariate = _inst.vonmisesvariate
752gammavariate = _inst.gammavariate
Tim Petersd7b5e882001-01-25 03:36:26 +0000753gauss = _inst.gauss
754betavariate = _inst.betavariate
755paretovariate = _inst.paretovariate
756weibullvariate = _inst.weibullvariate
757getstate = _inst.getstate
758setstate = _inst.setstate
Tim Petersd52269b2001-01-25 06:23:18 +0000759jumpahead = _inst.jumpahead
Tim Petersd7b5e882001-01-25 03:36:26 +0000760
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000761if __name__ == '__main__':
Tim Petersd7b5e882001-01-25 03:36:26 +0000762 _test()