8000 Merge pull request #27046 from WarrenWeckesser/zipf-large-param · numpy/numpy@e214a12 · GitHub
[go: up one dir, main page]

Skip to content

Commit e214a12

Browse files
authored
Merge pull request #27046 from WarrenWeckesser/zipf-large-param
BUG: random: prevent zipf from hanging when parameter is large.
2 parents 98d19bb + 339c927 commit e214a12

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

numpy/random/src/distributions/distributions.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,15 @@ int64_t random_geometric(bitgen_t *bitgen_state, double p) {
10001000
RAND_INT_TYPE random_zipf(bitgen_t *bitgen_state, double a) {
10011001
double am1, b;
10021002

1003+
if (a >= 1025) {
1004+
/*
1005+
* If a exceeds 1025, the calculation of b will overflow and the loop
1006+
* will not terminate. It is safe to simply return 1 here, because the
1007+
* probability of generating a value greater than 1 in this case is
1008+
* less than 3e-309.
1009+
*/
1010+
return (RAND_INT_TYPE) 1;
1011+
}
10031012
am1 = a - 1.0;
10041013
b = pow(2.0, am1);
10051014
while (1) {

numpy/random/tests/test_generator_mt19937_regressions.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,10 @@ def test_geometric_tiny_prob(self):
163163
# is 0.9999999999907766, so we expect the result to be all 2**63-1.
164164
assert_array_equal(self.mt19937.geometric(p=1e-30, size=3),
165165
np.iinfo(np.int64).max)
166+
167+
def test_zipf_large_parameter(self):
168+
# Regression test for part of gh-9829: a call such as rng.zipf(10000)
169+
# would hang.
170+
n = 8
171+
sample = self.mt19937.zipf(10000, size=n)
172+
assert_array_equal(sample, np.ones(n, dtype=np.int64))

0 commit comments

Comments
 (0)
0