diff options
author | Matti Picus <matti.picus@gmail.com> | 2020-03-17 00:02:06 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-16 17:02:06 -0500 |
commit | 4f2b219647ae6a7928590be2b709894ae2403274 (patch) | |
tree | 5448d5f350fdcbc2546f82dfe80bd4d3e0665ada /numpy/random/_examples/cython | |
parent | f77c5e83c07985aacbddb89525785a3f66ce1b3b (diff) | |
download | numpy-4f2b219647ae6a7928590be2b709894ae2403274.tar.gz |
BUG: add missing c_distributions.pxd, enables cython use of random C-API (gh-15463)
xref gh-14778
As pointed out in the comment by @jamesthomasgriffin, we did not include a pxd file to expose the distribution functions documented in the random c-api. This PR adds a c_distributions.pxd file that exposes them.
Squashed commits:
* BUG: add missing c_distributions.pxd to enable cython use of random C-API
* ENH, TST: add npyrandom library like npymath, test cython use of it
* BUG: actually prefix f-string with f
* MAINT: fixes from review, add _bit_generato_bit_generator.pxd
* STY: fixes from review
* BLD: don't use nprandom library for mtrand legacy build
* TST: WindowsPath cannot be used in subprocess's list2cmdline
* MAINT, API: move _bit_generator to bit_generator
* DOC: add release note about moving bit_generator
* DOC, MAINT: fixes from review
* MAINT: redo dtype determination from review
Diffstat (limited to 'numpy/random/_examples/cython')
-rw-r--r-- | numpy/random/_examples/cython/extending_distributions.pyx | 45 | ||||
-rw-r--r-- | numpy/random/_examples/cython/setup.py | 8 |
2 files changed, 51 insertions, 2 deletions
diff --git a/numpy/random/_examples/cython/extending_distributions.pyx b/numpy/random/_examples/cython/extending_distributions.pyx index 4da6a4b3a..d908e92d0 100644 --- a/numpy/random/_examples/cython/extending_distributions.pyx +++ b/numpy/random/_examples/cython/extending_distributions.pyx @@ -10,6 +10,8 @@ from cpython.pycapsule cimport PyCapsule_IsValid, PyCapsule_GetPointer from libc.stdint cimport uint16_t, uint64_t from numpy.random cimport bitgen_t from numpy.random import PCG64 +from numpy.random.c_distributions cimport ( + random_standard_uniform_fill, random_standard_uniform_fill_f) @cython.boundscheck(False) @@ -40,7 +42,7 @@ def uniforms(Py_ssize_t n): randoms = np.asarray(random_values) return randoms - + # cython example 2 @cython.boundscheck(False) @cython.wraparound(False) @@ -72,3 +74,44 @@ def uint10_uniforms(Py_ssize_t n): randoms = np.asarray(random_values) return randoms +# cython example 3 +def uniforms_ex(bit_generator, Py_ssize_t n, dtype=np.float64): + """ + Create an array of `n` uniformly distributed doubles via a "fill" function. + + A 'real' distribution would want to process the values into + some non-uniform distribution + + Parameters + ---------- + bit_generator: BitGenerator instance + n: int + Output vector length + dtype: {str, dtype}, optional + Desired dtype, either 'd' (or 'float64') or 'f' (or 'float32'). The + default dtype value is 'd' + """ + cdef Py_ssize_t i + cdef bitgen_t *rng + cdef const char *capsule_name = "BitGenerator" + cdef np.ndarray randoms + + capsule = bit_generator.capsule + # Optional check that the capsule if from a BitGenerator + if not PyCapsule_IsValid(capsule, capsule_name): + raise ValueError("Invalid pointer to anon_func_state") + # Cast the pointer + rng = <bitgen_t *> PyCapsule_GetPointer(capsule, capsule_name) + + _dtype = np.dtype(dtype) + randoms = np.empty(n, dtype=_dtype) + if _dtype == np.float32: + with bit_generator.lock: + random_standard_uniform_fill_f(rng, n, <float*>np.PyArray_DATA(randoms)) + elif _dtype == np.float64: + with bit_generator.lock: + random_standard_uniform_fill(rng, n, <double*>np.PyArray_DATA(randoms)) + else: + raise TypeError('Unsupported dtype %r for random' % _dtype) + return randoms + diff --git a/numpy/random/_examples/cython/setup.py b/numpy/random/_examples/cython/setup.py index 20cedc4e3..42425c2c1 100644 --- a/numpy/random/_examples/cython/setup.py +++ b/numpy/random/_examples/cython/setup.py @@ -12,7 +12,11 @@ from setuptools.extension import Extension from os.path import join, dirname path = dirname(__file__) +src_dir = join(dirname(path), '..', 'src') defs = [('NPY_NO_DEPRECATED_API', 0)] +inc_path = np.get_include() +# not so nice. We need the random/lib library from numpy +lib_path = join(np.get_include(), '..', '..', 'random', 'lib') extending = Extension("extending", sources=[join(path, 'extending.pyx')], @@ -24,7 +28,9 @@ extending = Extension("extending", ) distributions = Extension("extending_distributions", sources=[join(path, 'extending_distributions.pyx')], - include_dirs=[np.get_include()], + include_dirs=[inc_path], + library_dirs=[lib_path], + libraries=['npyrandom'], define_macros=defs, ) |