blob: a2415ae6bd989e43f4b7d8b99bfe107f14f873f9 [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
Raymond Hettinger2f726e92003-10-05 09:09:15 +000042from warnings import warn as _warn
43from types import MethodType as _MethodType, BuiltinMethodType as _BuiltinMethodType
Tim Petersd7b5e882001-01-25 03:36:26 +000044from math import log as _log, exp as _exp, pi as _pi, e as _e
45from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
Tim Peters9146f272002-08-16 03:41:39 +000046from math import floor as _floor
Guido van Rossumff03b1a1994-03-09 12:55:02 +000047
Raymond Hettingerf24eb352002-11-12 17:41:57 +000048__all__ = ["Random","seed","random","uniform","randint","choice","sample",
Skip Montanaro0de65802001-02-15 22:15:14 +000049 "randrange","shuffle","normalvariate","lognormvariate",
Raymond Hettingerf8a52d32003-08-05 12:23:19 +000050 "expovariate","vonmisesvariate","gammavariate",
51 "gauss","betavariate","paretovariate","weibullvariate",
Raymond Hettinger411c6022003-10-12 17:14:11 +000052 "getstate","setstate","jumpahead", "WichmannHill", "getrandbits"]
Tim Petersd7b5e882001-01-25 03:36:26 +000053
54NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0)
Tim Petersd7b5e882001-01-25 03:36:26 +000055TWOPI = 2.0*_pi
Tim Petersd7b5e882001-01-25 03:36:26 +000056LOG4 = _log(4.0)
Tim Petersd7b5e882001-01-25 03:36:26 +000057SG_MAGICCONST = 1.0 + _log(4.5)
Raymond Hettinger2f726e92003-10-05 09:09:15 +000058BPF = 53 # Number of bits in a float
Tim Petersd7b5e882001-01-25 03:36:26 +000059
60# Translated by Guido van Rossum from C source provided by
Raymond Hettinger40f62172002-12-29 23:03:38 +000061# Adrian Baddeley. Adapted by Raymond Hettinger for use with
62# the Mersenne Twister core generator.
Tim Petersd7b5e882001-01-25 03:36:26 +000063
Raymond Hettinger145a4a02003-01-07 10:25:55 +000064import _random
Raymond Hettinger40f62172002-12-29 23:03:38 +000065
Raymond Hettinger145a4a02003-01-07 10:25:55 +000066class Random(_random.Random):
Raymond Hettingerc32f0332002-05-23 19:44:49 +000067 """Random number generator base class used by bound module functions.
68
69 Used to instantiate instances of Random to get generators that don't
70 share state. Especially useful for multi-threaded programs, creating
71 a different instance of Random for each thread, and using the jumpahead()
72 method to ensure that the generated sequences seen by each thread don't
73 overlap.
74
75 Class Random can also be subclassed if you want to use a different basic
76 generator of your own devising: in that case, override the following
77 methods: random(), seed(), getstate(), setstate() and jumpahead().
Raymond Hettinger2f726e92003-10-05 09:09:15 +000078 Optionally, implement a getrandombits() method so that randrange()
79 can cover arbitrarily large ranges.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +000080
Raymond Hettingerc32f0332002-05-23 19:44:49 +000081 """
Tim Petersd7b5e882001-01-25 03:36:26 +000082
Raymond Hettinger40f62172002-12-29 23:03:38 +000083 VERSION = 2 # used by getstate/setstate
Tim Petersd7b5e882001-01-25 03:36:26 +000084
85 def __init__(self, x=None):
86 """Initialize an instance.
87
88 Optional argument x controls seeding, as for Random.seed().
89 """
90
91 self.seed(x)
Raymond Hettinger40f62172002-12-29 23:03:38 +000092 self.gauss_next = None
Tim Petersd7b5e882001-01-25 03:36:26 +000093
Tim Peters0de88fc2001-02-01 04:59:18 +000094 def seed(self, a=None):
95 """Initialize internal state from hashable object.
Tim Petersd7b5e882001-01-25 03:36:26 +000096
Tim Peters0de88fc2001-02-01 04:59:18 +000097 None or no argument seeds from current time.
98
Tim Petersbcd725f2001-02-01 10:06:53 +000099 If a is not None or an int or long, hash(a) is used instead.
Tim Petersd7b5e882001-01-25 03:36:26 +0000100 """
101
Raymond Hettinger3081d592003-08-09 18:30:57 +0000102 if a is None:
103 import time
104 a = long(time.time() * 256) # use fractional seconds
Raymond Hettinger145a4a02003-01-07 10:25:55 +0000105 super(Random, self).seed(a)
Tim Peters46c04e12002-05-05 20:40:00 +0000106 self.gauss_next = None
107
Tim Peterscd804102001-01-25 20:25:57 +0000108 def getstate(self):
109 """Return internal state; can be passed to setstate() later."""
Raymond Hettinger145a4a02003-01-07 10:25:55 +0000110 return self.VERSION, super(Random, self).getstate(), self.gauss_next
Tim Peterscd804102001-01-25 20:25:57 +0000111
112 def setstate(self, state):
113 """Restore internal state from object returned by getstate()."""
114 version = state[0]
Raymond Hettinger40f62172002-12-29 23:03:38 +0000115 if version == 2:
116 version, internalstate, self.gauss_next = state
Raymond Hettinger145a4a02003-01-07 10:25:55 +0000117 super(Random, self).setstate(internalstate)
Tim Peterscd804102001-01-25 20:25:57 +0000118 else:
119 raise ValueError("state with version %s passed to "
120 "Random.setstate() of version %s" %
121 (version, self.VERSION))
122
Tim Peterscd804102001-01-25 20:25:57 +0000123## ---- Methods below this point do not need to be overridden when
124## ---- subclassing for the purpose of using a different core generator.
125
126## -------------------- pickle support -------------------
127
128 def __getstate__(self): # for pickle
129 return self.getstate()
130
131 def __setstate__(self, state): # for pickle
132 self.setstate(state)
133
Raymond Hettinger5f078ff2003-06-24 20:29:04 +0000134 def __reduce__(self):
135 return self.__class__, (), self.getstate()
136
Tim Peterscd804102001-01-25 20:25:57 +0000137## -------------------- integer methods -------------------
138
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000139 def randrange(self, start, stop=None, step=1, int=int, default=None,
140 maxwidth=1L<<BPF):
Tim Petersd7b5e882001-01-25 03:36:26 +0000141 """Choose a random item from range(start, stop[, step]).
142
143 This fixes the problem with randint() which includes the
144 endpoint; in Python this is usually not what you want.
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000145 Do not supply the 'int', 'default', and 'maxwidth' arguments.
Tim Petersd7b5e882001-01-25 03:36:26 +0000146 """
147
148 # This code is a bit messy to make it fast for the
Tim Peters9146f272002-08-16 03:41:39 +0000149 # common case while still doing adequate error checking.
Tim Petersd7b5e882001-01-25 03:36:26 +0000150 istart = int(start)
151 if istart != start:
152 raise ValueError, "non-integer arg 1 for randrange()"
153 if stop is default:
154 if istart > 0:
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000155 if istart >= maxwidth:
156 return self._randbelow(istart)
Tim Petersd7b5e882001-01-25 03:36:26 +0000157 return int(self.random() * istart)
158 raise ValueError, "empty range for randrange()"
Tim Peters9146f272002-08-16 03:41:39 +0000159
160 # stop argument supplied.
Tim Petersd7b5e882001-01-25 03:36:26 +0000161 istop = int(stop)
162 if istop != stop:
163 raise ValueError, "non-integer stop for randrange()"
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000164 width = istop - istart
165 if step == 1 and width > 0:
Tim Peters76ca1d42003-06-19 03:46:46 +0000166 # Note that
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000167 # int(istart + self.random()*width)
Tim Peters76ca1d42003-06-19 03:46:46 +0000168 # instead would be incorrect. For example, consider istart
169 # = -2 and istop = 0. Then the guts would be in
170 # -2.0 to 0.0 exclusive on both ends (ignoring that random()
171 # might return 0.0), and because int() truncates toward 0, the
172 # final result would be -1 or 0 (instead of -2 or -1).
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000173 # istart + int(self.random()*width)
Tim Peters76ca1d42003-06-19 03:46:46 +0000174 # would also be incorrect, for a subtler reason: the RHS
175 # can return a long, and then randrange() would also return
176 # a long, but we're supposed to return an int (for backward
177 # compatibility).
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000178
179 if width >= maxwidth:
Tim Peters58eb11c2004-01-18 20:29:55 +0000180 return int(istart + self._randbelow(width))
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000181 return int(istart + int(self.random()*width))
Tim Petersd7b5e882001-01-25 03:36:26 +0000182 if step == 1:
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000183 raise ValueError, "empty range for randrange() (%d,%d, %d)" % (istart, istop, width)
Tim Peters9146f272002-08-16 03:41:39 +0000184
185 # Non-unit step argument supplied.
Tim Petersd7b5e882001-01-25 03:36:26 +0000186 istep = int(step)
187 if istep != step:
188 raise ValueError, "non-integer step for randrange()"
189 if istep > 0:
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000190 n = (width + istep - 1) / istep
Tim Petersd7b5e882001-01-25 03:36:26 +0000191 elif istep < 0:
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000192 n = (width + istep + 1) / istep
Tim Petersd7b5e882001-01-25 03:36:26 +0000193 else:
194 raise ValueError, "zero step for randrange()"
195
196 if n <= 0:
197 raise ValueError, "empty range for randrange()"
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000198
199 if n >= maxwidth:
200 return istart + self._randbelow(n)
Tim Petersd7b5e882001-01-25 03:36:26 +0000201 return istart + istep*int(self.random() * n)
202
203 def randint(self, a, b):
Tim Peterscd804102001-01-25 20:25:57 +0000204 """Return random integer in range [a, b], including both end points.
Tim Petersd7b5e882001-01-25 03:36:26 +0000205 """
206
207 return self.randrange(a, b+1)
208
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000209 def _randbelow(self, n, _log=_log, int=int, _maxwidth=1L<<BPF,
210 _Method=_MethodType, _BuiltinMethod=_BuiltinMethodType):
211 """Return a random int in the range [0,n)
212
213 Handles the case where n has more bits than returned
214 by a single call to the underlying generator.
215 """
216
217 try:
218 getrandbits = self.getrandbits
219 except AttributeError:
220 pass
221 else:
222 # Only call self.getrandbits if the original random() builtin method
223 # has not been overridden or if a new getrandbits() was supplied.
224 # This assures that the two methods correspond.
225 if type(self.random) is _BuiltinMethod or type(getrandbits) is _Method:
226 k = int(1.00001 + _log(n-1, 2.0)) # 2**k > n-1 > 2**(k-2)
227 r = getrandbits(k)
228 while r >= n:
229 r = getrandbits(k)
230 return r
231 if n >= _maxwidth:
232 _warn("Underlying random() generator does not supply \n"
233 "enough bits to choose from a population range this large")
234 return int(self.random() * n)
235
Tim Peterscd804102001-01-25 20:25:57 +0000236## -------------------- sequence methods -------------------
237
Tim Petersd7b5e882001-01-25 03:36:26 +0000238 def choice(self, seq):
239 """Choose a random element from a non-empty sequence."""
240 return seq[int(self.random() * len(seq))]
241
242 def shuffle(self, x, random=None, int=int):
243 """x, random=random.random -> shuffle list x in place; return None.
244
245 Optional arg random is a 0-argument function returning a random
246 float in [0.0, 1.0); by default, the standard random.random.
247
248 Note that for even rather small len(x), the total number of
249 permutations of x is larger than the period of most random number
250 generators; this implies that "most" permutations of a long
251 sequence can never be generated.
252 """
253
254 if random is None:
255 random = self.random
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000256 for i in reversed(xrange(1, len(x))):
Tim Peterscd804102001-01-25 20:25:57 +0000257 # pick an element in x[:i+1] with which to exchange x[i]
Tim Petersd7b5e882001-01-25 03:36:26 +0000258 j = int(random() * (i+1))
259 x[i], x[j] = x[j], x[i]
260
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000261 def sample(self, population, k):
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000262 """Chooses k unique random elements from a population sequence.
263
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000264 Returns a new list containing elements from the population while
265 leaving the original population unchanged. The resulting list is
266 in selection order so that all sub-slices will also be valid random
267 samples. This allows raffle winners (the sample) to be partitioned
268 into grand prize and second place winners (the subslices).
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000269
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000270 Members of the population need not be hashable or unique. If the
271 population contains repeats, then each occurrence is a possible
272 selection in the sample.
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000273
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000274 To choose a sample in a range of integers, use xrange as an argument.
275 This is especially fast and space efficient for sampling from a
276 large population: sample(xrange(10000000), 60)
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000277 """
278
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000279 # Sampling without replacement entails tracking either potential
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000280 # selections (the pool) in a list or previous selections in a
281 # dictionary.
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000282
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000283 # When the number of selections is small compared to the population,
284 # then tracking selections is efficient, requiring only a small
285 # dictionary and an occasional reselection. For a larger number of
286 # selections, the pool tracking method is preferred since the list takes
287 # less space than the dictionary and it doesn't suffer from frequent
288 # reselections.
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000289
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000290 n = len(population)
291 if not 0 <= k <= n:
292 raise ValueError, "sample larger than population"
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000293 random = self.random
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000294 _int = int
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000295 result = [None] * k
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000296 if n < 6 * k: # if n len list takes less space than a k len dict
Raymond Hettinger311f4192002-11-18 09:01:24 +0000297 pool = list(population)
298 for i in xrange(k): # invariant: non-selected at [0,n-i)
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000299 j = _int(random() * (n-i))
Raymond Hettinger311f4192002-11-18 09:01:24 +0000300 result[i] = pool[j]
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000301 pool[j] = pool[n-i-1] # move non-selected item into vacancy
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000302 else:
Raymond Hettinger66d09f12003-09-06 04:25:54 +0000303 try:
304 n > 0 and (population[0], population[n//2], population[n-1])
305 except (TypeError, KeyError): # handle sets and dictionaries
306 population = tuple(population)
Raymond Hettinger311f4192002-11-18 09:01:24 +0000307 selected = {}
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000308 for i in xrange(k):
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000309 j = _int(random() * n)
Raymond Hettinger311f4192002-11-18 09:01:24 +0000310 while j in selected:
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000311 j = _int(random() * n)
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000312 result[i] = selected[j] = population[j]
Raymond Hettinger311f4192002-11-18 09:01:24 +0000313 return result
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000314
Tim Peterscd804102001-01-25 20:25:57 +0000315## -------------------- real-valued distributions -------------------
316
317## -------------------- uniform distribution -------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000318
319 def uniform(self, a, b):
320 """Get a random number in the range [a, b)."""
321 return a + (b-a) * self.random()
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000322
Tim Peterscd804102001-01-25 20:25:57 +0000323## -------------------- normal distribution --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000324
Tim Petersd7b5e882001-01-25 03:36:26 +0000325 def normalvariate(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000326 """Normal distribution.
327
328 mu is the mean, and sigma is the standard deviation.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000329
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000330 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000331 # mu = mean, sigma = standard deviation
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000332
Tim Petersd7b5e882001-01-25 03:36:26 +0000333 # Uses Kinderman and Monahan method. Reference: Kinderman,
334 # A.J. and Monahan, J.F., "Computer generation of random
335 # variables using the ratio of uniform deviates", ACM Trans
336 # Math Software, 3, (1977), pp257-260.
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000337
Tim Petersd7b5e882001-01-25 03:36:26 +0000338 random = self.random
Raymond Hettinger311f4192002-11-18 09:01:24 +0000339 while True:
Tim Peters0c9886d2001-01-15 01:18:21 +0000340 u1 = random()
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000341 u2 = 1.0 - random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000342 z = NV_MAGICCONST*(u1-0.5)/u2
343 zz = z*z/4.0
344 if zz <= -_log(u2):
345 break
346 return mu + z*sigma
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000347
Tim Peterscd804102001-01-25 20:25:57 +0000348## -------------------- lognormal distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000349
350 def lognormvariate(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000351 """Log normal distribution.
352
353 If you take the natural logarithm of this distribution, you'll get a
354 normal distribution with mean mu and standard deviation sigma.
355 mu can have any value, and sigma must be greater than zero.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000356
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000357 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000358 return _exp(self.normalvariate(mu, sigma))
359
Tim Peterscd804102001-01-25 20:25:57 +0000360## -------------------- exponential distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000361
362 def expovariate(self, lambd):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000363 """Exponential distribution.
364
365 lambd is 1.0 divided by the desired mean. (The parameter would be
366 called "lambda", but that is a reserved word in Python.) Returned
367 values range from 0 to positive infinity.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000368
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000369 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000370 # lambd: rate lambd = 1/mean
371 # ('lambda' is a Python reserved word)
372
373 random = self.random
Tim Peters0c9886d2001-01-15 01:18:21 +0000374 u = random()
375 while u <= 1e-7:
376 u = random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000377 return -_log(u)/lambd
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000378
Tim Peterscd804102001-01-25 20:25:57 +0000379## -------------------- von Mises distribution --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000380
Tim Petersd7b5e882001-01-25 03:36:26 +0000381 def vonmisesvariate(self, mu, kappa):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000382 """Circular data distribution.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000383
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000384 mu is the mean angle, expressed in radians between 0 and 2*pi, and
385 kappa is the concentration parameter, which must be greater than or
386 equal to zero. If kappa is equal to zero, this distribution reduces
387 to a uniform random angle over the range 0 to 2*pi.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000388
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000389 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000390 # mu: mean angle (in radians between 0 and 2*pi)
391 # kappa: concentration parameter kappa (>= 0)
392 # if kappa = 0 generate uniform random angle
393
394 # Based upon an algorithm published in: Fisher, N.I.,
395 # "Statistical Analysis of Circular Data", Cambridge
396 # University Press, 1993.
397
398 # Thanks to Magnus Kessler for a correction to the
399 # implementation of step 4.
400
401 random = self.random
402 if kappa <= 1e-6:
403 return TWOPI * random()
404
405 a = 1.0 + _sqrt(1.0 + 4.0 * kappa * kappa)
406 b = (a - _sqrt(2.0 * a))/(2.0 * kappa)
407 r = (1.0 + b * b)/(2.0 * b)
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000408
Raymond Hettinger311f4192002-11-18 09:01:24 +0000409 while True:
Tim Peters0c9886d2001-01-15 01:18:21 +0000410 u1 = random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000411
412 z = _cos(_pi * u1)
413 f = (1.0 + r * z)/(r + z)
414 c = kappa * (r - f)
415
416 u2 = random()
417
418 if not (u2 >= c * (2.0 - c) and u2 > c * _exp(1.0 - c)):
Tim Peters0c9886d2001-01-15 01:18:21 +0000419 break
Tim Petersd7b5e882001-01-25 03:36:26 +0000420
421 u3 = random()
422 if u3 > 0.5:
423 theta = (mu % TWOPI) + _acos(f)
424 else:
425 theta = (mu % TWOPI) - _acos(f)
426
427 return theta
428
Tim Peterscd804102001-01-25 20:25:57 +0000429## -------------------- gamma distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000430
431 def gammavariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000432 """Gamma distribution. Not the gamma function!
433
434 Conditions on the parameters are alpha > 0 and beta > 0.
435
436 """
Tim Peters8ac14952002-05-23 15:15:30 +0000437
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000438 # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
Tim Peters8ac14952002-05-23 15:15:30 +0000439
Guido van Rossum570764d2002-05-14 14:08:12 +0000440 # Warning: a few older sources define the gamma distribution in terms
441 # of alpha > -1.0
442 if alpha <= 0.0 or beta <= 0.0:
443 raise ValueError, 'gammavariate: alpha and beta must be > 0.0'
Tim Peters8ac14952002-05-23 15:15:30 +0000444
Tim Petersd7b5e882001-01-25 03:36:26 +0000445 random = self.random
Tim Petersd7b5e882001-01-25 03:36:26 +0000446 if alpha > 1.0:
447
448 # Uses R.C.H. Cheng, "The generation of Gamma
449 # variables with non-integral shape parameters",
450 # Applied Statistics, (1977), 26, No. 1, p71-74
451
Raymond Hettingerca6cdc22002-05-13 23:40:14 +0000452 ainv = _sqrt(2.0 * alpha - 1.0)
453 bbb = alpha - LOG4
454 ccc = alpha + ainv
Tim Peters8ac14952002-05-23 15:15:30 +0000455
Raymond Hettinger311f4192002-11-18 09:01:24 +0000456 while True:
Tim Petersd7b5e882001-01-25 03:36:26 +0000457 u1 = random()
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000458 if not 1e-7 < u1 < .9999999:
459 continue
460 u2 = 1.0 - random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000461 v = _log(u1/(1.0-u1))/ainv
462 x = alpha*_exp(v)
463 z = u1*u1*u2
464 r = bbb+ccc*v-x
465 if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z):
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000466 return x * beta
Tim Petersd7b5e882001-01-25 03:36:26 +0000467
468 elif alpha == 1.0:
469 # expovariate(1)
470 u = random()
471 while u <= 1e-7:
472 u = random()
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000473 return -_log(u) * beta
Tim Petersd7b5e882001-01-25 03:36:26 +0000474
475 else: # alpha is between 0 and 1 (exclusive)
476
477 # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
478
Raymond Hettinger311f4192002-11-18 09:01:24 +0000479 while True:
Tim Petersd7b5e882001-01-25 03:36:26 +0000480 u = random()
481 b = (_e + alpha)/_e
482 p = b*u
483 if p <= 1.0:
484 x = pow(p, 1.0/alpha)
485 else:
486 # p > 1
487 x = -_log((b-p)/alpha)
488 u1 = random()
489 if not (((p <= 1.0) and (u1 > _exp(-x))) or
490 ((p > 1) and (u1 > pow(x, alpha - 1.0)))):
491 break
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000492 return x * beta
493
Tim Peterscd804102001-01-25 20:25:57 +0000494## -------------------- Gauss (faster alternative) --------------------
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000495
Tim Petersd7b5e882001-01-25 03:36:26 +0000496 def gauss(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000497 """Gaussian distribution.
498
499 mu is the mean, and sigma is the standard deviation. This is
500 slightly faster than the normalvariate() function.
501
502 Not thread-safe without a lock around calls.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000503
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000504 """
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000505
Tim Petersd7b5e882001-01-25 03:36:26 +0000506 # When x and y are two variables from [0, 1), uniformly
507 # distributed, then
508 #
509 # cos(2*pi*x)*sqrt(-2*log(1-y))
510 # sin(2*pi*x)*sqrt(-2*log(1-y))
511 #
512 # are two *independent* variables with normal distribution
513 # (mu = 0, sigma = 1).
514 # (Lambert Meertens)
515 # (corrected version; bug discovered by Mike Miller, fixed by LM)
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000516
Tim Petersd7b5e882001-01-25 03:36:26 +0000517 # Multithreading note: When two threads call this function
518 # simultaneously, it is possible that they will receive the
519 # same return value. The window is very small though. To
520 # avoid this, you have to use a lock around all calls. (I
521 # didn't want to slow this down in the serial case by using a
522 # lock here.)
Guido van Rossumd03e1191998-05-29 17:51:31 +0000523
Tim Petersd7b5e882001-01-25 03:36:26 +0000524 random = self.random
525 z = self.gauss_next
526 self.gauss_next = None
527 if z is None:
528 x2pi = random() * TWOPI
529 g2rad = _sqrt(-2.0 * _log(1.0 - random()))
530 z = _cos(x2pi) * g2rad
531 self.gauss_next = _sin(x2pi) * g2rad
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000532
Tim Petersd7b5e882001-01-25 03:36:26 +0000533 return mu + z*sigma
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000534
Tim Peterscd804102001-01-25 20:25:57 +0000535## -------------------- beta --------------------
Tim Peters85e2e472001-01-26 06:49:56 +0000536## See
537## http://sourceforge.net/bugs/?func=detailbug&bug_id=130030&group_id=5470
538## for Ivan Frohne's insightful analysis of why the original implementation:
539##
540## def betavariate(self, alpha, beta):
541## # Discrete Event Simulation in C, pp 87-88.
542##
543## y = self.expovariate(alpha)
544## z = self.expovariate(1.0/beta)
545## return z/(y+z)
546##
547## was dead wrong, and how it probably got that way.
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000548
Tim Petersd7b5e882001-01-25 03:36:26 +0000549 def betavariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000550 """Beta distribution.
551
552 Conditions on the parameters are alpha > -1 and beta} > -1.
553 Returned values range between 0 and 1.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000554
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000555 """
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000556
Tim Peters85e2e472001-01-26 06:49:56 +0000557 # This version due to Janne Sinkkonen, and matches all the std
558 # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
559 y = self.gammavariate(alpha, 1.)
560 if y == 0:
561 return 0.0
562 else:
563 return y / (y + self.gammavariate(beta, 1.))
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000564
Tim Peterscd804102001-01-25 20:25:57 +0000565## -------------------- Pareto --------------------
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000566
Tim Petersd7b5e882001-01-25 03:36:26 +0000567 def paretovariate(self, alpha):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000568 """Pareto distribution. alpha is the shape parameter."""
Tim Petersd7b5e882001-01-25 03:36:26 +0000569 # Jain, pg. 495
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000570
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000571 u = 1.0 - self.random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000572 return 1.0 / pow(u, 1.0/alpha)
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000573
Tim Peterscd804102001-01-25 20:25:57 +0000574## -------------------- Weibull --------------------
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000575
Tim Petersd7b5e882001-01-25 03:36:26 +0000576 def weibullvariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000577 """Weibull distribution.
578
579 alpha is the scale parameter and beta is the shape parameter.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000580
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000581 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000582 # Jain, pg. 499; bug fix courtesy Bill Arms
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000583
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000584 u = 1.0 - self.random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000585 return alpha * pow(-_log(u), 1.0/beta)
Guido van Rossum6c395ba1999-08-18 13:53:28 +0000586
Raymond Hettinger40f62172002-12-29 23:03:38 +0000587## -------------------- Wichmann-Hill -------------------
588
589class WichmannHill(Random):
590
591 VERSION = 1 # used by getstate/setstate
592
593 def seed(self, a=None):
594 """Initialize internal state from hashable object.
595
596 None or no argument seeds from current time.
597
598 If a is not None or an int or long, hash(a) is used instead.
599
600 If a is an int or long, a is used directly. Distinct values between
601 0 and 27814431486575L inclusive are guaranteed to yield distinct
602 internal states (this guarantee is specific to the default
603 Wichmann-Hill generator).
604 """
605
606 if a is None:
607 # Initialize from current time
608 import time
609 a = long(time.time() * 256)
610
611 if not isinstance(a, (int, long)):
612 a = hash(a)
613
614 a, x = divmod(a, 30268)
615 a, y = divmod(a, 30306)
616 a, z = divmod(a, 30322)
617 self._seed = int(x)+1, int(y)+1, int(z)+1
618
619 self.gauss_next = None
620
621 def random(self):
622 """Get the next random number in the range [0.0, 1.0)."""
623
624 # Wichman-Hill random number generator.
625 #
626 # Wichmann, B. A. & Hill, I. D. (1982)
627 # Algorithm AS 183:
628 # An efficient and portable pseudo-random number generator
629 # Applied Statistics 31 (1982) 188-190
630 #
631 # see also:
632 # Correction to Algorithm AS 183
633 # Applied Statistics 33 (1984) 123
634 #
635 # McLeod, A. I. (1985)
636 # A remark on Algorithm AS 183
637 # Applied Statistics 34 (1985),198-200
638
639 # This part is thread-unsafe:
640 # BEGIN CRITICAL SECTION
641 x, y, z = self._seed
642 x = (171 * x) % 30269
643 y = (172 * y) % 30307
644 z = (170 * z) % 30323
645 self._seed = x, y, z
646 # END CRITICAL SECTION
647
648 # Note: on a platform using IEEE-754 double arithmetic, this can
649 # never return 0.0 (asserted by Tim; proof too long for a comment).
650 return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0
651
652 def getstate(self):
653 """Return internal state; can be passed to setstate() later."""
654 return self.VERSION, self._seed, self.gauss_next
655
656 def setstate(self, state):
657 """Restore internal state from object returned by getstate()."""
658 version = state[0]
659 if version == 1:
660 version, self._seed, self.gauss_next = state
661 else:
662 raise ValueError("state with version %s passed to "
663 "Random.setstate() of version %s" %
664 (version, self.VERSION))
665
666 def jumpahead(self, n):
667 """Act as if n calls to random() were made, but quickly.
668
669 n is an int, greater than or equal to 0.
670
671 Example use: If you have 2 threads and know that each will
672 consume no more than a million random numbers, create two Random
673 objects r1 and r2, then do
674 r2.setstate(r1.getstate())
675 r2.jumpahead(1000000)
676 Then r1 and r2 will use guaranteed-disjoint segments of the full
677 period.
678 """
679
680 if not n >= 0:
681 raise ValueError("n must be >= 0")
682 x, y, z = self._seed
683 x = int(x * pow(171, n, 30269)) % 30269
684 y = int(y * pow(172, n, 30307)) % 30307
685 z = int(z * pow(170, n, 30323)) % 30323
686 self._seed = x, y, z
687
688 def __whseed(self, x=0, y=0, z=0):
689 """Set the Wichmann-Hill seed from (x, y, z).
690
691 These must be integers in the range [0, 256).
692 """
693
694 if not type(x) == type(y) == type(z) == int:
695 raise TypeError('seeds must be integers')
696 if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256):
697 raise ValueError('seeds must be in range(0, 256)')
698 if 0 == x == y == z:
699 # Initialize from current time
700 import time
701 t = long(time.time() * 256)
702 t = int((t&0xffffff) ^ (t>>24))
703 t, x = divmod(t, 256)
704 t, y = divmod(t, 256)
705 t, z = divmod(t, 256)
706 # Zero is a poor seed, so substitute 1
707 self._seed = (x or 1, y or 1, z or 1)
708
709 self.gauss_next = None
710
711 def whseed(self, a=None):
712 """Seed from hashable object's hash code.
713
714 None or no argument seeds from current time. It is not guaranteed
715 that objects with distinct hash codes lead to distinct internal
716 states.
717
718 This is obsolete, provided for compatibility with the seed routine
719 used prior to Python 2.1. Use the .seed() method instead.
720 """
721
722 if a is None:
723 self.__whseed()
724 return
725 a = hash(a)
726 a, x = divmod(a, 256)
727 a, y = divmod(a, 256)
728 a, z = divmod(a, 256)
729 x = (x + a) % 256 or 1
730 y = (y + a) % 256 or 1
731 z = (z + a) % 256 or 1
732 self.__whseed(x, y, z)
733
Tim Peterscd804102001-01-25 20:25:57 +0000734## -------------------- test program --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000735
Raymond Hettinger62297132003-08-30 01:24:19 +0000736def _test_generator(n, func, args):
Tim Peters0c9886d2001-01-15 01:18:21 +0000737 import time
Raymond Hettinger62297132003-08-30 01:24:19 +0000738 print n, 'times', func.__name__
Raymond Hettingerb98154e2003-05-24 17:26:02 +0000739 total = 0.0
Tim Peters0c9886d2001-01-15 01:18:21 +0000740 sqsum = 0.0
741 smallest = 1e10
742 largest = -1e10
743 t0 = time.time()
744 for i in range(n):
Raymond Hettinger62297132003-08-30 01:24:19 +0000745 x = func(*args)
Raymond Hettingerb98154e2003-05-24 17:26:02 +0000746 total += x
Tim Peters0c9886d2001-01-15 01:18:21 +0000747 sqsum = sqsum + x*x
748 smallest = min(x, smallest)
749 largest = max(x, largest)
750 t1 = time.time()
751 print round(t1-t0, 3), 'sec,',
Raymond Hettingerb98154e2003-05-24 17:26:02 +0000752 avg = total/n
Tim Petersd7b5e882001-01-25 03:36:26 +0000753 stddev = _sqrt(sqsum/n - avg*avg)
Tim Peters0c9886d2001-01-15 01:18:21 +0000754 print 'avg %g, stddev %g, min %g, max %g' % \
755 (avg, stddev, smallest, largest)
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000756
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000757
758def _test(N=2000):
Raymond Hettinger62297132003-08-30 01:24:19 +0000759 _test_generator(N, random, ())
760 _test_generator(N, normalvariate, (0.0, 1.0))
761 _test_generator(N, lognormvariate, (0.0, 1.0))
762 _test_generator(N, vonmisesvariate, (0.0, 1.0))
763 _test_generator(N, gammavariate, (0.01, 1.0))
764 _test_generator(N, gammavariate, (0.1, 1.0))
765 _test_generator(N, gammavariate, (0.1, 2.0))
766 _test_generator(N, gammavariate, (0.5, 1.0))
767 _test_generator(N, gammavariate, (0.9, 1.0))
768 _test_generator(N, gammavariate, (1.0, 1.0))
769 _test_generator(N, gammavariate, (2.0, 1.0))
770 _test_generator(N, gammavariate, (20.0, 1.0))
771 _test_generator(N, gammavariate, (200.0, 1.0))
772 _test_generator(N, gauss, (0.0, 1.0))
773 _test_generator(N, betavariate, (3.0, 3.0))
Tim Peterscd804102001-01-25 20:25:57 +0000774
Tim Peters715c4c42001-01-26 22:56:56 +0000775# Create one instance, seeded from current time, and export its methods
Raymond Hettinger40f62172002-12-29 23:03:38 +0000776# as module-level functions. The functions share state across all uses
777#(both in the user's code and in the Python libraries), but that's fine
778# for most programs and is easier for the casual user than making them
779# instantiate their own Random() instance.
780
Tim Petersd7b5e882001-01-25 03:36:26 +0000781_inst = Random()
782seed = _inst.seed
783random = _inst.random
784uniform = _inst.uniform
785randint = _inst.randint
786choice = _inst.choice
787randrange = _inst.randrange
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000788sample = _inst.sample
Tim Petersd7b5e882001-01-25 03:36:26 +0000789shuffle = _inst.shuffle
790normalvariate = _inst.normalvariate
791lognormvariate = _inst.lognormvariate
Tim Petersd7b5e882001-01-25 03:36:26 +0000792expovariate = _inst.expovariate
793vonmisesvariate = _inst.vonmisesvariate
794gammavariate = _inst.gammavariate
Tim Petersd7b5e882001-01-25 03:36:26 +0000795gauss = _inst.gauss
796betavariate = _inst.betavariate
797paretovariate = _inst.paretovariate
798weibullvariate = _inst.weibullvariate
799getstate = _inst.getstate
800setstate = _inst.setstate
Tim Petersd52269b2001-01-25 06:23:18 +0000801jumpahead = _inst.jumpahead
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000802getrandbits = _inst.getrandbits
Tim Petersd7b5e882001-01-25 03:36:26 +0000803
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000804if __name__ == '__main__':
Tim Petersd7b5e882001-01-25 03:36:26 +0000805 _test()