xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/random.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker"""Random variable generators.
2*cda5da8dSAndroid Build Coastguard Worker
3*cda5da8dSAndroid Build Coastguard Worker    bytes
4*cda5da8dSAndroid Build Coastguard Worker    -----
5*cda5da8dSAndroid Build Coastguard Worker           uniform bytes (values between 0 and 255)
6*cda5da8dSAndroid Build Coastguard Worker
7*cda5da8dSAndroid Build Coastguard Worker    integers
8*cda5da8dSAndroid Build Coastguard Worker    --------
9*cda5da8dSAndroid Build Coastguard Worker           uniform within range
10*cda5da8dSAndroid Build Coastguard Worker
11*cda5da8dSAndroid Build Coastguard Worker    sequences
12*cda5da8dSAndroid Build Coastguard Worker    ---------
13*cda5da8dSAndroid Build Coastguard Worker           pick random element
14*cda5da8dSAndroid Build Coastguard Worker           pick random sample
15*cda5da8dSAndroid Build Coastguard Worker           pick weighted random sample
16*cda5da8dSAndroid Build Coastguard Worker           generate random permutation
17*cda5da8dSAndroid Build Coastguard Worker
18*cda5da8dSAndroid Build Coastguard Worker    distributions on the real line:
19*cda5da8dSAndroid Build Coastguard Worker    ------------------------------
20*cda5da8dSAndroid Build Coastguard Worker           uniform
21*cda5da8dSAndroid Build Coastguard Worker           triangular
22*cda5da8dSAndroid Build Coastguard Worker           normal (Gaussian)
23*cda5da8dSAndroid Build Coastguard Worker           lognormal
24*cda5da8dSAndroid Build Coastguard Worker           negative exponential
25*cda5da8dSAndroid Build Coastguard Worker           gamma
26*cda5da8dSAndroid Build Coastguard Worker           beta
27*cda5da8dSAndroid Build Coastguard Worker           pareto
28*cda5da8dSAndroid Build Coastguard Worker           Weibull
29*cda5da8dSAndroid Build Coastguard Worker
30*cda5da8dSAndroid Build Coastguard Worker    distributions on the circle (angles 0 to 2pi)
31*cda5da8dSAndroid Build Coastguard Worker    ---------------------------------------------
32*cda5da8dSAndroid Build Coastguard Worker           circular uniform
33*cda5da8dSAndroid Build Coastguard Worker           von Mises
34*cda5da8dSAndroid Build Coastguard Worker
35*cda5da8dSAndroid Build Coastguard WorkerGeneral notes on the underlying Mersenne Twister core generator:
36*cda5da8dSAndroid Build Coastguard Worker
37*cda5da8dSAndroid Build Coastguard Worker* The period is 2**19937-1.
38*cda5da8dSAndroid Build Coastguard Worker* It is one of the most extensively tested generators in existence.
39*cda5da8dSAndroid Build Coastguard Worker* The random() method is implemented in C, executes in a single Python step,
40*cda5da8dSAndroid Build Coastguard Worker  and is, therefore, threadsafe.
41*cda5da8dSAndroid Build Coastguard Worker
42*cda5da8dSAndroid Build Coastguard Worker"""
43*cda5da8dSAndroid Build Coastguard Worker
44*cda5da8dSAndroid Build Coastguard Worker# Translated by Guido van Rossum from C source provided by
45*cda5da8dSAndroid Build Coastguard Worker# Adrian Baddeley.  Adapted by Raymond Hettinger for use with
46*cda5da8dSAndroid Build Coastguard Worker# the Mersenne Twister  and os.urandom() core generators.
47*cda5da8dSAndroid Build Coastguard Worker
48*cda5da8dSAndroid Build Coastguard Workerfrom warnings import warn as _warn
49*cda5da8dSAndroid Build Coastguard Workerfrom math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
50*cda5da8dSAndroid Build Coastguard Workerfrom math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
51*cda5da8dSAndroid Build Coastguard Workerfrom math import tau as TWOPI, floor as _floor, isfinite as _isfinite
52*cda5da8dSAndroid Build Coastguard Workerfrom os import urandom as _urandom
53*cda5da8dSAndroid Build Coastguard Workerfrom _collections_abc import Set as _Set, Sequence as _Sequence
54*cda5da8dSAndroid Build Coastguard Workerfrom operator import index as _index
55*cda5da8dSAndroid Build Coastguard Workerfrom itertools import accumulate as _accumulate, repeat as _repeat
56*cda5da8dSAndroid Build Coastguard Workerfrom bisect import bisect as _bisect
57*cda5da8dSAndroid Build Coastguard Workerimport os as _os
58*cda5da8dSAndroid Build Coastguard Workerimport _random
59*cda5da8dSAndroid Build Coastguard Worker
60*cda5da8dSAndroid Build Coastguard Workertry:
61*cda5da8dSAndroid Build Coastguard Worker    # hashlib is pretty heavy to load, try lean internal module first
62*cda5da8dSAndroid Build Coastguard Worker    from _sha512 import sha512 as _sha512
63*cda5da8dSAndroid Build Coastguard Workerexcept ImportError:
64*cda5da8dSAndroid Build Coastguard Worker    # fallback to official implementation
65*cda5da8dSAndroid Build Coastguard Worker    from hashlib import sha512 as _sha512
66*cda5da8dSAndroid Build Coastguard Worker
67*cda5da8dSAndroid Build Coastguard Worker__all__ = [
68*cda5da8dSAndroid Build Coastguard Worker    "Random",
69*cda5da8dSAndroid Build Coastguard Worker    "SystemRandom",
70*cda5da8dSAndroid Build Coastguard Worker    "betavariate",
71*cda5da8dSAndroid Build Coastguard Worker    "choice",
72*cda5da8dSAndroid Build Coastguard Worker    "choices",
73*cda5da8dSAndroid Build Coastguard Worker    "expovariate",
74*cda5da8dSAndroid Build Coastguard Worker    "gammavariate",
75*cda5da8dSAndroid Build Coastguard Worker    "gauss",
76*cda5da8dSAndroid Build Coastguard Worker    "getrandbits",
77*cda5da8dSAndroid Build Coastguard Worker    "getstate",
78*cda5da8dSAndroid Build Coastguard Worker    "lognormvariate",
79*cda5da8dSAndroid Build Coastguard Worker    "normalvariate",
80*cda5da8dSAndroid Build Coastguard Worker    "paretovariate",
81*cda5da8dSAndroid Build Coastguard Worker    "randbytes",
82*cda5da8dSAndroid Build Coastguard Worker    "randint",
83*cda5da8dSAndroid Build Coastguard Worker    "random",
84*cda5da8dSAndroid Build Coastguard Worker    "randrange",
85*cda5da8dSAndroid Build Coastguard Worker    "sample",
86*cda5da8dSAndroid Build Coastguard Worker    "seed",
87*cda5da8dSAndroid Build Coastguard Worker    "setstate",
88*cda5da8dSAndroid Build Coastguard Worker    "shuffle",
89*cda5da8dSAndroid Build Coastguard Worker    "triangular",
90*cda5da8dSAndroid Build Coastguard Worker    "uniform",
91*cda5da8dSAndroid Build Coastguard Worker    "vonmisesvariate",
92*cda5da8dSAndroid Build Coastguard Worker    "weibullvariate",
93*cda5da8dSAndroid Build Coastguard Worker]
94*cda5da8dSAndroid Build Coastguard Worker
95*cda5da8dSAndroid Build Coastguard WorkerNV_MAGICCONST = 4 * _exp(-0.5) / _sqrt(2.0)
96*cda5da8dSAndroid Build Coastguard WorkerLOG4 = _log(4.0)
97*cda5da8dSAndroid Build Coastguard WorkerSG_MAGICCONST = 1.0 + _log(4.5)
98*cda5da8dSAndroid Build Coastguard WorkerBPF = 53        # Number of bits in a float
99*cda5da8dSAndroid Build Coastguard WorkerRECIP_BPF = 2 ** -BPF
100*cda5da8dSAndroid Build Coastguard Worker_ONE = 1
101*cda5da8dSAndroid Build Coastguard Worker
102*cda5da8dSAndroid Build Coastguard Worker
103*cda5da8dSAndroid Build Coastguard Workerclass Random(_random.Random):
104*cda5da8dSAndroid Build Coastguard Worker    """Random number generator base class used by bound module functions.
105*cda5da8dSAndroid Build Coastguard Worker
106*cda5da8dSAndroid Build Coastguard Worker    Used to instantiate instances of Random to get generators that don't
107*cda5da8dSAndroid Build Coastguard Worker    share state.
108*cda5da8dSAndroid Build Coastguard Worker
109*cda5da8dSAndroid Build Coastguard Worker    Class Random can also be subclassed if you want to use a different basic
110*cda5da8dSAndroid Build Coastguard Worker    generator of your own devising: in that case, override the following
111*cda5da8dSAndroid Build Coastguard Worker    methods:  random(), seed(), getstate(), and setstate().
112*cda5da8dSAndroid Build Coastguard Worker    Optionally, implement a getrandbits() method so that randrange()
113*cda5da8dSAndroid Build Coastguard Worker    can cover arbitrarily large ranges.
114*cda5da8dSAndroid Build Coastguard Worker
115*cda5da8dSAndroid Build Coastguard Worker    """
116*cda5da8dSAndroid Build Coastguard Worker
117*cda5da8dSAndroid Build Coastguard Worker    VERSION = 3     # used by getstate/setstate
118*cda5da8dSAndroid Build Coastguard Worker
119*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, x=None):
120*cda5da8dSAndroid Build Coastguard Worker        """Initialize an instance.
121*cda5da8dSAndroid Build Coastguard Worker
122*cda5da8dSAndroid Build Coastguard Worker        Optional argument x controls seeding, as for Random.seed().
123*cda5da8dSAndroid Build Coastguard Worker        """
124*cda5da8dSAndroid Build Coastguard Worker
125*cda5da8dSAndroid Build Coastguard Worker        self.seed(x)
126*cda5da8dSAndroid Build Coastguard Worker        self.gauss_next = None
127*cda5da8dSAndroid Build Coastguard Worker
128*cda5da8dSAndroid Build Coastguard Worker    def seed(self, a=None, version=2):
129*cda5da8dSAndroid Build Coastguard Worker        """Initialize internal state from a seed.
130*cda5da8dSAndroid Build Coastguard Worker
131*cda5da8dSAndroid Build Coastguard Worker        The only supported seed types are None, int, float,
132*cda5da8dSAndroid Build Coastguard Worker        str, bytes, and bytearray.
133*cda5da8dSAndroid Build Coastguard Worker
134*cda5da8dSAndroid Build Coastguard Worker        None or no argument seeds from current time or from an operating
135*cda5da8dSAndroid Build Coastguard Worker        system specific randomness source if available.
136*cda5da8dSAndroid Build Coastguard Worker
137*cda5da8dSAndroid Build Coastguard Worker        If *a* is an int, all bits are used.
138*cda5da8dSAndroid Build Coastguard Worker
139*cda5da8dSAndroid Build Coastguard Worker        For version 2 (the default), all of the bits are used if *a* is a str,
140*cda5da8dSAndroid Build Coastguard Worker        bytes, or bytearray.  For version 1 (provided for reproducing random
141*cda5da8dSAndroid Build Coastguard Worker        sequences from older versions of Python), the algorithm for str and
142*cda5da8dSAndroid Build Coastguard Worker        bytes generates a narrower range of seeds.
143*cda5da8dSAndroid Build Coastguard Worker
144*cda5da8dSAndroid Build Coastguard Worker        """
145*cda5da8dSAndroid Build Coastguard Worker
146*cda5da8dSAndroid Build Coastguard Worker        if version == 1 and isinstance(a, (str, bytes)):
147*cda5da8dSAndroid Build Coastguard Worker            a = a.decode('latin-1') if isinstance(a, bytes) else a
148*cda5da8dSAndroid Build Coastguard Worker            x = ord(a[0]) << 7 if a else 0
149*cda5da8dSAndroid Build Coastguard Worker            for c in map(ord, a):
150*cda5da8dSAndroid Build Coastguard Worker                x = ((1000003 * x) ^ c) & 0xFFFFFFFFFFFFFFFF
151*cda5da8dSAndroid Build Coastguard Worker            x ^= len(a)
152*cda5da8dSAndroid Build Coastguard Worker            a = -2 if x == -1 else x
153*cda5da8dSAndroid Build Coastguard Worker
154*cda5da8dSAndroid Build Coastguard Worker        elif version == 2 and isinstance(a, (str, bytes, bytearray)):
155*cda5da8dSAndroid Build Coastguard Worker            if isinstance(a, str):
156*cda5da8dSAndroid Build Coastguard Worker                a = a.encode()
157*cda5da8dSAndroid Build Coastguard Worker            a = int.from_bytes(a + _sha512(a).digest())
158*cda5da8dSAndroid Build Coastguard Worker
159*cda5da8dSAndroid Build Coastguard Worker        elif not isinstance(a, (type(None), int, float, str, bytes, bytearray)):
160*cda5da8dSAndroid Build Coastguard Worker            raise TypeError('The only supported seed types are: None,\n'
161*cda5da8dSAndroid Build Coastguard Worker                            'int, float, str, bytes, and bytearray.')
162*cda5da8dSAndroid Build Coastguard Worker
163*cda5da8dSAndroid Build Coastguard Worker        super().seed(a)
164*cda5da8dSAndroid Build Coastguard Worker        self.gauss_next = None
165*cda5da8dSAndroid Build Coastguard Worker
166*cda5da8dSAndroid Build Coastguard Worker    def getstate(self):
167*cda5da8dSAndroid Build Coastguard Worker        """Return internal state; can be passed to setstate() later."""
168*cda5da8dSAndroid Build Coastguard Worker        return self.VERSION, super().getstate(), self.gauss_next
169*cda5da8dSAndroid Build Coastguard Worker
170*cda5da8dSAndroid Build Coastguard Worker    def setstate(self, state):
171*cda5da8dSAndroid Build Coastguard Worker        """Restore internal state from object returned by getstate()."""
172*cda5da8dSAndroid Build Coastguard Worker        version = state[0]
173*cda5da8dSAndroid Build Coastguard Worker        if version == 3:
174*cda5da8dSAndroid Build Coastguard Worker            version, internalstate, self.gauss_next = state
175*cda5da8dSAndroid Build Coastguard Worker            super().setstate(internalstate)
176*cda5da8dSAndroid Build Coastguard Worker        elif version == 2:
177*cda5da8dSAndroid Build Coastguard Worker            version, internalstate, self.gauss_next = state
178*cda5da8dSAndroid Build Coastguard Worker            # In version 2, the state was saved as signed ints, which causes
179*cda5da8dSAndroid Build Coastguard Worker            #   inconsistencies between 32/64-bit systems. The state is
180*cda5da8dSAndroid Build Coastguard Worker            #   really unsigned 32-bit ints, so we convert negative ints from
181*cda5da8dSAndroid Build Coastguard Worker            #   version 2 to positive longs for version 3.
182*cda5da8dSAndroid Build Coastguard Worker            try:
183*cda5da8dSAndroid Build Coastguard Worker                internalstate = tuple(x % (2 ** 32) for x in internalstate)
184*cda5da8dSAndroid Build Coastguard Worker            except ValueError as e:
185*cda5da8dSAndroid Build Coastguard Worker                raise TypeError from e
186*cda5da8dSAndroid Build Coastguard Worker            super().setstate(internalstate)
187*cda5da8dSAndroid Build Coastguard Worker        else:
188*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("state with version %s passed to "
189*cda5da8dSAndroid Build Coastguard Worker                             "Random.setstate() of version %s" %
190*cda5da8dSAndroid Build Coastguard Worker                             (version, self.VERSION))
191*cda5da8dSAndroid Build Coastguard Worker
192*cda5da8dSAndroid Build Coastguard Worker
193*cda5da8dSAndroid Build Coastguard Worker    ## -------------------------------------------------------
194*cda5da8dSAndroid Build Coastguard Worker    ## ---- Methods below this point do not need to be overridden or extended
195*cda5da8dSAndroid Build Coastguard Worker    ## ---- when subclassing for the purpose of using a different core generator.
196*cda5da8dSAndroid Build Coastguard Worker
197*cda5da8dSAndroid Build Coastguard Worker
198*cda5da8dSAndroid Build Coastguard Worker    ## -------------------- pickle support  -------------------
199*cda5da8dSAndroid Build Coastguard Worker
200*cda5da8dSAndroid Build Coastguard Worker    # Issue 17489: Since __reduce__ was defined to fix #759889 this is no
201*cda5da8dSAndroid Build Coastguard Worker    # longer called; we leave it here because it has been here since random was
202*cda5da8dSAndroid Build Coastguard Worker    # rewritten back in 2001 and why risk breaking something.
203*cda5da8dSAndroid Build Coastguard Worker    def __getstate__(self):  # for pickle
204*cda5da8dSAndroid Build Coastguard Worker        return self.getstate()
205*cda5da8dSAndroid Build Coastguard Worker
206*cda5da8dSAndroid Build Coastguard Worker    def __setstate__(self, state):  # for pickle
207*cda5da8dSAndroid Build Coastguard Worker        self.setstate(state)
208*cda5da8dSAndroid Build Coastguard Worker
209*cda5da8dSAndroid Build Coastguard Worker    def __reduce__(self):
210*cda5da8dSAndroid Build Coastguard Worker        return self.__class__, (), self.getstate()
211*cda5da8dSAndroid Build Coastguard Worker
212*cda5da8dSAndroid Build Coastguard Worker
213*cda5da8dSAndroid Build Coastguard Worker    ## ---- internal support method for evenly distributed integers ----
214*cda5da8dSAndroid Build Coastguard Worker
215*cda5da8dSAndroid Build Coastguard Worker    def __init_subclass__(cls, /, **kwargs):
216*cda5da8dSAndroid Build Coastguard Worker        """Control how subclasses generate random integers.
217*cda5da8dSAndroid Build Coastguard Worker
218*cda5da8dSAndroid Build Coastguard Worker        The algorithm a subclass can use depends on the random() and/or
219*cda5da8dSAndroid Build Coastguard Worker        getrandbits() implementation available to it and determines
220*cda5da8dSAndroid Build Coastguard Worker        whether it can generate random integers from arbitrarily large
221*cda5da8dSAndroid Build Coastguard Worker        ranges.
222*cda5da8dSAndroid Build Coastguard Worker        """
223*cda5da8dSAndroid Build Coastguard Worker
224*cda5da8dSAndroid Build Coastguard Worker        for c in cls.__mro__:
225*cda5da8dSAndroid Build Coastguard Worker            if '_randbelow' in c.__dict__:
226*cda5da8dSAndroid Build Coastguard Worker                # just inherit it
227*cda5da8dSAndroid Build Coastguard Worker                break
228*cda5da8dSAndroid Build Coastguard Worker            if 'getrandbits' in c.__dict__:
229*cda5da8dSAndroid Build Coastguard Worker                cls._randbelow = cls._randbelow_with_getrandbits
230*cda5da8dSAndroid Build Coastguard Worker                break
231*cda5da8dSAndroid Build Coastguard Worker            if 'random' in c.__dict__:
232*cda5da8dSAndroid Build Coastguard Worker                cls._randbelow = cls._randbelow_without_getrandbits
233*cda5da8dSAndroid Build Coastguard Worker                break
234*cda5da8dSAndroid Build Coastguard Worker
235*cda5da8dSAndroid Build Coastguard Worker    def _randbelow_with_getrandbits(self, n):
236*cda5da8dSAndroid Build Coastguard Worker        "Return a random int in the range [0,n).  Defined for n > 0."
237*cda5da8dSAndroid Build Coastguard Worker
238*cda5da8dSAndroid Build Coastguard Worker        getrandbits = self.getrandbits
239*cda5da8dSAndroid Build Coastguard Worker        k = n.bit_length()  # don't use (n-1) here because n can be 1
240*cda5da8dSAndroid Build Coastguard Worker        r = getrandbits(k)  # 0 <= r < 2**k
241*cda5da8dSAndroid Build Coastguard Worker        while r >= n:
242*cda5da8dSAndroid Build Coastguard Worker            r = getrandbits(k)
243*cda5da8dSAndroid Build Coastguard Worker        return r
244*cda5da8dSAndroid Build Coastguard Worker
245*cda5da8dSAndroid Build Coastguard Worker    def _randbelow_without_getrandbits(self, n, maxsize=1<<BPF):
246*cda5da8dSAndroid Build Coastguard Worker        """Return a random int in the range [0,n).  Defined for n > 0.
247*cda5da8dSAndroid Build Coastguard Worker
248*cda5da8dSAndroid Build Coastguard Worker        The implementation does not use getrandbits, but only random.
249*cda5da8dSAndroid Build Coastguard Worker        """
250*cda5da8dSAndroid Build Coastguard Worker
251*cda5da8dSAndroid Build Coastguard Worker        random = self.random
252*cda5da8dSAndroid Build Coastguard Worker        if n >= maxsize:
253*cda5da8dSAndroid Build Coastguard Worker            _warn("Underlying random() generator does not supply \n"
254*cda5da8dSAndroid Build Coastguard Worker                "enough bits to choose from a population range this large.\n"
255*cda5da8dSAndroid Build Coastguard Worker                "To remove the range limitation, add a getrandbits() method.")
256*cda5da8dSAndroid Build Coastguard Worker            return _floor(random() * n)
257*cda5da8dSAndroid Build Coastguard Worker        rem = maxsize % n
258*cda5da8dSAndroid Build Coastguard Worker        limit = (maxsize - rem) / maxsize   # int(limit * maxsize) % n == 0
259*cda5da8dSAndroid Build Coastguard Worker        r = random()
260*cda5da8dSAndroid Build Coastguard Worker        while r >= limit:
261*cda5da8dSAndroid Build Coastguard Worker            r = random()
262*cda5da8dSAndroid Build Coastguard Worker        return _floor(r * maxsize) % n
263*cda5da8dSAndroid Build Coastguard Worker
264*cda5da8dSAndroid Build Coastguard Worker    _randbelow = _randbelow_with_getrandbits
265*cda5da8dSAndroid Build Coastguard Worker
266*cda5da8dSAndroid Build Coastguard Worker
267*cda5da8dSAndroid Build Coastguard Worker    ## --------------------------------------------------------
268*cda5da8dSAndroid Build Coastguard Worker    ## ---- Methods below this point generate custom distributions
269*cda5da8dSAndroid Build Coastguard Worker    ## ---- based on the methods defined above.  They do not
270*cda5da8dSAndroid Build Coastguard Worker    ## ---- directly touch the underlying generator and only
271*cda5da8dSAndroid Build Coastguard Worker    ## ---- access randomness through the methods:  random(),
272*cda5da8dSAndroid Build Coastguard Worker    ## ---- getrandbits(), or _randbelow().
273*cda5da8dSAndroid Build Coastguard Worker
274*cda5da8dSAndroid Build Coastguard Worker
275*cda5da8dSAndroid Build Coastguard Worker    ## -------------------- bytes methods ---------------------
276*cda5da8dSAndroid Build Coastguard Worker
277*cda5da8dSAndroid Build Coastguard Worker    def randbytes(self, n):
278*cda5da8dSAndroid Build Coastguard Worker        """Generate n random bytes."""
279*cda5da8dSAndroid Build Coastguard Worker        return self.getrandbits(n * 8).to_bytes(n, 'little')
280*cda5da8dSAndroid Build Coastguard Worker
281*cda5da8dSAndroid Build Coastguard Worker
282*cda5da8dSAndroid Build Coastguard Worker    ## -------------------- integer methods  -------------------
283*cda5da8dSAndroid Build Coastguard Worker
284*cda5da8dSAndroid Build Coastguard Worker    def randrange(self, start, stop=None, step=_ONE):
285*cda5da8dSAndroid Build Coastguard Worker        """Choose a random item from range(stop) or range(start, stop[, step]).
286*cda5da8dSAndroid Build Coastguard Worker
287*cda5da8dSAndroid Build Coastguard Worker        Roughly equivalent to ``choice(range(start, stop, step))`` but
288*cda5da8dSAndroid Build Coastguard Worker        supports arbitrarily large ranges and is optimized for common cases.
289*cda5da8dSAndroid Build Coastguard Worker
290*cda5da8dSAndroid Build Coastguard Worker        """
291*cda5da8dSAndroid Build Coastguard Worker
292*cda5da8dSAndroid Build Coastguard Worker        # This code is a bit messy to make it fast for the
293*cda5da8dSAndroid Build Coastguard Worker        # common case while still doing adequate error checking.
294*cda5da8dSAndroid Build Coastguard Worker        try:
295*cda5da8dSAndroid Build Coastguard Worker            istart = _index(start)
296*cda5da8dSAndroid Build Coastguard Worker        except TypeError:
297*cda5da8dSAndroid Build Coastguard Worker            istart = int(start)
298*cda5da8dSAndroid Build Coastguard Worker            if istart != start:
299*cda5da8dSAndroid Build Coastguard Worker                _warn('randrange() will raise TypeError in the future',
300*cda5da8dSAndroid Build Coastguard Worker                      DeprecationWarning, 2)
301*cda5da8dSAndroid Build Coastguard Worker                raise ValueError("non-integer arg 1 for randrange()")
302*cda5da8dSAndroid Build Coastguard Worker            _warn('non-integer arguments to randrange() have been deprecated '
303*cda5da8dSAndroid Build Coastguard Worker                  'since Python 3.10 and will be removed in a subsequent '
304*cda5da8dSAndroid Build Coastguard Worker                  'version',
305*cda5da8dSAndroid Build Coastguard Worker                  DeprecationWarning, 2)
306*cda5da8dSAndroid Build Coastguard Worker        if stop is None:
307*cda5da8dSAndroid Build Coastguard Worker            # We don't check for "step != 1" because it hasn't been
308*cda5da8dSAndroid Build Coastguard Worker            # type checked and converted to an integer yet.
309*cda5da8dSAndroid Build Coastguard Worker            if step is not _ONE:
310*cda5da8dSAndroid Build Coastguard Worker                raise TypeError('Missing a non-None stop argument')
311*cda5da8dSAndroid Build Coastguard Worker            if istart > 0:
312*cda5da8dSAndroid Build Coastguard Worker                return self._randbelow(istart)
313*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("empty range for randrange()")
314*cda5da8dSAndroid Build Coastguard Worker
315*cda5da8dSAndroid Build Coastguard Worker        # stop argument supplied.
316*cda5da8dSAndroid Build Coastguard Worker        try:
317*cda5da8dSAndroid Build Coastguard Worker            istop = _index(stop)
318*cda5da8dSAndroid Build Coastguard Worker        except TypeError:
319*cda5da8dSAndroid Build Coastguard Worker            istop = int(stop)
320*cda5da8dSAndroid Build Coastguard Worker            if istop != stop:
321*cda5da8dSAndroid Build Coastguard Worker                _warn('randrange() will raise TypeError in the future',
322*cda5da8dSAndroid Build Coastguard Worker                      DeprecationWarning, 2)
323*cda5da8dSAndroid Build Coastguard Worker                raise ValueError("non-integer stop for randrange()")
324*cda5da8dSAndroid Build Coastguard Worker            _warn('non-integer arguments to randrange() have been deprecated '
325*cda5da8dSAndroid Build Coastguard Worker                  'since Python 3.10 and will be removed in a subsequent '
326*cda5da8dSAndroid Build Coastguard Worker                  'version',
327*cda5da8dSAndroid Build Coastguard Worker                  DeprecationWarning, 2)
328*cda5da8dSAndroid Build Coastguard Worker        width = istop - istart
329*cda5da8dSAndroid Build Coastguard Worker        try:
330*cda5da8dSAndroid Build Coastguard Worker            istep = _index(step)
331*cda5da8dSAndroid Build Coastguard Worker        except TypeError:
332*cda5da8dSAndroid Build Coastguard Worker            istep = int(step)
333*cda5da8dSAndroid Build Coastguard Worker            if istep != step:
334*cda5da8dSAndroid Build Coastguard Worker                _warn('randrange() will raise TypeError in the future',
335*cda5da8dSAndroid Build Coastguard Worker                      DeprecationWarning, 2)
336*cda5da8dSAndroid Build Coastguard Worker                raise ValueError("non-integer step for randrange()")
337*cda5da8dSAndroid Build Coastguard Worker            _warn('non-integer arguments to randrange() have been deprecated '
338*cda5da8dSAndroid Build Coastguard Worker                  'since Python 3.10 and will be removed in a subsequent '
339*cda5da8dSAndroid Build Coastguard Worker                  'version',
340*cda5da8dSAndroid Build Coastguard Worker                  DeprecationWarning, 2)
341*cda5da8dSAndroid Build Coastguard Worker        # Fast path.
342*cda5da8dSAndroid Build Coastguard Worker        if istep == 1:
343*cda5da8dSAndroid Build Coastguard Worker            if width > 0:
344*cda5da8dSAndroid Build Coastguard Worker                return istart + self._randbelow(width)
345*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width))
346*cda5da8dSAndroid Build Coastguard Worker
347*cda5da8dSAndroid Build Coastguard Worker        # Non-unit step argument supplied.
348*cda5da8dSAndroid Build Coastguard Worker        if istep > 0:
349*cda5da8dSAndroid Build Coastguard Worker            n = (width + istep - 1) // istep
350*cda5da8dSAndroid Build Coastguard Worker        elif istep < 0:
351*cda5da8dSAndroid Build Coastguard Worker            n = (width + istep + 1) // istep
352*cda5da8dSAndroid Build Coastguard Worker        else:
353*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("zero step for randrange()")
354*cda5da8dSAndroid Build Coastguard Worker        if n <= 0:
355*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("empty range for randrange()")
356*cda5da8dSAndroid Build Coastguard Worker        return istart + istep * self._randbelow(n)
357*cda5da8dSAndroid Build Coastguard Worker
358*cda5da8dSAndroid Build Coastguard Worker    def randint(self, a, b):
359*cda5da8dSAndroid Build Coastguard Worker        """Return random integer in range [a, b], including both end points.
360*cda5da8dSAndroid Build Coastguard Worker        """
361*cda5da8dSAndroid Build Coastguard Worker
362*cda5da8dSAndroid Build Coastguard Worker        return self.randrange(a, b+1)
363*cda5da8dSAndroid Build Coastguard Worker
364*cda5da8dSAndroid Build Coastguard Worker
365*cda5da8dSAndroid Build Coastguard Worker    ## -------------------- sequence methods  -------------------
366*cda5da8dSAndroid Build Coastguard Worker
367*cda5da8dSAndroid Build Coastguard Worker    def choice(self, seq):
368*cda5da8dSAndroid Build Coastguard Worker        """Choose a random element from a non-empty sequence."""
369*cda5da8dSAndroid Build Coastguard Worker
370*cda5da8dSAndroid Build Coastguard Worker        # As an accommodation for NumPy, we don't use "if not seq"
371*cda5da8dSAndroid Build Coastguard Worker        # because bool(numpy.array()) raises a ValueError.
372*cda5da8dSAndroid Build Coastguard Worker        if not len(seq):
373*cda5da8dSAndroid Build Coastguard Worker            raise IndexError('Cannot choose from an empty sequence')
374*cda5da8dSAndroid Build Coastguard Worker        return seq[self._randbelow(len(seq))]
375*cda5da8dSAndroid Build Coastguard Worker
376*cda5da8dSAndroid Build Coastguard Worker    def shuffle(self, x):
377*cda5da8dSAndroid Build Coastguard Worker        """Shuffle list x in place, and return None."""
378*cda5da8dSAndroid Build Coastguard Worker
379*cda5da8dSAndroid Build Coastguard Worker        randbelow = self._randbelow
380*cda5da8dSAndroid Build Coastguard Worker        for i in reversed(range(1, len(x))):
381*cda5da8dSAndroid Build Coastguard Worker            # pick an element in x[:i+1] with which to exchange x[i]
382*cda5da8dSAndroid Build Coastguard Worker            j = randbelow(i + 1)
383*cda5da8dSAndroid Build Coastguard Worker            x[i], x[j] = x[j], x[i]
384*cda5da8dSAndroid Build Coastguard Worker
385*cda5da8dSAndroid Build Coastguard Worker    def sample(self, population, k, *, counts=None):
386*cda5da8dSAndroid Build Coastguard Worker        """Chooses k unique random elements from a population sequence.
387*cda5da8dSAndroid Build Coastguard Worker
388*cda5da8dSAndroid Build Coastguard Worker        Returns a new list containing elements from the population while
389*cda5da8dSAndroid Build Coastguard Worker        leaving the original population unchanged.  The resulting list is
390*cda5da8dSAndroid Build Coastguard Worker        in selection order so that all sub-slices will also be valid random
391*cda5da8dSAndroid Build Coastguard Worker        samples.  This allows raffle winners (the sample) to be partitioned
392*cda5da8dSAndroid Build Coastguard Worker        into grand prize and second place winners (the subslices).
393*cda5da8dSAndroid Build Coastguard Worker
394*cda5da8dSAndroid Build Coastguard Worker        Members of the population need not be hashable or unique.  If the
395*cda5da8dSAndroid Build Coastguard Worker        population contains repeats, then each occurrence is a possible
396*cda5da8dSAndroid Build Coastguard Worker        selection in the sample.
397*cda5da8dSAndroid Build Coastguard Worker
398*cda5da8dSAndroid Build Coastguard Worker        Repeated elements can be specified one at a time or with the optional
399*cda5da8dSAndroid Build Coastguard Worker        counts parameter.  For example:
400*cda5da8dSAndroid Build Coastguard Worker
401*cda5da8dSAndroid Build Coastguard Worker            sample(['red', 'blue'], counts=[4, 2], k=5)
402*cda5da8dSAndroid Build Coastguard Worker
403*cda5da8dSAndroid Build Coastguard Worker        is equivalent to:
404*cda5da8dSAndroid Build Coastguard Worker
405*cda5da8dSAndroid Build Coastguard Worker            sample(['red', 'red', 'red', 'red', 'blue', 'blue'], k=5)
406*cda5da8dSAndroid Build Coastguard Worker
407*cda5da8dSAndroid Build Coastguard Worker        To choose a sample from a range of integers, use range() for the
408*cda5da8dSAndroid Build Coastguard Worker        population argument.  This is especially fast and space efficient
409*cda5da8dSAndroid Build Coastguard Worker        for sampling from a large population:
410*cda5da8dSAndroid Build Coastguard Worker
411*cda5da8dSAndroid Build Coastguard Worker            sample(range(10000000), 60)
412*cda5da8dSAndroid Build Coastguard Worker
413*cda5da8dSAndroid Build Coastguard Worker        """
414*cda5da8dSAndroid Build Coastguard Worker
415*cda5da8dSAndroid Build Coastguard Worker        # Sampling without replacement entails tracking either potential
416*cda5da8dSAndroid Build Coastguard Worker        # selections (the pool) in a list or previous selections in a set.
417*cda5da8dSAndroid Build Coastguard Worker
418*cda5da8dSAndroid Build Coastguard Worker        # When the number of selections is small compared to the
419*cda5da8dSAndroid Build Coastguard Worker        # population, then tracking selections is efficient, requiring
420*cda5da8dSAndroid Build Coastguard Worker        # only a small set and an occasional reselection.  For
421*cda5da8dSAndroid Build Coastguard Worker        # a larger number of selections, the pool tracking method is
422*cda5da8dSAndroid Build Coastguard Worker        # preferred since the list takes less space than the
423*cda5da8dSAndroid Build Coastguard Worker        # set and it doesn't suffer from frequent reselections.
424*cda5da8dSAndroid Build Coastguard Worker
425*cda5da8dSAndroid Build Coastguard Worker        # The number of calls to _randbelow() is kept at or near k, the
426*cda5da8dSAndroid Build Coastguard Worker        # theoretical minimum.  This is important because running time
427*cda5da8dSAndroid Build Coastguard Worker        # is dominated by _randbelow() and because it extracts the
428*cda5da8dSAndroid Build Coastguard Worker        # least entropy from the underlying random number generators.
429*cda5da8dSAndroid Build Coastguard Worker
430*cda5da8dSAndroid Build Coastguard Worker        # Memory requirements are kept to the smaller of a k-length
431*cda5da8dSAndroid Build Coastguard Worker        # set or an n-length list.
432*cda5da8dSAndroid Build Coastguard Worker
433*cda5da8dSAndroid Build Coastguard Worker        # There are other sampling algorithms that do not require
434*cda5da8dSAndroid Build Coastguard Worker        # auxiliary memory, but they were rejected because they made
435*cda5da8dSAndroid Build Coastguard Worker        # too many calls to _randbelow(), making them slower and
436*cda5da8dSAndroid Build Coastguard Worker        # causing them to eat more entropy than necessary.
437*cda5da8dSAndroid Build Coastguard Worker
438*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(population, _Sequence):
439*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("Population must be a sequence.  "
440*cda5da8dSAndroid Build Coastguard Worker                            "For dicts or sets, use sorted(d).")
441*cda5da8dSAndroid Build Coastguard Worker        n = len(population)
442*cda5da8dSAndroid Build Coastguard Worker        if counts is not None:
443*cda5da8dSAndroid Build Coastguard Worker            cum_counts = list(_accumulate(counts))
444*cda5da8dSAndroid Build Coastguard Worker            if len(cum_counts) != n:
445*cda5da8dSAndroid Build Coastguard Worker                raise ValueError('The number of counts does not match the population')
446*cda5da8dSAndroid Build Coastguard Worker            total = cum_counts.pop()
447*cda5da8dSAndroid Build Coastguard Worker            if not isinstance(total, int):
448*cda5da8dSAndroid Build Coastguard Worker                raise TypeError('Counts must be integers')
449*cda5da8dSAndroid Build Coastguard Worker            if total <= 0:
450*cda5da8dSAndroid Build Coastguard Worker                raise ValueError('Total of counts must be greater than zero')
451*cda5da8dSAndroid Build Coastguard Worker            selections = self.sample(range(total), k=k)
452*cda5da8dSAndroid Build Coastguard Worker            bisect = _bisect
453*cda5da8dSAndroid Build Coastguard Worker            return [population[bisect(cum_counts, s)] for s in selections]
454*cda5da8dSAndroid Build Coastguard Worker        randbelow = self._randbelow
455*cda5da8dSAndroid Build Coastguard Worker        if not 0 <= k <= n:
456*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("Sample larger than population or is negative")
457*cda5da8dSAndroid Build Coastguard Worker        result = [None] * k
458*cda5da8dSAndroid Build Coastguard Worker        setsize = 21        # size of a small set minus size of an empty list
459*cda5da8dSAndroid Build Coastguard Worker        if k > 5:
460*cda5da8dSAndroid Build Coastguard Worker            setsize += 4 ** _ceil(_log(k * 3, 4))  # table size for big sets
461*cda5da8dSAndroid Build Coastguard Worker        if n <= setsize:
462*cda5da8dSAndroid Build Coastguard Worker            # An n-length list is smaller than a k-length set.
463*cda5da8dSAndroid Build Coastguard Worker            # Invariant:  non-selected at pool[0 : n-i]
464*cda5da8dSAndroid Build Coastguard Worker            pool = list(population)
465*cda5da8dSAndroid Build Coastguard Worker            for i in range(k):
466*cda5da8dSAndroid Build Coastguard Worker                j = randbelow(n - i)
467*cda5da8dSAndroid Build Coastguard Worker                result[i] = pool[j]
468*cda5da8dSAndroid Build Coastguard Worker                pool[j] = pool[n - i - 1]  # move non-selected item into vacancy
469*cda5da8dSAndroid Build Coastguard Worker        else:
470*cda5da8dSAndroid Build Coastguard Worker            selected = set()
471*cda5da8dSAndroid Build Coastguard Worker            selected_add = selected.add
472*cda5da8dSAndroid Build Coastguard Worker            for i in range(k):
473*cda5da8dSAndroid Build Coastguard Worker                j = randbelow(n)
474*cda5da8dSAndroid Build Coastguard Worker                while j in selected:
475*cda5da8dSAndroid Build Coastguard Worker                    j = randbelow(n)
476*cda5da8dSAndroid Build Coastguard Worker                selected_add(j)
477*cda5da8dSAndroid Build Coastguard Worker                result[i] = population[j]
478*cda5da8dSAndroid Build Coastguard Worker        return result
479*cda5da8dSAndroid Build Coastguard Worker
480*cda5da8dSAndroid Build Coastguard Worker    def choices(self, population, weights=None, *, cum_weights=None, k=1):
481*cda5da8dSAndroid Build Coastguard Worker        """Return a k sized list of population elements chosen with replacement.
482*cda5da8dSAndroid Build Coastguard Worker
483*cda5da8dSAndroid Build Coastguard Worker        If the relative weights or cumulative weights are not specified,
484*cda5da8dSAndroid Build Coastguard Worker        the selections are made with equal probability.
485*cda5da8dSAndroid Build Coastguard Worker
486*cda5da8dSAndroid Build Coastguard Worker        """
487*cda5da8dSAndroid Build Coastguard Worker        random = self.random
488*cda5da8dSAndroid Build Coastguard Worker        n = len(population)
489*cda5da8dSAndroid Build Coastguard Worker        if cum_weights is None:
490*cda5da8dSAndroid Build Coastguard Worker            if weights is None:
491*cda5da8dSAndroid Build Coastguard Worker                floor = _floor
492*cda5da8dSAndroid Build Coastguard Worker                n += 0.0    # convert to float for a small speed improvement
493*cda5da8dSAndroid Build Coastguard Worker                return [population[floor(random() * n)] for i in _repeat(None, k)]
494*cda5da8dSAndroid Build Coastguard Worker            try:
495*cda5da8dSAndroid Build Coastguard Worker                cum_weights = list(_accumulate(weights))
496*cda5da8dSAndroid Build Coastguard Worker            except TypeError:
497*cda5da8dSAndroid Build Coastguard Worker                if not isinstance(weights, int):
498*cda5da8dSAndroid Build Coastguard Worker                    raise
499*cda5da8dSAndroid Build Coastguard Worker                k = weights
500*cda5da8dSAndroid Build Coastguard Worker                raise TypeError(
501*cda5da8dSAndroid Build Coastguard Worker                    f'The number of choices must be a keyword argument: {k=}'
502*cda5da8dSAndroid Build Coastguard Worker                ) from None
503*cda5da8dSAndroid Build Coastguard Worker        elif weights is not None:
504*cda5da8dSAndroid Build Coastguard Worker            raise TypeError('Cannot specify both weights and cumulative weights')
505*cda5da8dSAndroid Build Coastguard Worker        if len(cum_weights) != n:
506*cda5da8dSAndroid Build Coastguard Worker            raise ValueError('The number of weights does not match the population')
507*cda5da8dSAndroid Build Coastguard Worker        total = cum_weights[-1] + 0.0   # convert to float
508*cda5da8dSAndroid Build Coastguard Worker        if total <= 0.0:
509*cda5da8dSAndroid Build Coastguard Worker            raise ValueError('Total of weights must be greater than zero')
510*cda5da8dSAndroid Build Coastguard Worker        if not _isfinite(total):
511*cda5da8dSAndroid Build Coastguard Worker            raise ValueError('Total of weights must be finite')
512*cda5da8dSAndroid Build Coastguard Worker        bisect = _bisect
513*cda5da8dSAndroid Build Coastguard Worker        hi = n - 1
514*cda5da8dSAndroid Build Coastguard Worker        return [population[bisect(cum_weights, random() * total, 0, hi)]
515*cda5da8dSAndroid Build Coastguard Worker                for i in _repeat(None, k)]
516*cda5da8dSAndroid Build Coastguard Worker
517*cda5da8dSAndroid Build Coastguard Worker
518*cda5da8dSAndroid Build Coastguard Worker    ## -------------------- real-valued distributions  -------------------
519*cda5da8dSAndroid Build Coastguard Worker
520*cda5da8dSAndroid Build Coastguard Worker    def uniform(self, a, b):
521*cda5da8dSAndroid Build Coastguard Worker        "Get a random number in the range [a, b) or [a, b] depending on rounding."
522*cda5da8dSAndroid Build Coastguard Worker        return a + (b - a) * self.random()
523*cda5da8dSAndroid Build Coastguard Worker
524*cda5da8dSAndroid Build Coastguard Worker    def triangular(self, low=0.0, high=1.0, mode=None):
525*cda5da8dSAndroid Build Coastguard Worker        """Triangular distribution.
526*cda5da8dSAndroid Build Coastguard Worker
527*cda5da8dSAndroid Build Coastguard Worker        Continuous distribution bounded by given lower and upper limits,
528*cda5da8dSAndroid Build Coastguard Worker        and having a given mode value in-between.
529*cda5da8dSAndroid Build Coastguard Worker
530*cda5da8dSAndroid Build Coastguard Worker        http://en.wikipedia.org/wiki/Triangular_distribution
531*cda5da8dSAndroid Build Coastguard Worker
532*cda5da8dSAndroid Build Coastguard Worker        """
533*cda5da8dSAndroid Build Coastguard Worker        u = self.random()
534*cda5da8dSAndroid Build Coastguard Worker        try:
535*cda5da8dSAndroid Build Coastguard Worker            c = 0.5 if mode is None else (mode - low) / (high - low)
536*cda5da8dSAndroid Build Coastguard Worker        except ZeroDivisionError:
537*cda5da8dSAndroid Build Coastguard Worker            return low
538*cda5da8dSAndroid Build Coastguard Worker        if u > c:
539*cda5da8dSAndroid Build Coastguard Worker            u = 1.0 - u
540*cda5da8dSAndroid Build Coastguard Worker            c = 1.0 - c
541*cda5da8dSAndroid Build Coastguard Worker            low, high = high, low
542*cda5da8dSAndroid Build Coastguard Worker        return low + (high - low) * _sqrt(u * c)
543*cda5da8dSAndroid Build Coastguard Worker
544*cda5da8dSAndroid Build Coastguard Worker    def normalvariate(self, mu=0.0, sigma=1.0):
545*cda5da8dSAndroid Build Coastguard Worker        """Normal distribution.
546*cda5da8dSAndroid Build Coastguard Worker
547*cda5da8dSAndroid Build Coastguard Worker        mu is the mean, and sigma is the standard deviation.
548*cda5da8dSAndroid Build Coastguard Worker
549*cda5da8dSAndroid Build Coastguard Worker        """
550*cda5da8dSAndroid Build Coastguard Worker        # Uses Kinderman and Monahan method. Reference: Kinderman,
551*cda5da8dSAndroid Build Coastguard Worker        # A.J. and Monahan, J.F., "Computer generation of random
552*cda5da8dSAndroid Build Coastguard Worker        # variables using the ratio of uniform deviates", ACM Trans
553*cda5da8dSAndroid Build Coastguard Worker        # Math Software, 3, (1977), pp257-260.
554*cda5da8dSAndroid Build Coastguard Worker
555*cda5da8dSAndroid Build Coastguard Worker        random = self.random
556*cda5da8dSAndroid Build Coastguard Worker        while True:
557*cda5da8dSAndroid Build Coastguard Worker            u1 = random()
558*cda5da8dSAndroid Build Coastguard Worker            u2 = 1.0 - random()
559*cda5da8dSAndroid Build Coastguard Worker            z = NV_MAGICCONST * (u1 - 0.5) / u2
560*cda5da8dSAndroid Build Coastguard Worker            zz = z * z / 4.0
561*cda5da8dSAndroid Build Coastguard Worker            if zz <= -_log(u2):
562*cda5da8dSAndroid Build Coastguard Worker                break
563*cda5da8dSAndroid Build Coastguard Worker        return mu + z * sigma
564*cda5da8dSAndroid Build Coastguard Worker
565*cda5da8dSAndroid Build Coastguard Worker    def gauss(self, mu=0.0, sigma=1.0):
566*cda5da8dSAndroid Build Coastguard Worker        """Gaussian distribution.
567*cda5da8dSAndroid Build Coastguard Worker
568*cda5da8dSAndroid Build Coastguard Worker        mu is the mean, and sigma is the standard deviation.  This is
569*cda5da8dSAndroid Build Coastguard Worker        slightly faster than the normalvariate() function.
570*cda5da8dSAndroid Build Coastguard Worker
571*cda5da8dSAndroid Build Coastguard Worker        Not thread-safe without a lock around calls.
572*cda5da8dSAndroid Build Coastguard Worker
573*cda5da8dSAndroid Build Coastguard Worker        """
574*cda5da8dSAndroid Build Coastguard Worker        # When x and y are two variables from [0, 1), uniformly
575*cda5da8dSAndroid Build Coastguard Worker        # distributed, then
576*cda5da8dSAndroid Build Coastguard Worker        #
577*cda5da8dSAndroid Build Coastguard Worker        #    cos(2*pi*x)*sqrt(-2*log(1-y))
578*cda5da8dSAndroid Build Coastguard Worker        #    sin(2*pi*x)*sqrt(-2*log(1-y))
579*cda5da8dSAndroid Build Coastguard Worker        #
580*cda5da8dSAndroid Build Coastguard Worker        # are two *independent* variables with normal distribution
581*cda5da8dSAndroid Build Coastguard Worker        # (mu = 0, sigma = 1).
582*cda5da8dSAndroid Build Coastguard Worker        # (Lambert Meertens)
583*cda5da8dSAndroid Build Coastguard Worker        # (corrected version; bug discovered by Mike Miller, fixed by LM)
584*cda5da8dSAndroid Build Coastguard Worker
585*cda5da8dSAndroid Build Coastguard Worker        # Multithreading note: When two threads call this function
586*cda5da8dSAndroid Build Coastguard Worker        # simultaneously, it is possible that they will receive the
587*cda5da8dSAndroid Build Coastguard Worker        # same return value.  The window is very small though.  To
588*cda5da8dSAndroid Build Coastguard Worker        # avoid this, you have to use a lock around all calls.  (I
589*cda5da8dSAndroid Build Coastguard Worker        # didn't want to slow this down in the serial case by using a
590*cda5da8dSAndroid Build Coastguard Worker        # lock here.)
591*cda5da8dSAndroid Build Coastguard Worker
592*cda5da8dSAndroid Build Coastguard Worker        random = self.random
593*cda5da8dSAndroid Build Coastguard Worker        z = self.gauss_next
594*cda5da8dSAndroid Build Coastguard Worker        self.gauss_next = None
595*cda5da8dSAndroid Build Coastguard Worker        if z is None:
596*cda5da8dSAndroid Build Coastguard Worker            x2pi = random() * TWOPI
597*cda5da8dSAndroid Build Coastguard Worker            g2rad = _sqrt(-2.0 * _log(1.0 - random()))
598*cda5da8dSAndroid Build Coastguard Worker            z = _cos(x2pi) * g2rad
599*cda5da8dSAndroid Build Coastguard Worker            self.gauss_next = _sin(x2pi) * g2rad
600*cda5da8dSAndroid Build Coastguard Worker
601*cda5da8dSAndroid Build Coastguard Worker        return mu + z * sigma
602*cda5da8dSAndroid Build Coastguard Worker
603*cda5da8dSAndroid Build Coastguard Worker    def lognormvariate(self, mu, sigma):
604*cda5da8dSAndroid Build Coastguard Worker        """Log normal distribution.
605*cda5da8dSAndroid Build Coastguard Worker
606*cda5da8dSAndroid Build Coastguard Worker        If you take the natural logarithm of this distribution, you'll get a
607*cda5da8dSAndroid Build Coastguard Worker        normal distribution with mean mu and standard deviation sigma.
608*cda5da8dSAndroid Build Coastguard Worker        mu can have any value, and sigma must be greater than zero.
609*cda5da8dSAndroid Build Coastguard Worker
610*cda5da8dSAndroid Build Coastguard Worker        """
611*cda5da8dSAndroid Build Coastguard Worker        return _exp(self.normalvariate(mu, sigma))
612*cda5da8dSAndroid Build Coastguard Worker
613*cda5da8dSAndroid Build Coastguard Worker    def expovariate(self, lambd):
614*cda5da8dSAndroid Build Coastguard Worker        """Exponential distribution.
615*cda5da8dSAndroid Build Coastguard Worker
616*cda5da8dSAndroid Build Coastguard Worker        lambd is 1.0 divided by the desired mean.  It should be
617*cda5da8dSAndroid Build Coastguard Worker        nonzero.  (The parameter would be called "lambda", but that is
618*cda5da8dSAndroid Build Coastguard Worker        a reserved word in Python.)  Returned values range from 0 to
619*cda5da8dSAndroid Build Coastguard Worker        positive infinity if lambd is positive, and from negative
620*cda5da8dSAndroid Build Coastguard Worker        infinity to 0 if lambd is negative.
621*cda5da8dSAndroid Build Coastguard Worker
622*cda5da8dSAndroid Build Coastguard Worker        """
623*cda5da8dSAndroid Build Coastguard Worker        # lambd: rate lambd = 1/mean
624*cda5da8dSAndroid Build Coastguard Worker        # ('lambda' is a Python reserved word)
625*cda5da8dSAndroid Build Coastguard Worker
626*cda5da8dSAndroid Build Coastguard Worker        # we use 1-random() instead of random() to preclude the
627*cda5da8dSAndroid Build Coastguard Worker        # possibility of taking the log of zero.
628*cda5da8dSAndroid Build Coastguard Worker        return -_log(1.0 - self.random()) / lambd
629*cda5da8dSAndroid Build Coastguard Worker
630*cda5da8dSAndroid Build Coastguard Worker    def vonmisesvariate(self, mu, kappa):
631*cda5da8dSAndroid Build Coastguard Worker        """Circular data distribution.
632*cda5da8dSAndroid Build Coastguard Worker
633*cda5da8dSAndroid Build Coastguard Worker        mu is the mean angle, expressed in radians between 0 and 2*pi, and
634*cda5da8dSAndroid Build Coastguard Worker        kappa is the concentration parameter, which must be greater than or
635*cda5da8dSAndroid Build Coastguard Worker        equal to zero.  If kappa is equal to zero, this distribution reduces
636*cda5da8dSAndroid Build Coastguard Worker        to a uniform random angle over the range 0 to 2*pi.
637*cda5da8dSAndroid Build Coastguard Worker
638*cda5da8dSAndroid Build Coastguard Worker        """
639*cda5da8dSAndroid Build Coastguard Worker        # Based upon an algorithm published in: Fisher, N.I.,
640*cda5da8dSAndroid Build Coastguard Worker        # "Statistical Analysis of Circular Data", Cambridge
641*cda5da8dSAndroid Build Coastguard Worker        # University Press, 1993.
642*cda5da8dSAndroid Build Coastguard Worker
643*cda5da8dSAndroid Build Coastguard Worker        # Thanks to Magnus Kessler for a correction to the
644*cda5da8dSAndroid Build Coastguard Worker        # implementation of step 4.
645*cda5da8dSAndroid Build Coastguard Worker
646*cda5da8dSAndroid Build Coastguard Worker        random = self.random
647*cda5da8dSAndroid Build Coastguard Worker        if kappa <= 1e-6:
648*cda5da8dSAndroid Build Coastguard Worker            return TWOPI * random()
649*cda5da8dSAndroid Build Coastguard Worker
650*cda5da8dSAndroid Build Coastguard Worker        s = 0.5 / kappa
651*cda5da8dSAndroid Build Coastguard Worker        r = s + _sqrt(1.0 + s * s)
652*cda5da8dSAndroid Build Coastguard Worker
653*cda5da8dSAndroid Build Coastguard Worker        while True:
654*cda5da8dSAndroid Build Coastguard Worker            u1 = random()
655*cda5da8dSAndroid Build Coastguard Worker            z = _cos(_pi * u1)
656*cda5da8dSAndroid Build Coastguard Worker
657*cda5da8dSAndroid Build Coastguard Worker            d = z / (r + z)
658*cda5da8dSAndroid Build Coastguard Worker            u2 = random()
659*cda5da8dSAndroid Build Coastguard Worker            if u2 < 1.0 - d * d or u2 <= (1.0 - d) * _exp(d):
660*cda5da8dSAndroid Build Coastguard Worker                break
661*cda5da8dSAndroid Build Coastguard Worker
662*cda5da8dSAndroid Build Coastguard Worker        q = 1.0 / r
663*cda5da8dSAndroid Build Coastguard Worker        f = (q + z) / (1.0 + q * z)
664*cda5da8dSAndroid Build Coastguard Worker        u3 = random()
665*cda5da8dSAndroid Build Coastguard Worker        if u3 > 0.5:
666*cda5da8dSAndroid Build Coastguard Worker            theta = (mu + _acos(f)) % TWOPI
667*cda5da8dSAndroid Build Coastguard Worker        else:
668*cda5da8dSAndroid Build Coastguard Worker            theta = (mu - _acos(f)) % TWOPI
669*cda5da8dSAndroid Build Coastguard Worker
670*cda5da8dSAndroid Build Coastguard Worker        return theta
671*cda5da8dSAndroid Build Coastguard Worker
672*cda5da8dSAndroid Build Coastguard Worker    def gammavariate(self, alpha, beta):
673*cda5da8dSAndroid Build Coastguard Worker        """Gamma distribution.  Not the gamma function!
674*cda5da8dSAndroid Build Coastguard Worker
675*cda5da8dSAndroid Build Coastguard Worker        Conditions on the parameters are alpha > 0 and beta > 0.
676*cda5da8dSAndroid Build Coastguard Worker
677*cda5da8dSAndroid Build Coastguard Worker        The probability distribution function is:
678*cda5da8dSAndroid Build Coastguard Worker
679*cda5da8dSAndroid Build Coastguard Worker                    x ** (alpha - 1) * math.exp(-x / beta)
680*cda5da8dSAndroid Build Coastguard Worker          pdf(x) =  --------------------------------------
681*cda5da8dSAndroid Build Coastguard Worker                      math.gamma(alpha) * beta ** alpha
682*cda5da8dSAndroid Build Coastguard Worker
683*cda5da8dSAndroid Build Coastguard Worker        """
684*cda5da8dSAndroid Build Coastguard Worker        # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2
685*cda5da8dSAndroid Build Coastguard Worker
686*cda5da8dSAndroid Build Coastguard Worker        # Warning: a few older sources define the gamma distribution in terms
687*cda5da8dSAndroid Build Coastguard Worker        # of alpha > -1.0
688*cda5da8dSAndroid Build Coastguard Worker        if alpha <= 0.0 or beta <= 0.0:
689*cda5da8dSAndroid Build Coastguard Worker            raise ValueError('gammavariate: alpha and beta must be > 0.0')
690*cda5da8dSAndroid Build Coastguard Worker
691*cda5da8dSAndroid Build Coastguard Worker        random = self.random
692*cda5da8dSAndroid Build Coastguard Worker        if alpha > 1.0:
693*cda5da8dSAndroid Build Coastguard Worker
694*cda5da8dSAndroid Build Coastguard Worker            # Uses R.C.H. Cheng, "The generation of Gamma
695*cda5da8dSAndroid Build Coastguard Worker            # variables with non-integral shape parameters",
696*cda5da8dSAndroid Build Coastguard Worker            # Applied Statistics, (1977), 26, No. 1, p71-74
697*cda5da8dSAndroid Build Coastguard Worker
698*cda5da8dSAndroid Build Coastguard Worker            ainv = _sqrt(2.0 * alpha - 1.0)
699*cda5da8dSAndroid Build Coastguard Worker            bbb = alpha - LOG4
700*cda5da8dSAndroid Build Coastguard Worker            ccc = alpha + ainv
701*cda5da8dSAndroid Build Coastguard Worker
702*cda5da8dSAndroid Build Coastguard Worker            while True:
703*cda5da8dSAndroid Build Coastguard Worker                u1 = random()
704*cda5da8dSAndroid Build Coastguard Worker                if not 1e-7 < u1 < 0.9999999:
705*cda5da8dSAndroid Build Coastguard Worker                    continue
706*cda5da8dSAndroid Build Coastguard Worker                u2 = 1.0 - random()
707*cda5da8dSAndroid Build Coastguard Worker                v = _log(u1 / (1.0 - u1)) / ainv
708*cda5da8dSAndroid Build Coastguard Worker                x = alpha * _exp(v)
709*cda5da8dSAndroid Build Coastguard Worker                z = u1 * u1 * u2
710*cda5da8dSAndroid Build Coastguard Worker                r = bbb + ccc * v - x
711*cda5da8dSAndroid Build Coastguard Worker                if r + SG_MAGICCONST - 4.5 * z >= 0.0 or r >= _log(z):
712*cda5da8dSAndroid Build Coastguard Worker                    return x * beta
713*cda5da8dSAndroid Build Coastguard Worker
714*cda5da8dSAndroid Build Coastguard Worker        elif alpha == 1.0:
715*cda5da8dSAndroid Build Coastguard Worker            # expovariate(1/beta)
716*cda5da8dSAndroid Build Coastguard Worker            return -_log(1.0 - random()) * beta
717*cda5da8dSAndroid Build Coastguard Worker
718*cda5da8dSAndroid Build Coastguard Worker        else:
719*cda5da8dSAndroid Build Coastguard Worker            # alpha is between 0 and 1 (exclusive)
720*cda5da8dSAndroid Build Coastguard Worker            # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
721*cda5da8dSAndroid Build Coastguard Worker            while True:
722*cda5da8dSAndroid Build Coastguard Worker                u = random()
723*cda5da8dSAndroid Build Coastguard Worker                b = (_e + alpha) / _e
724*cda5da8dSAndroid Build Coastguard Worker                p = b * u
725*cda5da8dSAndroid Build Coastguard Worker                if p <= 1.0:
726*cda5da8dSAndroid Build Coastguard Worker                    x = p ** (1.0 / alpha)
727*cda5da8dSAndroid Build Coastguard Worker                else:
728*cda5da8dSAndroid Build Coastguard Worker                    x = -_log((b - p) / alpha)
729*cda5da8dSAndroid Build Coastguard Worker                u1 = random()
730*cda5da8dSAndroid Build Coastguard Worker                if p > 1.0:
731*cda5da8dSAndroid Build Coastguard Worker                    if u1 <= x ** (alpha - 1.0):
732*cda5da8dSAndroid Build Coastguard Worker                        break
733*cda5da8dSAndroid Build Coastguard Worker                elif u1 <= _exp(-x):
734*cda5da8dSAndroid Build Coastguard Worker                    break
735*cda5da8dSAndroid Build Coastguard Worker            return x * beta
736*cda5da8dSAndroid Build Coastguard Worker
737*cda5da8dSAndroid Build Coastguard Worker    def betavariate(self, alpha, beta):
738*cda5da8dSAndroid Build Coastguard Worker        """Beta distribution.
739*cda5da8dSAndroid Build Coastguard Worker
740*cda5da8dSAndroid Build Coastguard Worker        Conditions on the parameters are alpha > 0 and beta > 0.
741*cda5da8dSAndroid Build Coastguard Worker        Returned values range between 0 and 1.
742*cda5da8dSAndroid Build Coastguard Worker
743*cda5da8dSAndroid Build Coastguard Worker        """
744*cda5da8dSAndroid Build Coastguard Worker        ## See
745*cda5da8dSAndroid Build Coastguard Worker        ## http://mail.python.org/pipermail/python-bugs-list/2001-January/003752.html
746*cda5da8dSAndroid Build Coastguard Worker        ## for Ivan Frohne's insightful analysis of why the original implementation:
747*cda5da8dSAndroid Build Coastguard Worker        ##
748*cda5da8dSAndroid Build Coastguard Worker        ##    def betavariate(self, alpha, beta):
749*cda5da8dSAndroid Build Coastguard Worker        ##        # Discrete Event Simulation in C, pp 87-88.
750*cda5da8dSAndroid Build Coastguard Worker        ##
751*cda5da8dSAndroid Build Coastguard Worker        ##        y = self.expovariate(alpha)
752*cda5da8dSAndroid Build Coastguard Worker        ##        z = self.expovariate(1.0/beta)
753*cda5da8dSAndroid Build Coastguard Worker        ##        return z/(y+z)
754*cda5da8dSAndroid Build Coastguard Worker        ##
755*cda5da8dSAndroid Build Coastguard Worker        ## was dead wrong, and how it probably got that way.
756*cda5da8dSAndroid Build Coastguard Worker
757*cda5da8dSAndroid Build Coastguard Worker        # This version due to Janne Sinkkonen, and matches all the std
758*cda5da8dSAndroid Build Coastguard Worker        # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
759*cda5da8dSAndroid Build Coastguard Worker        y = self.gammavariate(alpha, 1.0)
760*cda5da8dSAndroid Build Coastguard Worker        if y:
761*cda5da8dSAndroid Build Coastguard Worker            return y / (y + self.gammavariate(beta, 1.0))
762*cda5da8dSAndroid Build Coastguard Worker        return 0.0
763*cda5da8dSAndroid Build Coastguard Worker
764*cda5da8dSAndroid Build Coastguard Worker    def paretovariate(self, alpha):
765*cda5da8dSAndroid Build Coastguard Worker        """Pareto distribution.  alpha is the shape parameter."""
766*cda5da8dSAndroid Build Coastguard Worker        # Jain, pg. 495
767*cda5da8dSAndroid Build Coastguard Worker
768*cda5da8dSAndroid Build Coastguard Worker        u = 1.0 - self.random()
769*cda5da8dSAndroid Build Coastguard Worker        return u ** (-1.0 / alpha)
770*cda5da8dSAndroid Build Coastguard Worker
771*cda5da8dSAndroid Build Coastguard Worker    def weibullvariate(self, alpha, beta):
772*cda5da8dSAndroid Build Coastguard Worker        """Weibull distribution.
773*cda5da8dSAndroid Build Coastguard Worker
774*cda5da8dSAndroid Build Coastguard Worker        alpha is the scale parameter and beta is the shape parameter.
775*cda5da8dSAndroid Build Coastguard Worker
776*cda5da8dSAndroid Build Coastguard Worker        """
777*cda5da8dSAndroid Build Coastguard Worker        # Jain, pg. 499; bug fix courtesy Bill Arms
778*cda5da8dSAndroid Build Coastguard Worker
779*cda5da8dSAndroid Build Coastguard Worker        u = 1.0 - self.random()
780*cda5da8dSAndroid Build Coastguard Worker        return alpha * (-_log(u)) ** (1.0 / beta)
781*cda5da8dSAndroid Build Coastguard Worker
782*cda5da8dSAndroid Build Coastguard Worker
783*cda5da8dSAndroid Build Coastguard Worker## ------------------------------------------------------------------
784*cda5da8dSAndroid Build Coastguard Worker## --------------- Operating System Random Source  ------------------
785*cda5da8dSAndroid Build Coastguard Worker
786*cda5da8dSAndroid Build Coastguard Worker
787*cda5da8dSAndroid Build Coastguard Workerclass SystemRandom(Random):
788*cda5da8dSAndroid Build Coastguard Worker    """Alternate random number generator using sources provided
789*cda5da8dSAndroid Build Coastguard Worker    by the operating system (such as /dev/urandom on Unix or
790*cda5da8dSAndroid Build Coastguard Worker    CryptGenRandom on Windows).
791*cda5da8dSAndroid Build Coastguard Worker
792*cda5da8dSAndroid Build Coastguard Worker     Not available on all systems (see os.urandom() for details).
793*cda5da8dSAndroid Build Coastguard Worker
794*cda5da8dSAndroid Build Coastguard Worker    """
795*cda5da8dSAndroid Build Coastguard Worker
796*cda5da8dSAndroid Build Coastguard Worker    def random(self):
797*cda5da8dSAndroid Build Coastguard Worker        """Get the next random number in the range 0.0 <= X < 1.0."""
798*cda5da8dSAndroid Build Coastguard Worker        return (int.from_bytes(_urandom(7)) >> 3) * RECIP_BPF
799*cda5da8dSAndroid Build Coastguard Worker
800*cda5da8dSAndroid Build Coastguard Worker    def getrandbits(self, k):
801*cda5da8dSAndroid Build Coastguard Worker        """getrandbits(k) -> x.  Generates an int with k random bits."""
802*cda5da8dSAndroid Build Coastguard Worker        if k < 0:
803*cda5da8dSAndroid Build Coastguard Worker            raise ValueError('number of bits must be non-negative')
804*cda5da8dSAndroid Build Coastguard Worker        numbytes = (k + 7) // 8                       # bits / 8 and rounded up
805*cda5da8dSAndroid Build Coastguard Worker        x = int.from_bytes(_urandom(numbytes))
806*cda5da8dSAndroid Build Coastguard Worker        return x >> (numbytes * 8 - k)                # trim excess bits
807*cda5da8dSAndroid Build Coastguard Worker
808*cda5da8dSAndroid Build Coastguard Worker    def randbytes(self, n):
809*cda5da8dSAndroid Build Coastguard Worker        """Generate n random bytes."""
810*cda5da8dSAndroid Build Coastguard Worker        # os.urandom(n) fails with ValueError for n < 0
811*cda5da8dSAndroid Build Coastguard Worker        # and returns an empty bytes string for n == 0.
812*cda5da8dSAndroid Build Coastguard Worker        return _urandom(n)
813*cda5da8dSAndroid Build Coastguard Worker
814*cda5da8dSAndroid Build Coastguard Worker    def seed(self, *args, **kwds):
815*cda5da8dSAndroid Build Coastguard Worker        "Stub method.  Not used for a system random number generator."
816*cda5da8dSAndroid Build Coastguard Worker        return None
817*cda5da8dSAndroid Build Coastguard Worker
818*cda5da8dSAndroid Build Coastguard Worker    def _notimplemented(self, *args, **kwds):
819*cda5da8dSAndroid Build Coastguard Worker        "Method should not be called for a system random number generator."
820*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError('System entropy source does not have state.')
821*cda5da8dSAndroid Build Coastguard Worker    getstate = setstate = _notimplemented
822*cda5da8dSAndroid Build Coastguard Worker
823*cda5da8dSAndroid Build Coastguard Worker
824*cda5da8dSAndroid Build Coastguard Worker# ----------------------------------------------------------------------
825*cda5da8dSAndroid Build Coastguard Worker# Create one instance, seeded from current time, and export its methods
826*cda5da8dSAndroid Build Coastguard Worker# as module-level functions.  The functions share state across all uses
827*cda5da8dSAndroid Build Coastguard Worker# (both in the user's code and in the Python libraries), but that's fine
828*cda5da8dSAndroid Build Coastguard Worker# for most programs and is easier for the casual user than making them
829*cda5da8dSAndroid Build Coastguard Worker# instantiate their own Random() instance.
830*cda5da8dSAndroid Build Coastguard Worker
831*cda5da8dSAndroid Build Coastguard Worker_inst = Random()
832*cda5da8dSAndroid Build Coastguard Workerseed = _inst.seed
833*cda5da8dSAndroid Build Coastguard Workerrandom = _inst.random
834*cda5da8dSAndroid Build Coastguard Workeruniform = _inst.uniform
835*cda5da8dSAndroid Build Coastguard Workertriangular = _inst.triangular
836*cda5da8dSAndroid Build Coastguard Workerrandint = _inst.randint
837*cda5da8dSAndroid Build Coastguard Workerchoice = _inst.choice
838*cda5da8dSAndroid Build Coastguard Workerrandrange = _inst.randrange
839*cda5da8dSAndroid Build Coastguard Workersample = _inst.sample
840*cda5da8dSAndroid Build Coastguard Workershuffle = _inst.shuffle
841*cda5da8dSAndroid Build Coastguard Workerchoices = _inst.choices
842*cda5da8dSAndroid Build Coastguard Workernormalvariate = _inst.normalvariate
843*cda5da8dSAndroid Build Coastguard Workerlognormvariate = _inst.lognormvariate
844*cda5da8dSAndroid Build Coastguard Workerexpovariate = _inst.expovariate
845*cda5da8dSAndroid Build Coastguard Workervonmisesvariate = _inst.vonmisesvariate
846*cda5da8dSAndroid Build Coastguard Workergammavariate = _inst.gammavariate
847*cda5da8dSAndroid Build Coastguard Workergauss = _inst.gauss
848*cda5da8dSAndroid Build Coastguard Workerbetavariate = _inst.betavariate
849*cda5da8dSAndroid Build Coastguard Workerparetovariate = _inst.paretovariate
850*cda5da8dSAndroid Build Coastguard Workerweibullvariate = _inst.weibullvariate
851*cda5da8dSAndroid Build Coastguard Workergetstate = _inst.getstate
852*cda5da8dSAndroid Build Coastguard Workersetstate = _inst.setstate
853*cda5da8dSAndroid Build Coastguard Workergetrandbits = _inst.getrandbits
854*cda5da8dSAndroid Build Coastguard Workerrandbytes = _inst.randbytes
855*cda5da8dSAndroid Build Coastguard Worker
856*cda5da8dSAndroid Build Coastguard Worker
857*cda5da8dSAndroid Build Coastguard Worker## ------------------------------------------------------
858*cda5da8dSAndroid Build Coastguard Worker## ----------------- test program -----------------------
859*cda5da8dSAndroid Build Coastguard Worker
860*cda5da8dSAndroid Build Coastguard Workerdef _test_generator(n, func, args):
861*cda5da8dSAndroid Build Coastguard Worker    from statistics import stdev, fmean as mean
862*cda5da8dSAndroid Build Coastguard Worker    from time import perf_counter
863*cda5da8dSAndroid Build Coastguard Worker
864*cda5da8dSAndroid Build Coastguard Worker    t0 = perf_counter()
865*cda5da8dSAndroid Build Coastguard Worker    data = [func(*args) for i in _repeat(None, n)]
866*cda5da8dSAndroid Build Coastguard Worker    t1 = perf_counter()
867*cda5da8dSAndroid Build Coastguard Worker
868*cda5da8dSAndroid Build Coastguard Worker    xbar = mean(data)
869*cda5da8dSAndroid Build Coastguard Worker    sigma = stdev(data, xbar)
870*cda5da8dSAndroid Build Coastguard Worker    low = min(data)
871*cda5da8dSAndroid Build Coastguard Worker    high = max(data)
872*cda5da8dSAndroid Build Coastguard Worker
873*cda5da8dSAndroid Build Coastguard Worker    print(f'{t1 - t0:.3f} sec, {n} times {func.__name__}')
874*cda5da8dSAndroid Build Coastguard Worker    print('avg %g, stddev %g, min %g, max %g\n' % (xbar, sigma, low, high))
875*cda5da8dSAndroid Build Coastguard Worker
876*cda5da8dSAndroid Build Coastguard Worker
877*cda5da8dSAndroid Build Coastguard Workerdef _test(N=2000):
878*cda5da8dSAndroid Build Coastguard Worker    _test_generator(N, random, ())
879*cda5da8dSAndroid Build Coastguard Worker    _test_generator(N, normalvariate, (0.0, 1.0))
880*cda5da8dSAndroid Build Coastguard Worker    _test_generator(N, lognormvariate, (0.0, 1.0))
881*cda5da8dSAndroid Build Coastguard Worker    _test_generator(N, vonmisesvariate, (0.0, 1.0))
882*cda5da8dSAndroid Build Coastguard Worker    _test_generator(N, gammavariate, (0.01, 1.0))
883*cda5da8dSAndroid Build Coastguard Worker    _test_generator(N, gammavariate, (0.1, 1.0))
884*cda5da8dSAndroid Build Coastguard Worker    _test_generator(N, gammavariate, (0.1, 2.0))
885*cda5da8dSAndroid Build Coastguard Worker    _test_generator(N, gammavariate, (0.5, 1.0))
886*cda5da8dSAndroid Build Coastguard Worker    _test_generator(N, gammavariate, (0.9, 1.0))
887*cda5da8dSAndroid Build Coastguard Worker    _test_generator(N, gammavariate, (1.0, 1.0))
888*cda5da8dSAndroid Build Coastguard Worker    _test_generator(N, gammavariate, (2.0, 1.0))
889*cda5da8dSAndroid Build Coastguard Worker    _test_generator(N, gammavariate, (20.0, 1.0))
890*cda5da8dSAndroid Build Coastguard Worker    _test_generator(N, gammavariate, (200.0, 1.0))
891*cda5da8dSAndroid Build Coastguard Worker    _test_generator(N, gauss, (0.0, 1.0))
892*cda5da8dSAndroid Build Coastguard Worker    _test_generator(N, betavariate, (3.0, 3.0))
893*cda5da8dSAndroid Build Coastguard Worker    _test_generator(N, triangular, (0.0, 1.0, 1.0 / 3.0))
894*cda5da8dSAndroid Build Coastguard Worker
895*cda5da8dSAndroid Build Coastguard Worker
896*cda5da8dSAndroid Build Coastguard Worker## ------------------------------------------------------
897*cda5da8dSAndroid Build Coastguard Worker## ------------------ fork support  ---------------------
898*cda5da8dSAndroid Build Coastguard Worker
899*cda5da8dSAndroid Build Coastguard Workerif hasattr(_os, "fork"):
900*cda5da8dSAndroid Build Coastguard Worker    _os.register_at_fork(after_in_child=_inst.seed)
901*cda5da8dSAndroid Build Coastguard Worker
902*cda5da8dSAndroid Build Coastguard Worker
903*cda5da8dSAndroid Build Coastguard Workerif __name__ == '__main__':
904*cda5da8dSAndroid Build Coastguard Worker    _test()
905