blob: 0937ba20dc010dc75e3e3dfb777d7ba490056633 [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",
48 "cunifvariate","expovariate","vonmisesvariate","gammavariate",
49 "stdgamma","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
126## -------------------- integer methods -------------------
127
Tim Petersd7b5e882001-01-25 03:36:26 +0000128 def randrange(self, start, stop=None, step=1, int=int, default=None):
129 """Choose a random item from range(start, stop[, step]).
130
131 This fixes the problem with randint() which includes the
132 endpoint; in Python this is usually not what you want.
133 Do not supply the 'int' and 'default' arguments.
134 """
135
136 # This code is a bit messy to make it fast for the
Tim Peters9146f272002-08-16 03:41:39 +0000137 # common case while still doing adequate error checking.
Tim Petersd7b5e882001-01-25 03:36:26 +0000138 istart = int(start)
139 if istart != start:
140 raise ValueError, "non-integer arg 1 for randrange()"
141 if stop is default:
142 if istart > 0:
143 return int(self.random() * istart)
144 raise ValueError, "empty range for randrange()"
Tim Peters9146f272002-08-16 03:41:39 +0000145
146 # stop argument supplied.
Tim Petersd7b5e882001-01-25 03:36:26 +0000147 istop = int(stop)
148 if istop != stop:
149 raise ValueError, "non-integer stop for randrange()"
Tim Peters9146f272002-08-16 03:41:39 +0000150 if step == 1 and istart < istop:
Tim Petersafb89792003-06-19 03:23:06 +0000151 return int(istart + self.random()*(istop - istart))
Tim Petersd7b5e882001-01-25 03:36:26 +0000152 if step == 1:
Tim Petersd7b5e882001-01-25 03:36:26 +0000153 raise ValueError, "empty range for randrange()"
Tim Peters9146f272002-08-16 03:41:39 +0000154
155 # Non-unit step argument supplied.
Tim Petersd7b5e882001-01-25 03:36:26 +0000156 istep = int(step)
157 if istep != step:
158 raise ValueError, "non-integer step for randrange()"
159 if istep > 0:
160 n = (istop - istart + istep - 1) / istep
161 elif istep < 0:
162 n = (istop - istart + istep + 1) / istep
163 else:
164 raise ValueError, "zero step for randrange()"
165
166 if n <= 0:
167 raise ValueError, "empty range for randrange()"
168 return istart + istep*int(self.random() * n)
169
170 def randint(self, a, b):
Tim Peterscd804102001-01-25 20:25:57 +0000171 """Return random integer in range [a, b], including both end points.
Tim Petersd7b5e882001-01-25 03:36:26 +0000172 """
173
174 return self.randrange(a, b+1)
175
Tim Peterscd804102001-01-25 20:25:57 +0000176## -------------------- sequence methods -------------------
177
Tim Petersd7b5e882001-01-25 03:36:26 +0000178 def choice(self, seq):
179 """Choose a random element from a non-empty sequence."""
180 return seq[int(self.random() * len(seq))]
181
182 def shuffle(self, x, random=None, int=int):
183 """x, random=random.random -> shuffle list x in place; return None.
184
185 Optional arg random is a 0-argument function returning a random
186 float in [0.0, 1.0); by default, the standard random.random.
187
188 Note that for even rather small len(x), the total number of
189 permutations of x is larger than the period of most random number
190 generators; this implies that "most" permutations of a long
191 sequence can never be generated.
192 """
193
194 if random is None:
195 random = self.random
196 for i in xrange(len(x)-1, 0, -1):
Tim Peterscd804102001-01-25 20:25:57 +0000197 # pick an element in x[:i+1] with which to exchange x[i]
Tim Petersd7b5e882001-01-25 03:36:26 +0000198 j = int(random() * (i+1))
199 x[i], x[j] = x[j], x[i]
200
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000201 def sample(self, population, k):
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000202 """Chooses k unique random elements from a population sequence.
203
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000204 Returns a new list containing elements from the population while
205 leaving the original population unchanged. The resulting list is
206 in selection order so that all sub-slices will also be valid random
207 samples. This allows raffle winners (the sample) to be partitioned
208 into grand prize and second place winners (the subslices).
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000209
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000210 Members of the population need not be hashable or unique. If the
211 population contains repeats, then each occurrence is a possible
212 selection in the sample.
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000213
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000214 To choose a sample in a range of integers, use xrange as an argument.
215 This is especially fast and space efficient for sampling from a
216 large population: sample(xrange(10000000), 60)
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000217 """
218
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000219 # Sampling without replacement entails tracking either potential
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000220 # selections (the pool) in a list or previous selections in a
221 # dictionary.
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000222
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000223 # When the number of selections is small compared to the population,
224 # then tracking selections is efficient, requiring only a small
225 # dictionary and an occasional reselection. For a larger number of
226 # selections, the pool tracking method is preferred since the list takes
227 # less space than the dictionary and it doesn't suffer from frequent
228 # reselections.
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000229
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000230 n = len(population)
231 if not 0 <= k <= n:
232 raise ValueError, "sample larger than population"
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000233 random = self.random
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000234 _int = int
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000235 result = [None] * k
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000236 if n < 6 * k: # if n len list takes less space than a k len dict
Raymond Hettinger311f4192002-11-18 09:01:24 +0000237 pool = list(population)
238 for i in xrange(k): # invariant: non-selected at [0,n-i)
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000239 j = _int(random() * (n-i))
Raymond Hettinger311f4192002-11-18 09:01:24 +0000240 result[i] = pool[j]
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000241 pool[j] = pool[n-i-1] # move non-selected item into vacancy
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000242 else:
Raymond Hettinger311f4192002-11-18 09:01:24 +0000243 selected = {}
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000244 for i in xrange(k):
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000245 j = _int(random() * n)
Raymond Hettinger311f4192002-11-18 09:01:24 +0000246 while j in selected:
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000247 j = _int(random() * n)
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000248 result[i] = selected[j] = population[j]
Raymond Hettinger311f4192002-11-18 09:01:24 +0000249 return result
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000250
Tim Peterscd804102001-01-25 20:25:57 +0000251## -------------------- real-valued distributions -------------------
252
253## -------------------- uniform distribution -------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000254
255 def uniform(self, a, b):
256 """Get a random number in the range [a, b)."""
257 return a + (b-a) * self.random()
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000258
Tim Peterscd804102001-01-25 20:25:57 +0000259## -------------------- normal distribution --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000260
Tim Petersd7b5e882001-01-25 03:36:26 +0000261 def normalvariate(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000262 """Normal distribution.
263
264 mu is the mean, and sigma is the standard deviation.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000265
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000266 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000267 # mu = mean, sigma = standard deviation
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000268
Tim Petersd7b5e882001-01-25 03:36:26 +0000269 # Uses Kinderman and Monahan method. Reference: Kinderman,
270 # A.J. and Monahan, J.F., "Computer generation of random
271 # variables using the ratio of uniform deviates", ACM Trans
272 # Math Software, 3, (1977), pp257-260.
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000273
Tim Petersd7b5e882001-01-25 03:36:26 +0000274 random = self.random
Raymond Hettinger311f4192002-11-18 09:01:24 +0000275 while True:
Tim Peters0c9886d2001-01-15 01:18:21 +0000276 u1 = random()
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000277 u2 = 1.0 - random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000278 z = NV_MAGICCONST*(u1-0.5)/u2
279 zz = z*z/4.0
280 if zz <= -_log(u2):
281 break
282 return mu + z*sigma
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000283
Tim Peterscd804102001-01-25 20:25:57 +0000284## -------------------- lognormal distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000285
286 def lognormvariate(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000287 """Log normal distribution.
288
289 If you take the natural logarithm of this distribution, you'll get a
290 normal distribution with mean mu and standard deviation sigma.
291 mu can have any value, and sigma must be greater than zero.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000292
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000293 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000294 return _exp(self.normalvariate(mu, sigma))
295
Tim Peterscd804102001-01-25 20:25:57 +0000296## -------------------- circular uniform --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000297
298 def cunifvariate(self, mean, arc):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000299 """Circular uniform distribution.
300
301 mean is the mean angle, and arc is the range of the distribution,
302 centered around the mean angle. Both values must be expressed in
303 radians. Returned values range between mean - arc/2 and
304 mean + arc/2 and are normalized to between 0 and pi.
305
306 Deprecated in version 2.3. Use:
307 (mean + arc * (Random.random() - 0.5)) % Math.pi
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000308
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000309 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000310 # mean: mean angle (in radians between 0 and pi)
311 # arc: range of distribution (in radians between 0 and pi)
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000312 import warnings
313 warnings.warn("The cunifvariate function is deprecated; Use (mean "
314 "+ arc * (Random.random() - 0.5)) % Math.pi instead",
315 DeprecationWarning)
Tim Petersd7b5e882001-01-25 03:36:26 +0000316
317 return (mean + arc * (self.random() - 0.5)) % _pi
318
Tim Peterscd804102001-01-25 20:25:57 +0000319## -------------------- exponential distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000320
321 def expovariate(self, lambd):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000322 """Exponential distribution.
323
324 lambd is 1.0 divided by the desired mean. (The parameter would be
325 called "lambda", but that is a reserved word in Python.) Returned
326 values range from 0 to positive infinity.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000327
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000328 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000329 # lambd: rate lambd = 1/mean
330 # ('lambda' is a Python reserved word)
331
332 random = self.random
Tim Peters0c9886d2001-01-15 01:18:21 +0000333 u = random()
334 while u <= 1e-7:
335 u = random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000336 return -_log(u)/lambd
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000337
Tim Peterscd804102001-01-25 20:25:57 +0000338## -------------------- von Mises distribution --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000339
Tim Petersd7b5e882001-01-25 03:36:26 +0000340 def vonmisesvariate(self, mu, kappa):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000341 """Circular data distribution.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000342
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000343 mu is the mean angle, expressed in radians between 0 and 2*pi, and
344 kappa is the concentration parameter, which must be greater than or
345 equal to zero. If kappa is equal to zero, this distribution reduces
346 to a uniform random angle over the range 0 to 2*pi.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000347
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000348 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000349 # mu: mean angle (in radians between 0 and 2*pi)
350 # kappa: concentration parameter kappa (>= 0)
351 # if kappa = 0 generate uniform random angle
352
353 # Based upon an algorithm published in: Fisher, N.I.,
354 # "Statistical Analysis of Circular Data", Cambridge
355 # University Press, 1993.
356
357 # Thanks to Magnus Kessler for a correction to the
358 # implementation of step 4.
359
360 random = self.random
361 if kappa <= 1e-6:
362 return TWOPI * random()
363
364 a = 1.0 + _sqrt(1.0 + 4.0 * kappa * kappa)
365 b = (a - _sqrt(2.0 * a))/(2.0 * kappa)
366 r = (1.0 + b * b)/(2.0 * b)
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000367
Raymond Hettinger311f4192002-11-18 09:01:24 +0000368 while True:
Tim Peters0c9886d2001-01-15 01:18:21 +0000369 u1 = random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000370
371 z = _cos(_pi * u1)
372 f = (1.0 + r * z)/(r + z)
373 c = kappa * (r - f)
374
375 u2 = random()
376
377 if not (u2 >= c * (2.0 - c) and u2 > c * _exp(1.0 - c)):
Tim Peters0c9886d2001-01-15 01:18:21 +0000378 break
Tim Petersd7b5e882001-01-25 03:36:26 +0000379
380 u3 = random()
381 if u3 > 0.5:
382 theta = (mu % TWOPI) + _acos(f)
383 else:
384 theta = (mu % TWOPI) - _acos(f)
385
386 return theta
387
Tim Peterscd804102001-01-25 20:25:57 +0000388## -------------------- gamma distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000389
390 def gammavariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000391 """Gamma distribution. Not the gamma function!
392
393 Conditions on the parameters are alpha > 0 and beta > 0.
394
395 """
Tim Peters8ac14952002-05-23 15:15:30 +0000396
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000397 # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
Tim Peters8ac14952002-05-23 15:15:30 +0000398
Guido van Rossum570764d2002-05-14 14:08:12 +0000399 # Warning: a few older sources define the gamma distribution in terms
400 # of alpha > -1.0
401 if alpha <= 0.0 or beta <= 0.0:
402 raise ValueError, 'gammavariate: alpha and beta must be > 0.0'
Tim Peters8ac14952002-05-23 15:15:30 +0000403
Tim Petersd7b5e882001-01-25 03:36:26 +0000404 random = self.random
Tim Petersd7b5e882001-01-25 03:36:26 +0000405 if alpha > 1.0:
406
407 # Uses R.C.H. Cheng, "The generation of Gamma
408 # variables with non-integral shape parameters",
409 # Applied Statistics, (1977), 26, No. 1, p71-74
410
Raymond Hettingerca6cdc22002-05-13 23:40:14 +0000411 ainv = _sqrt(2.0 * alpha - 1.0)
412 bbb = alpha - LOG4
413 ccc = alpha + ainv
Tim Peters8ac14952002-05-23 15:15:30 +0000414
Raymond Hettinger311f4192002-11-18 09:01:24 +0000415 while True:
Tim Petersd7b5e882001-01-25 03:36:26 +0000416 u1 = random()
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000417 if not 1e-7 < u1 < .9999999:
418 continue
419 u2 = 1.0 - random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000420 v = _log(u1/(1.0-u1))/ainv
421 x = alpha*_exp(v)
422 z = u1*u1*u2
423 r = bbb+ccc*v-x
424 if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z):
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000425 return x * beta
Tim Petersd7b5e882001-01-25 03:36:26 +0000426
427 elif alpha == 1.0:
428 # expovariate(1)
429 u = random()
430 while u <= 1e-7:
431 u = random()
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000432 return -_log(u) * beta
Tim Petersd7b5e882001-01-25 03:36:26 +0000433
434 else: # alpha is between 0 and 1 (exclusive)
435
436 # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
437
Raymond Hettinger311f4192002-11-18 09:01:24 +0000438 while True:
Tim Petersd7b5e882001-01-25 03:36:26 +0000439 u = random()
440 b = (_e + alpha)/_e
441 p = b*u
442 if p <= 1.0:
443 x = pow(p, 1.0/alpha)
444 else:
445 # p > 1
446 x = -_log((b-p)/alpha)
447 u1 = random()
448 if not (((p <= 1.0) and (u1 > _exp(-x))) or
449 ((p > 1) and (u1 > pow(x, alpha - 1.0)))):
450 break
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000451 return x * beta
452
453
454 def stdgamma(self, alpha, ainv, bbb, ccc):
455 # This method was (and shall remain) undocumented.
456 # This method is deprecated
457 # for the following reasons:
458 # 1. Returns same as .gammavariate(alpha, 1.0)
459 # 2. Requires caller to provide 3 extra arguments
460 # that are functions of alpha anyway
461 # 3. Can't be used for alpha < 0.5
462
463 # ainv = sqrt(2 * alpha - 1)
464 # bbb = alpha - log(4)
465 # ccc = alpha + ainv
466 import warnings
467 warnings.warn("The stdgamma function is deprecated; "
468 "use gammavariate() instead",
469 DeprecationWarning)
470 return self.gammavariate(alpha, 1.0)
471
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000472
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000473
Tim Peterscd804102001-01-25 20:25:57 +0000474## -------------------- Gauss (faster alternative) --------------------
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000475
Tim Petersd7b5e882001-01-25 03:36:26 +0000476 def gauss(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000477 """Gaussian distribution.
478
479 mu is the mean, and sigma is the standard deviation. This is
480 slightly faster than the normalvariate() function.
481
482 Not thread-safe without a lock around calls.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000483
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000484 """
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000485
Tim Petersd7b5e882001-01-25 03:36:26 +0000486 # When x and y are two variables from [0, 1), uniformly
487 # distributed, then
488 #
489 # cos(2*pi*x)*sqrt(-2*log(1-y))
490 # sin(2*pi*x)*sqrt(-2*log(1-y))
491 #
492 # are two *independent* variables with normal distribution
493 # (mu = 0, sigma = 1).
494 # (Lambert Meertens)
495 # (corrected version; bug discovered by Mike Miller, fixed by LM)
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000496
Tim Petersd7b5e882001-01-25 03:36:26 +0000497 # Multithreading note: When two threads call this function
498 # simultaneously, it is possible that they will receive the
499 # same return value. The window is very small though. To
500 # avoid this, you have to use a lock around all calls. (I
501 # didn't want to slow this down in the serial case by using a
502 # lock here.)
Guido van Rossumd03e1191998-05-29 17:51:31 +0000503
Tim Petersd7b5e882001-01-25 03:36:26 +0000504 random = self.random
505 z = self.gauss_next
506 self.gauss_next = None
507 if z is None:
508 x2pi = random() * TWOPI
509 g2rad = _sqrt(-2.0 * _log(1.0 - random()))
510 z = _cos(x2pi) * g2rad
511 self.gauss_next = _sin(x2pi) * g2rad
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000512
Tim Petersd7b5e882001-01-25 03:36:26 +0000513 return mu + z*sigma
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000514
Tim Peterscd804102001-01-25 20:25:57 +0000515## -------------------- beta --------------------
Tim Peters85e2e472001-01-26 06:49:56 +0000516## See
517## http://sourceforge.net/bugs/?func=detailbug&bug_id=130030&group_id=5470
518## for Ivan Frohne's insightful analysis of why the original implementation:
519##
520## def betavariate(self, alpha, beta):
521## # Discrete Event Simulation in C, pp 87-88.
522##
523## y = self.expovariate(alpha)
524## z = self.expovariate(1.0/beta)
525## return z/(y+z)
526##
527## was dead wrong, and how it probably got that way.
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000528
Tim Petersd7b5e882001-01-25 03:36:26 +0000529 def betavariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000530 """Beta distribution.
531
532 Conditions on the parameters are alpha > -1 and beta} > -1.
533 Returned values range between 0 and 1.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000534
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000535 """
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000536
Tim Peters85e2e472001-01-26 06:49:56 +0000537 # This version due to Janne Sinkkonen, and matches all the std
538 # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
539 y = self.gammavariate(alpha, 1.)
540 if y == 0:
541 return 0.0
542 else:
543 return y / (y + self.gammavariate(beta, 1.))
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000544
Tim Peterscd804102001-01-25 20:25:57 +0000545## -------------------- Pareto --------------------
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000546
Tim Petersd7b5e882001-01-25 03:36:26 +0000547 def paretovariate(self, alpha):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000548 """Pareto distribution. alpha is the shape parameter."""
Tim Petersd7b5e882001-01-25 03:36:26 +0000549 # Jain, pg. 495
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000550
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000551 u = 1.0 - self.random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000552 return 1.0 / pow(u, 1.0/alpha)
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000553
Tim Peterscd804102001-01-25 20:25:57 +0000554## -------------------- Weibull --------------------
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000555
Tim Petersd7b5e882001-01-25 03:36:26 +0000556 def weibullvariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000557 """Weibull distribution.
558
559 alpha is the scale parameter and beta is the shape parameter.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000560
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000561 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000562 # Jain, pg. 499; bug fix courtesy Bill Arms
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000563
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000564 u = 1.0 - self.random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000565 return alpha * pow(-_log(u), 1.0/beta)
Guido van Rossum6c395ba1999-08-18 13:53:28 +0000566
Raymond Hettinger40f62172002-12-29 23:03:38 +0000567## -------------------- Wichmann-Hill -------------------
568
569class WichmannHill(Random):
570
571 VERSION = 1 # used by getstate/setstate
572
573 def seed(self, a=None):
574 """Initialize internal state from hashable object.
575
576 None or no argument seeds from current time.
577
578 If a is not None or an int or long, hash(a) is used instead.
579
580 If a is an int or long, a is used directly. Distinct values between
581 0 and 27814431486575L inclusive are guaranteed to yield distinct
582 internal states (this guarantee is specific to the default
583 Wichmann-Hill generator).
584 """
585
586 if a is None:
587 # Initialize from current time
588 import time
589 a = long(time.time() * 256)
590
591 if not isinstance(a, (int, long)):
592 a = hash(a)
593
594 a, x = divmod(a, 30268)
595 a, y = divmod(a, 30306)
596 a, z = divmod(a, 30322)
597 self._seed = int(x)+1, int(y)+1, int(z)+1
598
599 self.gauss_next = None
600
601 def random(self):
602 """Get the next random number in the range [0.0, 1.0)."""
603
604 # Wichman-Hill random number generator.
605 #
606 # Wichmann, B. A. & Hill, I. D. (1982)
607 # Algorithm AS 183:
608 # An efficient and portable pseudo-random number generator
609 # Applied Statistics 31 (1982) 188-190
610 #
611 # see also:
612 # Correction to Algorithm AS 183
613 # Applied Statistics 33 (1984) 123
614 #
615 # McLeod, A. I. (1985)
616 # A remark on Algorithm AS 183
617 # Applied Statistics 34 (1985),198-200
618
619 # This part is thread-unsafe:
620 # BEGIN CRITICAL SECTION
621 x, y, z = self._seed
622 x = (171 * x) % 30269
623 y = (172 * y) % 30307
624 z = (170 * z) % 30323
625 self._seed = x, y, z
626 # END CRITICAL SECTION
627
628 # Note: on a platform using IEEE-754 double arithmetic, this can
629 # never return 0.0 (asserted by Tim; proof too long for a comment).
630 return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0
631
632 def getstate(self):
633 """Return internal state; can be passed to setstate() later."""
634 return self.VERSION, self._seed, self.gauss_next
635
636 def setstate(self, state):
637 """Restore internal state from object returned by getstate()."""
638 version = state[0]
639 if version == 1:
640 version, self._seed, self.gauss_next = state
641 else:
642 raise ValueError("state with version %s passed to "
643 "Random.setstate() of version %s" %
644 (version, self.VERSION))
645
646 def jumpahead(self, n):
647 """Act as if n calls to random() were made, but quickly.
648
649 n is an int, greater than or equal to 0.
650
651 Example use: If you have 2 threads and know that each will
652 consume no more than a million random numbers, create two Random
653 objects r1 and r2, then do
654 r2.setstate(r1.getstate())
655 r2.jumpahead(1000000)
656 Then r1 and r2 will use guaranteed-disjoint segments of the full
657 period.
658 """
659
660 if not n >= 0:
661 raise ValueError("n must be >= 0")
662 x, y, z = self._seed
663 x = int(x * pow(171, n, 30269)) % 30269
664 y = int(y * pow(172, n, 30307)) % 30307
665 z = int(z * pow(170, n, 30323)) % 30323
666 self._seed = x, y, z
667
668 def __whseed(self, x=0, y=0, z=0):
669 """Set the Wichmann-Hill seed from (x, y, z).
670
671 These must be integers in the range [0, 256).
672 """
673
674 if not type(x) == type(y) == type(z) == int:
675 raise TypeError('seeds must be integers')
676 if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256):
677 raise ValueError('seeds must be in range(0, 256)')
678 if 0 == x == y == z:
679 # Initialize from current time
680 import time
681 t = long(time.time() * 256)
682 t = int((t&0xffffff) ^ (t>>24))
683 t, x = divmod(t, 256)
684 t, y = divmod(t, 256)
685 t, z = divmod(t, 256)
686 # Zero is a poor seed, so substitute 1
687 self._seed = (x or 1, y or 1, z or 1)
688
689 self.gauss_next = None
690
691 def whseed(self, a=None):
692 """Seed from hashable object's hash code.
693
694 None or no argument seeds from current time. It is not guaranteed
695 that objects with distinct hash codes lead to distinct internal
696 states.
697
698 This is obsolete, provided for compatibility with the seed routine
699 used prior to Python 2.1. Use the .seed() method instead.
700 """
701
702 if a is None:
703 self.__whseed()
704 return
705 a = hash(a)
706 a, x = divmod(a, 256)
707 a, y = divmod(a, 256)
708 a, z = divmod(a, 256)
709 x = (x + a) % 256 or 1
710 y = (y + a) % 256 or 1
711 z = (z + a) % 256 or 1
712 self.__whseed(x, y, z)
713
Tim Peterscd804102001-01-25 20:25:57 +0000714## -------------------- test program --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000715
Tim Petersd7b5e882001-01-25 03:36:26 +0000716def _test_generator(n, funccall):
Tim Peters0c9886d2001-01-15 01:18:21 +0000717 import time
718 print n, 'times', funccall
719 code = compile(funccall, funccall, 'eval')
Raymond Hettingerb98154e2003-05-24 17:26:02 +0000720 total = 0.0
Tim Peters0c9886d2001-01-15 01:18:21 +0000721 sqsum = 0.0
722 smallest = 1e10
723 largest = -1e10
724 t0 = time.time()
725 for i in range(n):
726 x = eval(code)
Raymond Hettingerb98154e2003-05-24 17:26:02 +0000727 total += x
Tim Peters0c9886d2001-01-15 01:18:21 +0000728 sqsum = sqsum + x*x
729 smallest = min(x, smallest)
730 largest = max(x, largest)
731 t1 = time.time()
732 print round(t1-t0, 3), 'sec,',
Raymond Hettingerb98154e2003-05-24 17:26:02 +0000733 avg = total/n
Tim Petersd7b5e882001-01-25 03:36:26 +0000734 stddev = _sqrt(sqsum/n - avg*avg)
Tim Peters0c9886d2001-01-15 01:18:21 +0000735 print 'avg %g, stddev %g, min %g, max %g' % \
736 (avg, stddev, smallest, largest)
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000737
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000738
739def _test(N=2000):
Tim Petersd7b5e882001-01-25 03:36:26 +0000740 _test_generator(N, 'random()')
741 _test_generator(N, 'normalvariate(0.0, 1.0)')
742 _test_generator(N, 'lognormvariate(0.0, 1.0)')
743 _test_generator(N, 'cunifvariate(0.0, 1.0)')
Tim Petersd7b5e882001-01-25 03:36:26 +0000744 _test_generator(N, 'vonmisesvariate(0.0, 1.0)')
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000745 _test_generator(N, 'gammavariate(0.01, 1.0)')
746 _test_generator(N, 'gammavariate(0.1, 1.0)')
Tim Peters8ac14952002-05-23 15:15:30 +0000747 _test_generator(N, 'gammavariate(0.1, 2.0)')
Tim Petersd7b5e882001-01-25 03:36:26 +0000748 _test_generator(N, 'gammavariate(0.5, 1.0)')
749 _test_generator(N, 'gammavariate(0.9, 1.0)')
750 _test_generator(N, 'gammavariate(1.0, 1.0)')
751 _test_generator(N, 'gammavariate(2.0, 1.0)')
752 _test_generator(N, 'gammavariate(20.0, 1.0)')
753 _test_generator(N, 'gammavariate(200.0, 1.0)')
754 _test_generator(N, 'gauss(0.0, 1.0)')
755 _test_generator(N, 'betavariate(3.0, 3.0)')
Tim Peterscd804102001-01-25 20:25:57 +0000756
Tim Peters715c4c42001-01-26 22:56:56 +0000757# Create one instance, seeded from current time, and export its methods
Raymond Hettinger40f62172002-12-29 23:03:38 +0000758# as module-level functions. The functions share state across all uses
759#(both in the user's code and in the Python libraries), but that's fine
760# for most programs and is easier for the casual user than making them
761# instantiate their own Random() instance.
762
Tim Petersd7b5e882001-01-25 03:36:26 +0000763_inst = Random()
764seed = _inst.seed
765random = _inst.random
766uniform = _inst.uniform
767randint = _inst.randint
768choice = _inst.choice
769randrange = _inst.randrange
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000770sample = _inst.sample
Tim Petersd7b5e882001-01-25 03:36:26 +0000771shuffle = _inst.shuffle
772normalvariate = _inst.normalvariate
773lognormvariate = _inst.lognormvariate
774cunifvariate = _inst.cunifvariate
775expovariate = _inst.expovariate
776vonmisesvariate = _inst.vonmisesvariate
777gammavariate = _inst.gammavariate
778stdgamma = _inst.stdgamma
779gauss = _inst.gauss
780betavariate = _inst.betavariate
781paretovariate = _inst.paretovariate
782weibullvariate = _inst.weibullvariate
783getstate = _inst.getstate
784setstate = _inst.setstate
Tim Petersd52269b2001-01-25 06:23:18 +0000785jumpahead = _inst.jumpahead
Tim Petersd7b5e882001-01-25 03:36:26 +0000786
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000787if __name__ == '__main__':
Tim Petersd7b5e882001-01-25 03:36:26 +0000788 _test()