blob: fd9374a7f18e73ddf815b42023265bf0ffe6f1a5 [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
Raymond Hettinger3fa19d72004-08-31 01:05:15 +000046from math import floor as _floor, ldexp as _ldexp
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 Hettinger356a4592004-08-30 06:14:31 +000052 "getstate","setstate","jumpahead", "WichmannHill", "getrandbits",
53 "HardwareRandom"]
Tim Petersd7b5e882001-01-25 03:36:26 +000054
55NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0)
Tim Petersd7b5e882001-01-25 03:36:26 +000056TWOPI = 2.0*_pi
Tim Petersd7b5e882001-01-25 03:36:26 +000057LOG4 = _log(4.0)
Tim Petersd7b5e882001-01-25 03:36:26 +000058SG_MAGICCONST = 1.0 + _log(4.5)
Raymond Hettinger2f726e92003-10-05 09:09:15 +000059BPF = 53 # Number of bits in a float
Tim Petersd7b5e882001-01-25 03:36:26 +000060
Raymond Hettinger356a4592004-08-30 06:14:31 +000061try:
62 from os import urandom as _urandom
63 from binascii import hexlify as _hexlify
64except ImportError:
65 _urandom = None
Raymond Hettinger356a4592004-08-30 06:14:31 +000066
67
Tim Petersd7b5e882001-01-25 03:36:26 +000068# Translated by Guido van Rossum from C source provided by
Raymond Hettinger40f62172002-12-29 23:03:38 +000069# Adrian Baddeley. Adapted by Raymond Hettinger for use with
Raymond Hettinger3fa19d72004-08-31 01:05:15 +000070# the Mersenne Twister and os.urandom() core generators.
Tim Petersd7b5e882001-01-25 03:36:26 +000071
Raymond Hettinger145a4a02003-01-07 10:25:55 +000072import _random
Raymond Hettinger40f62172002-12-29 23:03:38 +000073
Raymond Hettinger145a4a02003-01-07 10:25:55 +000074class Random(_random.Random):
Raymond Hettingerc32f0332002-05-23 19:44:49 +000075 """Random number generator base class used by bound module functions.
76
77 Used to instantiate instances of Random to get generators that don't
78 share state. Especially useful for multi-threaded programs, creating
79 a different instance of Random for each thread, and using the jumpahead()
80 method to ensure that the generated sequences seen by each thread don't
81 overlap.
82
83 Class Random can also be subclassed if you want to use a different basic
84 generator of your own devising: in that case, override the following
85 methods: random(), seed(), getstate(), setstate() and jumpahead().
Raymond Hettinger2f726e92003-10-05 09:09:15 +000086 Optionally, implement a getrandombits() method so that randrange()
87 can cover arbitrarily large ranges.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +000088
Raymond Hettingerc32f0332002-05-23 19:44:49 +000089 """
Tim Petersd7b5e882001-01-25 03:36:26 +000090
Raymond Hettinger40f62172002-12-29 23:03:38 +000091 VERSION = 2 # used by getstate/setstate
Tim Petersd7b5e882001-01-25 03:36:26 +000092
93 def __init__(self, x=None):
94 """Initialize an instance.
95
96 Optional argument x controls seeding, as for Random.seed().
97 """
98
99 self.seed(x)
Raymond Hettinger40f62172002-12-29 23:03:38 +0000100 self.gauss_next = None
Tim Petersd7b5e882001-01-25 03:36:26 +0000101
Tim Peters0de88fc2001-02-01 04:59:18 +0000102 def seed(self, a=None):
103 """Initialize internal state from hashable object.
Tim Petersd7b5e882001-01-25 03:36:26 +0000104
Raymond Hettinger356a4592004-08-30 06:14:31 +0000105 None or no argument seeds from current time or from a hardware
106 randomness source if available.
Tim Peters0de88fc2001-02-01 04:59:18 +0000107
Tim Petersbcd725f2001-02-01 10:06:53 +0000108 If a is not None or an int or long, hash(a) is used instead.
Tim Petersd7b5e882001-01-25 03:36:26 +0000109 """
110
Raymond Hettinger3081d592003-08-09 18:30:57 +0000111 if a is None:
Raymond Hettinger356a4592004-08-30 06:14:31 +0000112 if _urandom is None:
113 import time
114 a = long(time.time() * 256) # use fractional seconds
115 else:
116 a = long(_hexlify(_urandom(16)), 16)
117
Raymond Hettinger145a4a02003-01-07 10:25:55 +0000118 super(Random, self).seed(a)
Tim Peters46c04e12002-05-05 20:40:00 +0000119 self.gauss_next = None
120
Tim Peterscd804102001-01-25 20:25:57 +0000121 def getstate(self):
122 """Return internal state; can be passed to setstate() later."""
Raymond Hettinger145a4a02003-01-07 10:25:55 +0000123 return self.VERSION, super(Random, self).getstate(), self.gauss_next
Tim Peterscd804102001-01-25 20:25:57 +0000124
125 def setstate(self, state):
126 """Restore internal state from object returned by getstate()."""
127 version = state[0]
Raymond Hettinger40f62172002-12-29 23:03:38 +0000128 if version == 2:
129 version, internalstate, self.gauss_next = state
Raymond Hettinger145a4a02003-01-07 10:25:55 +0000130 super(Random, self).setstate(internalstate)
Tim Peterscd804102001-01-25 20:25:57 +0000131 else:
132 raise ValueError("state with version %s passed to "
133 "Random.setstate() of version %s" %
134 (version, self.VERSION))
135
Tim Peterscd804102001-01-25 20:25:57 +0000136## ---- Methods below this point do not need to be overridden when
137## ---- subclassing for the purpose of using a different core generator.
138
139## -------------------- pickle support -------------------
140
141 def __getstate__(self): # for pickle
142 return self.getstate()
143
144 def __setstate__(self, state): # for pickle
145 self.setstate(state)
146
Raymond Hettinger5f078ff2003-06-24 20:29:04 +0000147 def __reduce__(self):
148 return self.__class__, (), self.getstate()
149
Tim Peterscd804102001-01-25 20:25:57 +0000150## -------------------- integer methods -------------------
151
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000152 def randrange(self, start, stop=None, step=1, int=int, default=None,
153 maxwidth=1L<<BPF):
Tim Petersd7b5e882001-01-25 03:36:26 +0000154 """Choose a random item from range(start, stop[, step]).
155
156 This fixes the problem with randint() which includes the
157 endpoint; in Python this is usually not what you want.
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000158 Do not supply the 'int', 'default', and 'maxwidth' arguments.
Tim Petersd7b5e882001-01-25 03:36:26 +0000159 """
160
161 # This code is a bit messy to make it fast for the
Tim Peters9146f272002-08-16 03:41:39 +0000162 # common case while still doing adequate error checking.
Tim Petersd7b5e882001-01-25 03:36:26 +0000163 istart = int(start)
164 if istart != start:
165 raise ValueError, "non-integer arg 1 for randrange()"
166 if stop is default:
167 if istart > 0:
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000168 if istart >= maxwidth:
169 return self._randbelow(istart)
Tim Petersd7b5e882001-01-25 03:36:26 +0000170 return int(self.random() * istart)
171 raise ValueError, "empty range for randrange()"
Tim Peters9146f272002-08-16 03:41:39 +0000172
173 # stop argument supplied.
Tim Petersd7b5e882001-01-25 03:36:26 +0000174 istop = int(stop)
175 if istop != stop:
176 raise ValueError, "non-integer stop for randrange()"
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000177 width = istop - istart
178 if step == 1 and width > 0:
Tim Peters76ca1d42003-06-19 03:46:46 +0000179 # Note that
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000180 # int(istart + self.random()*width)
Tim Peters76ca1d42003-06-19 03:46:46 +0000181 # instead would be incorrect. For example, consider istart
182 # = -2 and istop = 0. Then the guts would be in
183 # -2.0 to 0.0 exclusive on both ends (ignoring that random()
184 # might return 0.0), and because int() truncates toward 0, the
185 # final result would be -1 or 0 (instead of -2 or -1).
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000186 # istart + int(self.random()*width)
Tim Peters76ca1d42003-06-19 03:46:46 +0000187 # would also be incorrect, for a subtler reason: the RHS
188 # can return a long, and then randrange() would also return
189 # a long, but we're supposed to return an int (for backward
190 # compatibility).
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000191
192 if width >= maxwidth:
Tim Peters58eb11c2004-01-18 20:29:55 +0000193 return int(istart + self._randbelow(width))
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000194 return int(istart + int(self.random()*width))
Tim Petersd7b5e882001-01-25 03:36:26 +0000195 if step == 1:
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000196 raise ValueError, "empty range for randrange() (%d,%d, %d)" % (istart, istop, width)
Tim Peters9146f272002-08-16 03:41:39 +0000197
198 # Non-unit step argument supplied.
Tim Petersd7b5e882001-01-25 03:36:26 +0000199 istep = int(step)
200 if istep != step:
201 raise ValueError, "non-integer step for randrange()"
202 if istep > 0:
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000203 n = (width + istep - 1) / istep
Tim Petersd7b5e882001-01-25 03:36:26 +0000204 elif istep < 0:
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000205 n = (width + istep + 1) / istep
Tim Petersd7b5e882001-01-25 03:36:26 +0000206 else:
207 raise ValueError, "zero step for randrange()"
208
209 if n <= 0:
210 raise ValueError, "empty range for randrange()"
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000211
212 if n >= maxwidth:
213 return istart + self._randbelow(n)
Tim Petersd7b5e882001-01-25 03:36:26 +0000214 return istart + istep*int(self.random() * n)
215
216 def randint(self, a, b):
Tim Peterscd804102001-01-25 20:25:57 +0000217 """Return random integer in range [a, b], including both end points.
Tim Petersd7b5e882001-01-25 03:36:26 +0000218 """
219
220 return self.randrange(a, b+1)
221
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000222 def _randbelow(self, n, _log=_log, int=int, _maxwidth=1L<<BPF,
223 _Method=_MethodType, _BuiltinMethod=_BuiltinMethodType):
224 """Return a random int in the range [0,n)
225
226 Handles the case where n has more bits than returned
227 by a single call to the underlying generator.
228 """
229
230 try:
231 getrandbits = self.getrandbits
232 except AttributeError:
233 pass
234 else:
235 # Only call self.getrandbits if the original random() builtin method
236 # has not been overridden or if a new getrandbits() was supplied.
237 # This assures that the two methods correspond.
238 if type(self.random) is _BuiltinMethod or type(getrandbits) is _Method:
239 k = int(1.00001 + _log(n-1, 2.0)) # 2**k > n-1 > 2**(k-2)
240 r = getrandbits(k)
241 while r >= n:
242 r = getrandbits(k)
243 return r
244 if n >= _maxwidth:
245 _warn("Underlying random() generator does not supply \n"
246 "enough bits to choose from a population range this large")
247 return int(self.random() * n)
248
Tim Peterscd804102001-01-25 20:25:57 +0000249## -------------------- sequence methods -------------------
250
Tim Petersd7b5e882001-01-25 03:36:26 +0000251 def choice(self, seq):
252 """Choose a random element from a non-empty sequence."""
Raymond Hettinger5dae5052004-06-07 02:07:15 +0000253 return seq[int(self.random() * len(seq))] # raises IndexError if seq is empty
Tim Petersd7b5e882001-01-25 03:36:26 +0000254
255 def shuffle(self, x, random=None, int=int):
256 """x, random=random.random -> shuffle list x in place; return None.
257
258 Optional arg random is a 0-argument function returning a random
259 float in [0.0, 1.0); by default, the standard random.random.
260
261 Note that for even rather small len(x), the total number of
262 permutations of x is larger than the period of most random number
263 generators; this implies that "most" permutations of a long
264 sequence can never be generated.
265 """
266
267 if random is None:
268 random = self.random
Raymond Hettinger85c20a42003-11-06 14:06:48 +0000269 for i in reversed(xrange(1, len(x))):
Tim Peterscd804102001-01-25 20:25:57 +0000270 # pick an element in x[:i+1] with which to exchange x[i]
Tim Petersd7b5e882001-01-25 03:36:26 +0000271 j = int(random() * (i+1))
272 x[i], x[j] = x[j], x[i]
273
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000274 def sample(self, population, k):
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000275 """Chooses k unique random elements from a population sequence.
276
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000277 Returns a new list containing elements from the population while
278 leaving the original population unchanged. The resulting list is
279 in selection order so that all sub-slices will also be valid random
280 samples. This allows raffle winners (the sample) to be partitioned
281 into grand prize and second place winners (the subslices).
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000282
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000283 Members of the population need not be hashable or unique. If the
284 population contains repeats, then each occurrence is a possible
285 selection in the sample.
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000286
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000287 To choose a sample in a range of integers, use xrange as an argument.
288 This is especially fast and space efficient for sampling from a
289 large population: sample(xrange(10000000), 60)
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000290 """
291
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000292 # Sampling without replacement entails tracking either potential
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000293 # selections (the pool) in a list or previous selections in a
294 # dictionary.
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000295
Jeremy Hylton2b55d352004-02-23 17:27:57 +0000296 # When the number of selections is small compared to the
297 # population, then tracking selections is efficient, requiring
298 # only a small dictionary and an occasional reselection. For
299 # a larger number of selections, the pool tracking method is
300 # preferred since the list takes less space than the
301 # dictionary and it doesn't suffer from frequent reselections.
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000302
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000303 n = len(population)
304 if not 0 <= k <= n:
305 raise ValueError, "sample larger than population"
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000306 random = self.random
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000307 _int = int
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000308 result = [None] * k
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000309 if n < 6 * k: # if n len list takes less space than a k len dict
Raymond Hettinger311f4192002-11-18 09:01:24 +0000310 pool = list(population)
311 for i in xrange(k): # invariant: non-selected at [0,n-i)
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000312 j = _int(random() * (n-i))
Raymond Hettinger311f4192002-11-18 09:01:24 +0000313 result[i] = pool[j]
Raymond Hettinger8b9aa8d2003-01-04 05:20:33 +0000314 pool[j] = pool[n-i-1] # move non-selected item into vacancy
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000315 else:
Raymond Hettinger66d09f12003-09-06 04:25:54 +0000316 try:
317 n > 0 and (population[0], population[n//2], population[n-1])
318 except (TypeError, KeyError): # handle sets and dictionaries
319 population = tuple(population)
Raymond Hettinger311f4192002-11-18 09:01:24 +0000320 selected = {}
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000321 for i in xrange(k):
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000322 j = _int(random() * n)
Raymond Hettinger311f4192002-11-18 09:01:24 +0000323 while j in selected:
Raymond Hettingerfdbe5222003-06-13 07:01:51 +0000324 j = _int(random() * n)
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000325 result[i] = selected[j] = population[j]
Raymond Hettinger311f4192002-11-18 09:01:24 +0000326 return result
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000327
Tim Peterscd804102001-01-25 20:25:57 +0000328## -------------------- real-valued distributions -------------------
329
330## -------------------- uniform distribution -------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000331
332 def uniform(self, a, b):
333 """Get a random number in the range [a, b)."""
334 return a + (b-a) * self.random()
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000335
Tim Peterscd804102001-01-25 20:25:57 +0000336## -------------------- normal distribution --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000337
Tim Petersd7b5e882001-01-25 03:36:26 +0000338 def normalvariate(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000339 """Normal distribution.
340
341 mu is the mean, and sigma is the standard deviation.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000342
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000343 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000344 # mu = mean, sigma = standard deviation
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000345
Tim Petersd7b5e882001-01-25 03:36:26 +0000346 # Uses Kinderman and Monahan method. Reference: Kinderman,
347 # A.J. and Monahan, J.F., "Computer generation of random
348 # variables using the ratio of uniform deviates", ACM Trans
349 # Math Software, 3, (1977), pp257-260.
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000350
Tim Petersd7b5e882001-01-25 03:36:26 +0000351 random = self.random
Raymond Hettinger311f4192002-11-18 09:01:24 +0000352 while True:
Tim Peters0c9886d2001-01-15 01:18:21 +0000353 u1 = random()
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000354 u2 = 1.0 - random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000355 z = NV_MAGICCONST*(u1-0.5)/u2
356 zz = z*z/4.0
357 if zz <= -_log(u2):
358 break
359 return mu + z*sigma
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000360
Tim Peterscd804102001-01-25 20:25:57 +0000361## -------------------- lognormal distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000362
363 def lognormvariate(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000364 """Log normal distribution.
365
366 If you take the natural logarithm of this distribution, you'll get a
367 normal distribution with mean mu and standard deviation sigma.
368 mu can have any value, and sigma must be greater than zero.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000369
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000370 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000371 return _exp(self.normalvariate(mu, sigma))
372
Tim Peterscd804102001-01-25 20:25:57 +0000373## -------------------- exponential distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000374
375 def expovariate(self, lambd):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000376 """Exponential distribution.
377
378 lambd is 1.0 divided by the desired mean. (The parameter would be
379 called "lambda", but that is a reserved word in Python.) Returned
380 values range from 0 to positive infinity.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000381
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000382 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000383 # lambd: rate lambd = 1/mean
384 # ('lambda' is a Python reserved word)
385
386 random = self.random
Tim Peters0c9886d2001-01-15 01:18:21 +0000387 u = random()
388 while u <= 1e-7:
389 u = random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000390 return -_log(u)/lambd
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000391
Tim Peterscd804102001-01-25 20:25:57 +0000392## -------------------- von Mises distribution --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000393
Tim Petersd7b5e882001-01-25 03:36:26 +0000394 def vonmisesvariate(self, mu, kappa):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000395 """Circular data distribution.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000396
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000397 mu is the mean angle, expressed in radians between 0 and 2*pi, and
398 kappa is the concentration parameter, which must be greater than or
399 equal to zero. If kappa is equal to zero, this distribution reduces
400 to a uniform random angle over the range 0 to 2*pi.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000401
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000402 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000403 # mu: mean angle (in radians between 0 and 2*pi)
404 # kappa: concentration parameter kappa (>= 0)
405 # if kappa = 0 generate uniform random angle
406
407 # Based upon an algorithm published in: Fisher, N.I.,
408 # "Statistical Analysis of Circular Data", Cambridge
409 # University Press, 1993.
410
411 # Thanks to Magnus Kessler for a correction to the
412 # implementation of step 4.
413
414 random = self.random
415 if kappa <= 1e-6:
416 return TWOPI * random()
417
418 a = 1.0 + _sqrt(1.0 + 4.0 * kappa * kappa)
419 b = (a - _sqrt(2.0 * a))/(2.0 * kappa)
420 r = (1.0 + b * b)/(2.0 * b)
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000421
Raymond Hettinger311f4192002-11-18 09:01:24 +0000422 while True:
Tim Peters0c9886d2001-01-15 01:18:21 +0000423 u1 = random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000424
425 z = _cos(_pi * u1)
426 f = (1.0 + r * z)/(r + z)
427 c = kappa * (r - f)
428
429 u2 = random()
430
431 if not (u2 >= c * (2.0 - c) and u2 > c * _exp(1.0 - c)):
Tim Peters0c9886d2001-01-15 01:18:21 +0000432 break
Tim Petersd7b5e882001-01-25 03:36:26 +0000433
434 u3 = random()
435 if u3 > 0.5:
436 theta = (mu % TWOPI) + _acos(f)
437 else:
438 theta = (mu % TWOPI) - _acos(f)
439
440 return theta
441
Tim Peterscd804102001-01-25 20:25:57 +0000442## -------------------- gamma distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000443
444 def gammavariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000445 """Gamma distribution. Not the gamma function!
446
447 Conditions on the parameters are alpha > 0 and beta > 0.
448
449 """
Tim Peters8ac14952002-05-23 15:15:30 +0000450
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000451 # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
Tim Peters8ac14952002-05-23 15:15:30 +0000452
Guido van Rossum570764d2002-05-14 14:08:12 +0000453 # Warning: a few older sources define the gamma distribution in terms
454 # of alpha > -1.0
455 if alpha <= 0.0 or beta <= 0.0:
456 raise ValueError, 'gammavariate: alpha and beta must be > 0.0'
Tim Peters8ac14952002-05-23 15:15:30 +0000457
Tim Petersd7b5e882001-01-25 03:36:26 +0000458 random = self.random
Tim Petersd7b5e882001-01-25 03:36:26 +0000459 if alpha > 1.0:
460
461 # Uses R.C.H. Cheng, "The generation of Gamma
462 # variables with non-integral shape parameters",
463 # Applied Statistics, (1977), 26, No. 1, p71-74
464
Raymond Hettingerca6cdc22002-05-13 23:40:14 +0000465 ainv = _sqrt(2.0 * alpha - 1.0)
466 bbb = alpha - LOG4
467 ccc = alpha + ainv
Tim Peters8ac14952002-05-23 15:15:30 +0000468
Raymond Hettinger311f4192002-11-18 09:01:24 +0000469 while True:
Tim Petersd7b5e882001-01-25 03:36:26 +0000470 u1 = random()
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000471 if not 1e-7 < u1 < .9999999:
472 continue
473 u2 = 1.0 - random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000474 v = _log(u1/(1.0-u1))/ainv
475 x = alpha*_exp(v)
476 z = u1*u1*u2
477 r = bbb+ccc*v-x
478 if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z):
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000479 return x * beta
Tim Petersd7b5e882001-01-25 03:36:26 +0000480
481 elif alpha == 1.0:
482 # expovariate(1)
483 u = random()
484 while u <= 1e-7:
485 u = random()
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000486 return -_log(u) * beta
Tim Petersd7b5e882001-01-25 03:36:26 +0000487
488 else: # alpha is between 0 and 1 (exclusive)
489
490 # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
491
Raymond Hettinger311f4192002-11-18 09:01:24 +0000492 while True:
Tim Petersd7b5e882001-01-25 03:36:26 +0000493 u = random()
494 b = (_e + alpha)/_e
495 p = b*u
496 if p <= 1.0:
497 x = pow(p, 1.0/alpha)
498 else:
499 # p > 1
500 x = -_log((b-p)/alpha)
501 u1 = random()
502 if not (((p <= 1.0) and (u1 > _exp(-x))) or
503 ((p > 1) and (u1 > pow(x, alpha - 1.0)))):
504 break
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000505 return x * beta
506
Tim Peterscd804102001-01-25 20:25:57 +0000507## -------------------- Gauss (faster alternative) --------------------
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000508
Tim Petersd7b5e882001-01-25 03:36:26 +0000509 def gauss(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000510 """Gaussian distribution.
511
512 mu is the mean, and sigma is the standard deviation. This is
513 slightly faster than the normalvariate() function.
514
515 Not thread-safe without a lock around calls.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000516
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000517 """
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000518
Tim Petersd7b5e882001-01-25 03:36:26 +0000519 # When x and y are two variables from [0, 1), uniformly
520 # distributed, then
521 #
522 # cos(2*pi*x)*sqrt(-2*log(1-y))
523 # sin(2*pi*x)*sqrt(-2*log(1-y))
524 #
525 # are two *independent* variables with normal distribution
526 # (mu = 0, sigma = 1).
527 # (Lambert Meertens)
528 # (corrected version; bug discovered by Mike Miller, fixed by LM)
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000529
Tim Petersd7b5e882001-01-25 03:36:26 +0000530 # Multithreading note: When two threads call this function
531 # simultaneously, it is possible that they will receive the
532 # same return value. The window is very small though. To
533 # avoid this, you have to use a lock around all calls. (I
534 # didn't want to slow this down in the serial case by using a
535 # lock here.)
Guido van Rossumd03e1191998-05-29 17:51:31 +0000536
Tim Petersd7b5e882001-01-25 03:36:26 +0000537 random = self.random
538 z = self.gauss_next
539 self.gauss_next = None
540 if z is None:
541 x2pi = random() * TWOPI
542 g2rad = _sqrt(-2.0 * _log(1.0 - random()))
543 z = _cos(x2pi) * g2rad
544 self.gauss_next = _sin(x2pi) * g2rad
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000545
Tim Petersd7b5e882001-01-25 03:36:26 +0000546 return mu + z*sigma
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000547
Tim Peterscd804102001-01-25 20:25:57 +0000548## -------------------- beta --------------------
Tim Peters85e2e472001-01-26 06:49:56 +0000549## See
550## http://sourceforge.net/bugs/?func=detailbug&bug_id=130030&group_id=5470
551## for Ivan Frohne's insightful analysis of why the original implementation:
552##
553## def betavariate(self, alpha, beta):
554## # Discrete Event Simulation in C, pp 87-88.
555##
556## y = self.expovariate(alpha)
557## z = self.expovariate(1.0/beta)
558## return z/(y+z)
559##
560## was dead wrong, and how it probably got that way.
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000561
Tim Petersd7b5e882001-01-25 03:36:26 +0000562 def betavariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000563 """Beta distribution.
564
565 Conditions on the parameters are alpha > -1 and beta} > -1.
566 Returned values range between 0 and 1.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000567
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000568 """
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000569
Tim Peters85e2e472001-01-26 06:49:56 +0000570 # This version due to Janne Sinkkonen, and matches all the std
571 # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
572 y = self.gammavariate(alpha, 1.)
573 if y == 0:
574 return 0.0
575 else:
576 return y / (y + self.gammavariate(beta, 1.))
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000577
Tim Peterscd804102001-01-25 20:25:57 +0000578## -------------------- Pareto --------------------
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000579
Tim Petersd7b5e882001-01-25 03:36:26 +0000580 def paretovariate(self, alpha):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000581 """Pareto distribution. alpha is the shape parameter."""
Tim Petersd7b5e882001-01-25 03:36:26 +0000582 # Jain, pg. 495
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 1.0 / pow(u, 1.0/alpha)
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000586
Tim Peterscd804102001-01-25 20:25:57 +0000587## -------------------- Weibull --------------------
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000588
Tim Petersd7b5e882001-01-25 03:36:26 +0000589 def weibullvariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000590 """Weibull distribution.
591
592 alpha is the scale parameter and beta is the shape parameter.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000593
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000594 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000595 # Jain, pg. 499; bug fix courtesy Bill Arms
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000596
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000597 u = 1.0 - self.random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000598 return alpha * pow(-_log(u), 1.0/beta)
Guido van Rossum6c395ba1999-08-18 13:53:28 +0000599
Raymond Hettinger40f62172002-12-29 23:03:38 +0000600## -------------------- Wichmann-Hill -------------------
601
602class WichmannHill(Random):
603
604 VERSION = 1 # used by getstate/setstate
605
606 def seed(self, a=None):
607 """Initialize internal state from hashable object.
608
Raymond Hettinger356a4592004-08-30 06:14:31 +0000609 None or no argument seeds from current time or from a hardware
610 randomness source if available.
Raymond Hettinger40f62172002-12-29 23:03:38 +0000611
612 If a is not None or an int or long, hash(a) is used instead.
613
614 If a is an int or long, a is used directly. Distinct values between
615 0 and 27814431486575L inclusive are guaranteed to yield distinct
616 internal states (this guarantee is specific to the default
617 Wichmann-Hill generator).
618 """
619
620 if a is None:
Raymond Hettinger356a4592004-08-30 06:14:31 +0000621 if _urandom is None:
622 import time
623 a = long(time.time() * 256) # use fractional seconds
624 else:
625 a = long(_hexlify(_urandom(16)), 16)
Raymond Hettinger40f62172002-12-29 23:03:38 +0000626
627 if not isinstance(a, (int, long)):
628 a = hash(a)
629
630 a, x = divmod(a, 30268)
631 a, y = divmod(a, 30306)
632 a, z = divmod(a, 30322)
633 self._seed = int(x)+1, int(y)+1, int(z)+1
634
635 self.gauss_next = None
636
637 def random(self):
638 """Get the next random number in the range [0.0, 1.0)."""
639
640 # Wichman-Hill random number generator.
641 #
642 # Wichmann, B. A. & Hill, I. D. (1982)
643 # Algorithm AS 183:
644 # An efficient and portable pseudo-random number generator
645 # Applied Statistics 31 (1982) 188-190
646 #
647 # see also:
648 # Correction to Algorithm AS 183
649 # Applied Statistics 33 (1984) 123
650 #
651 # McLeod, A. I. (1985)
652 # A remark on Algorithm AS 183
653 # Applied Statistics 34 (1985),198-200
654
655 # This part is thread-unsafe:
656 # BEGIN CRITICAL SECTION
657 x, y, z = self._seed
658 x = (171 * x) % 30269
659 y = (172 * y) % 30307
660 z = (170 * z) % 30323
661 self._seed = x, y, z
662 # END CRITICAL SECTION
663
664 # Note: on a platform using IEEE-754 double arithmetic, this can
665 # never return 0.0 (asserted by Tim; proof too long for a comment).
666 return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0
667
668 def getstate(self):
669 """Return internal state; can be passed to setstate() later."""
670 return self.VERSION, self._seed, self.gauss_next
671
672 def setstate(self, state):
673 """Restore internal state from object returned by getstate()."""
674 version = state[0]
675 if version == 1:
676 version, self._seed, self.gauss_next = state
677 else:
678 raise ValueError("state with version %s passed to "
679 "Random.setstate() of version %s" %
680 (version, self.VERSION))
681
682 def jumpahead(self, n):
683 """Act as if n calls to random() were made, but quickly.
684
685 n is an int, greater than or equal to 0.
686
687 Example use: If you have 2 threads and know that each will
688 consume no more than a million random numbers, create two Random
689 objects r1 and r2, then do
690 r2.setstate(r1.getstate())
691 r2.jumpahead(1000000)
692 Then r1 and r2 will use guaranteed-disjoint segments of the full
693 period.
694 """
695
696 if not n >= 0:
697 raise ValueError("n must be >= 0")
698 x, y, z = self._seed
699 x = int(x * pow(171, n, 30269)) % 30269
700 y = int(y * pow(172, n, 30307)) % 30307
701 z = int(z * pow(170, n, 30323)) % 30323
702 self._seed = x, y, z
703
704 def __whseed(self, x=0, y=0, z=0):
705 """Set the Wichmann-Hill seed from (x, y, z).
706
707 These must be integers in the range [0, 256).
708 """
709
710 if not type(x) == type(y) == type(z) == int:
711 raise TypeError('seeds must be integers')
712 if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256):
713 raise ValueError('seeds must be in range(0, 256)')
714 if 0 == x == y == z:
715 # Initialize from current time
716 import time
717 t = long(time.time() * 256)
718 t = int((t&0xffffff) ^ (t>>24))
719 t, x = divmod(t, 256)
720 t, y = divmod(t, 256)
721 t, z = divmod(t, 256)
722 # Zero is a poor seed, so substitute 1
723 self._seed = (x or 1, y or 1, z or 1)
724
725 self.gauss_next = None
726
727 def whseed(self, a=None):
728 """Seed from hashable object's hash code.
729
730 None or no argument seeds from current time. It is not guaranteed
731 that objects with distinct hash codes lead to distinct internal
732 states.
733
734 This is obsolete, provided for compatibility with the seed routine
735 used prior to Python 2.1. Use the .seed() method instead.
736 """
737
738 if a is None:
739 self.__whseed()
740 return
741 a = hash(a)
742 a, x = divmod(a, 256)
743 a, y = divmod(a, 256)
744 a, z = divmod(a, 256)
745 x = (x + a) % 256 or 1
746 y = (y + a) % 256 or 1
747 z = (z + a) % 256 or 1
748 self.__whseed(x, y, z)
749
Raymond Hettinger356a4592004-08-30 06:14:31 +0000750## -------------------- Hardware Random Source -------------------
751
752class HardwareRandom(Random):
753 """Alternate random number generator using hardware sources.
754
755 Not available on all systems (see os.urandom() for details).
756 """
757
758 def random(self):
759 """Get the next random number in the range [0.0, 1.0)."""
760 if _urandom is None:
761 raise NotImplementedError('Cannot find hardware entropy source')
Raymond Hettinger3fa19d72004-08-31 01:05:15 +0000762 return _ldexp(long(_hexlify(_urandom(7)), 16) >> 3, -BPF)
Raymond Hettinger356a4592004-08-30 06:14:31 +0000763
764 def getrandbits(self, k):
765 """getrandbits(k) -> x. Generates a long int with k random bits."""
766 if _urandom is None:
767 raise NotImplementedError('Cannot find hardware entropy source')
768 if k <= 0:
769 raise ValueError('number of bits must be greater than zero')
770 if k != int(k):
771 raise TypeError('number of bits should be an integer')
772 bytes = (k + 7) // 8 # bits / 8 and rounded up
773 x = long(_hexlify(_urandom(bytes)), 16)
774 return x >> (bytes * 8 - k) # trim excess bits
775
776 def _stub(self, *args, **kwds):
777 "Stub method. Not used for a hardware random number generator."
778 return None
779 seed = jumpahead = _stub
780
781 def _notimplemented(self, *args, **kwds):
782 "Method should not be called for a hardware random number generator."
783 raise NotImplementedError('Hardware entropy source does not have state.')
784 getstate = setstate = _notimplemented
785
Tim Peterscd804102001-01-25 20:25:57 +0000786## -------------------- test program --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000787
Raymond Hettinger62297132003-08-30 01:24:19 +0000788def _test_generator(n, func, args):
Tim Peters0c9886d2001-01-15 01:18:21 +0000789 import time
Raymond Hettinger62297132003-08-30 01:24:19 +0000790 print n, 'times', func.__name__
Raymond Hettingerb98154e2003-05-24 17:26:02 +0000791 total = 0.0
Tim Peters0c9886d2001-01-15 01:18:21 +0000792 sqsum = 0.0
793 smallest = 1e10
794 largest = -1e10
795 t0 = time.time()
796 for i in range(n):
Raymond Hettinger62297132003-08-30 01:24:19 +0000797 x = func(*args)
Raymond Hettingerb98154e2003-05-24 17:26:02 +0000798 total += x
Tim Peters0c9886d2001-01-15 01:18:21 +0000799 sqsum = sqsum + x*x
800 smallest = min(x, smallest)
801 largest = max(x, largest)
802 t1 = time.time()
803 print round(t1-t0, 3), 'sec,',
Raymond Hettingerb98154e2003-05-24 17:26:02 +0000804 avg = total/n
Tim Petersd7b5e882001-01-25 03:36:26 +0000805 stddev = _sqrt(sqsum/n - avg*avg)
Tim Peters0c9886d2001-01-15 01:18:21 +0000806 print 'avg %g, stddev %g, min %g, max %g' % \
807 (avg, stddev, smallest, largest)
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000808
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000809
810def _test(N=2000):
Raymond Hettinger62297132003-08-30 01:24:19 +0000811 _test_generator(N, random, ())
812 _test_generator(N, normalvariate, (0.0, 1.0))
813 _test_generator(N, lognormvariate, (0.0, 1.0))
814 _test_generator(N, vonmisesvariate, (0.0, 1.0))
815 _test_generator(N, gammavariate, (0.01, 1.0))
816 _test_generator(N, gammavariate, (0.1, 1.0))
817 _test_generator(N, gammavariate, (0.1, 2.0))
818 _test_generator(N, gammavariate, (0.5, 1.0))
819 _test_generator(N, gammavariate, (0.9, 1.0))
820 _test_generator(N, gammavariate, (1.0, 1.0))
821 _test_generator(N, gammavariate, (2.0, 1.0))
822 _test_generator(N, gammavariate, (20.0, 1.0))
823 _test_generator(N, gammavariate, (200.0, 1.0))
824 _test_generator(N, gauss, (0.0, 1.0))
825 _test_generator(N, betavariate, (3.0, 3.0))
Tim Peterscd804102001-01-25 20:25:57 +0000826
Tim Peters715c4c42001-01-26 22:56:56 +0000827# Create one instance, seeded from current time, and export its methods
Raymond Hettinger40f62172002-12-29 23:03:38 +0000828# as module-level functions. The functions share state across all uses
829#(both in the user's code and in the Python libraries), but that's fine
830# for most programs and is easier for the casual user than making them
831# instantiate their own Random() instance.
832
Tim Petersd7b5e882001-01-25 03:36:26 +0000833_inst = Random()
834seed = _inst.seed
835random = _inst.random
836uniform = _inst.uniform
837randint = _inst.randint
838choice = _inst.choice
839randrange = _inst.randrange
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000840sample = _inst.sample
Tim Petersd7b5e882001-01-25 03:36:26 +0000841shuffle = _inst.shuffle
842normalvariate = _inst.normalvariate
843lognormvariate = _inst.lognormvariate
Tim Petersd7b5e882001-01-25 03:36:26 +0000844expovariate = _inst.expovariate
845vonmisesvariate = _inst.vonmisesvariate
846gammavariate = _inst.gammavariate
Tim Petersd7b5e882001-01-25 03:36:26 +0000847gauss = _inst.gauss
848betavariate = _inst.betavariate
849paretovariate = _inst.paretovariate
850weibullvariate = _inst.weibullvariate
851getstate = _inst.getstate
852setstate = _inst.setstate
Tim Petersd52269b2001-01-25 06:23:18 +0000853jumpahead = _inst.jumpahead
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000854getrandbits = _inst.getrandbits
Tim Petersd7b5e882001-01-25 03:36:26 +0000855
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000856if __name__ == '__main__':
Tim Petersd7b5e882001-01-25 03:36:26 +0000857 _test()