Skip to content

Commit 4ef1d3b

Browse files
committed
TST: Add tests for nan guards
Add tests to ensure guards work Synchronize with randomgen Remove comments no longer relevant
1 parent d15ec91 commit 4ef1d3b

File tree

6 files changed

+236
-148
lines changed

6 files changed

+236
-148
lines changed

numpy/random/randomgen/common.pyx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,9 @@ cdef int check_constraint(double val, object name, constraint_type cons) except
337337
elif cons == CONS_BOUNDED_0_1:
338338
if not (val >= 0) or not (val <= 1):
339339
raise ValueError("{0} < 0 , {0} > 1 or {0} is NaN".format(name))
340+
elif cons == CONS_BOUNDED_GT_0_1:
341+
if not val >0 or not val <= 1:
342+
raise ValueError("{0} <= 0 , {0} > 1 or {0} contains NaNs".format(name))
340343
elif cons == CONS_GT_1:
341344
if not (val > 1):
342345
raise ValueError("{0} <= 1 or {0} is NaN".format(name))

numpy/random/randomgen/src/legacy/distributions-boxmuller.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ double legacy_gauss(aug_brng_t *aug_state) {
1212
return temp;
1313
} else {
1414
double f, x1, x2, r2;
15-
double f, x1, x2, r2;
1615

1716
do {
1817
x1 = 2.0 * legacy_double(aug_state) - 1.0;

numpy/random/randomgen/tests/test_against_numpy.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -570,9 +570,9 @@ def test_multivariate_normal(self):
570570
self._is_state_common_legacy()
571571

572572

573-
funcs = [randomgen.generator.zipf,
574-
randomgen.generator.logseries,
575-
randomgen.generator.poisson]
573+
funcs = [generator.zipf,
574+
generator.logseries,
575+
generator.poisson]
576576
ids = [f.__name__ for f in funcs]
577577

578578

numpy/random/randomgen/tests/test_direct.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,14 +233,14 @@ def test_seed_out_of_range_array(self):
233233

234234
def test_repr(self):
235235
rs = RandomGenerator(self.brng(*self.data1['seed']))
236-
assert 'RandomGenerator' in rs.__repr__()
237-
assert str(hex(id(rs)))[2:].upper() in rs.__repr__()
236+
assert 'RandomGenerator' in repr(rs)
237+
assert '{:#x}'.format(id(rs)).upper().replace('X', 'x') in repr(rs)
238238

239239
def test_str(self):
240240
rs = RandomGenerator(self.brng(*self.data1['seed']))
241241
assert 'RandomGenerator' in str(rs)
242242
assert str(self.brng.__name__) in str(rs)
243-
assert str(hex(id(rs)))[2:].upper() not in str(rs)
243+
assert '{:#x}'.format(id(rs)).upper().replace('X', 'x') not in str(rs)
244244

245245
def test_generator(self):
246246
brng = self.brng(*self.data1['seed'])

numpy/random/randomgen/tests/test_generator_mt19937.py

Lines changed: 84 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ def test_n_zero(self):
5353
# This test addresses issue #3480.
5454
zeros = np.zeros(2, dtype='int')
5555
for p in [0, .5, 1]:
56-
val = random.binomial(0, p)
57-
assert val == 0
56+
assert_(random.binomial(0, p) == 0)
5857
assert_array_equal(random.binomial(zeros, p), zeros)
5958

6059
def test_p_is_nan(self):
@@ -96,40 +95,40 @@ def test_invalid_prob(self):
9695
class TestSetState(object):
9796
def setup(self):
9897
self.seed = 1234567890
99-
self.brng = RandomGenerator(MT19937(self.seed))
100-
self.state = self.brng.state
98+
self.rg = RandomGenerator(MT19937(self.seed))
99+
self.state = self.rg.state
101100
self.legacy_state = (self.state['brng'],
102101
self.state['state']['key'],
103102
self.state['state']['pos'])
104103

105104
def test_basic(self):
106-
old = self.brng.tomaxint(16)
107-
self.brng.state = self.state
108-
new = self.brng.tomaxint(16)
105+
old = self.rg.tomaxint(16)
106+
self.rg.state = self.state
107+
new = self.rg.tomaxint(16)
109108
assert_(np.all(old == new))
110109

111110
def test_gaussian_reset(self):
112111
# Make sure the cached every-other-Gaussian is reset.
113-
old = self.brng.standard_normal(size=3)
114-
self.brng.state = self.state
115-
new = self.brng.standard_normal(size=3)
112+
old = self.rg.standard_normal(size=3)
113+
self.rg.state = self.state
114+
new = self.rg.standard_normal(size=3)
116115
assert_(np.all(old == new))
117116

118117
def test_gaussian_reset_in_media_res(self):
119118
# When the state is saved with a cached Gaussian, make sure the
120119
# cached Gaussian is restored.
121120

122-
self.brng.standard_normal()
123-
state = self.brng.state
124-
old = self.brng.standard_normal(size=3)
125-
self.brng.state = state
126-
new = self.brng.standard_normal(size=3)
121+
self.rg.standard_normal()
122+
state = self.rg.state
123+
old = self.rg.standard_normal(size=3)
124+
self.rg.state = state
125+
new = self.rg.standard_normal(size=3)
127126
assert_(np.all(old == new))
128127

129128
def test_negative_binomial(self):
130129
# Ensure that the negative binomial results take floating point
131130
# arguments without truncation.
132-
self.brng.negative_binomial(0.5, 0.5)
131+
self.rg.negative_binomial(0.5, 0.5)
133132

134133

135134
class TestRandint(object):
@@ -554,8 +553,7 @@ def test_choice_uniform_noreplace(self):
554553

555554
def test_choice_nonuniform_noreplace(self):
556555
random.seed(self.seed)
557-
actual = random.choice(4, 3, replace=False,
558-
p=[0.1, 0.3, 0.5, 0.1])
556+
actual = random.choice(4, 3, replace=False, p=[0.1, 0.3, 0.5, 0.1])
559557
desired = np.array([2, 3, 1])
560558
assert_array_equal(actual, desired)
561559

@@ -614,11 +612,11 @@ def test_choice_return_shape(self):
614612
# Check multi dimensional array
615613
s = (2, 3)
616614
p = [0.1, 0.1, 0.1, 0.1, 0.4, 0.2]
617-
assert_(random.choice(6, s, replace=True).shape, s)
618-
assert_(random.choice(6, s, replace=False).shape, s)
619-
assert_(random.choice(6, s, replace=True, p=p).shape, s)
620-
assert_(random.choice(6, s, replace=False, p=p).shape, s)
621-
assert_(random.choice(np.arange(6), s, replace=True).shape, s)
615+
assert_equal(random.choice(6, s, replace=True).shape, s)
616+
assert_equal(random.choice(6, s, replace=False).shape, s)
617+
assert_equal(random.choice(6, s, replace=True, p=p).shape, s)
618+
assert_equal(random.choice(6, s, replace=False, p=p).shape, s)
619+
assert_equal(random.choice(np.arange(6), s, replace=True).shape, s)
622620

623621
# Check zero-size
624622
assert_equal(random.randint(0, 0, size=(3, 0, 4)).shape, (3, 0, 4))
@@ -711,6 +709,11 @@ def test_binomial(self):
711709
[46, 45]])
712710
assert_array_equal(actual, desired)
713711

712+
random.seed(self.seed)
713+
actual = random.binomial(100.123, .456)
714+
desired = 37
715+
assert_array_equal(actual, desired)
716+
714717
def test_chisquare(self):
715718
random.seed(self.seed)
716719
actual = random.chisquare(50, size=(3, 2))
@@ -795,6 +798,16 @@ def test_geometric(self):
795798
[5, 12]])
796799
assert_array_equal(actual, desired)
797800

801+
def test_geometric_exceptions(self):
802+
assert_raises(ValueError, random.geometric, 1.1)
803+
assert_raises(ValueError, random.geometric, [1.1] * 10)
804+
assert_raises(ValueError, random.geometric, -0.1)
805+
assert_raises(ValueError, random.geometric, [-0.1] * 10)
806+
with suppress_warnings() as sup:
807+
sup.record(RuntimeWarning)
808+
assert_raises(ValueError, random.geometric, np.nan)
809+
assert_raises(ValueError, random.geometric, [np.nan] * 10)
810+
798811
def test_gumbel(self):
799812
random.seed(self.seed)
800813
actual = random.gumbel(loc=.123456789, scale=2.0, size=(3, 2))
@@ -873,6 +886,12 @@ def test_logseries(self):
873886
[3, 6]])
874887
assert_array_equal(actual, desired)
875888

889+
def test_logseries_exceptions(self):
890+
with suppress_warnings() as sup:
891+
sup.record(RuntimeWarning)
892+
assert_raises(ValueError, random.logseries, np.nan)
893+
assert_raises(ValueError, random.logseries, [np.nan] * 10)
894+
876895
def test_multinomial(self):
877896
random.seed(self.seed)
878897
actual = random.multinomial(20, [1 / 6.] * 6, size=(3, 2))
@@ -943,6 +962,13 @@ def test_negative_binomial(self):
943962
[723, 751]])
944963
assert_array_equal(actual, desired)
945964

965+
def test_negative_binomial_exceptions(self):
966+
with suppress_warnings() as sup:
967+
sup.record(RuntimeWarning)
968+
assert_raises(ValueError, random.negative_binomial, 100, np.nan)
969+
assert_raises(ValueError, random.negative_binomial, 100,
970+
[np.nan] * 10)
971+
946972
def test_noncentral_chisquare(self):
947973
random.seed(self.seed)
948974
actual = random.noncentral_chisquare(df=5, nonc=5, size=(3, 2))
@@ -973,6 +999,11 @@ def test_noncentral_f(self):
973999
[1.16362730891403, 2.54104276581491]])
9741000
assert_array_almost_equal(actual, desired, decimal=14)
9751001

1002+
def test_noncentral_f_nan(self):
1003+
random.seed(self.seed)
1004+
actual = random.noncentral_f(dfnum=5, dfden=2, nonc=np.nan)
1005+
assert np.isnan(actual)
1006+
9761007
def test_normal(self):
9771008
random.seed(self.seed)
9781009
actual = random.normal(loc=.123456789, scale=2.0, size=(3, 2))
@@ -993,7 +1024,7 @@ def test_pareto(self):
9931024
[1.1281132447159091e+01, 3.1895968171107006e+08]])
9941025
# For some reason on 32-bit x86 Ubuntu 12.10 the [1, 0] entry in this
9951026
# matrix differs by 24 nulps. Discussion:
996-
# http://mail.scipy.org/pipermail/numpy-discussion/2012-September/063801.html
1027+
# https://mail.python.org/pipermail/numpy-discussion/2012-September/063801.html
9971028
# Consensus is that this is probably some gcc quirk that affects
9981029
# rounding but not in any important way, so we just use a looser
9991030
# tolerance on this test:
@@ -1014,6 +1045,10 @@ def test_poisson_exceptions(self):
10141045
assert_raises(ValueError, random.poisson, [lamneg] * 10)
10151046
assert_raises(ValueError, random.poisson, lambig)
10161047
assert_raises(ValueError, random.poisson, [lambig] * 10)
1048+
with suppress_warnings() as sup:
1049+
sup.record(RuntimeWarning)
1050+
assert_raises(ValueError, random.poisson, np.nan)
1051+
assert_raises(ValueError, random.poisson, [np.nan] * 10)
10171052

10181053
def test_power(self):
10191054
random.seed(self.seed)
@@ -1168,8 +1203,8 @@ def __float__(self):
11681203
raise TypeError
11691204

11701205
throwing_float = np.array(1.0).view(ThrowingFloat)
1171-
assert_raises(TypeError, random.uniform,
1172-
throwing_float, throwing_float)
1206+
assert_raises(TypeError, random.uniform, throwing_float,
1207+
throwing_float)
11731208

11741209
class ThrowingInteger(np.ndarray):
11751210
def __int__(self):
@@ -1189,9 +1224,14 @@ def test_vonmises(self):
11891224
def test_vonmises_small(self):
11901225
# check infinite loop, gh-4720
11911226
random.seed(self.seed)
1192-
r = random.vonmises(mu=0., kappa=1.1e-8, size=10 ** 6)
1227+
r = random.vonmises(mu=0., kappa=1.1e-8, size=10**6)
11931228
assert_(np.isfinite(r).all())
11941229

1230+
def test_vonmises_nan(self):
1231+
random.seed(self.seed)
1232+
r = random.vonmises(mu=0., kappa=np.nan)
1233+
assert_(np.isnan(r))
1234+
11951235
def test_wald(self):
11961236
random.seed(self.seed)
11971237
actual = random.wald(mean=1.23, scale=1.54, size=(3, 2))
@@ -1372,8 +1412,9 @@ def test_noncentral_f(self):
13721412

13731413
self.set_seed()
13741414
actual = nonc_f(dfnum * 3, dfden, nonc)
1375-
mt_nonc_f = random.noncentral_f
13761415
assert_array_almost_equal(actual, desired, decimal=14)
1416+
assert np.all(np.isnan(nonc_f(dfnum, dfden, [np.nan] * 3)))
1417+
13771418
assert_raises(ValueError, nonc_f, bad_dfnum * 3, dfden, nonc)
13781419
assert_raises(ValueError, nonc_f, dfnum * 3, bad_dfden, nonc)
13791420
assert_raises(ValueError, nonc_f, dfnum * 3, dfden, bad_nonc)
@@ -1391,9 +1432,12 @@ def test_noncentral_f(self):
13911432
assert_raises(ValueError, nonc_f, bad_dfnum, dfden, nonc * 3)
13921433
assert_raises(ValueError, nonc_f, dfnum, bad_dfden, nonc * 3)
13931434
assert_raises(ValueError, nonc_f, dfnum, dfden, bad_nonc * 3)
1394-
assert_raises(ValueError, mt_nonc_f, bad_dfnum, dfden, nonc * 3)
1395-
assert_raises(ValueError, mt_nonc_f, dfnum, bad_dfden, nonc * 3)
1396-
assert_raises(ValueError, mt_nonc_f, dfnum, dfden, bad_nonc * 3)
1435+
1436+
def test_noncentral_f_small_df(self):
1437+
self.set_seed()
1438+
desired = np.array([21.57878070681719, 1.17110217503908])
1439+
actual = random.noncentral_f(0.9, 0.9, 2, size=2)
1440+
assert_array_almost_equal(actual, desired, decimal=14)
13971441

13981442
def test_chisquare(self):
13991443
df = [1]
@@ -1420,20 +1464,15 @@ def test_noncentral_chisquare(self):
14201464

14211465
self.set_seed()
14221466
actual = nonc_chi(df * 3, nonc)
1423-
mt_nonc_chi2 = random.noncentral_chisquare
14241467
assert_array_almost_equal(actual, desired, decimal=14)
14251468
assert_raises(ValueError, nonc_chi, bad_df * 3, nonc)
14261469
assert_raises(ValueError, nonc_chi, df * 3, bad_nonc)
1427-
assert_raises(ValueError, mt_nonc_chi2, bad_df * 3, nonc)
1428-
assert_raises(ValueError, mt_nonc_chi2, df * 3, bad_nonc)
14291470

14301471
self.set_seed()
14311472
actual = nonc_chi(df, nonc * 3)
14321473
assert_array_almost_equal(actual, desired, decimal=14)
14331474
assert_raises(ValueError, nonc_chi, bad_df, nonc * 3)
14341475
assert_raises(ValueError, nonc_chi, df, bad_nonc * 3)
1435-
assert_raises(ValueError, mt_nonc_chi2, bad_df, nonc * 3)
1436-
assert_raises(ValueError, mt_nonc_chi2, df, bad_nonc * 3)
14371476

14381477
def test_standard_t(self):
14391478
df = [1]
@@ -1645,24 +1684,24 @@ def test_triangular(self):
16451684
assert_array_almost_equal(actual, desired, decimal=14)
16461685
assert_raises(ValueError, triangular, bad_left_one * 3, mode, right)
16471686
assert_raises(ValueError, triangular, left * 3, bad_mode_one, right)
1648-
assert_raises(ValueError, triangular,
1649-
bad_left_two * 3, bad_mode_two, right)
1687+
assert_raises(ValueError, triangular, bad_left_two * 3, bad_mode_two,
1688+
right)
16501689

16511690
self.set_seed()
16521691
actual = triangular(left, mode * 3, right)
16531692
assert_array_almost_equal(actual, desired, decimal=14)
16541693
assert_raises(ValueError, triangular, bad_left_one, mode * 3, right)
16551694
assert_raises(ValueError, triangular, left, bad_mode_one * 3, right)
1656-
assert_raises(ValueError, triangular, bad_left_two,
1657-
bad_mode_two * 3, right)
1695+
assert_raises(ValueError, triangular, bad_left_two, bad_mode_two * 3,
1696+
right)
16581697

16591698
self.set_seed()
16601699
actual = triangular(left, mode, right * 3)
16611700
assert_array_almost_equal(actual, desired, decimal=14)
16621701
assert_raises(ValueError, triangular, bad_left_one, mode, right * 3)
16631702
assert_raises(ValueError, triangular, left, bad_mode_one, right * 3)
1664-
assert_raises(ValueError, triangular, bad_left_two,
1665-
bad_mode_two, right * 3)
1703+
assert_raises(ValueError, triangular, bad_left_two, bad_mode_two,
1704+
right * 3)
16661705

16671706
assert_raises(ValueError, triangular, 10., 0., 20.)
16681707
assert_raises(ValueError, triangular, 10., 25., 20.)
@@ -1739,6 +1778,9 @@ def test_zipf(self):
17391778
actual = zipf(a * 3)
17401779
assert_array_equal(actual, desired)
17411780
assert_raises(ValueError, zipf, bad_a * 3)
1781+
with np.errstate(invalid='ignore'):
1782+
assert_raises(ValueError, zipf, np.nan)
1783+
assert_raises(ValueError, zipf, [0, 0, np.nan])
17421784

17431785
def test_geometric(self):
17441786
p = [0.5]
@@ -1809,7 +1851,6 @@ def test_logseries(self):
18091851

18101852
class TestThread(object):
18111853
# make sure each state produces the same sequence even in threads
1812-
18131854
def setup(self):
18141855
self.seeds = range(4)
18151856

0 commit comments

Comments
 (0)