8000 BUG: random: Fix long delays/hangs with zipf(a) when a near 1. by WarrenWeckesser · Pull Request #27048 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

BUG: random: Fix long delays/hangs with zipf(a) when a near 1. #27048

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 26, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
MAINT: Restore legacy zipf implementation.
  • Loading branch information
WarrenWeckesser committed Jul 26, 2024
commit 0a576b5c93e596a10db676ddabb7069bf637b74a
26 changes: 25 additions & 1 deletion numpy/random/src/legacy/legacy-distributions.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,31 @@ int64_t legacy_random_poisson(bitgen_t *bitgen_state, double lam) {
}

int64_t legacy_random_zipf(bitgen_t *bitgen_state, double a) {
return (int64_t)random_zipf(bitgen_state, a);
double am1, b;

am1 = a - 1.0;
b = pow(2.0, am1);
while (1) {
double T, U, V, X;

U = 1.0 - next_double(bitgen_state);
V = next_double(bitgen_state);
X = floor(pow(U, -1.0 / am1));
/*
* The real result may be above what can be represented in a signed
* long. Since this is a straightforward rejection algorithm, we can
* just reject this value. This function then models a Zipf
* distribution truncated to sys.maxint.
*/
if (X > (double)RAND_INT_MAX || X < 1.0) {
continue;
}

T = pow(1.0 + 1.0 / X, am1);
if (V * X * (T - 1.0) / (b - 1.0) <= T / b) {
return (RAND_INT_TYPE)X;
}
}
}


Expand Down
Loading
0