blob: ae7b5cf4e72e874fedd5bcc08463597d2fa189eb [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
Raymond Hettingere8f1e002016-09-06 17:15:29 -070011 pick weighted random sample
Tim Petersd7b5e882001-01-25 03:36:26 +000012 generate random permutation
13
Guido van Rossume7b146f2000-02-04 15:28:42 +000014 distributions on the real line:
15 ------------------------------
Tim Petersd7b5e882001-01-25 03:36:26 +000016 uniform
Christian Heimesfe337bf2008-03-23 21:54:12 +000017 triangular
Guido van Rossume7b146f2000-02-04 15:28:42 +000018 normal (Gaussian)
19 lognormal
20 negative exponential
21 gamma
22 beta
Raymond Hettinger40f62172002-12-29 23:03:38 +000023 pareto
24 Weibull
Guido van Rossumff03b1a1994-03-09 12:55:02 +000025
Guido van Rossume7b146f2000-02-04 15:28:42 +000026 distributions on the circle (angles 0 to 2pi)
27 ---------------------------------------------
28 circular uniform
29 von Mises
30
Raymond Hettinger40f62172002-12-29 23:03:38 +000031General notes on the underlying Mersenne Twister core generator:
Guido van Rossume7b146f2000-02-04 15:28:42 +000032
Raymond Hettinger40f62172002-12-29 23:03:38 +000033* The period is 2**19937-1.
Thomas Wouters0e3f5912006-08-11 14:57:12 +000034* It is one of the most extensively tested generators in existence.
Thomas Wouters0e3f5912006-08-11 14:57:12 +000035* The random() method is implemented in C, executes in a single Python step,
36 and is, therefore, threadsafe.
Tim Peterse360d952001-01-26 10:00:39 +000037
Guido van Rossume7b146f2000-02-04 15:28:42 +000038"""
Guido van Rossumd03e1191998-05-29 17:51:31 +000039
Raymond Hettinger2f726e92003-10-05 09:09:15 +000040from warnings import warn as _warn
Raymond Hettinger91e27c22005-08-19 01:36:35 +000041from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
Miss Islington (bot)cd696202020-06-22 21:22:40 -070042from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
43from math import tau as TWOPI, floor as _floor
Raymond Hettingerc1c43ca2004-09-05 00:00:42 +000044from os import urandom as _urandom
Christian Heimesf1dc3ee2013-10-13 02:04:20 +020045from _collections_abc import Set as _Set, Sequence as _Sequence
Raymond Hettinger53822032019-02-16 13:30:51 -080046from itertools import accumulate as _accumulate, repeat as _repeat
Raymond Hettingercfd31f02019-02-13 02:04:17 -080047from bisect import bisect as _bisect
Antoine Pitrou346cbd32017-05-27 17:50:54 +020048import os as _os
Guido van Rossumff03b1a1994-03-09 12:55:02 +000049
Christian Heimesd9145962019-04-10 22:18:02 +020050try:
51 # hashlib is pretty heavy to load, try lean internal module first
52 from _sha512 import sha512 as _sha512
53except ImportError:
54 # fallback to official implementation
55 from hashlib import sha512 as _sha512
56
57
Miss Islington (bot)f1534d02020-06-13 10:23:48 -070058__all__ = [
59 "Random",
60 "SystemRandom",
61 "betavariate",
62 "choice",
63 "choices",
64 "expovariate",
65 "gammavariate",
66 "gauss",
67 "getrandbits",
68 "getstate",
69 "lognormvariate",
70 "normalvariate",
71 "paretovariate",
72 "randint",
73 "random",
74 "randrange",
75 "sample",
76 "seed",
77 "setstate",
78 "shuffle",
79 "triangular",
80 "uniform",
81 "vonmisesvariate",
82 "weibullvariate",
83]
Tim Petersd7b5e882001-01-25 03:36:26 +000084
Miss Islington (bot)f1534d02020-06-13 10:23:48 -070085NV_MAGICCONST = 4 * _exp(-0.5) / _sqrt(2.0)
Tim Petersd7b5e882001-01-25 03:36:26 +000086LOG4 = _log(4.0)
Tim Petersd7b5e882001-01-25 03:36:26 +000087SG_MAGICCONST = 1.0 + _log(4.5)
Raymond Hettinger2f726e92003-10-05 09:09:15 +000088BPF = 53 # Number of bits in a float
Miss Islington (bot)f1534d02020-06-13 10:23:48 -070089RECIP_BPF = 2 ** -BPF
Tim Petersd7b5e882001-01-25 03:36:26 +000090
Raymond Hettinger356a4592004-08-30 06:14:31 +000091
Tim Petersd7b5e882001-01-25 03:36:26 +000092# Translated by Guido van Rossum from C source provided by
Raymond Hettinger40f62172002-12-29 23:03:38 +000093# Adrian Baddeley. Adapted by Raymond Hettinger for use with
Raymond Hettinger3fa19d72004-08-31 01:05:15 +000094# the Mersenne Twister and os.urandom() core generators.
Tim Petersd7b5e882001-01-25 03:36:26 +000095
Raymond Hettinger145a4a02003-01-07 10:25:55 +000096import _random
Raymond Hettinger40f62172002-12-29 23:03:38 +000097
Miss Islington (bot)f1534d02020-06-13 10:23:48 -070098
Raymond Hettinger145a4a02003-01-07 10:25:55 +000099class Random(_random.Random):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000100 """Random number generator base class used by bound module functions.
101
102 Used to instantiate instances of Random to get generators that don't
Raymond Hettinger28de64f2008-01-13 23:40:30 +0000103 share state.
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000104
105 Class Random can also be subclassed if you want to use a different basic
106 generator of your own devising: in that case, override the following
Raymond Hettinger28de64f2008-01-13 23:40:30 +0000107 methods: random(), seed(), getstate(), and setstate().
Benjamin Petersond18de0e2008-07-31 20:21:46 +0000108 Optionally, implement a getrandbits() method so that randrange()
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000109 can cover arbitrarily large ranges.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000110
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000111 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000112
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000113 VERSION = 3 # used by getstate/setstate
Tim Petersd7b5e882001-01-25 03:36:26 +0000114
115 def __init__(self, x=None):
116 """Initialize an instance.
117
118 Optional argument x controls seeding, as for Random.seed().
119 """
120
121 self.seed(x)
Raymond Hettinger40f62172002-12-29 23:03:38 +0000122 self.gauss_next = None
Tim Petersd7b5e882001-01-25 03:36:26 +0000123
Serhiy Storchaka2085bd02019-06-01 11:00:15 +0300124 def __init_subclass__(cls, /, **kwargs):
Wolfgang Maierba3a87a2018-04-17 17:16:17 +0200125 """Control how subclasses generate random integers.
126
127 The algorithm a subclass can use depends on the random() and/or
128 getrandbits() implementation available to it and determines
129 whether it can generate random integers from arbitrarily large
130 ranges.
131 """
132
Serhiy Storchakaec1622d2018-05-08 15:45:15 +0300133 for c in cls.__mro__:
134 if '_randbelow' in c.__dict__:
135 # just inherit it
136 break
137 if 'getrandbits' in c.__dict__:
138 cls._randbelow = cls._randbelow_with_getrandbits
139 break
140 if 'random' in c.__dict__:
141 cls._randbelow = cls._randbelow_without_getrandbits
142 break
Wolfgang Maierba3a87a2018-04-17 17:16:17 +0200143
Raymond Hettingerf763a722010-09-07 00:38:15 +0000144 def seed(self, a=None, version=2):
Raymond Hettingerd0cdeaa2019-08-22 09:19:36 -0700145 """Initialize internal state from a seed.
146
147 The only supported seed types are None, int, float,
148 str, bytes, and bytearray.
Tim Petersd7b5e882001-01-25 03:36:26 +0000149
Raymond Hettinger23f12412004-09-13 22:23:21 +0000150 None or no argument seeds from current time or from an operating
151 system specific randomness source if available.
Tim Peters0de88fc2001-02-01 04:59:18 +0000152
Raymond Hettinger183cd1f2010-09-08 18:48:21 +0000153 If *a* is an int, all bits are used.
Raymond Hettingerf763a722010-09-07 00:38:15 +0000154
Raymond Hettinger16eb8272016-09-04 11:17:28 -0700155 For version 2 (the default), all of the bits are used if *a* is a str,
156 bytes, or bytearray. For version 1 (provided for reproducing random
157 sequences from older versions of Python), the algorithm for str and
158 bytes generates a narrower range of seeds.
159
Tim Petersd7b5e882001-01-25 03:36:26 +0000160 """
161
Raymond Hettingerc7bab7c2016-08-31 15:01:08 -0700162 if version == 1 and isinstance(a, (str, bytes)):
Raymond Hettinger132a7d72017-09-17 09:04:30 -0700163 a = a.decode('latin-1') if isinstance(a, bytes) else a
Raymond Hettingerc7bab7c2016-08-31 15:01:08 -0700164 x = ord(a[0]) << 7 if a else 0
Raymond Hettinger132a7d72017-09-17 09:04:30 -0700165 for c in map(ord, a):
166 x = ((1000003 * x) ^ c) & 0xFFFFFFFFFFFFFFFF
Raymond Hettingerc7bab7c2016-08-31 15:01:08 -0700167 x ^= len(a)
168 a = -2 if x == -1 else x
169
Raymond Hettingerd0cdeaa2019-08-22 09:19:36 -0700170 elif version == 2 and isinstance(a, (str, bytes, bytearray)):
Raymond Hettinger2f9cc7a2016-08-31 23:00:32 -0700171 if isinstance(a, str):
172 a = a.encode()
173 a += _sha512(a).digest()
174 a = int.from_bytes(a, 'big')
Raymond Hettingerf763a722010-09-07 00:38:15 +0000175
Raymond Hettingerd0cdeaa2019-08-22 09:19:36 -0700176 elif not isinstance(a, (type(None), int, float, str, bytes, bytearray)):
177 _warn('Seeding based on hashing is deprecated\n'
178 'since Python 3.9 and will be removed in a subsequent '
179 'version. The only \n'
180 'supported seed types are: None, '
181 'int, float, str, bytes, and bytearray.',
182 DeprecationWarning, 2)
183
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000184 super().seed(a)
Tim Peters46c04e12002-05-05 20:40:00 +0000185 self.gauss_next = None
186
Tim Peterscd804102001-01-25 20:25:57 +0000187 def getstate(self):
188 """Return internal state; can be passed to setstate() later."""
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000189 return self.VERSION, super().getstate(), self.gauss_next
Tim Peterscd804102001-01-25 20:25:57 +0000190
191 def setstate(self, state):
192 """Restore internal state from object returned by getstate()."""
193 version = state[0]
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000194 if version == 3:
Raymond Hettinger40f62172002-12-29 23:03:38 +0000195 version, internalstate, self.gauss_next = state
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000196 super().setstate(internalstate)
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000197 elif version == 2:
198 version, internalstate, self.gauss_next = state
199 # In version 2, the state was saved as signed ints, which causes
200 # inconsistencies between 32/64-bit systems. The state is
201 # really unsigned 32-bit ints, so we convert negative ints from
202 # version 2 to positive longs for version 3.
203 try:
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700204 internalstate = tuple(x % (2 ** 32) for x in internalstate)
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000205 except ValueError as e:
206 raise TypeError from e
Raymond Hettinger183cd1f2010-09-08 18:48:21 +0000207 super().setstate(internalstate)
Tim Peterscd804102001-01-25 20:25:57 +0000208 else:
209 raise ValueError("state with version %s passed to "
210 "Random.setstate() of version %s" %
211 (version, self.VERSION))
212
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700213 ## ---- Methods below this point do not need to be overridden when
214 ## ---- subclassing for the purpose of using a different core generator.
Tim Peterscd804102001-01-25 20:25:57 +0000215
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700216 ## -------------------- bytes methods ---------------------
Victor Stinner2d875772020-04-29 18:49:00 +0200217
218 def randbytes(self, n):
219 """Generate n random bytes."""
220 return self.getrandbits(n * 8).to_bytes(n, 'little')
221
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700222 ## -------------------- pickle support -------------------
Tim Peterscd804102001-01-25 20:25:57 +0000223
R David Murrayd9ebf4d2013-04-02 13:10:52 -0400224 # Issue 17489: Since __reduce__ was defined to fix #759889 this is no
225 # longer called; we leave it here because it has been here since random was
226 # rewritten back in 2001 and why risk breaking something.
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700227 def __getstate__(self): # for pickle
Tim Peterscd804102001-01-25 20:25:57 +0000228 return self.getstate()
229
230 def __setstate__(self, state): # for pickle
231 self.setstate(state)
232
Raymond Hettinger5f078ff2003-06-24 20:29:04 +0000233 def __reduce__(self):
234 return self.__class__, (), self.getstate()
235
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700236 ## -------------------- integer methods -------------------
Tim Peterscd804102001-01-25 20:25:57 +0000237
Miss Islington (bot)cd696202020-06-22 21:22:40 -0700238 def randrange(self, start, stop=None, step=1):
Tim Petersd7b5e882001-01-25 03:36:26 +0000239 """Choose a random item from range(start, stop[, step]).
240
241 This fixes the problem with randint() which includes the
242 endpoint; in Python this is usually not what you want.
Raymond Hettinger3051cc32010-09-07 00:48:40 +0000243
Tim Petersd7b5e882001-01-25 03:36:26 +0000244 """
245
246 # This code is a bit messy to make it fast for the
Tim Peters9146f272002-08-16 03:41:39 +0000247 # common case while still doing adequate error checking.
Miss Islington (bot)cd696202020-06-22 21:22:40 -0700248 istart = int(start)
Tim Petersd7b5e882001-01-25 03:36:26 +0000249 if istart != start:
Collin Winterce36ad82007-08-30 01:19:48 +0000250 raise ValueError("non-integer arg 1 for randrange()")
Raymond Hettinger3051cc32010-09-07 00:48:40 +0000251 if stop is None:
Tim Petersd7b5e882001-01-25 03:36:26 +0000252 if istart > 0:
Raymond Hettinger05156612010-09-07 04:44:52 +0000253 return self._randbelow(istart)
Collin Winterce36ad82007-08-30 01:19:48 +0000254 raise ValueError("empty range for randrange()")
Tim Peters9146f272002-08-16 03:41:39 +0000255
256 # stop argument supplied.
Miss Islington (bot)cd696202020-06-22 21:22:40 -0700257 istop = int(stop)
Tim Petersd7b5e882001-01-25 03:36:26 +0000258 if istop != stop:
Collin Winterce36ad82007-08-30 01:19:48 +0000259 raise ValueError("non-integer stop for randrange()")
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000260 width = istop - istart
261 if step == 1 and width > 0:
Raymond Hettingerc3246972010-09-07 09:32:57 +0000262 return istart + self._randbelow(width)
Tim Petersd7b5e882001-01-25 03:36:26 +0000263 if step == 1:
Kumar Akshay2433a2a2019-01-22 00:49:59 +0530264 raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width))
Tim Peters9146f272002-08-16 03:41:39 +0000265
266 # Non-unit step argument supplied.
Miss Islington (bot)cd696202020-06-22 21:22:40 -0700267 istep = int(step)
Tim Petersd7b5e882001-01-25 03:36:26 +0000268 if istep != step:
Collin Winterce36ad82007-08-30 01:19:48 +0000269 raise ValueError("non-integer step for randrange()")
Tim Petersd7b5e882001-01-25 03:36:26 +0000270 if istep > 0:
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +0000271 n = (width + istep - 1) // istep
Tim Petersd7b5e882001-01-25 03:36:26 +0000272 elif istep < 0:
Raymond Hettingerffdb8bb2004-09-27 15:29:05 +0000273 n = (width + istep + 1) // istep
Tim Petersd7b5e882001-01-25 03:36:26 +0000274 else:
Collin Winterce36ad82007-08-30 01:19:48 +0000275 raise ValueError("zero step for randrange()")
Tim Petersd7b5e882001-01-25 03:36:26 +0000276
277 if n <= 0:
Collin Winterce36ad82007-08-30 01:19:48 +0000278 raise ValueError("empty range for randrange()")
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000279
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700280 return istart + istep * self._randbelow(n)
Tim Petersd7b5e882001-01-25 03:36:26 +0000281
282 def randint(self, a, b):
Tim Peterscd804102001-01-25 20:25:57 +0000283 """Return random integer in range [a, b], including both end points.
Tim Petersd7b5e882001-01-25 03:36:26 +0000284 """
285
286 return self.randrange(a, b+1)
287
Wolfgang Maierba3a87a2018-04-17 17:16:17 +0200288 def _randbelow_with_getrandbits(self, n):
Raymond Hettinger4168f1e2020-05-01 10:34:19 -0700289 "Return a random int in the range [0,n). Returns 0 if n==0."
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000290
Antoine Pitrou75a33782020-04-17 19:32:14 +0200291 if not n:
Raymond Hettinger4168f1e2020-05-01 10:34:19 -0700292 return 0
Raymond Hettingerc3246972010-09-07 09:32:57 +0000293 getrandbits = self.getrandbits
Wolfgang Maierba3a87a2018-04-17 17:16:17 +0200294 k = n.bit_length() # don't use (n-1) here because n can be 1
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700295 r = getrandbits(k) # 0 <= r < 2**k
Wolfgang Maierba3a87a2018-04-17 17:16:17 +0200296 while r >= n:
297 r = getrandbits(k)
298 return r
299
Miss Islington (bot)cd696202020-06-22 21:22:40 -0700300 def _randbelow_without_getrandbits(self, n, maxsize=1<<BPF):
Raymond Hettinger4168f1e2020-05-01 10:34:19 -0700301 """Return a random int in the range [0,n). Returns 0 if n==0.
Wolfgang Maierba3a87a2018-04-17 17:16:17 +0200302
303 The implementation does not use getrandbits, but only random.
304 """
305
306 random = self.random
Raymond Hettingere4a3e992010-09-08 00:30:28 +0000307 if n >= maxsize:
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000308 _warn("Underlying random() generator does not supply \n"
Raymond Hettingerf015b3f2010-09-07 20:04:42 +0000309 "enough bits to choose from a population range this large.\n"
310 "To remove the range limitation, add a getrandbits() method.")
Miss Islington (bot)cd696202020-06-22 21:22:40 -0700311 return _floor(random() * n)
Wolfgang Maier091e95e2018-04-05 17:19:44 +0200312 if n == 0:
Raymond Hettinger4168f1e2020-05-01 10:34:19 -0700313 return 0
Raymond Hettingere4a3e992010-09-08 00:30:28 +0000314 rem = maxsize % n
315 limit = (maxsize - rem) / maxsize # int(limit * maxsize) % n == 0
316 r = random()
317 while r >= limit:
318 r = random()
Miss Islington (bot)cd696202020-06-22 21:22:40 -0700319 return _floor(r * maxsize) % n
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000320
Wolfgang Maierba3a87a2018-04-17 17:16:17 +0200321 _randbelow = _randbelow_with_getrandbits
322
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700323 ## -------------------- sequence methods -------------------
Tim Peterscd804102001-01-25 20:25:57 +0000324
Tim Petersd7b5e882001-01-25 03:36:26 +0000325 def choice(self, seq):
326 """Choose a random element from a non-empty sequence."""
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700327 # raises IndexError if seq is empty
328 return seq[self._randbelow(len(seq))]
Tim Petersd7b5e882001-01-25 03:36:26 +0000329
Raymond Hettinger8fe47c32013-10-05 21:48:21 -0700330 def shuffle(self, x, random=None):
Antoine Pitrou5e394332012-11-04 02:10:33 +0100331 """Shuffle list x in place, and return None.
Tim Petersd7b5e882001-01-25 03:36:26 +0000332
Antoine Pitrou5e394332012-11-04 02:10:33 +0100333 Optional argument random is a 0-argument function returning a
334 random float in [0.0, 1.0); if it is the default None, the
335 standard random.random will be used.
Senthil Kumaranf8ce51a2013-09-11 22:54:31 -0700336
Tim Petersd7b5e882001-01-25 03:36:26 +0000337 """
338
Raymond Hettinger8fe47c32013-10-05 21:48:21 -0700339 if random is None:
340 randbelow = self._randbelow
341 for i in reversed(range(1, len(x))):
342 # pick an element in x[:i+1] with which to exchange x[i]
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700343 j = randbelow(i + 1)
Raymond Hettinger8fe47c32013-10-05 21:48:21 -0700344 x[i], x[j] = x[j], x[i]
345 else:
Raymond Hettinger190fac92020-05-02 16:45:32 -0700346 _warn('The *random* parameter to shuffle() has been deprecated\n'
347 'since Python 3.9 and will be removed in a subsequent '
348 'version.',
349 DeprecationWarning, 2)
Miss Islington (bot)cd696202020-06-22 21:22:40 -0700350 floor = _floor
Raymond Hettinger8fe47c32013-10-05 21:48:21 -0700351 for i in reversed(range(1, len(x))):
352 # pick an element in x[:i+1] with which to exchange x[i]
Miss Islington (bot)cd696202020-06-22 21:22:40 -0700353 j = floor(random() * (i + 1))
Raymond Hettinger8fe47c32013-10-05 21:48:21 -0700354 x[i], x[j] = x[j], x[i]
Tim Petersd7b5e882001-01-25 03:36:26 +0000355
Raymond Hettinger81a5fc32020-05-08 07:53:15 -0700356 def sample(self, population, k, *, counts=None):
Raymond Hettinger1acde192008-01-14 01:00:53 +0000357 """Chooses k unique random elements from a population sequence or set.
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000358
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000359 Returns a new list containing elements from the population while
360 leaving the original population unchanged. The resulting list is
361 in selection order so that all sub-slices will also be valid random
362 samples. This allows raffle winners (the sample) to be partitioned
363 into grand prize and second place winners (the subslices).
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000364
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000365 Members of the population need not be hashable or unique. If the
366 population contains repeats, then each occurrence is a possible
367 selection in the sample.
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000368
Raymond Hettinger81a5fc32020-05-08 07:53:15 -0700369 Repeated elements can be specified one at a time or with the optional
370 counts parameter. For example:
371
372 sample(['red', 'blue'], counts=[4, 2], k=5)
373
374 is equivalent to:
375
376 sample(['red', 'red', 'red', 'red', 'blue', 'blue'], k=5)
377
378 To choose a sample from a range of integers, use range() for the
379 population argument. This is especially fast and space efficient
380 for sampling from a large population:
381
382 sample(range(10000000), 60)
383
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000384 """
385
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000386 # Sampling without replacement entails tracking either potential
Raymond Hettinger91e27c22005-08-19 01:36:35 +0000387 # selections (the pool) in a list or previous selections in a set.
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000388
Jeremy Hylton2b55d352004-02-23 17:27:57 +0000389 # When the number of selections is small compared to the
390 # population, then tracking selections is efficient, requiring
Raymond Hettinger91e27c22005-08-19 01:36:35 +0000391 # only a small set and an occasional reselection. For
Jeremy Hylton2b55d352004-02-23 17:27:57 +0000392 # a larger number of selections, the pool tracking method is
393 # preferred since the list takes less space than the
Raymond Hettinger91e27c22005-08-19 01:36:35 +0000394 # set and it doesn't suffer from frequent reselections.
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000395
Raymond Hettinger7fc633f2018-12-04 00:13:38 -0800396 # The number of calls to _randbelow() is kept at or near k, the
397 # theoretical minimum. This is important because running time
398 # is dominated by _randbelow() and because it extracts the
399 # least entropy from the underlying random number generators.
400
401 # Memory requirements are kept to the smaller of a k-length
402 # set or an n-length list.
403
404 # There are other sampling algorithms that do not require
405 # auxiliary memory, but they were rejected because they made
406 # too many calls to _randbelow(), making them slower and
407 # causing them to eat more entropy than necessary.
408
Raymond Hettinger57d1a882011-02-23 00:46:28 +0000409 if isinstance(population, _Set):
Raymond Hettinger4fe00202020-04-19 00:36:42 -0700410 _warn('Sampling from a set deprecated\n'
411 'since Python 3.9 and will be removed in a subsequent version.',
412 DeprecationWarning, 2)
Raymond Hettinger1acde192008-01-14 01:00:53 +0000413 population = tuple(population)
Raymond Hettinger57d1a882011-02-23 00:46:28 +0000414 if not isinstance(population, _Sequence):
Raymond Hettinger4fe00202020-04-19 00:36:42 -0700415 raise TypeError("Population must be a sequence. For dicts or sets, use sorted(d).")
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000416 n = len(population)
Raymond Hettinger81a5fc32020-05-08 07:53:15 -0700417 if counts is not None:
418 cum_counts = list(_accumulate(counts))
419 if len(cum_counts) != n:
420 raise ValueError('The number of counts does not match the population')
421 total = cum_counts.pop()
422 if not isinstance(total, int):
423 raise TypeError('Counts must be integers')
424 if total <= 0:
425 raise ValueError('Total of counts must be greater than zero')
426 selections = sample(range(total), k=k)
427 bisect = _bisect
428 return [population[bisect(cum_counts, s)] for s in selections]
429 randbelow = self._randbelow
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000430 if not 0 <= k <= n:
Raymond Hettingerbf871262016-11-21 14:34:33 -0800431 raise ValueError("Sample larger than population or is negative")
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000432 result = [None] * k
Raymond Hettinger91e27c22005-08-19 01:36:35 +0000433 setsize = 21 # size of a small set minus size of an empty list
434 if k > 5:
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700435 setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets
Raymond Hettinger1acde192008-01-14 01:00:53 +0000436 if n <= setsize:
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700437 # An n-length list is smaller than a k-length set.
438 # Invariant: non-selected at pool[0 : n-i]
Raymond Hettinger311f4192002-11-18 09:01:24 +0000439 pool = list(population)
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700440 for i in range(k):
441 j = randbelow(n - i)
Raymond Hettinger311f4192002-11-18 09:01:24 +0000442 result[i] = pool[j]
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700443 pool[j] = pool[n - i - 1] # move non-selected item into vacancy
Raymond Hettingerc0b40342002-11-13 15:26:37 +0000444 else:
Raymond Hettinger1acde192008-01-14 01:00:53 +0000445 selected = set()
446 selected_add = selected.add
447 for i in range(k):
Raymond Hettinger05a505f2010-09-07 19:19:33 +0000448 j = randbelow(n)
Raymond Hettinger1acde192008-01-14 01:00:53 +0000449 while j in selected:
Raymond Hettinger05a505f2010-09-07 19:19:33 +0000450 j = randbelow(n)
Raymond Hettinger1acde192008-01-14 01:00:53 +0000451 selected_add(j)
452 result[i] = population[j]
Raymond Hettinger311f4192002-11-18 09:01:24 +0000453 return result
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000454
Raymond Hettinger9016f282016-09-26 21:45:57 -0700455 def choices(self, population, weights=None, *, cum_weights=None, k=1):
Raymond Hettingere8f1e002016-09-06 17:15:29 -0700456 """Return a k sized list of population elements chosen with replacement.
457
458 If the relative weights or cumulative weights are not specified,
459 the selections are made with equal probability.
460
461 """
Raymond Hettinger30d00e52016-10-29 16:55:36 -0700462 random = self.random
Raymond Hettingere69cd162018-07-04 15:28:20 -0700463 n = len(population)
Raymond Hettingere8f1e002016-09-06 17:15:29 -0700464 if cum_weights is None:
465 if weights is None:
Miss Islington (bot)cd696202020-06-22 21:22:40 -0700466 floor = _floor
Raymond Hettinger0a18e052018-11-09 02:39:50 -0800467 n += 0.0 # convert to float for a small speed improvement
Miss Islington (bot)cd696202020-06-22 21:22:40 -0700468 return [population[floor(random() * n)] for i in _repeat(None, k)]
Raymond Hettingercfd31f02019-02-13 02:04:17 -0800469 cum_weights = list(_accumulate(weights))
Raymond Hettingere8f1e002016-09-06 17:15:29 -0700470 elif weights is not None:
Raymond Hettinger24e42392016-11-13 00:42:56 -0500471 raise TypeError('Cannot specify both weights and cumulative weights')
Raymond Hettingere69cd162018-07-04 15:28:20 -0700472 if len(cum_weights) != n:
Raymond Hettingere8f1e002016-09-06 17:15:29 -0700473 raise ValueError('The number of weights does not match the population')
Raymond Hettinger0a18e052018-11-09 02:39:50 -0800474 total = cum_weights[-1] + 0.0 # convert to float
Raymond Hettinger041d8b42019-11-23 02:22:13 -0800475 if total <= 0.0:
476 raise ValueError('Total of weights must be greater than zero')
477 bisect = _bisect
Raymond Hettingere69cd162018-07-04 15:28:20 -0700478 hi = n - 1
Raymond Hettingerddf71712018-06-27 01:08:31 -0700479 return [population[bisect(cum_weights, random() * total, 0, hi)]
Raymond Hettinger53822032019-02-16 13:30:51 -0800480 for i in _repeat(None, k)]
Raymond Hettingere8f1e002016-09-06 17:15:29 -0700481
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700482 ## -------------------- real-valued distributions -------------------
Tim Peterscd804102001-01-25 20:25:57 +0000483
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700484 ## -------------------- uniform distribution -------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000485
486 def uniform(self, a, b):
Raymond Hettingerbe40db02009-06-11 23:12:14 +0000487 "Get a random number in the range [a, b) or [a, b] depending on rounding."
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700488 return a + (b - a) * self.random()
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000489
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700490 ## -------------------- triangular --------------------
Christian Heimesfe337bf2008-03-23 21:54:12 +0000491
492 def triangular(self, low=0.0, high=1.0, mode=None):
493 """Triangular distribution.
494
495 Continuous distribution bounded by given lower and upper limits,
496 and having a given mode value in-between.
497
498 http://en.wikipedia.org/wiki/Triangular_distribution
499
500 """
501 u = self.random()
Raymond Hettinger978c6ab2014-05-25 17:25:27 -0700502 try:
503 c = 0.5 if mode is None else (mode - low) / (high - low)
504 except ZeroDivisionError:
505 return low
Christian Heimesfe337bf2008-03-23 21:54:12 +0000506 if u > c:
507 u = 1.0 - u
508 c = 1.0 - c
509 low, high = high, low
Raymond Hettingerf5ea83f2017-09-04 16:51:06 -0700510 return low + (high - low) * _sqrt(u * c)
Christian Heimesfe337bf2008-03-23 21:54:12 +0000511
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700512 ## -------------------- normal distribution --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000513
Tim Petersd7b5e882001-01-25 03:36:26 +0000514 def normalvariate(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000515 """Normal distribution.
516
517 mu is the mean, and sigma is the standard deviation.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000518
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000519 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000520 # mu = mean, sigma = standard deviation
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000521
Tim Petersd7b5e882001-01-25 03:36:26 +0000522 # Uses Kinderman and Monahan method. Reference: Kinderman,
523 # A.J. and Monahan, J.F., "Computer generation of random
524 # variables using the ratio of uniform deviates", ACM Trans
525 # Math Software, 3, (1977), pp257-260.
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000526
Tim Petersd7b5e882001-01-25 03:36:26 +0000527 random = self.random
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700528 while True:
Tim Peters0c9886d2001-01-15 01:18:21 +0000529 u1 = random()
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000530 u2 = 1.0 - random()
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700531 z = NV_MAGICCONST * (u1 - 0.5) / u2
532 zz = z * z / 4.0
Tim Petersd7b5e882001-01-25 03:36:26 +0000533 if zz <= -_log(u2):
534 break
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700535 return mu + z * sigma
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000536
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700537 ## -------------------- lognormal distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000538
539 def lognormvariate(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000540 """Log normal distribution.
541
542 If you take the natural logarithm of this distribution, you'll get a
543 normal distribution with mean mu and standard deviation sigma.
544 mu can have any value, and sigma must be greater than zero.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000545
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000546 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000547 return _exp(self.normalvariate(mu, sigma))
548
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700549 ## -------------------- exponential distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000550
551 def expovariate(self, lambd):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000552 """Exponential distribution.
553
Mark Dickinson2f947362009-01-07 17:54:07 +0000554 lambd is 1.0 divided by the desired mean. It should be
555 nonzero. (The parameter would be called "lambda", but that is
556 a reserved word in Python.) Returned values range from 0 to
557 positive infinity if lambd is positive, and from negative
558 infinity to 0 if lambd is negative.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000559
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000560 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000561 # lambd: rate lambd = 1/mean
562 # ('lambda' is a Python reserved word)
563
Raymond Hettinger5279fb92011-06-25 11:30:53 +0200564 # we use 1-random() instead of random() to preclude the
565 # possibility of taking the log of zero.
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700566 return -_log(1.0 - self.random()) / lambd
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000567
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700568 ## -------------------- von Mises distribution --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000569
Tim Petersd7b5e882001-01-25 03:36:26 +0000570 def vonmisesvariate(self, mu, kappa):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000571 """Circular data distribution.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000572
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000573 mu is the mean angle, expressed in radians between 0 and 2*pi, and
574 kappa is the concentration parameter, which must be greater than or
575 equal to zero. If kappa is equal to zero, this distribution reduces
576 to a uniform random angle over the range 0 to 2*pi.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000577
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000578 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000579 # mu: mean angle (in radians between 0 and 2*pi)
580 # kappa: concentration parameter kappa (>= 0)
581 # if kappa = 0 generate uniform random angle
582
583 # Based upon an algorithm published in: Fisher, N.I.,
584 # "Statistical Analysis of Circular Data", Cambridge
585 # University Press, 1993.
586
587 # Thanks to Magnus Kessler for a correction to the
588 # implementation of step 4.
589
590 random = self.random
591 if kappa <= 1e-6:
592 return TWOPI * random()
593
Serhiy Storchaka6c22b1d2013-02-10 19:28:56 +0200594 s = 0.5 / kappa
595 r = s + _sqrt(1.0 + s * s)
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000596
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700597 while True:
Tim Peters0c9886d2001-01-15 01:18:21 +0000598 u1 = random()
Tim Petersd7b5e882001-01-25 03:36:26 +0000599 z = _cos(_pi * u1)
Tim Petersd7b5e882001-01-25 03:36:26 +0000600
Serhiy Storchaka6c22b1d2013-02-10 19:28:56 +0200601 d = z / (r + z)
Tim Petersd7b5e882001-01-25 03:36:26 +0000602 u2 = random()
Serhiy Storchaka6c22b1d2013-02-10 19:28:56 +0200603 if u2 < 1.0 - d * d or u2 <= (1.0 - d) * _exp(d):
Tim Peters0c9886d2001-01-15 01:18:21 +0000604 break
Tim Petersd7b5e882001-01-25 03:36:26 +0000605
Serhiy Storchaka6c22b1d2013-02-10 19:28:56 +0200606 q = 1.0 / r
607 f = (q + z) / (1.0 + q * z)
Tim Petersd7b5e882001-01-25 03:36:26 +0000608 u3 = random()
609 if u3 > 0.5:
Mark Dickinsonbe5f9192013-02-10 14:16:10 +0000610 theta = (mu + _acos(f)) % TWOPI
Tim Petersd7b5e882001-01-25 03:36:26 +0000611 else:
Mark Dickinsonbe5f9192013-02-10 14:16:10 +0000612 theta = (mu - _acos(f)) % TWOPI
Tim Petersd7b5e882001-01-25 03:36:26 +0000613
614 return theta
615
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700616 ## -------------------- gamma distribution --------------------
Tim Petersd7b5e882001-01-25 03:36:26 +0000617
618 def gammavariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000619 """Gamma distribution. Not the gamma function!
620
621 Conditions on the parameters are alpha > 0 and beta > 0.
622
Raymond Hettingera8e4d6e2011-03-22 15:55:51 -0700623 The probability distribution function is:
624
625 x ** (alpha - 1) * math.exp(-x / beta)
626 pdf(x) = --------------------------------------
627 math.gamma(alpha) * beta ** alpha
628
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000629 """
Tim Peters8ac14952002-05-23 15:15:30 +0000630
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000631 # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
Tim Peters8ac14952002-05-23 15:15:30 +0000632
Guido van Rossum570764d2002-05-14 14:08:12 +0000633 # Warning: a few older sources define the gamma distribution in terms
634 # of alpha > -1.0
635 if alpha <= 0.0 or beta <= 0.0:
Collin Winterce36ad82007-08-30 01:19:48 +0000636 raise ValueError('gammavariate: alpha and beta must be > 0.0')
Tim Peters8ac14952002-05-23 15:15:30 +0000637
Tim Petersd7b5e882001-01-25 03:36:26 +0000638 random = self.random
Tim Petersd7b5e882001-01-25 03:36:26 +0000639 if alpha > 1.0:
640
641 # Uses R.C.H. Cheng, "The generation of Gamma
642 # variables with non-integral shape parameters",
643 # Applied Statistics, (1977), 26, No. 1, p71-74
644
Raymond Hettingerca6cdc22002-05-13 23:40:14 +0000645 ainv = _sqrt(2.0 * alpha - 1.0)
646 bbb = alpha - LOG4
647 ccc = alpha + ainv
Tim Peters8ac14952002-05-23 15:15:30 +0000648
Raymond Hettinger42406e62005-04-30 09:02:51 +0000649 while 1:
Tim Petersd7b5e882001-01-25 03:36:26 +0000650 u1 = random()
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700651 if not 1e-7 < u1 < 0.9999999:
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000652 continue
653 u2 = 1.0 - random()
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700654 v = _log(u1 / (1.0 - u1)) / ainv
655 x = alpha * _exp(v)
656 z = u1 * u1 * u2
657 r = bbb + ccc * v - x
658 if r + SG_MAGICCONST - 4.5 * z >= 0.0 or r >= _log(z):
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000659 return x * beta
Tim Petersd7b5e882001-01-25 03:36:26 +0000660
661 elif alpha == 1.0:
leodema9f396b62017-06-04 07:41:41 +0100662 # expovariate(1/beta)
leodema63d15222018-12-24 07:54:25 +0100663 return -_log(1.0 - random()) * beta
Tim Petersd7b5e882001-01-25 03:36:26 +0000664
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700665 else:
666 # alpha is between 0 and 1 (exclusive)
Tim Petersd7b5e882001-01-25 03:36:26 +0000667 # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700668 while True:
Tim Petersd7b5e882001-01-25 03:36:26 +0000669 u = random()
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700670 b = (_e + alpha) / _e
671 p = b * u
Tim Petersd7b5e882001-01-25 03:36:26 +0000672 if p <= 1.0:
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700673 x = p ** (1.0 / alpha)
Tim Petersd7b5e882001-01-25 03:36:26 +0000674 else:
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700675 x = -_log((b - p) / alpha)
Tim Petersd7b5e882001-01-25 03:36:26 +0000676 u1 = random()
Raymond Hettinger42406e62005-04-30 09:02:51 +0000677 if p > 1.0:
678 if u1 <= x ** (alpha - 1.0):
679 break
680 elif u1 <= _exp(-x):
Tim Petersd7b5e882001-01-25 03:36:26 +0000681 break
Raymond Hettingerb760efb2002-05-14 06:40:34 +0000682 return x * beta
683
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700684 ## -------------------- Gauss (faster alternative) --------------------
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000685
Tim Petersd7b5e882001-01-25 03:36:26 +0000686 def gauss(self, mu, sigma):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000687 """Gaussian distribution.
688
689 mu is the mean, and sigma is the standard deviation. This is
690 slightly faster than the normalvariate() function.
691
692 Not thread-safe without a lock around calls.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000693
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000694 """
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000695
Tim Petersd7b5e882001-01-25 03:36:26 +0000696 # When x and y are two variables from [0, 1), uniformly
697 # distributed, then
698 #
699 # cos(2*pi*x)*sqrt(-2*log(1-y))
700 # sin(2*pi*x)*sqrt(-2*log(1-y))
701 #
702 # are two *independent* variables with normal distribution
703 # (mu = 0, sigma = 1).
704 # (Lambert Meertens)
705 # (corrected version; bug discovered by Mike Miller, fixed by LM)
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000706
Tim Petersd7b5e882001-01-25 03:36:26 +0000707 # Multithreading note: When two threads call this function
708 # simultaneously, it is possible that they will receive the
709 # same return value. The window is very small though. To
710 # avoid this, you have to use a lock around all calls. (I
711 # didn't want to slow this down in the serial case by using a
712 # lock here.)
Guido van Rossumd03e1191998-05-29 17:51:31 +0000713
Tim Petersd7b5e882001-01-25 03:36:26 +0000714 random = self.random
715 z = self.gauss_next
716 self.gauss_next = None
717 if z is None:
718 x2pi = random() * TWOPI
719 g2rad = _sqrt(-2.0 * _log(1.0 - random()))
720 z = _cos(x2pi) * g2rad
721 self.gauss_next = _sin(x2pi) * g2rad
Guido van Rossumcc32ac91994-03-15 16:10:24 +0000722
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700723 return mu + z * sigma
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000724
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700725 ## -------------------- beta --------------------
726 ## See
727 ## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html
728 ## for Ivan Frohne's insightful analysis of why the original implementation:
729 ##
730 ## def betavariate(self, alpha, beta):
731 ## # Discrete Event Simulation in C, pp 87-88.
732 ##
733 ## y = self.expovariate(alpha)
734 ## z = self.expovariate(1.0/beta)
735 ## return z/(y+z)
736 ##
737 ## was dead wrong, and how it probably got that way.
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000738
Tim Petersd7b5e882001-01-25 03:36:26 +0000739 def betavariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000740 """Beta distribution.
741
Thomas Woutersb2137042007-02-01 18:02:27 +0000742 Conditions on the parameters are alpha > 0 and beta > 0.
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000743 Returned values range between 0 and 1.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000744
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000745 """
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000746
Tim Peters85e2e472001-01-26 06:49:56 +0000747 # This version due to Janne Sinkkonen, and matches all the std
748 # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
Raymond Hettinger650c1c92016-06-25 05:36:42 +0300749 y = self.gammavariate(alpha, 1.0)
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700750 if y:
Raymond Hettinger650c1c92016-06-25 05:36:42 +0300751 return y / (y + self.gammavariate(beta, 1.0))
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700752 return 0.0
Guido van Rossum95bfcda1994-03-09 14:21:05 +0000753
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700754 ## -------------------- Pareto --------------------
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000755
Tim Petersd7b5e882001-01-25 03:36:26 +0000756 def paretovariate(self, alpha):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000757 """Pareto distribution. alpha is the shape parameter."""
Tim Petersd7b5e882001-01-25 03:36:26 +0000758 # Jain, pg. 495
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000759
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000760 u = 1.0 - self.random()
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700761 return 1.0 / u ** (1.0 / alpha)
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000762
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700763 ## -------------------- Weibull --------------------
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000764
Tim Petersd7b5e882001-01-25 03:36:26 +0000765 def weibullvariate(self, alpha, beta):
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000766 """Weibull distribution.
767
768 alpha is the scale parameter and beta is the shape parameter.
Raymond Hettingeref4d4bd2002-05-23 23:58:17 +0000769
Raymond Hettingerc32f0332002-05-23 19:44:49 +0000770 """
Tim Petersd7b5e882001-01-25 03:36:26 +0000771 # Jain, pg. 499; bug fix courtesy Bill Arms
Guido van Rossumcf4559a1997-12-02 02:47:39 +0000772
Raymond Hettinger73ced7e2003-01-04 09:26:32 +0000773 u = 1.0 - self.random()
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700774 return alpha * (-_log(u)) ** (1.0 / beta)
775
Guido van Rossum6c395ba1999-08-18 13:53:28 +0000776
Raymond Hettinger23f12412004-09-13 22:23:21 +0000777## --------------- Operating System Random Source ------------------
Raymond Hettinger356a4592004-08-30 06:14:31 +0000778
Raymond Hettinger23f12412004-09-13 22:23:21 +0000779class SystemRandom(Random):
780 """Alternate random number generator using sources provided
781 by the operating system (such as /dev/urandom on Unix or
782 CryptGenRandom on Windows).
Raymond Hettinger356a4592004-08-30 06:14:31 +0000783
784 Not available on all systems (see os.urandom() for details).
785 """
786
787 def random(self):
788 """Get the next random number in the range [0.0, 1.0)."""
Raymond Hettinger183cd1f2010-09-08 18:48:21 +0000789 return (int.from_bytes(_urandom(7), 'big') >> 3) * RECIP_BPF
Raymond Hettinger356a4592004-08-30 06:14:31 +0000790
791 def getrandbits(self, k):
Serhiy Storchaka95949422013-08-27 19:40:23 +0300792 """getrandbits(k) -> x. Generates an int with k random bits."""
Antoine Pitrou75a33782020-04-17 19:32:14 +0200793 if k < 0:
794 raise ValueError('number of bits must be non-negative')
Raymond Hettinger63b17672010-09-08 19:27:59 +0000795 numbytes = (k + 7) // 8 # bits / 8 and rounded up
796 x = int.from_bytes(_urandom(numbytes), 'big')
797 return x >> (numbytes * 8 - k) # trim excess bits
Raymond Hettinger356a4592004-08-30 06:14:31 +0000798
Victor Stinner9f5fe792020-04-17 19:05:35 +0200799 def randbytes(self, n):
800 """Generate n random bytes."""
801 # os.urandom(n) fails with ValueError for n < 0
802 # and returns an empty bytes string for n == 0.
803 return _urandom(n)
804
Raymond Hettinger28de64f2008-01-13 23:40:30 +0000805 def seed(self, *args, **kwds):
Raymond Hettinger23f12412004-09-13 22:23:21 +0000806 "Stub method. Not used for a system random number generator."
Raymond Hettinger356a4592004-08-30 06:14:31 +0000807 return None
Raymond Hettinger356a4592004-08-30 06:14:31 +0000808
809 def _notimplemented(self, *args, **kwds):
Raymond Hettinger23f12412004-09-13 22:23:21 +0000810 "Method should not be called for a system random number generator."
811 raise NotImplementedError('System entropy source does not have state.')
Raymond Hettinger356a4592004-08-30 06:14:31 +0000812 getstate = setstate = _notimplemented
813
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700814
Tim Peterscd804102001-01-25 20:25:57 +0000815## -------------------- test program --------------------
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000816
Raymond Hettinger62297132003-08-30 01:24:19 +0000817def _test_generator(n, func, args):
Miss Islington (bot)cd696202020-06-22 21:22:40 -0700818 from statistics import stdev, fmean as mean
819 from time import perf_counter
820
821 t0 = perf_counter()
822 data = [func(*args) for i in range(n)]
823 t1 = perf_counter()
824
825 xbar = mean(data)
826 sigma = stdev(data, xbar)
827 low = min(data)
828 high = max(data)
829
830 print(f'{t1 - t0:.3f} sec, {n} times {func.__name__}')
831 print('avg %g, stddev %g, min %g, max %g\n' % (xbar, sigma, low, high))
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000832
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000833
834def _test(N=2000):
Raymond Hettinger62297132003-08-30 01:24:19 +0000835 _test_generator(N, random, ())
836 _test_generator(N, normalvariate, (0.0, 1.0))
837 _test_generator(N, lognormvariate, (0.0, 1.0))
838 _test_generator(N, vonmisesvariate, (0.0, 1.0))
839 _test_generator(N, gammavariate, (0.01, 1.0))
840 _test_generator(N, gammavariate, (0.1, 1.0))
841 _test_generator(N, gammavariate, (0.1, 2.0))
842 _test_generator(N, gammavariate, (0.5, 1.0))
843 _test_generator(N, gammavariate, (0.9, 1.0))
844 _test_generator(N, gammavariate, (1.0, 1.0))
845 _test_generator(N, gammavariate, (2.0, 1.0))
846 _test_generator(N, gammavariate, (20.0, 1.0))
847 _test_generator(N, gammavariate, (200.0, 1.0))
848 _test_generator(N, gauss, (0.0, 1.0))
849 _test_generator(N, betavariate, (3.0, 3.0))
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700850 _test_generator(N, triangular, (0.0, 1.0, 1.0 / 3.0))
Tim Peterscd804102001-01-25 20:25:57 +0000851
Tim Peters715c4c42001-01-26 22:56:56 +0000852# Create one instance, seeded from current time, and export its methods
Raymond Hettinger40f62172002-12-29 23:03:38 +0000853# as module-level functions. The functions share state across all uses
Miss Islington (bot)f1534d02020-06-13 10:23:48 -0700854# (both in the user's code and in the Python libraries), but that's fine
Raymond Hettinger40f62172002-12-29 23:03:38 +0000855# for most programs and is easier for the casual user than making them
856# instantiate their own Random() instance.
857
Tim Petersd7b5e882001-01-25 03:36:26 +0000858_inst = Random()
859seed = _inst.seed
860random = _inst.random
861uniform = _inst.uniform
Christian Heimesfe337bf2008-03-23 21:54:12 +0000862triangular = _inst.triangular
Tim Petersd7b5e882001-01-25 03:36:26 +0000863randint = _inst.randint
864choice = _inst.choice
865randrange = _inst.randrange
Raymond Hettingerf24eb352002-11-12 17:41:57 +0000866sample = _inst.sample
Tim Petersd7b5e882001-01-25 03:36:26 +0000867shuffle = _inst.shuffle
Raymond Hettinger28aa4a02016-09-07 00:08:44 -0700868choices = _inst.choices
Tim Petersd7b5e882001-01-25 03:36:26 +0000869normalvariate = _inst.normalvariate
870lognormvariate = _inst.lognormvariate
Tim Petersd7b5e882001-01-25 03:36:26 +0000871expovariate = _inst.expovariate
872vonmisesvariate = _inst.vonmisesvariate
873gammavariate = _inst.gammavariate
Tim Petersd7b5e882001-01-25 03:36:26 +0000874gauss = _inst.gauss
875betavariate = _inst.betavariate
876paretovariate = _inst.paretovariate
877weibullvariate = _inst.weibullvariate
878getstate = _inst.getstate
879setstate = _inst.setstate
Raymond Hettinger2f726e92003-10-05 09:09:15 +0000880getrandbits = _inst.getrandbits
Victor Stinner9f5fe792020-04-17 19:05:35 +0200881randbytes = _inst.randbytes
Tim Petersd7b5e882001-01-25 03:36:26 +0000882
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200883if hasattr(_os, "fork"):
Gregory P. Smith163468a2017-05-29 10:03:41 -0700884 _os.register_at_fork(after_in_child=_inst.seed)
Antoine Pitrou346cbd32017-05-27 17:50:54 +0200885
886
Guido van Rossumff03b1a1994-03-09 12:55:02 +0000887if __name__ == '__main__':
Tim Petersd7b5e882001-01-25 03:36:26 +0000888 _test()