Skip to content

Commit

Permalink
Merge pull request #182 from bashtage/backport-rand-uint
Browse files Browse the repository at this point in the history
ENH: Restore random_unitegers
  • Loading branch information
bashtage committed Jul 22, 2019
2 parents cf6b5a7 + fa2c779 commit 13de99d
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 1 deletion.
54 changes: 54 additions & 0 deletions randomgen/generator.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,60 @@ cdef class RandomGenerator:
def state(self, value):
self._basicrng.state = value

def random_uintegers(self, size=None, int bits=64):
"""
random_uintegers(size=None, bits=64)
Return random unsigned integers
Parameters
----------
size : int or tuple of ints, optional
Output shape. If the given shape is, e.g., ``(m, n, k)``, then
``m * n * k`` samples are drawn. Default is None, in which case a
single value is returned.
bits : int {32, 64}
Size of the unsigned integer to return, either 32 bit or 64 bit.
Returns
-------
out : uint or ndarray
Drawn samples.
Notes
-----
This method effectively exposes access to the raw underlying
pseudo-random number generator since these all produce unsigned
integers. In practice these are most useful for generating other
random numbers.
These should not be used to produce bounded random numbers by
simple truncation.
"""
cdef np.npy_intp i, n
cdef np.ndarray array
cdef uint32_t* data32
cdef uint64_t* data64
if bits == 64:
if size is None:
with self.lock:
return self._brng.next_uint64(self._brng.state)
array = <np.ndarray>np.empty(size, np.uint64)
n = np.PyArray_SIZE(array)
data64 = <uint64_t *>np.PyArray_DATA(array)
with self.lock, nogil:
for i in range(n):
data64[i] = self._brng.next_uint64(self._brng.state)
elif bits == 32:
if size is None:
with self.lock:
return self._brng.next_uint32(self._brng.state)
array = <np.ndarray>np.empty(size, np.uint32)
n = np.PyArray_SIZE(array)
data32 = <uint32_t *>np.PyArray_DATA(array)
with self.lock, nogil:
for i in range(n):
data32[i] = self._brng.next_uint32(self._brng.state)
else:
raise ValueError('Unknown value of bits. Must be either 32 or 64.')

return array

def random_sample(self, size=None, dtype=np.float64, out=None):
"""
random_sample(size=None, dtype='d', out=None)
Expand Down
2 changes: 1 addition & 1 deletion randomgen/tests/test_direct.py
Original file line number Diff line number Diff line change
Expand Up @@ -640,4 +640,4 @@ def setup_class(cls):

@pytest.mark.skip
def test_advance_symmetry(self):
pass
pass
39 changes: 39 additions & 0 deletions randomgen/tests/test_smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
Xoshiro256StarStar, Xoshiro512StarStar, entropy)
from randomgen._testing import suppress_warnings

PY3 = sys.version_info >= (3,)

if PY3:
long = int


@pytest.fixture(scope='module',
params=(np.bool, np.int8, np.int16, np.int32, np.int64,
Expand Down Expand Up @@ -854,6 +859,40 @@ def test_complex_normal_zero_variance(self):
assert_almost_equal(c.real, 0.0)
np.testing.assert_allclose(c.imag, n, atol=1e-8)

def test_random_uintegers(self):
assert len(self.rg.random_uintegers(10)) == 10
assert len(self.rg.random_uintegers(10, bits=32)) == 10
assert isinstance(self.rg.random_uintegers(), (int, long))
assert isinstance(self.rg.random_uintegers(bits=32), (int, long))
with pytest.raises(ValueError):
self.rg.random_uintegers(bits=128)

def test_bit_generator_raw_large(self):
bg = self.rg.brng
state = bg.state
raw = bg.random_raw(100000)
bg.state = state
assert_equal(raw, bg.random_raw(100000))

def test_bit_generator_raw(self):
bg = self.rg.brng
val = bg.random_raw()
assert np.isscalar(val)
val = bg.random_raw(1)
assert val.shape == (1,)
val = bg.random_raw(1000)
assert val.shape == (1000,)
assert val.dtype == np.uint64

def test_bit_generator_benchmark(self):
bg = self.rg.brng
state = bg.state
bg._benchmark(1000)
assert not comp_state(state, bg.state)
state = bg.state
bg._benchmark(1000, 'double')
assert not comp_state(state, bg.state)


class TestMT19937(RNG):
@classmethod
Expand Down

0 comments on commit 13de99d

Please sign in to comment.