8000 BUG: test, fix nonrandom first uint32 in MT19937 state initialization · numpy/numpy@19eb3ff · GitHub
[go: up one dir, main page]

Skip to content

Commit 19eb3ff

Browse files
committed
BUG: test, fix nonrandom first uint32 in MT19937 state initialization
1 parent dcc1fc2 commit 19eb3ff

File tree

3 files changed

+43
-6
lines changed

3 files changed

+43
-6
lines changed

numpy/random/_mt19937.pyx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,9 @@ cdef class MT19937(BitGenerator):
129129
BitGenerator.__init__(self, seed)
130130
val = self._seed_seq.generate_state(RK_STATE_LEN, np.uint32)
131131
# MSB is 1; assuring non-zero initial array
132-
self.rng_state.key[0] = 0x80000000UL
133-
for i in range(1, RK_STATE_LEN):
132+
for i in range(RK_STATE_LEN):
134133
self.rng_state.key[i] = val[i]
134+
self.rng_state.key[0] |= 0x80000000UL
135135
self.rng_state.pos = i
136136

137137
self._bitgen.state = &self.rng_state
@@ -169,9 +169,9 @@ cdef class MT19937(BitGenerator):
169169
seed = SeedSequence()
170170
val = seed.generate_state(RK_STATE_LEN)
171171
# MSB is 1; assuring non-zero initial array
172-
self.rng_state.key[0] = 0x80000000UL
173-
for i in range(1, RK_STATE_LEN):
172+
for i in range(RK_STATE_LEN):
174173
self.rng_state.key[i] = val[i]
174+
self.rng_state.key[0] |= 0x80000000UL
175175
else:
176176
if hasattr(seed, 'squeeze'):
177177
seed = seed.squeeze()

numpy/random/tests/test_generator_mt19937.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,26 @@ def test_noninstantized_bitgen(self):
5656
assert_raises(ValueError, Generator, MT19937)
5757

5858

59+
def test_seed_init(self):
60+
# gh-14844. seed[0] was not correctly initialized
61+
# key[0] always held the same value
62+
63+
class FullSeedSequence(SeedSequence):
64+
65+
def __init__(self, x):
66+
self.x = x
67+
68+
def generate_state(self, n_words, dtype=np.uint32):
69+
return np.full(n_words, self.x, dtype=dtype)
70+
71+
for i in range(32):
72+
ss = FullSeedSequence(1 << i)
73+
key = MT19937(ss).state['state']['key']
74+
expected = np.full(624, 1 << i, dtype=np.uint32)
75+
expected[0] |= 0x80000000
76+
np.testing.assert_array_equal(key, expected)
77+
78+
5979
class TestBinomial(object):
6080
def test_n_zero(self):
6181
# Tests the corner case of n == 0 for the binomial distribution.
@@ -944,7 +964,7 @@ def test_permutation(self):
944964
arr_2d = np.atleast_2d([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]).T
945965
actual = random.permutation(arr_2d)
946966
assert_array_equal(actual, np.atleast_2d(desired).T)
947-
967+
948968
bad_x_str = "abcd"
949969
assert_raises(np.AxisError, random.permutation, bad_x_str)
950970

numpy/random/tests/test_randomstate.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,23 @@ def test_cannot_seed(self):
107107
def test_invalid_initialization(self):
108108
assert_raises(ValueError, random.RandomState, MT19937)
109109

110+
def test_init_unique(self):
111+
# gh-14844. seed[0] was not correctly initialized;
112+
# key[0] always held the same value
113+
rs = random.RandomState()
114+
key = rs._bit_generator.state['state']['key']
115+
res = np.empty((32,) + key.shape, dtype=key.dtype)
116+
for i in range(32):
117+
# enter the _legacy_seed(None) path
118+
rs.seed()
119+
key = rs._bit_generator.state['state']['key']
120+
res[i, ...] = key
121+
# make sure each the corresponding values at each position in key
122+
# are unique. The chances of that failing should be very low.
123+
res.shape = (32, -1)
124+
for i in range(res.shape[1]):
125+
assert len(np.unique(res[:, i])) == 32
126+
110127

111128
class TestBinomial(object):
112129
def test_n_zero(self):
@@ -618,7 +635,7 @@ def test_choice_nan_probabilities(self):
618635
a = np.array([42, 1, 2])
619636
p = [None, None, None]
620637
assert_raises(ValueError, random.choice, a, p=p)
621-
638+
622639
def test_choice_p_non_contiguous(self):
623640
p = np.ones(10) / 5
624641
p[1::2] = 3.0

0 commit comments

Comments
 (0)
0