这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
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
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ version of the MT19937 generator that is especially fast at generating doubles
support an additional `method` keyword argument which can be `bm` or
`zig` where `bm` corresponds to the current method using the Box-Muller
transformation and `zig` uses the much faster (100%+) ziggurat method.
* `random_sample` can produce either single precision (`np.float32`) or
double precision (`np.float64`, the default) using an the optional keyword
argument `dtype`.

### New Functions

Expand Down
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This is a library and generic interface for alternative random
generators in Python and Numpy.

Features
--------

- Immediate drop in replacement for NumPy's RandomState

Expand Down
15 changes: 15 additions & 0 deletions doc/source/change-log.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@

Change Log
==========
Version 1.11.2
--------------
* Added keyword argument `dtype` to `random_sample` which allows for single
precision as well as double precision uniforms to be generated.

.. ipython:: python

import numpy as np
import randomstate as rs
rs.seed(23456)
rs.random_sample(3, dtype=np.float64)

rs.seed(23456)
rs.random_sample(3, dtype=np.float32)


Version 1.11.1
--------------
Expand Down
4 changes: 3 additions & 1 deletion doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
'sphinx.ext.mathjax',
'sphinx.ext.napoleon',
'sphinx.ext.autosummary',
'IPython.sphinxext.ipython_console_highlighting',
'IPython.sphinxext.ipython_directive'
]

# Add any paths that contain templates here, relative to this directory.
Expand Down Expand Up @@ -65,7 +67,7 @@
# The short X.Y version.
version = '1.11'
# The full version, including alpha/beta/rc tags.
release = '1.11.1'
release = '1.11.2'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
23 changes: 20 additions & 3 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ What's New or Different
* ``randomstate.entropy.random_entropy`` provides access to the system
source of randomness that is used in cryptographic applications (e.g.,
``/dev/urandom`` on Unix).
* The normal generator supports a 256-step ziggurat method which is 2-6 times
faster than NumPy's ``standard_normal``. This generator can be accessed using
* The normal generator supports a 256-step Ziggurat method which is 2-6 times
faster than NumPy's ``standard_normal``. This generator can be accessed
by passing the keyword argument ``method='zig'``.
* ``random_sample`` accepts the optional keyword argument ``dtype`` which
accepts ``np.float32`` or ``np.float64`` to produce either single or
double prevision uniform random variables
* For changes since the previous release, see the :ref:`change-log`

.. code-block:: python
Expand Down Expand Up @@ -69,6 +73,14 @@ generators, 'in addition' to the standard PRNG in NumPy. The included PRNGs are
.. _`wiki page on Fibonacci generators`: https://en.wikipedia.org/wiki/Lagged_Fibonacci_generator
.. _`MRG32K3A author's page`: http://simul.iro.umontreal.ca/

New Features
~~~~~~~~~~~~
.. toctree::
:maxdepth: 2

Using in Parallel Applications <parallel>
Reading System Entropy <entropy>


Individual Pseudo Random Number Generators
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand All @@ -85,8 +97,13 @@ Individual Pseudo Random Number Generators
PCG-64 <pcg64>
MLFG <mlfg>
MRG32K3A <mrg32k3a>
Reading System Entropy <entropy>

Changes
~~~~~~~
.. toctree::
:maxdepth: 2

Change Log <change-log>

Indices and tables
~~~~~~~~~~~~~~~~~~
Expand Down
21 changes: 21 additions & 0 deletions randomstate/array_utilities.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ ctypedef uint32_t (* random_uint_1_i_32)(aug_state* state, uint32_t a) nogil
ctypedef int32_t (* random_int_2_i_32)(aug_state* state, int32_t a, int32_t b) nogil
ctypedef int64_t (* random_int_2_i)(aug_state* state, int64_t a, int64_t b) nogil

ctypedef void (* random_float_fill)(aug_state* state, np.npy_intp count, float *out) nogil
ctypedef void (* random_double_fill)(aug_state* state, np.npy_intp count, double *out) nogil


cdef np.npy_intp compute_numel(size):
cdef np.npy_intp i, n = 1
if isinstance(size, tuple):
Expand Down Expand Up @@ -613,6 +615,25 @@ cdef object double_fill(aug_state* state, void *func, object size, object lock):
out_array = <np.ndarray>np.empty(size, np.float64)
n = np.PyArray_SIZE(out_array)
out_array_data = <double *>np.PyArray_DATA(out_array)
with lock, nogil:
f(state, n, out_array_data)
return out_array

cdef object float_fill(aug_state* state, void *func, object size, object lock):
cdef random_float_fill f = <random_float_fill>func
cdef float out
cdef float *out_array_data
cdef np.ndarray out_array
cdef np.npy_intp n

if size is None:
with lock:
f(state, 1, &out)
return out
else:
out_array = <np.ndarray>np.empty(size, np.float32)
n = np.PyArray_SIZE(out_array)
out_array_data = <float *>np.PyArray_DATA(out_array)
with lock, nogil:
f(state, n, out_array_data)
return out_array
16 changes: 14 additions & 2 deletions randomstate/distributions.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,25 @@ unsigned long random_uint(aug_state* state)
}


double random_standard_uniform(aug_state* state)
float random_standard_uniform32(aug_state* state)
{
return (random_uint32(state) >> 9) * (1.0 / 8388608.0);
}

double random_standard_uniform64(aug_state* state)
{
return random_double(state);
}

void random_uniform_fill32(aug_state* state, npy_intp count, float *out)
{
int i;
for (i=0; i < count; i++) {
out[i] = (random_uint32(state) >> 9) * (float)(1.0 / 8388608.0);
}
}

void random_uniform_fill(aug_state* state, npy_intp count, double *out)
void random_uniform_fill64(aug_state* state, npy_intp count, double *out)
{
int i;
for (i=0; i < count; i++) {
Expand Down
8 changes: 6 additions & 2 deletions randomstate/distributions.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ extern int64_t random_positive_int64(aug_state* state);

extern int32_t random_positive_int32(aug_state* state);

extern double random_standard_uniform(aug_state* state);
extern float random_standard_uniform32(aug_state* state);

extern double random_standard_uniform64(aug_state* state);

extern double random_standard_exponential(aug_state* state);

Expand Down Expand Up @@ -138,7 +140,9 @@ extern void random_bounded_uint8_fill(aug_state *state, uint8_t off, uint8_t rng

extern void random_bounded_bool_fill(aug_state *state, npy_bool off, npy_bool rng, npy_intp cnt, npy_bool *out);

extern void random_uniform_fill(aug_state* state, npy_intp count, double *out);
extern void random_uniform_fill32(aug_state* state, npy_intp count, float *out);

extern void random_uniform_fill64(aug_state* state, npy_intp count, double *out);

extern void random_standard_exponential_fill(aug_state* state, npy_intp count, double *out);

Expand Down
4 changes: 3 additions & 1 deletion randomstate/interface/dSFMT/dSFMT-shim.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,16 @@ static inline double random_double_from_buffer(aug_state *state)

static inline uint32_t random_uint32(aug_state* state)
{
/* TODO: This can be improved to use upper bits */
double d = random_double_from_buffer(state);//dsfmt_genrand_close1_open2(state->rng);
uint64_t *out = (uint64_t *)&d;
return (uint32_t)(*out & 0xffffffff);
}

static inline uint64_t random_uint64(aug_state* state)
{
double d = random_double_from_buffer(state);//dsfmt_genrand_close1_open2(state->rng);
/* TODO: This can be improved to use upper bits */
double d = random_double_from_buffer(state); //dsfmt_genrand_close1_open2(state->rng);
uint64_t out;
uint64_t *tmp;
tmp = (uint64_t *)&d;
Expand Down
19 changes: 15 additions & 4 deletions randomstate/randomstate.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ cdef extern from "distributions.h":

cdef void entropy_init(aug_state* state) nogil

cdef double random_standard_uniform(aug_state* state) nogil
cdef float random_standard_uniform32(aug_state* state) nogil

cdef double random_standard_uniform64(aug_state* state) nogil
cdef double random_gauss(aug_state* state) nogil
cdef double random_gauss_zig(aug_state* state) nogil
cdef double random_gauss_zig_julia(aug_state* state) nogil
Expand Down Expand Up @@ -114,7 +116,8 @@ cdef extern from "distributions.h":
cdef void random_bounded_uint16_fill(aug_state *state, uint16_t off, uint16_t rng, intptr_t cnt, uint16_t *out) nogil
cdef void random_bounded_uint8_fill(aug_state *state, uint8_t off, uint8_t rng, intptr_t cnt, uint8_t *out) nogil
cdef void random_bounded_bool_fill(aug_state *state, np.npy_bool off, np.npy_bool rng, intptr_t cnt, np.npy_bool *out) nogil
cdef void random_uniform_fill(aug_state *state, intptr_t cnt, double *out) nogil
cdef void random_uniform_fill32(aug_state *state, intptr_t cnt, double *out) nogil
cdef void random_uniform_fill64(aug_state *state, intptr_t cnt, double *out) nogil
cdef void random_standard_exponential_fill(aug_state* state, intptr_t count, double *out) nogil
cdef void random_gauss_fill(aug_state* state, intptr_t count, double *out) nogil
cdef void random_gauss_zig_julia_fill(aug_state* state, intptr_t count, double *out) nogil
Expand Down Expand Up @@ -680,7 +683,7 @@ cdef class RandomState:
self.get_state())

# Basic distributions:
def random_sample(self, size=None):
def random_sample(self, size=None, dtype=np.float64):
"""
random_sample(size=None)

Expand All @@ -698,6 +701,9 @@ cdef class RandomState:
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.
dtype : dtype, optional
Desired dtype of the result, either np.float64 (default)
or np.float32.

Returns
-------
Expand All @@ -722,7 +728,12 @@ cdef class RandomState:
[-1.23204345, -1.75224494]])

"""
return double_fill(&self.rng_state, &random_uniform_fill, size, self.lock)
if dtype is np.float64:
return double_fill(&self.rng_state, &random_uniform_fill64, size, self.lock)
elif dtype is np.float32:
return float_fill(&self.rng_state, &random_uniform_fill32, size, self.lock)
else:
raise ValueError('Unknown dtype')

def tomaxint(self, size=None):
"""
Expand Down
Loading