blob: a4128c28fb2c6b08c2654da79c9fde04f5d9ba59 [file] [log] [blame]
Guido van Rossume7b146f2000-02-04 15:28:42 +00001"""Random variable generators.
Guido van Rossumff03b1a1994-03-09 12:55:02 +00002
Raymond Hettingeref19bad2020-06-25 17:03:50 -07003 bytes
4 -----
5 uniform bytes (values between 0 and 255)
6
Tim Petersd7b5e882001-01-25 03:36:26 +00007 integers
8 --------
9 uniform within range
10
11 sequences
12 ---------
13 pick random element
Raymond Hettingerf24eb352002-11-12 17:41:57 +000014 pick random sample
Raymond Hettingere8f1e002016-09-06 17:15:29 -070015 pick weighted random sample
Tim Petersd7b5e882001-01-25 03:36:26 +000016 generate random permutation
17
Guido van Rossume7b146f2000-02-04 15:28:42 +000018 distributions on the real line:
19 ------------------------------
Tim Petersd7b5e882001-01-25 03:36:26 +000020 uniform
Christian Heimesfe337bf2008-03-23 21:54:12 +000021 triangular
Guido van Rossume7b146f2000-02-04 15:28:42 +000022 normal (Gaussian)
23 lognormal
24 negative exponential
25 gamma
26 beta
Raymond Hettinger40f62172002-12-29 23:03:38 +000027 pareto
28 Weibull
Guido van Rossumff03b1a1994-03-09 12:55:02 +000029
Guido van Rossume7b146f2000-02-04 15:28:42 +000030 distributions on the circle (angles 0 to 2pi)
31 ---------------------------------------------
32 circular uniform
33 von Mises
34
Raymond Hettinger40f62172002-12-29 23:03:38 +000035General notes on the underlying Mersenne Twister core generator:
Guido van Rossume7b146f2000-02-04 15:28:42 +000036
Raymond Hettinger40f62172002-12-29 23:03:38 +000037* The period is 2**19937-1.
Thomas Wouters0e3f5912006-08-11 14:57:12 +000038* It is one of the most extensively tested generators in existence.
Thomas Wouters0e3f5912006-08-11 14:57:12 +000039* The random() method is implemented in C, executes in a single Python step,
40 and is, therefore, threadsafe.
Tim Peterse360d952001-01-26 10:00:39 +000041
Guido van Rossume7b146f2000-02-04 15:28:42 +000042"""
Guido van Rossumd03e1191998-05-29 17:51:31 +000043
Raymond Hettingeref19bad2020-06-25 17:03:50 -070044# Translated by Guido van Rossum from C source provided by
45# Adrian Baddeley. Adapted by Raymond Hettinger for use with
46# the Mersenne Twister and os.urandom() core generators.
47
Raymond Hettinger2f726e92003-10-05 09:09:15 +000048from warnings import warn as _warn
Raymond Hettinger91e27c22005-08-19 01:36:35 +000049from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
Raymond Hettinger26a1ad12020-06-22 19:38:59 -070050from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
Ram Rachumb0dfc752020-09-29 04:32:10 +030051from math import tau as TWOPI, floor as _floor, isfinite as _isfinite
Raymond Hettingerc1c43ca2004-09-05 00:00:42 +000052from os import urandom as _urandom
Christian Heimesf1dc3ee2013-10-13 02:04:20 +020053from _collections_abc import Set as _Set, Sequence as _Sequence
Raymond Hettingera9621bb2020-12-28 11:10:34 -080054from operator import index as _index
Raymond Hettinger53822032019-02-16 13:30:51 -080055from itertools import accumulate as _accumulate, repeat as _repeat
Raymond Hettingercfd31f02019-02-13 02:04:17 -080056from bisect import bisect as _bisect
Antoine Pitrou346cbd32017-05-27 17:50:54 +020057import os as _os
Raymond Hettingeref19bad2020-06-25 17:03:50 -070058import _random
Guido van Rossumff03b1a1994-03-09 12:55:02 +000059
Christian Heimesd9145962019-04-10 22:18:02 +020060try:
61 # hashlib is pretty heavy to load, try lean internal module first
62 from _sha512 import sha512 as _sha512
63except ImportError:
64 # fallback to official implementation
65 from hashlib import sha512 as _sha512
66
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -070067__all__ = [
68 "Random",
69 "SystemRandom",
70 "betavariate",
71 "choice",
72 "choices",
73 "expovariate",
74 "gammavariate",
75 "gauss",
76 "getrandbits",
77 "getstate",
78 "lognormvariate",
79 "normalvariate",
80 "paretovariate",
81 "randint",
82 "random",
83 "randrange",
84 "sample",
85 "seed",
86 "setstate",
87 "shuffle",
88 "triangular",
89 "uniform",
90 "vonmisesvariate",
91 "weibullvariate",
92]
Tim Petersd7b5e882001-01-25 03:36:26 +000093
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -070094NV_MAGICCONST = 4 * _exp(-0.5) / _sqrt(2.0)
Tim Petersd7b5e882001-01-25 03:36:26 +000095LOG4 = _log(4.0)
Tim Petersd7b5e882001-01-25 03:36:26 +000096SG_MAGICCONST = 1.0 + _log(4.5)
Raymond Hettinger2f726e92003-10-05 09:09:15 +000097BPF = 53 # Number of bits in a float
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -070098RECIP_BPF = 2 ** -BPF
Tim Petersd7b5e882001-01-25 03:36:26 +000099
Raymond Hettinger356a4592004-08-30 06:14:31 +0000100
Raymond Hettinger145a4a02003-01-07 10:25:55 +0000101class Random(_random.Random):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000102 """Random number generator base class used by bound module functions.
103
104 Used to instantiate instances of Random to get generators that don't
Raymond Hettinger28de64f2008-01-13 23:40:30 +0000105 share state.
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000106
107 Class Random can also be subclassed if you want to use a different basic
108 generator of your own devising: in that case, override the following
Raymond Hettinger28de64f2008-01-13 23:40:30 +0000109 methods: random(), seed(), getstate(), and setstate().
Benjamin Petersond18de0e2008-07-31 20:21:46 +0000110 Optionally, implement a getrandbits() method so that randrange()
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000111 can cover arbitrarily large ranges.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000112
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000113 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000114
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000115 VERSION = 3 # used by getstate/setstate
Tim Petersd7b5e882001-01-25 03:36:26 +0000116
117 def __init__(self, x=None):
118 """Initialize an instance.
119
120 Optional argument x controls seeding, as for Random.seed().
121 """
122
123 self.seed(x)
Raymond Hettinger40f62172002-12-29 23:03:38 +0000124 self.gauss_next = None
Tim Petersd7b5e882001-01-25 03:36:26 +0000125
Raymond Hettingerf763a722010-09-07 00:38:15 +0000126 def seed(self, a=None, version=2):
Raymond Hettingerd0cdeaa2019-08-22 09:19:36 -0700127 """Initialize internal state from a seed.
128
129 The only supported seed types are None, int, float,
130 str, bytes, and bytearray.
Tim Petersd7b5e882001-01-25 03:36:26 +0000131
Raymond Hettinger23f12412004-09-13 22:23:21 +0000132 None or no argument seeds from current time or from an operating
133 system specific randomness source if available.
Tim Peters0de88fc2001-02-01 04:59:18 +0000134
Raymond Hettinger183cd1f2010-09-08 18:48:21 +0000135 If *a* is an int, all bits are used.
Raymond Hettingerf763a722010-09-07 00:38:15 +0000136
Raymond Hettinger16eb8272016-09-04 11:17:28 -0700137 For version 2 (the default), all of the bits are used if *a* is a str,
138 bytes, or bytearray. For version 1 (provided for reproducing random
139 sequences from older versions of Python), the algorithm for str and
140 bytes generates a narrower range of seeds.
141
Tim Petersd7b5e882001-01-25 03:36:26 +0000142 """
143
Raymond Hettingerc7bab7c2016-08-31 15:01:08 -0700144 if version == 1 and isinstance(a, (str, bytes)):
Raymond Hettinger132a7d72017-09-17 09:04:30 -0700145 a = a.decode('latin-1') if isinstance(a, bytes) else a
Raymond Hettingerc7bab7c2016-08-31 15:01:08 -0700146 x = ord(a[0]) << 7 if a else 0
Raymond Hettinger132a7d72017-09-17 09:04:30 -0700147 for c in map(ord, a):
148 x = ((1000003 * x) ^ c) & 0xFFFFFFFFFFFFFFFF
Raymond Hettingerc7bab7c2016-08-31 15:01:08 -0700149 x ^= len(a)
150 a = -2 if x == -1 else x
151
Raymond Hettingerd0cdeaa2019-08-22 09:19:36 -0700152 elif version == 2 and isinstance(a, (str, bytes, bytearray)):
Raymond Hettinger2f9cc7a2016-08-31 23:00:32 -0700153 if isinstance(a, str):
154 a = a.encode()
155 a += _sha512(a).digest()
156 a = int.from_bytes(a, 'big')
Raymond Hettingerf763a722010-09-07 00:38:15 +0000157
Raymond Hettingerd0cdeaa2019-08-22 09:19:36 -0700158 elif not isinstance(a, (type(None), int, float, str, bytes, bytearray)):
159 _warn('Seeding based on hashing is deprecated\n'
160 'since Python 3.9 and will be removed in a subsequent '
161 'version. The only \n'
162 'supported seed types are: None, '
163 'int, float, str, bytes, and bytearray.',
164 DeprecationWarning, 2)
165
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000166 super().seed(a)
Tim Peters46c04e12002-05-05 20:40:00 +0000167 self.gauss_next = None
168
Tim Peterscd804102001-01-25 20:25:57 +0000169 def getstate(self):
170 """Return internal state; can be passed to setstate() later."""
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000171 return self.VERSION, super().getstate(), self.gauss_next
Tim Peterscd804102001-01-25 20:25:57 +0000172
173 def setstate(self, state):
174 """Restore internal state from object returned by getstate()."""
175 version = state[0]
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000176 if version == 3:
Raymond Hettinger40f62172002-12-29 23:03:38 +0000177 version, internalstate, self.gauss_next = state
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000178 super().setstate(internalstate)
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000179 elif version == 2:
180 version, internalstate, self.gauss_next = state
181 # In version 2, the state was saved as signed ints, which causes
182 # inconsistencies between 32/64-bit systems. The state is
183 # really unsigned 32-bit ints, so we convert negative ints from
184 # version 2 to positive longs for version 3.
185 try:
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700186 internalstate = tuple(x % (2 ** 32) for x in internalstate)
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000187 except ValueError as e:
188 raise TypeError from e
Raymond Hettinger183cd1f2010-09-08 18:48:21 +0000189 super().setstate(internalstate)
Tim Peterscd804102001-01-25 20:25:57 +0000190 else:
191 raise ValueError("state with version %s passed to "
192 "Random.setstate() of version %s" %
193 (version, self.VERSION))
194
Tim Peterscd804102001-01-25 20:25:57 +0000195
Raymond Hettingeref19bad2020-06-25 17:03:50 -0700196 ## -------------------------------------------------------
197 ## ---- Methods below this point do not need to be overridden or extended
198 ## ---- when subclassing for the purpose of using a different core generator.
Victor Stinner2d875772020-04-29 18:49:00 +0200199
Victor Stinner2d875772020-04-29 18:49:00 +0200200
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700201 ## -------------------- pickle support -------------------
Tim Peterscd804102001-01-25 20:25:57 +0000202
R David Murrayd9ebf4d2013-04-02 13:10:52 -0400203 # Issue 17489: Since __reduce__ was defined to fix #759889 this is no
204 # longer called; we leave it here because it has been here since random was
205 # rewritten back in 2001 and why risk breaking something.
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700206 def __getstate__(self): # for pickle
Tim Peterscd804102001-01-25 20:25:57 +0000207 return self.getstate()
208
209 def __setstate__(self, state): # for pickle
210 self.setstate(state)
211
Raymond Hettinger5f078ff2003-06-24 20:29:04 +0000212 def __reduce__(self):
213 return self.__class__, (), self.getstate()
214
Raymond Hettingeref19bad2020-06-25 17:03:50 -0700215
216 ## ---- internal support method for evenly distributed integers ----
217
218 def __init_subclass__(cls, /, **kwargs):
219 """Control how subclasses generate random integers.
220
221 The algorithm a subclass can use depends on the random() and/or
222 getrandbits() implementation available to it and determines
223 whether it can generate random integers from arbitrarily large
224 ranges.
225 """
226
227 for c in cls.__mro__:
228 if '_randbelow' in c.__dict__:
229 # just inherit it
230 break
231 if 'getrandbits' in c.__dict__:
232 cls._randbelow = cls._randbelow_with_getrandbits
233 break
234 if 'random' in c.__dict__:
235 cls._randbelow = cls._randbelow_without_getrandbits
236 break
237
238 def _randbelow_with_getrandbits(self, n):
239 "Return a random int in the range [0,n). Returns 0 if n==0."
240
241 if not n:
242 return 0
243 getrandbits = self.getrandbits
244 k = n.bit_length() # don't use (n-1) here because n can be 1
245 r = getrandbits(k) # 0 <= r < 2**k
246 while r >= n:
247 r = getrandbits(k)
248 return r
249
250 def _randbelow_without_getrandbits(self, n, maxsize=1<<BPF):
251 """Return a random int in the range [0,n). Returns 0 if n==0.
252
253 The implementation does not use getrandbits, but only random.
254 """
255
256 random = self.random
257 if n >= maxsize:
258 _warn("Underlying random() generator does not supply \n"
259 "enough bits to choose from a population range this large.\n"
260 "To remove the range limitation, add a getrandbits() method.")
261 return _floor(random() * n)
262 if n == 0:
263 return 0
264 rem = maxsize % n
265 limit = (maxsize - rem) / maxsize # int(limit * maxsize) % n == 0
266 r = random()
267 while r >= limit:
268 r = random()
269 return _floor(r * maxsize) % n
270
271 _randbelow = _randbelow_with_getrandbits
272
273
274 ## --------------------------------------------------------
275 ## ---- Methods below this point generate custom distributions
276 ## ---- based on the methods defined above. They do not
277 ## ---- directly touch the underlying generator and only
278 ## ---- access randomness through the methods: random(),
279 ## ---- getrandbits(), or _randbelow().
280
281
282 ## -------------------- bytes methods ---------------------
283
284 def randbytes(self, n):
285 """Generate n random bytes."""
286 return self.getrandbits(n * 8).to_bytes(n, 'little')
287
288
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700289 ## -------------------- integer methods -------------------
Tim Peterscd804102001-01-25 20:25:57 +0000290
Raymond Hettinger26a1ad12020-06-22 19:38:59 -0700291 def randrange(self, start, stop=None, step=1):
Tim Petersd7b5e882001-01-25 03:36:26 +0000292 """Choose a random item from range(start, stop[, step]).
293
294 This fixes the problem with randint() which includes the
295 endpoint; in Python this is usually not what you want.
Raymond Hettinger3051cc32010-09-07 00:48:40 +0000296
Tim Petersd7b5e882001-01-25 03:36:26 +0000297 """
298
299 # This code is a bit messy to make it fast for the
Tim Peters9146f272002-08-16 03:41:39 +0000300 # common case while still doing adequate error checking.
Raymond Hettingera9621bb2020-12-28 11:10:34 -0800301 try:
302 istart = _index(start)
303 except TypeError:
304 if int(start) == start:
305 istart = int(start)
306 _warn('Float arguments to randrange() have been deprecated\n'
307 'since Python 3.10 and will be removed in a subsequent '
308 'version.',
309 DeprecationWarning, 2)
310 else:
311 _warn('randrange() will raise TypeError in the future',
312 DeprecationWarning, 2)
313 raise ValueError("non-integer arg 1 for randrange()")
Raymond Hettinger3051cc32010-09-07 00:48:40 +0000314 if stop is None:
Tim Petersd7b5e882001-01-25 03:36:26 +0000315 if istart > 0:
Raymond Hettinger05156612010-09-07 04:44:52 +0000316 return self._randbelow(istart)
Collin Winterce36ad82007-08-30 01:19:48 +0000317 raise ValueError("empty range for randrange()")
Tim Peters9146f272002-08-16 03:41:39 +0000318
319 # stop argument supplied.
Raymond Hettingera9621bb2020-12-28 11:10:34 -0800320 try:
321 istop = _index(stop)
322 except TypeError:
323 if int(stop) == stop:
324 istop = int(stop)
325 _warn('Float arguments to randrange() have been deprecated\n'
326 'since Python 3.10 and will be removed in a subsequent '
327 'version.',
328 DeprecationWarning, 2)
329 else:
330 _warn('randrange() will raise TypeError in the future',
331 DeprecationWarning, 2)
332 raise ValueError("non-integer stop for randrange()")
333
334 try:
335 istep = _index(step)
336 except TypeError:
337 if int(step) == step:
338 istep = int(step)
339 _warn('Float arguments to randrange() have been deprecated\n'
340 'since Python 3.10 and will be removed in a subsequent '
341 'version.',
342 DeprecationWarning, 2)
343 else:
344 _warn('randrange() will raise TypeError in the future',
345 DeprecationWarning, 2)
346 raise ValueError("non-integer step for randrange()")
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000347 width = istop - istart
Raymond Hettingera9621bb2020-12-28 11:10:34 -0800348 if istep == 1 and width > 0:
Raymond Hettingerc3246972010-09-07 09:32:57 +0000349 return istart + self._randbelow(width)
Raymond Hettingera9621bb2020-12-28 11:10:34 -0800350 if istep == 1:
Kumar Akshay2433a2a2019-01-22 00:49:59 +0530351 raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width))
Tim Peters9146f272002-08-16 03:41:39 +0000352
353 # Non-unit step argument supplied.
Tim Petersd7b5e882001-01-25 03:36:26 +0000354 if istep > 0:
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +0000355 n = (width + istep - 1) // istep
Tim Petersd7b5e882001-01-25 03:36:26 +0000356 elif istep < 0:
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +0000357 n = (width + istep + 1) // istep
Tim Petersd7b5e882001-01-25 03:36:26 +0000358 else:
Collin Winterce36ad82007-08-30 01:19:48 +0000359 raise ValueError("zero step for randrange()")
Tim Petersd7b5e882001-01-25 03:36:26 +0000360
361 if n <= 0:
Collin Winterce36ad82007-08-30 01:19:48 +0000362 raise ValueError("empty range for randrange()")
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000363
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700364 return istart + istep * self._randbelow(n)
Tim Petersd7b5e882001-01-25 03:36:26 +0000365
366 def randint(self, a, b):
Tim Peterscd804102001-01-25 20:25:57 +0000367 """Return random integer in range [a, b], including both end points.
Tim Petersd7b5e882001-01-25 03:36:26 +0000368 """
369
370 return self.randrange(a, b+1)
371
Wolfgang Maierba3a87a2018-04-17 17:16:17 +0200372
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700373 ## -------------------- sequence methods -------------------
Tim Peterscd804102001-01-25 20:25:57 +0000374
Tim Petersd7b5e882001-01-25 03:36:26 +0000375 def choice(self, seq):
376 """Choose a random element from a non-empty sequence."""
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700377 # raises IndexError if seq is empty
378 return seq[self._randbelow(len(seq))]
Tim Petersd7b5e882001-01-25 03:36:26 +0000379
Raymond Hettinger8fe47c32013-10-05 21:48:21 -0700380 def shuffle(self, x, random=None):
Antoine Pitrou5e394332012-11-04 02:10:33 +0100381 """Shuffle list x in place, and return None.
Tim Petersd7b5e882001-01-25 03:36:26 +0000382
Antoine Pitrou5e394332012-11-04 02:10:33 +0100383 Optional argument random is a 0-argument function returning a
384 random float in [0.0, 1.0); if it is the default None, the
385 standard random.random will be used.
Senthil Kumaranf8ce51a2013-09-11 22:54:31 -0700386
Tim Petersd7b5e882001-01-25 03:36:26 +0000387 """
388
Raymond Hettinger8fe47c32013-10-05 21:48:21 -0700389 if random is None:
390 randbelow = self._randbelow
391 for i in reversed(range(1, len(x))):
392 # pick an element in x[:i+1] with which to exchange x[i]
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700393 j = randbelow(i + 1)
Raymond Hettinger8fe47c32013-10-05 21:48:21 -0700394 x[i], x[j] = x[j], x[i]
395 else:
Raymond Hettinger190fac92020-05-02 16:45:32 -0700396 _warn('The *random* parameter to shuffle() has been deprecated\n'
397 'since Python 3.9 and will be removed in a subsequent '
398 'version.',
399 DeprecationWarning, 2)
Raymond Hettinger26a1ad12020-06-22 19:38:59 -0700400 floor = _floor
Raymond Hettinger8fe47c32013-10-05 21:48:21 -0700401 for i in reversed(range(1, len(x))):
402 # pick an element in x[:i+1] with which to exchange x[i]
Raymond Hettinger26a1ad12020-06-22 19:38:59 -0700403 j = floor(random() * (i + 1))
Raymond Hettinger8fe47c32013-10-05 21:48:21 -0700404 x[i], x[j] = x[j], x[i]
Tim Petersd7b5e882001-01-25 03:36:26 +0000405
Raymond Hettinger81a5fc32020-05-08 07:53:15 -0700406 def sample(self, population, k, *, counts=None):
Raymond Hettinger1acde192008-01-14 01:00:53 +0000407 """Chooses k unique random elements from a population sequence or set.
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000408
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000409 Returns a new list containing elements from the population while
410 leaving the original population unchanged. The resulting list is
411 in selection order so that all sub-slices will also be valid random
412 samples. This allows raffle winners (the sample) to be partitioned
413 into grand prize and second place winners (the subslices).
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000414
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000415 Members of the population need not be hashable or unique. If the
416 population contains repeats, then each occurrence is a possible
417 selection in the sample.
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000418
Raymond Hettinger81a5fc32020-05-08 07:53:15 -0700419 Repeated elements can be specified one at a time or with the optional
420 counts parameter. For example:
421
422 sample(['red', 'blue'], counts=[4, 2], k=5)
423
424 is equivalent to:
425
426 sample(['red', 'red', 'red', 'red', 'blue', 'blue'], k=5)
427
428 To choose a sample from a range of integers, use range() for the
429 population argument. This is especially fast and space efficient
430 for sampling from a large population:
431
432 sample(range(10000000), 60)
433
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000434 """
435
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000436 # Sampling without replacement entails tracking either potential
Raymond Hettinger91e27c22005-08-19 01:36:35 +0000437 # selections (the pool) in a list or previous selections in a set.
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000438
Jeremy Hylton2b55d352004-02-23 17:27:57 +0000439 # When the number of selections is small compared to the
440 # population, then tracking selections is efficient, requiring
Raymond Hettinger91e27c22005-08-19 01:36:35 +0000441 # only a small set and an occasional reselection. For
Jeremy Hylton2b55d352004-02-23 17:27:57 +0000442 # a larger number of selections, the pool tracking method is
443 # preferred since the list takes less space than the
Raymond Hettinger91e27c22005-08-19 01:36:35 +0000444 # set and it doesn't suffer from frequent reselections.
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000445
Raymond Hettinger7fc633f2018-12-04 00:13:38 -0800446 # The number of calls to _randbelow() is kept at or near k, the
447 # theoretical minimum. This is important because running time
448 # is dominated by _randbelow() and because it extracts the
449 # least entropy from the underlying random number generators.
450
451 # Memory requirements are kept to the smaller of a k-length
452 # set or an n-length list.
453
454 # There are other sampling algorithms that do not require
455 # auxiliary memory, but they were rejected because they made
456 # too many calls to _randbelow(), making them slower and
457 # causing them to eat more entropy than necessary.
458
Raymond Hettinger57d1a882011-02-23 00:46:28 +0000459 if not isinstance(population, _Sequence):
masklinn1e27b572020-12-19 05:33:36 +0100460 if isinstance(population, _Set):
461 _warn('Sampling from a set deprecated\n'
462 'since Python 3.9 and will be removed in a subsequent version.',
463 DeprecationWarning, 2)
464 population = tuple(population)
465 else:
466 raise TypeError("Population must be a sequence. For dicts or sets, use sorted(d).")
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000467 n = len(population)
Raymond Hettinger81a5fc32020-05-08 07:53:15 -0700468 if counts is not None:
469 cum_counts = list(_accumulate(counts))
470 if len(cum_counts) != n:
471 raise ValueError('The number of counts does not match the population')
472 total = cum_counts.pop()
473 if not isinstance(total, int):
474 raise TypeError('Counts must be integers')
475 if total <= 0:
476 raise ValueError('Total of counts must be greater than zero')
477 selections = sample(range(total), k=k)
478 bisect = _bisect
479 return [population[bisect(cum_counts, s)] for s in selections]
480 randbelow = self._randbelow
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000481 if not 0 <= k <= n:
Raymond Hettingerbf871262016-11-21 14:34:33 -0800482 raise ValueError("Sample larger than population or is negative")
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000483 result = [None] * k
Raymond Hettinger91e27c22005-08-19 01:36:35 +0000484 setsize = 21 # size of a small set minus size of an empty list
485 if k > 5:
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700486 setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets
Raymond Hettinger1acde192008-01-14 01:00:53 +0000487 if n <= setsize:
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700488 # An n-length list is smaller than a k-length set.
489 # Invariant: non-selected at pool[0 : n-i]
Raymond Hettinger311f4192002-11-18 09:01:24 +0000490 pool = list(population)
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700491 for i in range(k):
492 j = randbelow(n - i)
Raymond Hettinger311f4192002-11-18 09:01:24 +0000493 result[i] = pool[j]
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700494 pool[j] = pool[n - i - 1] # move non-selected item into vacancy
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000495 else:
Raymond Hettinger1acde192008-01-14 01:00:53 +0000496 selected = set()
497 selected_add = selected.add
498 for i in range(k):
Raymond Hettinger05a505f2010-09-07 19:19:33 +0000499 j = randbelow(n)
Raymond Hettinger1acde192008-01-14 01:00:53 +0000500 while j in selected:
Raymond Hettinger05a505f2010-09-07 19:19:33 +0000501 j = randbelow(n)
Raymond Hettinger1acde192008-01-14 01:00:53 +0000502 selected_add(j)
503 result[i] = population[j]
Raymond Hettinger311f4192002-11-18 09:01:24 +0000504 return result
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000505
Raymond Hettinger9016f282016-09-26 21:45:57 -0700506 def choices(self, population, weights=None, *, cum_weights=None, k=1):
Raymond Hettingere8f1e002016-09-06 17:15:29 -0700507 """Return a k sized list of population elements chosen with replacement.
508
509 If the relative weights or cumulative weights are not specified,
510 the selections are made with equal probability.
511
512 """
Raymond Hettinger30d00e52016-10-29 16:55:36 -0700513 random = self.random
Raymond Hettingere69cd162018-07-04 15:28:20 -0700514 n = len(population)
Raymond Hettingere8f1e002016-09-06 17:15:29 -0700515 if cum_weights is None:
516 if weights is None:
Raymond Hettinger26a1ad12020-06-22 19:38:59 -0700517 floor = _floor
Raymond Hettinger0a18e052018-11-09 02:39:50 -0800518 n += 0.0 # convert to float for a small speed improvement
Raymond Hettinger26a1ad12020-06-22 19:38:59 -0700519 return [population[floor(random() * n)] for i in _repeat(None, k)]
Raymond Hettingercfd31f02019-02-13 02:04:17 -0800520 cum_weights = list(_accumulate(weights))
Raymond Hettingere8f1e002016-09-06 17:15:29 -0700521 elif weights is not None:
Raymond Hettinger24e42392016-11-13 00:42:56 -0500522 raise TypeError('Cannot specify both weights and cumulative weights')
Raymond Hettingere69cd162018-07-04 15:28:20 -0700523 if len(cum_weights) != n:
Raymond Hettingere8f1e002016-09-06 17:15:29 -0700524 raise ValueError('The number of weights does not match the population')
Raymond Hettinger0a18e052018-11-09 02:39:50 -0800525 total = cum_weights[-1] + 0.0 # convert to float
Raymond Hettinger041d8b42019-11-23 02:22:13 -0800526 if total <= 0.0:
527 raise ValueError('Total of weights must be greater than zero')
Ram Rachumb0dfc752020-09-29 04:32:10 +0300528 if not _isfinite(total):
529 raise ValueError('Total of weights must be finite')
Raymond Hettinger041d8b42019-11-23 02:22:13 -0800530 bisect = _bisect
Raymond Hettingere69cd162018-07-04 15:28:20 -0700531 hi = n - 1
Raymond Hettingerddf71712018-06-27 01:08:31 -0700532 return [population[bisect(cum_weights, random() * total, 0, hi)]
Raymond Hettinger53822032019-02-16 13:30:51 -0800533 for i in _repeat(None, k)]
Raymond Hettingere8f1e002016-09-06 17:15:29 -0700534
Tim Peterscd804102001-01-25 20:25:57 +0000535
Raymond Hettingeref19bad2020-06-25 17:03:50 -0700536 ## -------------------- real-valued distributions -------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000537
538 def uniform(self, a, b):
Raymond Hettingerbe40db02009-06-11 23:12:14 +0000539 "Get a random number in the range [a, b) or [a, b] depending on rounding."
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700540 return a + (b - a) * self.random()
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000541
Christian Heimesfe337bf2008-03-23 21:54:12 +0000542 def triangular(self, low=0.0, high=1.0, mode=None):
543 """Triangular distribution.
544
545 Continuous distribution bounded by given lower and upper limits,
546 and having a given mode value in-between.
547
548 http://en.wikipedia.org/wiki/Triangular_distribution
549
550 """
551 u = self.random()
Raymond Hettinger978c6ab2014-05-25 17:25:27 -0700552 try:
553 c = 0.5 if mode is None else (mode - low) / (high - low)
554 except ZeroDivisionError:
555 return low
Christian Heimesfe337bf2008-03-23 21:54:12 +0000556 if u > c:
557 u = 1.0 - u
558 c = 1.0 - c
559 low, high = high, low
Raymond Hettingerf5ea83f2017-09-04 16:51:06 -0700560 return low + (high - low) * _sqrt(u * c)
Christian Heimesfe337bf2008-03-23 21:54:12 +0000561
Tim Petersd7b5e882001-01-25 03:36:26 +0000562 def normalvariate(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000563 """Normal distribution.
564
565 mu is the mean, and sigma is the standard deviation.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000566
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000567 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000568 # Uses Kinderman and Monahan method. Reference: Kinderman,
569 # A.J. and Monahan, J.F., "Computer generation of random
570 # variables using the ratio of uniform deviates", ACM Trans
571 # Math Software, 3, (1977), pp257-260.
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000572
Tim Petersd7b5e882001-01-25 03:36:26 +0000573 random = self.random
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700574 while True:
Tim Peters0c9886d2001-01-15 01:18:21 +0000575 u1 = random()
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000576 u2 = 1.0 - random()
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700577 z = NV_MAGICCONST * (u1 - 0.5) / u2
578 zz = z * z / 4.0
Tim Petersd7b5e882001-01-25 03:36:26 +0000579 if zz <= -_log(u2):
580 break
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700581 return mu + z * sigma
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000582
Raymond Hettingeref19bad2020-06-25 17:03:50 -0700583 def gauss(self, mu, sigma):
584 """Gaussian distribution.
585
586 mu is the mean, and sigma is the standard deviation. This is
587 slightly faster than the normalvariate() function.
588
589 Not thread-safe without a lock around calls.
590
591 """
592 # When x and y are two variables from [0, 1), uniformly
593 # distributed, then
594 #
595 # cos(2*pi*x)*sqrt(-2*log(1-y))
596 # sin(2*pi*x)*sqrt(-2*log(1-y))
597 #
598 # are two *independent* variables with normal distribution
599 # (mu = 0, sigma = 1).
600 # (Lambert Meertens)
601 # (corrected version; bug discovered by Mike Miller, fixed by LM)
602
603 # Multithreading note: When two threads call this function
604 # simultaneously, it is possible that they will receive the
605 # same return value. The window is very small though. To
606 # avoid this, you have to use a lock around all calls. (I
607 # didn't want to slow this down in the serial case by using a
608 # lock here.)
609
610 random = self.random
611 z = self.gauss_next
612 self.gauss_next = None
613 if z is None:
614 x2pi = random() * TWOPI
615 g2rad = _sqrt(-2.0 * _log(1.0 - random()))
616 z = _cos(x2pi) * g2rad
617 self.gauss_next = _sin(x2pi) * g2rad
618
619 return mu + z * sigma
Tim Petersd7b5e882001-01-25 03:36:26 +0000620
621 def lognormvariate(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000622 """Log normal distribution.
623
624 If you take the natural logarithm of this distribution, you'll get a
625 normal distribution with mean mu and standard deviation sigma.
626 mu can have any value, and sigma must be greater than zero.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000627
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000628 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000629 return _exp(self.normalvariate(mu, sigma))
630
Tim Petersd7b5e882001-01-25 03:36:26 +0000631 def expovariate(self, lambd):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000632 """Exponential distribution.
633
Mark Dickinson2f947362009-01-07 17:54:07 +0000634 lambd is 1.0 divided by the desired mean. It should be
635 nonzero. (The parameter would be called "lambda", but that is
636 a reserved word in Python.) Returned values range from 0 to
637 positive infinity if lambd is positive, and from negative
638 infinity to 0 if lambd is negative.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000639
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000640 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000641 # lambd: rate lambd = 1/mean
642 # ('lambda' is a Python reserved word)
643
Raymond Hettinger5279fb92011-06-25 11:30:53 +0200644 # we use 1-random() instead of random() to preclude the
645 # possibility of taking the log of zero.
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700646 return -_log(1.0 - self.random()) / lambd
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000647
Tim Petersd7b5e882001-01-25 03:36:26 +0000648 def vonmisesvariate(self, mu, kappa):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000649 """Circular data distribution.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000650
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000651 mu is the mean angle, expressed in radians between 0 and 2*pi, and
652 kappa is the concentration parameter, which must be greater than or
653 equal to zero. If kappa is equal to zero, this distribution reduces
654 to a uniform random angle over the range 0 to 2*pi.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000655
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000656 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000657 # Based upon an algorithm published in: Fisher, N.I.,
658 # "Statistical Analysis of Circular Data", Cambridge
659 # University Press, 1993.
660
661 # Thanks to Magnus Kessler for a correction to the
662 # implementation of step 4.
663
664 random = self.random
665 if kappa <= 1e-6:
666 return TWOPI * random()
667
Serhiy Storchaka6c22b1d2013-02-10 19:28:56 +0200668 s = 0.5 / kappa
669 r = s + _sqrt(1.0 + s * s)
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000670
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700671 while True:
Tim Peters0c9886d2001-01-15 01:18:21 +0000672 u1 = random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000673 z = _cos(_pi * u1)
Tim Petersd7b5e882001-01-25 03:36:26 +0000674
Serhiy Storchaka6c22b1d2013-02-10 19:28:56 +0200675 d = z / (r + z)
Tim Petersd7b5e882001-01-25 03:36:26 +0000676 u2 = random()
Serhiy Storchaka6c22b1d2013-02-10 19:28:56 +0200677 if u2 < 1.0 - d * d or u2 <= (1.0 - d) * _exp(d):
Tim Peters0c9886d2001-01-15 01:18:21 +0000678 break
Tim Petersd7b5e882001-01-25 03:36:26 +0000679
Serhiy Storchaka6c22b1d2013-02-10 19:28:56 +0200680 q = 1.0 / r
681 f = (q + z) / (1.0 + q * z)
Tim Petersd7b5e882001-01-25 03:36:26 +0000682 u3 = random()
683 if u3 > 0.5:
Mark Dickinsonbe5f9192013-02-10 14:16:10 +0000684 theta = (mu + _acos(f)) % TWOPI
Tim Petersd7b5e882001-01-25 03:36:26 +0000685 else:
Mark Dickinsonbe5f9192013-02-10 14:16:10 +0000686 theta = (mu - _acos(f)) % TWOPI
Tim Petersd7b5e882001-01-25 03:36:26 +0000687
688 return theta
689
Tim Petersd7b5e882001-01-25 03:36:26 +0000690 def gammavariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000691 """Gamma distribution. Not the gamma function!
692
693 Conditions on the parameters are alpha > 0 and beta > 0.
694
Raymond Hettingera8e4d6e2011-03-22 15:55:51 -0700695 The probability distribution function is:
696
697 x ** (alpha - 1) * math.exp(-x / beta)
698 pdf(x) = --------------------------------------
699 math.gamma(alpha) * beta ** alpha
700
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000701 """
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000702 # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
Tim Peters8ac14952002-05-23 15:15:30 +0000703
Guido van Rossum570764d2002-05-14 14:08:12 +0000704 # Warning: a few older sources define the gamma distribution in terms
705 # of alpha > -1.0
706 if alpha <= 0.0 or beta <= 0.0:
Collin Winterce36ad82007-08-30 01:19:48 +0000707 raise ValueError('gammavariate: alpha and beta must be > 0.0')
Tim Peters8ac14952002-05-23 15:15:30 +0000708
Tim Petersd7b5e882001-01-25 03:36:26 +0000709 random = self.random
Tim Petersd7b5e882001-01-25 03:36:26 +0000710 if alpha > 1.0:
711
712 # Uses R.C.H. Cheng, "The generation of Gamma
713 # variables with non-integral shape parameters",
714 # Applied Statistics, (1977), 26, No. 1, p71-74
715
Raymond Hettingerca6cdc22002-05-13 23:40:14 +0000716 ainv = _sqrt(2.0 * alpha - 1.0)
717 bbb = alpha - LOG4
718 ccc = alpha + ainv
Tim Peters8ac14952002-05-23 15:15:30 +0000719
Raymond Hettinger6a613f92020-08-02 12:03:32 -0700720 while True:
Tim Petersd7b5e882001-01-25 03:36:26 +0000721 u1 = random()
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700722 if not 1e-7 < u1 < 0.9999999:
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000723 continue
724 u2 = 1.0 - random()
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700725 v = _log(u1 / (1.0 - u1)) / ainv
726 x = alpha * _exp(v)
727 z = u1 * u1 * u2
728 r = bbb + ccc * v - x
729 if r + SG_MAGICCONST - 4.5 * z >= 0.0 or r >= _log(z):
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000730 return x * beta
Tim Petersd7b5e882001-01-25 03:36:26 +0000731
732 elif alpha == 1.0:
leodema9f396b62017-06-04 07:41:41 +0100733 # expovariate(1/beta)
leodema63d15222018-12-24 07:54:25 +0100734 return -_log(1.0 - random()) * beta
Tim Petersd7b5e882001-01-25 03:36:26 +0000735
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700736 else:
737 # alpha is between 0 and 1 (exclusive)
Tim Petersd7b5e882001-01-25 03:36:26 +0000738 # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700739 while True:
Tim Petersd7b5e882001-01-25 03:36:26 +0000740 u = random()
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700741 b = (_e + alpha) / _e
742 p = b * u
Tim Petersd7b5e882001-01-25 03:36:26 +0000743 if p <= 1.0:
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700744 x = p ** (1.0 / alpha)
Tim Petersd7b5e882001-01-25 03:36:26 +0000745 else:
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700746 x = -_log((b - p) / alpha)
Tim Petersd7b5e882001-01-25 03:36:26 +0000747 u1 = random()
Raymond Hettinger42406e62005-04-30 09:02:51 +0000748 if p > 1.0:
749 if u1 <= x ** (alpha - 1.0):
750 break
751 elif u1 <= _exp(-x):
Tim Petersd7b5e882001-01-25 03:36:26 +0000752 break
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000753 return x * beta
754
Tim Petersd7b5e882001-01-25 03:36:26 +0000755 def betavariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000756 """Beta distribution.
757
Thomas Woutersb2137042007-02-01 18:02:27 +0000758 Conditions on the parameters are alpha > 0 and beta > 0.
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000759 Returned values range between 0 and 1.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000760
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000761 """
Raymond Hettingeref19bad2020-06-25 17:03:50 -0700762 ## See
763 ## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html
764 ## for Ivan Frohne's insightful analysis of why the original implementation:
765 ##
766 ## def betavariate(self, alpha, beta):
767 ## # Discrete Event Simulation in C, pp 87-88.
768 ##
769 ## y = self.expovariate(alpha)
770 ## z = self.expovariate(1.0/beta)
771 ## return z/(y+z)
772 ##
773 ## was dead wrong, and how it probably got that way.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000774
Tim Peters85e2e472001-01-26 06:49:56 +0000775 # This version due to Janne Sinkkonen, and matches all the std
776 # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
Raymond Hettinger650c1c92016-06-25 05:36:42 +0300777 y = self.gammavariate(alpha, 1.0)
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700778 if y:
Raymond Hettinger650c1c92016-06-25 05:36:42 +0300779 return y / (y + self.gammavariate(beta, 1.0))
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700780 return 0.0
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000781
Tim Petersd7b5e882001-01-25 03:36:26 +0000782 def paretovariate(self, alpha):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000783 """Pareto distribution. alpha is the shape parameter."""
Tim Petersd7b5e882001-01-25 03:36:26 +0000784 # Jain, pg. 495
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000785
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000786 u = 1.0 - self.random()
Raymond Hettinger5c327092020-08-01 01:18:26 -0700787 return u ** (-1.0 / alpha)
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000788
Tim Petersd7b5e882001-01-25 03:36:26 +0000789 def weibullvariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000790 """Weibull distribution.
791
792 alpha is the scale parameter and beta is the shape parameter.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000793
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000794 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000795 # Jain, pg. 499; bug fix courtesy Bill Arms
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000796
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000797 u = 1.0 - self.random()
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700798 return alpha * (-_log(u)) ** (1.0 / beta)
799
Guido van Rossum6c395ba1999-08-18 13:53:28 +0000800
Raymond Hettingeref19bad2020-06-25 17:03:50 -0700801## ------------------------------------------------------------------
Raymond Hettinger23f12412004-09-13 22:23:21 +0000802## --------------- Operating System Random Source ------------------
Raymond Hettinger356a4592004-08-30 06:14:31 +0000803
Raymond Hettingeref19bad2020-06-25 17:03:50 -0700804
Raymond Hettinger23f12412004-09-13 22:23:21 +0000805class SystemRandom(Random):
806 """Alternate random number generator using sources provided
807 by the operating system (such as /dev/urandom on Unix or
808 CryptGenRandom on Windows).
Raymond Hettinger356a4592004-08-30 06:14:31 +0000809
810 Not available on all systems (see os.urandom() for details).
Raymond Hettingeref19bad2020-06-25 17:03:50 -0700811
Raymond Hettinger356a4592004-08-30 06:14:31 +0000812 """
813
814 def random(self):
815 """Get the next random number in the range [0.0, 1.0)."""
Raymond Hettinger183cd1f2010-09-08 18:48:21 +0000816 return (int.from_bytes(_urandom(7), 'big') >> 3) * RECIP_BPF
Raymond Hettinger356a4592004-08-30 06:14:31 +0000817
818 def getrandbits(self, k):
Serhiy Storchaka95949422013-08-27 19:40:23 +0300819 """getrandbits(k) -> x. Generates an int with k random bits."""
Antoine Pitrou75a33782020-04-17 19:32:14 +0200820 if k < 0:
821 raise ValueError('number of bits must be non-negative')
Raymond Hettinger63b17672010-09-08 19:27:59 +0000822 numbytes = (k + 7) // 8 # bits / 8 and rounded up
823 x = int.from_bytes(_urandom(numbytes), 'big')
824 return x >> (numbytes * 8 - k) # trim excess bits
Raymond Hettinger356a4592004-08-30 06:14:31 +0000825
Victor Stinner9f5fe792020-04-17 19:05:35 +0200826 def randbytes(self, n):
827 """Generate n random bytes."""
828 # os.urandom(n) fails with ValueError for n < 0
829 # and returns an empty bytes string for n == 0.
830 return _urandom(n)
831
Raymond Hettinger28de64f2008-01-13 23:40:30 +0000832 def seed(self, *args, **kwds):
Raymond Hettinger23f12412004-09-13 22:23:21 +0000833 "Stub method. Not used for a system random number generator."
Raymond Hettinger356a4592004-08-30 06:14:31 +0000834 return None
Raymond Hettinger356a4592004-08-30 06:14:31 +0000835
836 def _notimplemented(self, *args, **kwds):
Raymond Hettinger23f12412004-09-13 22:23:21 +0000837 "Method should not be called for a system random number generator."
838 raise NotImplementedError('System entropy source does not have state.')
Raymond Hettinger356a4592004-08-30 06:14:31 +0000839 getstate = setstate = _notimplemented
840
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700841
Raymond Hettingeref19bad2020-06-25 17:03:50 -0700842# ----------------------------------------------------------------------
843# Create one instance, seeded from current time, and export its methods
844# as module-level functions. The functions share state across all uses
845# (both in the user's code and in the Python libraries), but that's fine
846# for most programs and is easier for the casual user than making them
847# instantiate their own Random() instance.
848
849_inst = Random()
850seed = _inst.seed
851random = _inst.random
852uniform = _inst.uniform
853triangular = _inst.triangular
854randint = _inst.randint
855choice = _inst.choice
856randrange = _inst.randrange
857sample = _inst.sample
858shuffle = _inst.shuffle
859choices = _inst.choices
860normalvariate = _inst.normalvariate
861lognormvariate = _inst.lognormvariate
862expovariate = _inst.expovariate
863vonmisesvariate = _inst.vonmisesvariate
864gammavariate = _inst.gammavariate
865gauss = _inst.gauss
866betavariate = _inst.betavariate
867paretovariate = _inst.paretovariate
868weibullvariate = _inst.weibullvariate
869getstate = _inst.getstate
870setstate = _inst.setstate
871getrandbits = _inst.getrandbits
872randbytes = _inst.randbytes
873
874
875## ------------------------------------------------------
876## ----------------- test program -----------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000877
Raymond Hettinger62297132003-08-30 01:24:19 +0000878def _test_generator(n, func, args):
Raymond Hettinger26a1ad12020-06-22 19:38:59 -0700879 from statistics import stdev, fmean as mean
880 from time import perf_counter
881
882 t0 = perf_counter()
883 data = [func(*args) for i in range(n)]
884 t1 = perf_counter()
885
886 xbar = mean(data)
887 sigma = stdev(data, xbar)
888 low = min(data)
889 high = max(data)
890
891 print(f'{t1 - t0:.3f} sec, {n} times {func.__name__}')
892 print('avg %g, stddev %g, min %g, max %g\n' % (xbar, sigma, low, high))
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000893
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000894
895def _test(N=2000):
Raymond Hettinger62297132003-08-30 01:24:19 +0000896 _test_generator(N, random, ())
897 _test_generator(N, normalvariate, (0.0, 1.0))
898 _test_generator(N, lognormvariate, (0.0, 1.0))
899 _test_generator(N, vonmisesvariate, (0.0, 1.0))
900 _test_generator(N, gammavariate, (0.01, 1.0))
901 _test_generator(N, gammavariate, (0.1, 1.0))
902 _test_generator(N, gammavariate, (0.1, 2.0))
903 _test_generator(N, gammavariate, (0.5, 1.0))
904 _test_generator(N, gammavariate, (0.9, 1.0))
905 _test_generator(N, gammavariate, (1.0, 1.0))
906 _test_generator(N, gammavariate, (2.0, 1.0))
907 _test_generator(N, gammavariate, (20.0, 1.0))
908 _test_generator(N, gammavariate, (200.0, 1.0))
909 _test_generator(N, gauss, (0.0, 1.0))
910 _test_generator(N, betavariate, (3.0, 3.0))
Raymond Hettinger9db5b8d2020-06-13 09:46:47 -0700911 _test_generator(N, triangular, (0.0, 1.0, 1.0 / 3.0))
Tim Peterscd804102001-01-25 20:25:57 +0000912
Raymond Hettinger40f62172002-12-29 23:03:38 +0000913
Raymond Hettingeref19bad2020-06-25 17:03:50 -0700914## ------------------------------------------------------
915## ------------------ fork support ---------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000916
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200917if hasattr(_os, "fork"):
Gregory P. Smith163468a2017-05-29 10:03:41 -0700918 _os.register_at_fork(after_in_child=_inst.seed)
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200919
920
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000921if __name__ == '__main__':
Tim Petersd7b5e882001-01-25 03:36:26 +0000922 _test()