Minor code clean-ups (GH-20838)

This commit is contained in:
Raymond Hettinger 2020-06-13 09:46:47 -07:00 committed by GitHub
parent 9672912e8f
commit 9db5b8d448
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -39,7 +39,7 @@ General notes on the underlying Mersenne Twister core generator:
from warnings import warn as _warn from warnings import warn as _warn
from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin, tau as TWOPI
from os import urandom as _urandom from os import urandom as _urandom
from _collections_abc import Set as _Set, Sequence as _Sequence from _collections_abc import Set as _Set, Sequence as _Sequence
from itertools import accumulate as _accumulate, repeat as _repeat from itertools import accumulate as _accumulate, repeat as _repeat
@ -54,15 +54,34 @@ except ImportError:
from hashlib import sha512 as _sha512 from hashlib import sha512 as _sha512
__all__ = ["Random","seed","random","uniform","randint","choice","sample", __all__ = [
"randrange","shuffle","normalvariate","lognormvariate", "Random",
"expovariate","vonmisesvariate","gammavariate","triangular", "SystemRandom",
"gauss","betavariate","paretovariate","weibullvariate", "betavariate",
"getstate","setstate", "getrandbits", "choices", "choice",
"SystemRandom"] "choices",
"expovariate",
"gammavariate",
"gauss",
"getrandbits",
"getstate",
"lognormvariate",
"normalvariate",
"paretovariate",
"randint",
"random",
"randrange",
"sample",
"seed",
"setstate",
"shuffle",
"triangular",
"uniform",
"vonmisesvariate",
"weibullvariate",
]
NV_MAGICCONST = 4 * _exp(-0.5) / _sqrt(2.0) NV_MAGICCONST = 4 * _exp(-0.5) / _sqrt(2.0)
TWOPI = 2.0*_pi
LOG4 = _log(4.0) LOG4 = _log(4.0)
SG_MAGICCONST = 1.0 + _log(4.5) SG_MAGICCONST = 1.0 + _log(4.5)
BPF = 53 # Number of bits in a float BPF = 53 # Number of bits in a float
@ -75,6 +94,7 @@ RECIP_BPF = 2**-BPF
import _random import _random
class Random(_random.Random): class Random(_random.Random):
"""Random number generator base class used by bound module functions. """Random number generator base class used by bound module functions.
@ -303,7 +323,8 @@ class Random(_random.Random):
def choice(self, seq): def choice(self, seq):
"""Choose a random element from a non-empty sequence.""" """Choose a random element from a non-empty sequence."""
return seq[self._randbelow(len(seq))] # raises IndexError if seq is empty # raises IndexError if seq is empty
return seq[self._randbelow(len(seq))]
def shuffle(self, x, random=None): def shuffle(self, x, random=None):
"""Shuffle list x in place, and return None. """Shuffle list x in place, and return None.
@ -412,9 +433,10 @@ class Random(_random.Random):
if k > 5: if k > 5:
setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets setsize += 4 ** _ceil(_log(k * 3, 4)) # table size for big sets
if n <= setsize: if n <= setsize:
# An n-length list is smaller than a k-length set # An n-length list is smaller than a k-length set.
# Invariant: non-selected at pool[0 : n-i]
pool = list(population) pool = list(population)
for i in range(k): # invariant: non-selected at [0,n-i) for i in range(k):
j = randbelow(n - i) j = randbelow(n - i)
result[i] = pool[j] result[i] = pool[j]
pool[j] = pool[n - i - 1] # move non-selected item into vacancy pool[j] = pool[n - i - 1] # move non-selected item into vacancy
@ -502,7 +524,7 @@ class Random(_random.Random):
# Math Software, 3, (1977), pp257-260. # Math Software, 3, (1977), pp257-260.
random = self.random random = self.random
while 1: while True:
u1 = random() u1 = random()
u2 = 1.0 - random() u2 = 1.0 - random()
z = NV_MAGICCONST * (u1 - 0.5) / u2 z = NV_MAGICCONST * (u1 - 0.5) / u2
@ -571,7 +593,7 @@ class Random(_random.Random):
s = 0.5 / kappa s = 0.5 / kappa
r = s + _sqrt(1.0 + s * s) r = s + _sqrt(1.0 + s * s)
while 1: while True:
u1 = random() u1 = random()
z = _cos(_pi * u1) z = _cos(_pi * u1)
@ -625,7 +647,7 @@ class Random(_random.Random):
while 1: while 1:
u1 = random() u1 = random()
if not 1e-7 < u1 < .9999999: if not 1e-7 < u1 < 0.9999999:
continue continue
u2 = 1.0 - random() u2 = 1.0 - random()
v = _log(u1 / (1.0 - u1)) / ainv v = _log(u1 / (1.0 - u1)) / ainv
@ -639,11 +661,10 @@ class Random(_random.Random):
# expovariate(1/beta) # expovariate(1/beta)
return -_log(1.0 - random()) * beta return -_log(1.0 - random()) * beta
else: # alpha is between 0 and 1 (exclusive) else:
# alpha is between 0 and 1 (exclusive)
# Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle
while True:
while 1:
u = random() u = random()
b = (_e + alpha) / _e b = (_e + alpha) / _e
p = b * u p = b * u
@ -725,10 +746,9 @@ class Random(_random.Random):
# This version due to Janne Sinkkonen, and matches all the std # This version due to Janne Sinkkonen, and matches all the std
# texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution"). # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution").
y = self.gammavariate(alpha, 1.0) y = self.gammavariate(alpha, 1.0)
if y == 0: if y:
return 0.0
else:
return y / (y + self.gammavariate(beta, 1.0)) return y / (y + self.gammavariate(beta, 1.0))
return 0.0
## -------------------- Pareto -------------------- ## -------------------- Pareto --------------------
@ -752,6 +772,7 @@ class Random(_random.Random):
u = 1.0 - self.random() u = 1.0 - self.random()
return alpha * (-_log(u)) ** (1.0 / beta) return alpha * (-_log(u)) ** (1.0 / beta)
## --------------- Operating System Random Source ------------------ ## --------------- Operating System Random Source ------------------
class SystemRandom(Random): class SystemRandom(Random):
@ -789,6 +810,7 @@ class SystemRandom(Random):
raise NotImplementedError('System entropy source does not have state.') raise NotImplementedError('System entropy source does not have state.')
getstate = setstate = _notimplemented getstate = setstate = _notimplemented
## -------------------- test program -------------------- ## -------------------- test program --------------------
def _test_generator(n, func, args): def _test_generator(n, func, args):
@ -809,8 +831,7 @@ def _test_generator(n, func, args):
print(round(t1 - t0, 3), 'sec,', end=' ') print(round(t1 - t0, 3), 'sec,', end=' ')
avg = total / n avg = total / n
stddev = _sqrt(sqsum / n - avg * avg) stddev = _sqrt(sqsum / n - avg * avg)
print('avg %g, stddev %g, min %g, max %g\n' % \ print('avg %g, stddev %g, min %g, max %g\n' % (avg, stddev, smallest, largest))
(avg, stddev, smallest, largest))
def _test(N=2000): def _test(N=2000):