cpython: bdd993847ad0 (original) (raw)
--- a/Lib/random.py +++ b/Lib/random.py @@ -431,22 +431,20 @@ class Random(_random.Random): if kappa <= 1e-6: return TWOPI * random()
a = 1.0 + _sqrt(1.0 + 4.0 * kappa * kappa)[](#l1.7)
b = (a - _sqrt(2.0 * a))/(2.0 * kappa)[](#l1.8)
r = (1.0 + b * b)/(2.0 * b)[](#l1.9)
s = 0.5 / kappa[](#l1.10)
r = s + _sqrt(1.0 + s * s)[](#l1.11)
z = _cos(_pi * u1)[](#l1.15)
z = _cos(_pi * u1)[](#l1.17)
f = (1.0 + r * z)/(r + z)[](#l1.18)
c = kappa * (r - f)[](#l1.19)
d = z / (r + z)[](#l1.21) u2 = random()[](#l1.22)
if u2 < c * (2.0 - c) or u2 <= c * _exp(1.0 - c):[](#l1.24)
if u2 < 1.0 - d * d or u2 <= (1.0 - d) * _exp(d):[](#l1.25) break[](#l1.26)
q = 1.0 / r[](#l1.28)
f = (q + z) / (1.0 + q * z)[](#l1.29) u3 = random()[](#l1.30) if u3 > 0.5:[](#l1.31) theta = (mu + _acos(f)) % TWOPI[](#l1.32)
--- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -440,6 +440,7 @@ class TestDistributions(unittest.TestCas g.random = x[:].pop; g.paretovariate(1.0) g.random = x[:].pop; g.expovariate(1.0) g.random = x[:].pop; g.weibullvariate(1.0, 1.0)
g.random = x[:].pop; g.vonmisesvariate(1.0, 1.0)[](#l2.7) g.random = x[:].pop; g.normalvariate(0.0, 1.0)[](#l2.8) g.random = x[:].pop; g.gauss(0.0, 1.0)[](#l2.9) g.random = x[:].pop; g.lognormvariate(0.0, 1.0)[](#l2.10)
@@ -460,6 +461,7 @@ class TestDistributions(unittest.TestCas (g.uniform, (1.0,10.0), (10.0+1.0)/2, (10.0-1.0)2/12), (g.triangular, (0.0, 1.0, 1.0/3.0), 4.0/9.0, 7.0/9.0/18.0), (g.expovariate, (1.5,), 1/1.5, 1/1.52),
(g.vonmisesvariate, (1.23, 0), pi, pi**2/3),[](#l2.15) (g.paretovariate, (5.0,), 5.0/(5.0-1),[](#l2.16) 5.0/((5.0-1)**2*(5.0-2))),[](#l2.17) (g.weibullvariate, (1.0, 3.0), gamma(1+1/3.0),[](#l2.18)
@@ -476,8 +478,30 @@ class TestDistributions(unittest.TestCas s1 += e s2 += (e - mu) ** 2 N = len(y)
self.assertAlmostEqual(s1/N, mu, places=2)[](#l2.23)
self.assertAlmostEqual(s2/(N-1), sigmasqrd, places=2)[](#l2.24)
self.assertAlmostEqual(s1/N, mu, places=2,[](#l2.25)
msg='%s%r' % (variate.__name__, args))[](#l2.26)
self.assertAlmostEqual(s2/(N-1), sigmasqrd, places=2,[](#l2.27)
msg='%s%r' % (variate.__name__, args))[](#l2.28)
- def test_constant(self):
g = random.Random()[](#l2.31)
N = 100[](#l2.32)
for variate, args, expected in [[](#l2.33)
(g.uniform, (10.0, 10.0), 10.0),[](#l2.34)
(g.triangular, (10.0, 10.0), 10.0),[](#l2.35)
#(g.triangular, (10.0, 10.0, 10.0), 10.0),[](#l2.36)
(g.expovariate, (float('inf'),), 0.0),[](#l2.37)
(g.vonmisesvariate, (3.0, float('inf')), 3.0),[](#l2.38)
(g.gauss, (10.0, 0.0), 10.0),[](#l2.39)
(g.lognormvariate, (0.0, 0.0), 1.0),[](#l2.40)
(g.lognormvariate, (-float('inf'), 0.0), 0.0),[](#l2.41)
(g.normalvariate, (10.0, 0.0), 10.0),[](#l2.42)
(g.paretovariate, (float('inf'),), 1.0),[](#l2.43)
(g.weibullvariate, (10.0, float('inf')), 10.0),[](#l2.44)
(g.weibullvariate, (0.0, 10.0), 0.0),[](#l2.45)
]:[](#l2.46)
for i in range(N):[](#l2.47)
self.assertEqual(variate(*args), expected)[](#l2.48)
def test_von_mises_range(self): # Issue 17149: von mises variates were not consistently in the @@ -493,6 +517,12 @@ class TestDistributions(unittest.TestCas msg=("vonmisesvariate({}, {}) produced a result {} out" " of range [0, 2*pi]").format(mu, kappa, sample))
- def test_von_mises_large_kappa(self):
# Issue #17141: vonmisesvariate() was hang for large kappas[](#l2.57)
random.vonmisesvariate(0, 1e15)[](#l2.58)
random.vonmisesvariate(0, 1e100)[](#l2.59)
+ + class TestModule(unittest.TestCase): def testMagicConstants(self): self.assertAlmostEqual(random.NV_MAGICCONST, 1.71552776992141)
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -175,6 +175,8 @@ Core and Builtins Library ------- +- Issue #17141: random.vonmisesvariate() no more hangs for large kappas. +