Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
9 changes: 6 additions & 3 deletions numpy/random/src/distributions/distributions.c
Original file line number Diff line number Diff line change
Expand Up @@ -845,12 +845,15 @@ double random_noncentral_f(bitgen_t *bitgen_state, double dfnum, double dfden,

double random_wald(bitgen_t *bitgen_state, double mean, double scale) {
double U, X, Y;
double mu_2l;
double d;

mu_2l = mean / (2 * scale);
Y = random_standard_normal(bitgen_state);
if (Y == 0) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does the Y need to be exactly 0 or close to zero within some epsilon like fabs(Y) < 1e-12 ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good question. I tried it with forcing Y=1e-10 or 1e-15, etc, and it doesn't seem to cause any issues.

For what it's worth, I realized that even without the check for if (Y==0), it's still fine when Y=0, because you get d=inf (per the IEEE standard), and then X = mean * (1 - d/inf) = mean.

I'm not sure what is the usual numpy practice here -- can we rely on inf as an intermediate step?

return mean;
}
Y = mean * Y * Y;
X = mean + mu_2l * (Y - sqrt(4 * scale * Y + Y * Y));
d = 1 + sqrt(1 + 4 * scale / Y);
X = mean * (1 - 2 / d);
U = next_double(bitgen_state);
if (U <= mean / (mean + X)) {
return X;
Expand Down
5 changes: 5 additions & 0 deletions numpy/random/tests/test_generator_mt19937.py
Original file line number Diff line number Diff line change
Expand Up @@ -1874,6 +1874,11 @@ def test_wald(self):
[2.07093587449261, 0.73073890064369]])
assert_array_almost_equal(actual, desired, decimal=14)

def test_wald_nonnegative(self):
random = Generator(MT19937(self.seed))
samples = random.wald(mean=1e9, scale=2.25, size=1000)
assert_(np.all(samples >= 0.0))

def test_weibull(self):
random = Generator(MT19937(self.seed))
actual = random.weibull(a=1.23, size=(3, 2))
Expand Down
Loading