diff options
35 files changed, 167 insertions, 1894 deletions
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 4c868d735..25322bd34 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1,3 @@ +github: [numfocus] tidelift: pypi/numpy custom: https://www.numpy.org/#support-numpy diff --git a/doc/neps/nep-0029-deprecation_policy.rst b/doc/neps/nep-0029-deprecation_policy.rst index 2f5c8ecb5..bdc0baa39 100644 --- a/doc/neps/nep-0029-deprecation_policy.rst +++ b/doc/neps/nep-0029-deprecation_policy.rst @@ -110,6 +110,7 @@ Jul 23, 2020 3.7+ 1.16+ Jan 13, 2021 3.7+ 1.17+ Jul 26, 2021 3.7+ 1.18+ Dec 26, 2021 3.8+ 1.18+ +Apr 14, 2023 3.9+ 1.18+ ============ ====== ===== @@ -125,6 +126,7 @@ Drop Schedule On Jan 13, 2021 drop support for Numpy 1.16 (initially released on Jan 13, 2019) On Jul 26, 2021 drop support for Numpy 1.17 (initially released on Jul 26, 2019) On Dec 26, 2021 drop support for Python 3.7 (initially released on Jun 27, 2018) + On Apr 14, 2023 drop support for Python 3.8 (initially released on Oct 14, 2019) Implementation @@ -243,13 +245,14 @@ Code to generate support and drop schedule tables :: data = """Jan 15, 2017: Numpy 1.12 Sep 13, 2015: Python 3.5 - Jun 27, 2018: Python 3.7 Dec 23, 2016: Python 3.6 + Jun 27, 2018: Python 3.7 Jun 07, 2017: Numpy 1.13 Jan 06, 2018: Numpy 1.14 Jul 23, 2018: Numpy 1.15 Jan 13, 2019: Numpy 1.16 Jul 26, 2019: Numpy 1.17 + Oct 14, 2019: Python 3.8 """ releases = [] @@ -269,7 +272,7 @@ Code to generate support and drop schedule tables :: releases = sorted(releases, key=lambda x: x[0]) - minpy = '3.8+' + minpy = '3.9+' minnum = '1.18+' toprint_drop_dates = [''] diff --git a/doc/neps/roadmap.rst b/doc/neps/roadmap.rst index 2ec0b7520..c5abc5f25 100644 --- a/doc/neps/roadmap.rst +++ b/doc/neps/roadmap.rst @@ -42,7 +42,7 @@ improve the dtype system. - One of these should probably be the default for text data. The current behavior on Python 3 is neither efficient nor user friendly. -- `np.int` should not be platform dependent +- ``np.dtype(int)`` should not be platform dependent - Better coercion for string + number Performance diff --git a/doc/source/reference/random/index.rst b/doc/source/reference/random/index.rst index 9b19620d8..15c161244 100644 --- a/doc/source/reference/random/index.rst +++ b/doc/source/reference/random/index.rst @@ -57,7 +57,7 @@ cleanup means that legacy and compatibility methods have been removed from ``randint``, ``integers`` Add an ``endpoint`` kwarg ``random_integers`` ------------------- -------------- ------------ -``tomaxint`` removed Use ``integers(0, np.iinfo(np.int).max,`` +``tomaxint`` removed Use ``integers(0, np.iinfo(np.int_).max,`` ``endpoint=False)`` ------------------- -------------- ------------ ``seed`` removed Use `~.SeedSequence.spawn` diff --git a/doc/source/reference/random/multithreading.rst b/doc/source/reference/random/multithreading.rst index 6883d3672..a0a31d0ea 100644 --- a/doc/source/reference/random/multithreading.rst +++ b/doc/source/reference/random/multithreading.rst @@ -41,7 +41,7 @@ seed will produce the same outputs. self.n = n self.executor = concurrent.futures.ThreadPoolExecutor(threads) self.values = np.empty(n) - self.step = np.ceil(n / threads).astype(np.int) + self.step = np.ceil(n / threads).astype(np.int_) def fill(self): def _fill(random_state, out, first, last): diff --git a/doc/source/release/1.11.0-notes.rst b/doc/source/release/1.11.0-notes.rst index 166502ac5..1a179657b 100644 --- a/doc/source/release/1.11.0-notes.rst +++ b/doc/source/release/1.11.0-notes.rst @@ -200,7 +200,7 @@ New Features * A ``dtype`` parameter has been added to ``np.random.randint`` Random ndarrays of the following types can now be generated: - - ``np.bool``, + - ``np.bool_``, - ``np.int8``, ``np.uint8``, - ``np.int16``, ``np.uint16``, - ``np.int32``, ``np.uint32``, diff --git a/doc/source/release/1.13.0-notes.rst b/doc/source/release/1.13.0-notes.rst index 3b719db09..5d8c932fe 100644 --- a/doc/source/release/1.13.0-notes.rst +++ b/doc/source/release/1.13.0-notes.rst @@ -275,7 +275,7 @@ In particular ``np.gradient`` can now take: This means that, e.g., it is now possible to do the following:: - >>> f = np.array([[1, 2, 6], [3, 4, 5]], dtype=np.float) + >>> f = np.array([[1, 2, 6], [3, 4, 5]], dtype=np.float_) >>> dx = 2. >>> y = [1., 1.5, 3.5] >>> np.gradient(f, dx, y) diff --git a/numpy/__init__.py b/numpy/__init__.py index fef8245de..349914b2f 100644 --- a/numpy/__init__.py +++ b/numpy/__init__.py @@ -158,6 +158,7 @@ else: # Make these accessible from numpy name-space # but not imported in from numpy import * + # TODO[gh-6103]: Deprecate these if sys.version_info[0] >= 3: from builtins import bool, int, float, complex, object, str unicode = str @@ -168,14 +169,17 @@ else: # now that numpy modules are imported, can initialize limits core.getlimits._register_known_types() - __all__.extend(['bool', 'int', 'float', 'complex', 'object', 'unicode', - 'str']) __all__.extend(['__version__', 'show_config']) __all__.extend(core.__all__) __all__.extend(_mat.__all__) __all__.extend(lib.__all__) __all__.extend(['linalg', 'fft', 'random', 'ctypeslib', 'ma']) + # These are added by `from .core import *` and `core.__all__`, but we + # overwrite them above with builtins we do _not_ want to export. + __all__.remove('long') + __all__.remove('unicode') + # Remove things that are in the numpy.lib but not in the numpy namespace # Note that there is a test (numpy/tests/test_public_api.py:test_numpy_namespace) # that prevents adding more things to the main namespace by accident. @@ -216,7 +220,7 @@ else: "{!r}".format(__name__, attr)) def __dir__(): - return __all__ + ['Tester', 'testing'] + return list(globals().keys()) + ['Tester', 'testing'] else: # We don't actually use this ourselves anymore, but I'm not 100% sure that diff --git a/numpy/core/code_generators/genapi.py b/numpy/core/code_generators/genapi.py index 7336e5e13..22afa0320 100644 --- a/numpy/core/code_generators/genapi.py +++ b/numpy/core/code_generators/genapi.py @@ -8,8 +8,11 @@ specified. """ from __future__ import division, absolute_import, print_function +from numpy.distutils.conv_template import process_file as process_c_file + import sys, os, re import hashlib +import io import textwrap @@ -215,7 +218,10 @@ def find_functions(filename, tag='API'): This function does foo... */ """ - fo = open(filename, 'r') + if filename.endswith(('.c.src', '.h.src')): + fo = io.StringIO(process_c_file(filename)) + else: + fo = open(filename, 'r') functions = [] return_type = None function_name = None diff --git a/numpy/core/numerictypes.py b/numpy/core/numerictypes.py index ab1ff65a4..761c7087c 100644 --- a/numpy/core/numerictypes.py +++ b/numpy/core/numerictypes.py @@ -485,7 +485,7 @@ def sctype2char(sctype): Examples -------- - >>> for sctype in [np.int32, np.double, np.complex, np.string_, np.ndarray]: + >>> for sctype in [np.int32, np.double, np.complex_, np.string_, np.ndarray]: ... print(np.sctype2char(sctype)) l # may vary d diff --git a/numpy/core/src/umath/loops.c.src b/numpy/core/src/umath/loops.c.src index e6d8eca0d..cb627800b 100644 --- a/numpy/core/src/umath/loops.c.src +++ b/numpy/core/src/umath/loops.c.src @@ -54,210 +54,123 @@ ** GENERIC FLOAT LOOPS ** *****************************************************************************/ +/* direct loops using a suitable callback */ -typedef float halfUnaryFunc(npy_half x); -typedef float floatUnaryFunc(float x); -typedef double doubleUnaryFunc(double x); -typedef npy_longdouble longdoubleUnaryFunc(npy_longdouble x); -typedef npy_half halfBinaryFunc(npy_half x, npy_half y); -typedef float floatBinaryFunc(float x, float y); -typedef double doubleBinaryFunc(double x, double y); -typedef npy_longdouble longdoubleBinaryFunc(npy_longdouble x, npy_longdouble y); - +/**begin repeat + * #c = e, f, d, g# + * #type = npy_half, npy_float, npy_double, npy_longdouble# + **/ /*UFUNC_API*/ NPY_NO_EXPORT void -PyUFunc_e_e(char **args, npy_intp *dimensions, npy_intp *steps, void *func) +PyUFunc_@c@_@c@(char **args, npy_intp *dimensions, npy_intp *steps, void *func) { - halfUnaryFunc *f = (halfUnaryFunc *)func; + typedef @type@ func_type(@type@); + func_type *f = (func_type *)func; UNARY_LOOP { - const npy_half in1 = *(npy_half *)ip1; - *(npy_half *)op1 = f(in1); + const @type@ in1 = *(@type@ *)ip1; + *(@type@ *)op1 = f(in1); } } /*UFUNC_API*/ NPY_NO_EXPORT void -PyUFunc_e_e_As_f_f(char **args, npy_intp *dimensions, npy_intp *steps, void *func) +PyUFunc_@c@@c@_@c@(char **args, npy_intp *dimensions, npy_intp *steps, void *func) { - floatUnaryFunc *f = (floatUnaryFunc *)func; - UNARY_LOOP { - const float in1 = npy_half_to_float(*(npy_half *)ip1); - *(npy_half *)op1 = npy_float_to_half(f(in1)); + typedef @type@ func_type(@type@, @type@); + func_type *f = (func_type *)func; + BINARY_LOOP { + @type@ in1 = *(@type@ *)ip1; + @type@ in2 = *(@type@ *)ip2; + *(@type@ *)op1 = f(in1, in2); } } -/*UFUNC_API*/ -NPY_NO_EXPORT void -PyUFunc_e_e_As_d_d(char **args, npy_intp *dimensions, npy_intp *steps, void *func) -{ - doubleUnaryFunc *f = (doubleUnaryFunc *)func; - UNARY_LOOP { - const double in1 = npy_half_to_double(*(npy_half *)ip1); - *(npy_half *)op1 = npy_double_to_half(f(in1)); - } -} +/**end repeat**/ -/*UFUNC_API*/ -NPY_NO_EXPORT void -PyUFunc_f_f(char **args, npy_intp *dimensions, npy_intp *steps, void *func) -{ - floatUnaryFunc *f = (floatUnaryFunc *)func; - UNARY_LOOP { - const float in1 = *(float *)ip1; - *(float *)op1 = f(in1); - } -} +/* indirect loops with casting */ +/**begin repeat + * #c1 = e, e, f# + * #type1 = npy_half, npy_half, npy_float# + * #c2 = f, d, d# + * #type2 = npy_float, npy_double, npy_double# + * + * #conv12 = npy_half_to_float, npy_half_to_double, (double)# + * #conv21 = npy_float_to_half, npy_double_to_half, (float)# + **/ /*UFUNC_API*/ NPY_NO_EXPORT void -PyUFunc_f_f_As_d_d(char **args, npy_intp *dimensions, npy_intp *steps, void *func) +PyUFunc_@c1@_@c1@_As_@c2@_@c2@(char **args, npy_intp *dimensions, npy_intp *steps, void *func) { - doubleUnaryFunc *f = (doubleUnaryFunc *)func; + typedef @type2@ func_type(@type2@); + func_type *f = (func_type *)func; UNARY_LOOP { - const float in1 = *(float *)ip1; - *(float *)op1 = (float)f((double)in1); + const @type2@ in1 = @conv12@(*(@type1@ *)ip1); + *(@type1@ *)op1 = @conv21@(f(in1)); } } - -/*UFUNC_API*/ -NPY_NO_EXPORT void -PyUFunc_ee_e(char **args, npy_intp *dimensions, npy_intp *steps, void *func) -{ - halfBinaryFunc *f = (halfBinaryFunc *)func; - BINARY_LOOP { - npy_half in1 = *(npy_half *)ip1; - npy_half in2 = *(npy_half *)ip2; - *(npy_half *)op1 = f(in1, in2); - } -} - /*UFUNC_API*/ NPY_NO_EXPORT void -PyUFunc_ee_e_As_ff_f(char **args, npy_intp *dimensions, npy_intp *steps, void *func) +PyUFunc_@c1@@c1@_@c1@_As_@c2@@c2@_@c2@(char **args, npy_intp *dimensions, npy_intp *steps, void *func) { - floatBinaryFunc *f = (floatBinaryFunc *)func; + typedef @type2@ func_type(@type2@, @type2@); + func_type *f = (func_type *)func; BINARY_LOOP { - float in1 = npy_half_to_float(*(npy_half *)ip1); - float in2 = npy_half_to_float(*(npy_half *)ip2); - *(npy_half *)op1 = npy_float_to_half(f(in1, in2)); + const @type2@ in1 = @conv12@(*(@type1@ *)ip1); + const @type2@ in2 = @conv12@(*(@type1@ *)ip2); + *(@type1@ *)op1 = @conv21@(f(in1, in2)); } } -/*UFUNC_API*/ -NPY_NO_EXPORT void -PyUFunc_ee_e_As_dd_d(char **args, npy_intp *dimensions, npy_intp *steps, void *func) -{ - doubleBinaryFunc *f = (doubleBinaryFunc *)func; - BINARY_LOOP { - double in1 = npy_half_to_double(*(npy_half *)ip1); - double in2 = npy_half_to_double(*(npy_half *)ip2); - *(npy_half *)op1 = npy_double_to_half(f(in1, in2)); - } -} - -/*UFUNC_API*/ -NPY_NO_EXPORT void -PyUFunc_ff_f(char **args, npy_intp *dimensions, npy_intp *steps, void *func) -{ - floatBinaryFunc *f = (floatBinaryFunc *)func; - BINARY_LOOP { - float in1 = *(float *)ip1; - float in2 = *(float *)ip2; - *(float *)op1 = f(in1, in2); - } -} - -/*UFUNC_API*/ -NPY_NO_EXPORT void -PyUFunc_ff_f_As_dd_d(char **args, npy_intp *dimensions, npy_intp *steps, void *func) -{ - doubleBinaryFunc *f = (doubleBinaryFunc *)func; - BINARY_LOOP { - float in1 = *(float *)ip1; - float in2 = *(float *)ip2; - *(float *)op1 = (double)f((double)in1, (double)in2); - } -} +/**end repeat**/ -/*UFUNC_API*/ -NPY_NO_EXPORT void -PyUFunc_d_d(char **args, npy_intp *dimensions, npy_intp *steps, void *func) -{ - doubleUnaryFunc *f = (doubleUnaryFunc *)func; - UNARY_LOOP { - double in1 = *(double *)ip1; - *(double *)op1 = f(in1); - } -} +/****************************************************************************** + ** GENERIC COMPLEX LOOPS ** + *****************************************************************************/ -/*UFUNC_API*/ -NPY_NO_EXPORT void -PyUFunc_dd_d(char **args, npy_intp *dimensions, npy_intp *steps, void *func) -{ - doubleBinaryFunc *f = (doubleBinaryFunc *)func; - BINARY_LOOP { - double in1 = *(double *)ip1; - double in2 = *(double *)ip2; - *(double *)op1 = f(in1, in2); - } -} +/* direct loops using a suitable callback */ +/**begin repeat + * #c = F, D, G# + * #type = npy_cfloat, npy_cdouble, npy_clongdouble# + **/ /*UFUNC_API*/ NPY_NO_EXPORT void -PyUFunc_g_g(char **args, npy_intp *dimensions, npy_intp *steps, void *func) +PyUFunc_@c@_@c@(char **args, npy_intp *dimensions, npy_intp *steps, void *func) { - longdoubleUnaryFunc *f = (longdoubleUnaryFunc *)func; + typedef void func_type(@type@ *, @type@ *); + func_type *f = (func_type *)func; UNARY_LOOP { - npy_longdouble in1 = *(npy_longdouble *)ip1; - *(npy_longdouble *)op1 = f(in1); + @type@ in1 = *(@type@ *)ip1; + @type@ *out = (@type@ *)op1; + f(&in1, out); } } /*UFUNC_API*/ NPY_NO_EXPORT void -PyUFunc_gg_g(char **args, npy_intp *dimensions, npy_intp *steps, void *func) +PyUFunc_@c@@c@_@c@(char **args, npy_intp *dimensions, npy_intp *steps, void *func) { - longdoubleBinaryFunc *f = (longdoubleBinaryFunc *)func; + typedef void func_type(@type@ *, @type@ *, @type@ *); + func_type *f = (func_type *)func; BINARY_LOOP { - npy_longdouble in1 = *(npy_longdouble *)ip1; - npy_longdouble in2 = *(npy_longdouble *)ip2; - *(npy_longdouble *)op1 = f(in1, in2); + @type@ in1 = *(@type@ *)ip1; + @type@ in2 = *(@type@ *)ip2; + @type@ *out = (@type@ *)op1; + f(&in1, &in2, out); } } +/**end repeat**/ - -/****************************************************************************** - ** GENERIC COMPLEX LOOPS ** - *****************************************************************************/ - - -typedef void cdoubleUnaryFunc(npy_cdouble *x, npy_cdouble *r); -typedef void cfloatUnaryFunc(npy_cfloat *x, npy_cfloat *r); -typedef void clongdoubleUnaryFunc(npy_clongdouble *x, npy_clongdouble *r); -typedef void cdoubleBinaryFunc(npy_cdouble *x, npy_cdouble *y, npy_cdouble *r); -typedef void cfloatBinaryFunc(npy_cfloat *x, npy_cfloat *y, npy_cfloat *r); -typedef void clongdoubleBinaryFunc(npy_clongdouble *x, npy_clongdouble *y, - npy_clongdouble *r); - -/*UFUNC_API*/ -NPY_NO_EXPORT void -PyUFunc_F_F(char **args, npy_intp *dimensions, npy_intp *steps, void *func) -{ - cfloatUnaryFunc *f = (cfloatUnaryFunc *)func; - UNARY_LOOP { - npy_cfloat in1 = *(npy_cfloat *)ip1; - npy_cfloat *out = (npy_cfloat *)op1; - f(&in1, out); - } -} - +/* indirect loops with casting */ /*UFUNC_API*/ NPY_NO_EXPORT void PyUFunc_F_F_As_D_D(char **args, npy_intp *dimensions, npy_intp *steps, void *func) { - cdoubleUnaryFunc *f = (cdoubleUnaryFunc *)func; + typedef void func_type(npy_cdouble *, npy_cdouble *); + func_type *f = (func_type *)func; UNARY_LOOP { npy_cdouble tmp, out; tmp.real = (double)((float *)ip1)[0]; @@ -270,22 +183,10 @@ PyUFunc_F_F_As_D_D(char **args, npy_intp *dimensions, npy_intp *steps, void *fun /*UFUNC_API*/ NPY_NO_EXPORT void -PyUFunc_FF_F(char **args, npy_intp *dimensions, npy_intp *steps, void *func) -{ - cfloatBinaryFunc *f = (cfloatBinaryFunc *)func; - BINARY_LOOP { - npy_cfloat in1 = *(npy_cfloat *)ip1; - npy_cfloat in2 = *(npy_cfloat *)ip2; - npy_cfloat *out = (npy_cfloat *)op1; - f(&in1, &in2, out); - } -} - -/*UFUNC_API*/ -NPY_NO_EXPORT void PyUFunc_FF_F_As_DD_D(char **args, npy_intp *dimensions, npy_intp *steps, void *func) { - cdoubleBinaryFunc *f = (cdoubleBinaryFunc *)func; + typedef void func_type(npy_cdouble *, npy_cdouble *, npy_cdouble *); + func_type *f = (func_type *)func; BINARY_LOOP { npy_cdouble tmp1, tmp2, out; tmp1.real = (double)((float *)ip1)[0]; @@ -298,56 +199,6 @@ PyUFunc_FF_F_As_DD_D(char **args, npy_intp *dimensions, npy_intp *steps, void *f } } -/*UFUNC_API*/ -NPY_NO_EXPORT void -PyUFunc_D_D(char **args, npy_intp *dimensions, npy_intp *steps, void *func) -{ - cdoubleUnaryFunc *f = (cdoubleUnaryFunc *)func; - UNARY_LOOP { - npy_cdouble in1 = *(npy_cdouble *)ip1; - npy_cdouble *out = (npy_cdouble *)op1; - f(&in1, out); - } -} - -/*UFUNC_API*/ -NPY_NO_EXPORT void -PyUFunc_DD_D(char **args, npy_intp *dimensions, npy_intp *steps, void *func) -{ - cdoubleBinaryFunc *f = (cdoubleBinaryFunc *)func; - BINARY_LOOP { - npy_cdouble in1 = *(npy_cdouble *)ip1; - npy_cdouble in2 = *(npy_cdouble *)ip2; - npy_cdouble *out = (npy_cdouble *)op1; - f(&in1, &in2, out); - } -} - -/*UFUNC_API*/ -NPY_NO_EXPORT void -PyUFunc_G_G(char **args, npy_intp *dimensions, npy_intp *steps, void *func) -{ - clongdoubleUnaryFunc *f = (clongdoubleUnaryFunc *)func; - UNARY_LOOP { - npy_clongdouble in1 = *(npy_clongdouble *)ip1; - npy_clongdouble *out = (npy_clongdouble *)op1; - f(&in1, out); - } -} - -/*UFUNC_API*/ -NPY_NO_EXPORT void -PyUFunc_GG_G(char **args, npy_intp *dimensions, npy_intp *steps, void *func) -{ - clongdoubleBinaryFunc *f = (clongdoubleBinaryFunc *)func; - BINARY_LOOP { - npy_clongdouble in1 = *(npy_clongdouble *)ip1; - npy_clongdouble in2 = *(npy_clongdouble *)ip2; - npy_clongdouble *out = (npy_clongdouble *)op1; - f(&in1, &in2, out); - } -} - /****************************************************************************** ** GENERIC OBJECT lOOPS ** diff --git a/numpy/core/tests/test_api.py b/numpy/core/tests/test_api.py index 32e2ea537..89fc2b0b9 100644 --- a/numpy/core/tests/test_api.py +++ b/numpy/core/tests/test_api.py @@ -296,7 +296,7 @@ def test_array_astype(): ) def test_array_astype_warning(t): # test ComplexWarning when casting from complex to float or int - a = np.array(10, dtype=np.complex) + a = np.array(10, dtype=np.complex_) assert_warns(np.ComplexWarning, a.astype, t) def test_copyto_fromscalar(): diff --git a/numpy/core/tests/test_dtype.py b/numpy/core/tests/test_dtype.py index d2fbbae5b..e18e66c64 100644 --- a/numpy/core/tests/test_dtype.py +++ b/numpy/core/tests/test_dtype.py @@ -25,7 +25,7 @@ def assert_dtype_not_equal(a, b): class TestBuiltin(object): @pytest.mark.parametrize('t', [int, float, complex, np.int32, str, object, - np.unicode]) + np.compat.unicode]) def test_run(self, t): """Only test hash runs at all.""" dt = np.dtype(t) @@ -986,7 +986,7 @@ class TestPickling(object): assert_equal(x[0], y[0]) @pytest.mark.parametrize('t', [int, float, complex, np.int32, str, object, - np.unicode, bool]) + np.compat.unicode, bool]) def test_builtin(self, t): self.check_pickling(np.dtype(t)) diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index c699a9bc1..0b604e8b8 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -964,7 +964,7 @@ class TestCreation(object): @pytest.mark.skipif(sys.version_info[0] >= 3, reason="Not Python 2") def test_sequence_long(self): - assert_equal(np.array([long(4), long(4)]).dtype, np.long) + assert_equal(np.array([long(4), long(4)]).dtype, long) assert_equal(np.array([long(4), 2**80]).dtype, object) assert_equal(np.array([long(4), 2**80, long(4)]).dtype, object) assert_equal(np.array([2**80, long(4)]).dtype, object) @@ -1807,7 +1807,7 @@ class TestMethods(object): # test unicode sorts. s = 'aaaaaaaa' - a = np.array([s + chr(i) for i in range(101)], dtype=np.unicode) + a = np.array([s + chr(i) for i in range(101)], dtype=np.unicode_) b = a[::-1].copy() for kind in self.sort_kinds: msg = "unicode sort, kind=%s" % kind @@ -2059,7 +2059,7 @@ class TestMethods(object): # test unicode argsorts. s = 'aaaaaaaa' - a = np.array([s + chr(i) for i in range(101)], dtype=np.unicode) + a = np.array([s + chr(i) for i in range(101)], dtype=np.unicode_) b = a[::-1] r = np.arange(101) rr = r[::-1] @@ -2142,7 +2142,7 @@ class TestMethods(object): a = np.array(['aaaaaaaaa' for i in range(100)]) assert_equal(a.argsort(kind='m'), r) # unicode - a = np.array(['aaaaaaaaa' for i in range(100)], dtype=np.unicode) + a = np.array(['aaaaaaaaa' for i in range(100)], dtype=np.unicode_) assert_equal(a.argsort(kind='m'), r) def test_sort_unicode_kind(self): @@ -2271,7 +2271,7 @@ class TestMethods(object): 'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100197_1', 'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100198_1', 'P:\\20x_dapi_cy3\\20x_dapi_cy3_20100199_1'], - dtype=np.unicode) + dtype=np.unicode_) ind = np.arange(len(a)) assert_equal([a.searchsorted(v, 'left') for v in a], ind) assert_equal([a.searchsorted(v, 'right') for v in a], ind + 1) @@ -7930,20 +7930,20 @@ class TestBytestringArrayNonzero(object): class TestUnicodeArrayNonzero(object): def test_empty_ustring_array_is_falsey(self): - assert_(not np.array([''], dtype=np.unicode)) + assert_(not np.array([''], dtype=np.unicode_)) def test_whitespace_ustring_array_is_falsey(self): - a = np.array(['eggs'], dtype=np.unicode) + a = np.array(['eggs'], dtype=np.unicode_) a[0] = ' \0\0' assert_(not a) def test_all_null_ustring_array_is_falsey(self): - a = np.array(['eggs'], dtype=np.unicode) + a = np.array(['eggs'], dtype=np.unicode_) a[0] = '\0\0\0\0' assert_(not a) def test_null_inside_ustring_array_is_truthy(self): - a = np.array(['eggs'], dtype=np.unicode) + a = np.array(['eggs'], dtype=np.unicode_) a[0] = ' \0 \0' assert_(a) diff --git a/numpy/core/tests/test_nditer.py b/numpy/core/tests/test_nditer.py index cf66751f8..daec9ce6d 100644 --- a/numpy/core/tests/test_nditer.py +++ b/numpy/core/tests/test_nditer.py @@ -2104,7 +2104,7 @@ def test_iter_buffering_string(): assert_equal(i[0], b'abc') assert_equal(i[0].dtype, np.dtype('S6')) - a = np.array(['abc', 'a', 'abcd'], dtype=np.unicode) + a = np.array(['abc', 'a', 'abcd'], dtype=np.unicode_) assert_equal(a.dtype, np.dtype('U4')) assert_raises(TypeError, nditer, a, ['buffered'], ['readonly'], op_dtypes='U2') diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py index 4d322e50e..ffebdf648 100644 --- a/numpy/core/tests/test_numeric.py +++ b/numpy/core/tests/test_numeric.py @@ -2953,7 +2953,7 @@ class TestIndices(object): assert_array_equal(x, np.array([[0], [1], [2], [3]])) assert_array_equal(y, np.array([[0, 1, 2]])) - @pytest.mark.parametrize("dtype", [np.int, np.float32, np.float64]) + @pytest.mark.parametrize("dtype", [np.int32, np.int64, np.float32, np.float64]) @pytest.mark.parametrize("dims", [(), (0,), (4, 3)]) def test_return_type(self, dtype, dims): inds = np.indices(dims, dtype=dtype) diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index 9dc231deb..c7f242642 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -1511,7 +1511,7 @@ class TestRegression(object): min //= -1 with np.errstate(divide="ignore"): - for t in (np.int8, np.int16, np.int32, np.int64, int, np.long): + for t in (np.int8, np.int16, np.int32, np.int64, int, np.compat.long): test_type(t) def test_buffer_hashlib(self): @@ -2112,7 +2112,7 @@ class TestRegression(object): # Ticket #1578, the mismatch only showed up when running # python-debug for python versions >= 2.7, and then as # a core dump and error message. - a = np.array(['abc'], dtype=np.unicode)[0] + a = np.array(['abc'], dtype=np.unicode_)[0] del a def test_refcount_error_in_clip(self): diff --git a/numpy/core/tests/test_scalarinherit.py b/numpy/core/tests/test_scalarinherit.py index 9e32cf624..6a5c4fde9 100644 --- a/numpy/core/tests/test_scalarinherit.py +++ b/numpy/core/tests/test_scalarinherit.py @@ -68,8 +68,7 @@ class TestCharacter(object): def test_char_repeat(self): np_s = np.string_('abc') np_u = np.unicode_('abc') - np_i = np.int(5) res_s = b'abc' * 5 res_u = u'abc' * 5 - assert_(np_s * np_i == res_s) - assert_(np_u * np_i == res_u) + assert_(np_s * 5 == res_s) + assert_(np_u * 5 == res_u) diff --git a/numpy/core/tests/test_ufunc.py b/numpy/core/tests/test_ufunc.py index ba1aee55b..526925ece 100644 --- a/numpy/core/tests/test_ufunc.py +++ b/numpy/core/tests/test_ufunc.py @@ -980,7 +980,7 @@ class TestUfunc(object): assert_array_equal(out, mm_row_col_vec.squeeze()) def test_matrix_multiply(self): - self.compare_matrix_multiply_results(np.long) + self.compare_matrix_multiply_results(np.int64) self.compare_matrix_multiply_results(np.double) def test_matrix_multiply_umath_empty(self): diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py index 1d71766ef..e892e81d2 100644 --- a/numpy/core/tests/test_umath.py +++ b/numpy/core/tests/test_umath.py @@ -792,7 +792,7 @@ class TestAVXFloat32Transcendental(object): def test_sincos_float32(self): np.random.seed(42) N = 1000000 - M = np.int(N/20) + M = np.int_(N/20) index = np.random.randint(low=0, high=N, size=M) x_f32 = np.float32(np.random.uniform(low=-100.,high=100.,size=N)) # test coverage for elements > 117435.992f for which glibc is used diff --git a/numpy/core/tests/test_umath_accuracy.py b/numpy/core/tests/test_umath_accuracy.py index 0bab04df2..fec180786 100644 --- a/numpy/core/tests/test_umath_accuracy.py +++ b/numpy/core/tests/test_umath_accuracy.py @@ -38,7 +38,7 @@ class TestAccuracy(object): with open(filepath) as fid: file_without_comments = (r for r in fid if not r[0] in ('$', '#')) data = np.genfromtxt(file_without_comments, - dtype=('|S39','|S39','|S39',np.int), + dtype=('|S39','|S39','|S39',int), names=('type','input','output','ulperr'), delimiter=',', skip_header=1) diff --git a/numpy/doc/basics.py b/numpy/doc/basics.py index 1871512bf..c05f347a1 100644 --- a/numpy/doc/basics.py +++ b/numpy/doc/basics.py @@ -18,7 +18,7 @@ The primitive types supported are tied closely to those in C: - C type - Description - * - `np.bool` + * - `np.bool_` - ``bool`` - Boolean (True or False) stored as a byte @@ -283,7 +283,7 @@ NumPy provides `numpy.iinfo` and `numpy.finfo` to verify the minimum or maximum values of NumPy integer and floating point values respectively :: - >>> np.iinfo(np.int) # Bounds of the default integer on this system. + >>> np.iinfo(int) # Bounds of the default integer on this system. iinfo(min=-9223372036854775808, max=9223372036854775807, dtype=int64) >>> np.iinfo(np.int32) # Bounds of a 32-bit integer iinfo(min=-2147483648, max=2147483647, dtype=int32) diff --git a/numpy/lib/npyio.py b/numpy/lib/npyio.py index 7e1d4db4f..430d44374 100644 --- a/numpy/lib/npyio.py +++ b/numpy/lib/npyio.py @@ -1529,9 +1529,9 @@ def fromregex(file, regexp, dtype, encoding=None): dtype = np.dtype(dtype) content = file.read() - if isinstance(content, bytes) and isinstance(regexp, np.unicode): + if isinstance(content, bytes) and isinstance(regexp, np.compat.unicode): regexp = asbytes(regexp) - elif isinstance(content, np.unicode) and isinstance(regexp, bytes): + elif isinstance(content, np.compat.unicode) and isinstance(regexp, bytes): regexp = asstr(regexp) if not hasattr(regexp, 'match'): diff --git a/numpy/lib/tests/test_io.py b/numpy/lib/tests/test_io.py index 1181fe986..6e2291ca3 100644 --- a/numpy/lib/tests/test_io.py +++ b/numpy/lib/tests/test_io.py @@ -518,7 +518,7 @@ class TestSaveTxt(object): def test_unicode(self): utf8 = b'\xcf\x96'.decode('UTF-8') - a = np.array([utf8], dtype=np.unicode) + a = np.array([utf8], dtype=np.unicode_) with tempdir() as tmpdir: # set encoding as on windows it may not be unicode even on py3 np.savetxt(os.path.join(tmpdir, 'test.csv'), a, fmt=['%s'], @@ -526,7 +526,7 @@ class TestSaveTxt(object): def test_unicode_roundtrip(self): utf8 = b'\xcf\x96'.decode('UTF-8') - a = np.array([utf8], dtype=np.unicode) + a = np.array([utf8], dtype=np.unicode_) # our gz wrapper support encoding suffixes = ['', '.gz'] # stdlib 2 versions do not support encoding @@ -540,12 +540,12 @@ class TestSaveTxt(object): np.savetxt(os.path.join(tmpdir, 'test.csv' + suffix), a, fmt=['%s'], encoding='UTF-16-LE') b = np.loadtxt(os.path.join(tmpdir, 'test.csv' + suffix), - encoding='UTF-16-LE', dtype=np.unicode) + encoding='UTF-16-LE', dtype=np.unicode_) assert_array_equal(a, b) def test_unicode_bytestream(self): utf8 = b'\xcf\x96'.decode('UTF-8') - a = np.array([utf8], dtype=np.unicode) + a = np.array([utf8], dtype=np.unicode_) s = BytesIO() np.savetxt(s, a, fmt=['%s'], encoding='UTF-8') s.seek(0) @@ -553,7 +553,7 @@ class TestSaveTxt(object): def test_unicode_stringstream(self): utf8 = b'\xcf\x96'.decode('UTF-8') - a = np.array([utf8], dtype=np.unicode) + a = np.array([utf8], dtype=np.unicode_) s = StringIO() np.savetxt(s, a, fmt=['%s'], encoding='UTF-8') s.seek(0) @@ -632,12 +632,12 @@ class LoadTxtBase(object): with temppath() as path: with open(path, "wb") as f: f.write(nonascii.encode("UTF-16")) - x = self.loadfunc(path, encoding="UTF-16", dtype=np.unicode) + x = self.loadfunc(path, encoding="UTF-16", dtype=np.unicode_) assert_array_equal(x, nonascii) def test_binary_decode(self): utf16 = b'\xff\xfeh\x04 \x00i\x04 \x00j\x04' - v = self.loadfunc(BytesIO(utf16), dtype=np.unicode, encoding='UTF-16') + v = self.loadfunc(BytesIO(utf16), dtype=np.unicode_, encoding='UTF-16') assert_array_equal(v, np.array(utf16.decode('UTF-16').split())) def test_converters_decode(self): @@ -645,7 +645,7 @@ class LoadTxtBase(object): c = TextIO() c.write(b'\xcf\x96') c.seek(0) - x = self.loadfunc(c, dtype=np.unicode, + x = self.loadfunc(c, dtype=np.unicode_, converters={0: lambda x: x.decode('UTF-8')}) a = np.array([b'\xcf\x96'.decode('UTF-8')]) assert_array_equal(x, a) @@ -656,7 +656,7 @@ class LoadTxtBase(object): with temppath() as path: with io.open(path, 'wt', encoding='UTF-8') as f: f.write(utf8) - x = self.loadfunc(path, dtype=np.unicode, + x = self.loadfunc(path, dtype=np.unicode_, converters={0: lambda x: x + 't'}, encoding='UTF-8') a = np.array([utf8 + 't']) @@ -1104,7 +1104,7 @@ class TestLoadTxt(LoadTxtBase): with open(path, "wb") as f: f.write(butf8) with open(path, "rb") as f: - x = np.loadtxt(f, encoding="UTF-8", dtype=np.unicode) + x = np.loadtxt(f, encoding="UTF-8", dtype=np.unicode_) assert_array_equal(x, sutf8) # test broken latin1 conversion people now rely on with open(path, "rb") as f: @@ -1587,7 +1587,7 @@ M 33 21.99 with open(path, 'wb') as f: f.write(b'skip,skip,2001-01-01' + utf8 + b',1.0,skip') test = np.genfromtxt(path, delimiter=",", names=None, dtype=float, - usecols=(2, 3), converters={2: np.unicode}, + usecols=(2, 3), converters={2: np.compat.unicode}, encoding='UTF-8') control = np.array([('2001-01-01' + utf8.decode('UTF-8'), 1.)], dtype=[('', '|U11'), ('', float)]) @@ -2126,7 +2126,7 @@ M 33 21.99 ctl = np.array([ ["test1", "testNonethe" + utf8.decode("UTF-8"), "test3"], ["test1", "testNonethe" + utf8.decode("UTF-8"), "test3"]], - dtype=np.unicode) + dtype=np.unicode_) assert_array_equal(test, ctl) # test a mixed dtype @@ -2169,7 +2169,7 @@ M 33 21.99 ["norm1", "norm2", "norm3"], ["norm1", latin1, "norm3"], ["test1", "testNonethe" + utf8, "test3"]], - dtype=np.unicode) + dtype=np.unicode_) assert_array_equal(test, ctl) def test_recfromtxt(self): diff --git a/numpy/lib/tests/test_ufunclike.py b/numpy/lib/tests/test_ufunclike.py index 0f06876a1..64280616f 100644 --- a/numpy/lib/tests/test_ufunclike.py +++ b/numpy/lib/tests/test_ufunclike.py @@ -21,7 +21,7 @@ class TestUfunclike(object): assert_equal(res, tgt) assert_equal(out, tgt) - a = a.astype(np.complex) + a = a.astype(np.complex_) with assert_raises(TypeError): ufl.isposinf(a) @@ -36,7 +36,7 @@ class TestUfunclike(object): assert_equal(res, tgt) assert_equal(out, tgt) - a = a.astype(np.complex) + a = a.astype(np.complex_) with assert_raises(TypeError): ufl.isneginf(a) diff --git a/numpy/random/.gitignore b/numpy/random/.gitignore new file mode 100644 index 000000000..fea3f955a --- /dev/null +++ b/numpy/random/.gitignore @@ -0,0 +1,3 @@ +# generated files +_bounded_integers.pyx +_bounded_integers.pxd diff --git a/numpy/random/_bounded_integers.pxd b/numpy/random/_bounded_integers.pxd deleted file mode 100644 index d3ee97a70..000000000 --- a/numpy/random/_bounded_integers.pxd +++ /dev/null @@ -1,29 +0,0 @@ -from libc.stdint cimport (uint8_t, uint16_t, uint32_t, uint64_t, - int8_t, int16_t, int32_t, int64_t, intptr_t) -import numpy as np -cimport numpy as np -ctypedef np.npy_bool bool_t - -from ._bit_generator cimport bitgen_t - -cdef inline uint64_t _gen_mask(uint64_t max_val) nogil: - """Mask generator for use in bounded random numbers""" - # Smallest bit mask >= max - cdef uint64_t mask = max_val - mask |= mask >> 1 - mask |= mask >> 2 - mask |= mask >> 4 - mask |= mask >> 8 - mask |= mask >> 16 - mask |= mask >> 32 - return mask - -cdef object _rand_uint64(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) -cdef object _rand_uint32(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) -cdef object _rand_uint16(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) -cdef object _rand_uint8(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) -cdef object _rand_bool(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) -cdef object _rand_int64(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) -cdef object _rand_int32(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) -cdef object _rand_int16(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) -cdef object _rand_int8(object low, object high, object size, bint use_masked, bint closed, bitgen_t *state, object lock) diff --git a/numpy/random/_bounded_integers.pyx b/numpy/random/_bounded_integers.pyx deleted file mode 100644 index d6a534b43..000000000 --- a/numpy/random/_bounded_integers.pyx +++ /dev/null @@ -1,1564 +0,0 @@ -#!python -#cython: wraparound=False, nonecheck=False, boundscheck=False, cdivision=True - -import numpy as np -cimport numpy as np - -__all__ = [] - -np.import_array() - -cdef extern from "include/distributions.h": - # Generate random numbers in closed interval [off, off + rng]. - uint64_t random_bounded_uint64(bitgen_t *bitgen_state, - uint64_t off, uint64_t rng, - uint64_t mask, bint use_masked) nogil - uint32_t random_buffered_bounded_uint32(bitgen_t *bitgen_state, - uint32_t off, uint32_t rng, - uint32_t mask, bint use_masked, - int *bcnt, uint32_t *buf) nogil - uint16_t random_buffered_bounded_uint16(bitgen_t *bitgen_state, - uint16_t off, uint16_t rng, - uint16_t mask, bint use_masked, - int *bcnt, uint32_t *buf) nogil - uint8_t random_buffered_bounded_uint8(bitgen_t *bitgen_state, - uint8_t off, uint8_t rng, - uint8_t mask, bint use_masked, - int *bcnt, uint32_t *buf) nogil - np.npy_bool random_buffered_bounded_bool(bitgen_t *bitgen_state, - np.npy_bool off, np.npy_bool rng, - np.npy_bool mask, bint use_masked, - int *bcnt, uint32_t *buf) nogil - void random_bounded_uint64_fill(bitgen_t *bitgen_state, - uint64_t off, uint64_t rng, np.npy_intp cnt, - bint use_masked, - uint64_t *out) nogil - void random_bounded_uint32_fill(bitgen_t *bitgen_state, - uint32_t off, uint32_t rng, np.npy_intp cnt, - bint use_masked, - uint32_t *out) nogil - void random_bounded_uint16_fill(bitgen_t *bitgen_state, - uint16_t off, uint16_t rng, np.npy_intp cnt, - bint use_masked, - uint16_t *out) nogil - void random_bounded_uint8_fill(bitgen_t *bitgen_state, - uint8_t off, uint8_t rng, np.npy_intp cnt, - bint use_masked, - uint8_t *out) nogil - void random_bounded_bool_fill(bitgen_t *bitgen_state, - np.npy_bool off, np.npy_bool rng, np.npy_intp cnt, - bint use_masked, - np.npy_bool *out) nogil - - - -_integers_types = {'bool': (0, 2), - 'int8': (-2**7, 2**7), - 'int16': (-2**15, 2**15), - 'int32': (-2**31, 2**31), - 'int64': (-2**63, 2**63), - 'uint8': (0, 2**8), - 'uint16': (0, 2**16), - 'uint32': (0, 2**32), - 'uint64': (0, 2**64)} - - -cdef object _rand_uint32_broadcast(np.ndarray low, np.ndarray high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - Array path for smaller integer types - - This path is simpler since the high value in the open interval [low, high) - must be in-range for the next larger type, uint64. Here we case to - this type for checking and the recast to uint32 when producing the - random integers. - """ - cdef uint32_t rng, last_rng, off, val, mask, out_val, is_open - cdef uint32_t buf - cdef uint32_t *out_data - cdef uint64_t low_v, high_v - cdef np.ndarray low_arr, high_arr, out_arr - cdef np.npy_intp i, cnt - cdef np.broadcast it - cdef int buf_rem = 0 - - # Array path - is_open = not closed - low_arr = <np.ndarray>low - high_arr = <np.ndarray>high - if np.any(np.less(low_arr, 0)): - raise ValueError('low is out of bounds for uint32') - if closed: - high_comp = np.greater_equal - low_high_comp = np.greater - else: - high_comp = np.greater - low_high_comp = np.greater_equal - - if np.any(high_comp(high_arr, 0X100000000ULL)): - raise ValueError('high is out of bounds for uint32') - if np.any(low_high_comp(low_arr, high_arr)): - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - low_arr = <np.ndarray>np.PyArray_FROM_OTF(low, np.NPY_UINT64, np.NPY_ALIGNED | np.NPY_FORCECAST) - high_arr = <np.ndarray>np.PyArray_FROM_OTF(high, np.NPY_UINT64, np.NPY_ALIGNED | np.NPY_FORCECAST) - - if size is not None: - out_arr = <np.ndarray>np.empty(size, np.uint32) - else: - it = np.PyArray_MultiIterNew2(low_arr, high_arr) - out_arr = <np.ndarray>np.empty(it.shape, np.uint32) - - it = np.PyArray_MultiIterNew3(low_arr, high_arr, out_arr) - out_data = <uint32_t *>np.PyArray_DATA(out_arr) - cnt = np.PyArray_SIZE(out_arr) - mask = last_rng = 0 - with lock, nogil: - for i in range(cnt): - low_v = (<uint64_t*>np.PyArray_MultiIter_DATA(it, 0))[0] - high_v = (<uint64_t*>np.PyArray_MultiIter_DATA(it, 1))[0] - # Subtract 1 since generator produces values on the closed int [off, off+rng] - rng = <uint32_t>((high_v - is_open) - low_v) - off = <uint32_t>(<uint64_t>low_v) - - if rng != last_rng: - # Smallest bit mask >= max - mask = <uint32_t>_gen_mask(rng) - - out_data[i] = random_buffered_bounded_uint32(state, off, rng, mask, use_masked, &buf_rem, &buf) - - np.PyArray_MultiIter_NEXT(it) - return out_arr - -cdef object _rand_uint16_broadcast(np.ndarray low, np.ndarray high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - Array path for smaller integer types - - This path is simpler since the high value in the open interval [low, high) - must be in-range for the next larger type, uint32. Here we case to - this type for checking and the recast to uint16 when producing the - random integers. - """ - cdef uint16_t rng, last_rng, off, val, mask, out_val, is_open - cdef uint32_t buf - cdef uint16_t *out_data - cdef uint32_t low_v, high_v - cdef np.ndarray low_arr, high_arr, out_arr - cdef np.npy_intp i, cnt - cdef np.broadcast it - cdef int buf_rem = 0 - - # Array path - is_open = not closed - low_arr = <np.ndarray>low - high_arr = <np.ndarray>high - if np.any(np.less(low_arr, 0)): - raise ValueError('low is out of bounds for uint16') - if closed: - high_comp = np.greater_equal - low_high_comp = np.greater - else: - high_comp = np.greater - low_high_comp = np.greater_equal - - if np.any(high_comp(high_arr, 0X10000UL)): - raise ValueError('high is out of bounds for uint16') - if np.any(low_high_comp(low_arr, high_arr)): - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - low_arr = <np.ndarray>np.PyArray_FROM_OTF(low, np.NPY_UINT32, np.NPY_ALIGNED | np.NPY_FORCECAST) - high_arr = <np.ndarray>np.PyArray_FROM_OTF(high, np.NPY_UINT32, np.NPY_ALIGNED | np.NPY_FORCECAST) - - if size is not None: - out_arr = <np.ndarray>np.empty(size, np.uint16) - else: - it = np.PyArray_MultiIterNew2(low_arr, high_arr) - out_arr = <np.ndarray>np.empty(it.shape, np.uint16) - - it = np.PyArray_MultiIterNew3(low_arr, high_arr, out_arr) - out_data = <uint16_t *>np.PyArray_DATA(out_arr) - cnt = np.PyArray_SIZE(out_arr) - mask = last_rng = 0 - with lock, nogil: - for i in range(cnt): - low_v = (<uint32_t*>np.PyArray_MultiIter_DATA(it, 0))[0] - high_v = (<uint32_t*>np.PyArray_MultiIter_DATA(it, 1))[0] - # Subtract 1 since generator produces values on the closed int [off, off+rng] - rng = <uint16_t>((high_v - is_open) - low_v) - off = <uint16_t>(<uint32_t>low_v) - - if rng != last_rng: - # Smallest bit mask >= max - mask = <uint16_t>_gen_mask(rng) - - out_data[i] = random_buffered_bounded_uint16(state, off, rng, mask, use_masked, &buf_rem, &buf) - - np.PyArray_MultiIter_NEXT(it) - return out_arr - -cdef object _rand_uint8_broadcast(np.ndarray low, np.ndarray high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - Array path for smaller integer types - - This path is simpler since the high value in the open interval [low, high) - must be in-range for the next larger type, uint16. Here we case to - this type for checking and the recast to uint8 when producing the - random integers. - """ - cdef uint8_t rng, last_rng, off, val, mask, out_val, is_open - cdef uint32_t buf - cdef uint8_t *out_data - cdef uint16_t low_v, high_v - cdef np.ndarray low_arr, high_arr, out_arr - cdef np.npy_intp i, cnt - cdef np.broadcast it - cdef int buf_rem = 0 - - # Array path - is_open = not closed - low_arr = <np.ndarray>low - high_arr = <np.ndarray>high - if np.any(np.less(low_arr, 0)): - raise ValueError('low is out of bounds for uint8') - if closed: - high_comp = np.greater_equal - low_high_comp = np.greater - else: - high_comp = np.greater - low_high_comp = np.greater_equal - - if np.any(high_comp(high_arr, 0X100UL)): - raise ValueError('high is out of bounds for uint8') - if np.any(low_high_comp(low_arr, high_arr)): - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - low_arr = <np.ndarray>np.PyArray_FROM_OTF(low, np.NPY_UINT16, np.NPY_ALIGNED | np.NPY_FORCECAST) - high_arr = <np.ndarray>np.PyArray_FROM_OTF(high, np.NPY_UINT16, np.NPY_ALIGNED | np.NPY_FORCECAST) - - if size is not None: - out_arr = <np.ndarray>np.empty(size, np.uint8) - else: - it = np.PyArray_MultiIterNew2(low_arr, high_arr) - out_arr = <np.ndarray>np.empty(it.shape, np.uint8) - - it = np.PyArray_MultiIterNew3(low_arr, high_arr, out_arr) - out_data = <uint8_t *>np.PyArray_DATA(out_arr) - cnt = np.PyArray_SIZE(out_arr) - mask = last_rng = 0 - with lock, nogil: - for i in range(cnt): - low_v = (<uint16_t*>np.PyArray_MultiIter_DATA(it, 0))[0] - high_v = (<uint16_t*>np.PyArray_MultiIter_DATA(it, 1))[0] - # Subtract 1 since generator produces values on the closed int [off, off+rng] - rng = <uint8_t>((high_v - is_open) - low_v) - off = <uint8_t>(<uint16_t>low_v) - - if rng != last_rng: - # Smallest bit mask >= max - mask = <uint8_t>_gen_mask(rng) - - out_data[i] = random_buffered_bounded_uint8(state, off, rng, mask, use_masked, &buf_rem, &buf) - - np.PyArray_MultiIter_NEXT(it) - return out_arr - -cdef object _rand_bool_broadcast(np.ndarray low, np.ndarray high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - Array path for smaller integer types - - This path is simpler since the high value in the open interval [low, high) - must be in-range for the next larger type, uint8. Here we case to - this type for checking and the recast to bool when producing the - random integers. - """ - cdef bool_t rng, last_rng, off, val, mask, out_val, is_open - cdef uint32_t buf - cdef bool_t *out_data - cdef uint8_t low_v, high_v - cdef np.ndarray low_arr, high_arr, out_arr - cdef np.npy_intp i, cnt - cdef np.broadcast it - cdef int buf_rem = 0 - - # Array path - is_open = not closed - low_arr = <np.ndarray>low - high_arr = <np.ndarray>high - if np.any(np.less(low_arr, 0)): - raise ValueError('low is out of bounds for bool') - if closed: - high_comp = np.greater_equal - low_high_comp = np.greater - else: - high_comp = np.greater - low_high_comp = np.greater_equal - - if np.any(high_comp(high_arr, 0x2UL)): - raise ValueError('high is out of bounds for bool') - if np.any(low_high_comp(low_arr, high_arr)): - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - low_arr = <np.ndarray>np.PyArray_FROM_OTF(low, np.NPY_UINT8, np.NPY_ALIGNED | np.NPY_FORCECAST) - high_arr = <np.ndarray>np.PyArray_FROM_OTF(high, np.NPY_UINT8, np.NPY_ALIGNED | np.NPY_FORCECAST) - - if size is not None: - out_arr = <np.ndarray>np.empty(size, np.bool_) - else: - it = np.PyArray_MultiIterNew2(low_arr, high_arr) - out_arr = <np.ndarray>np.empty(it.shape, np.bool_) - - it = np.PyArray_MultiIterNew3(low_arr, high_arr, out_arr) - out_data = <bool_t *>np.PyArray_DATA(out_arr) - cnt = np.PyArray_SIZE(out_arr) - mask = last_rng = 0 - with lock, nogil: - for i in range(cnt): - low_v = (<uint8_t*>np.PyArray_MultiIter_DATA(it, 0))[0] - high_v = (<uint8_t*>np.PyArray_MultiIter_DATA(it, 1))[0] - # Subtract 1 since generator produces values on the closed int [off, off+rng] - rng = <bool_t>((high_v - is_open) - low_v) - off = <bool_t>(<uint8_t>low_v) - - if rng != last_rng: - # Smallest bit mask >= max - mask = <bool_t>_gen_mask(rng) - - out_data[i] = random_buffered_bounded_bool(state, off, rng, mask, use_masked, &buf_rem, &buf) - - np.PyArray_MultiIter_NEXT(it) - return out_arr - -cdef object _rand_int32_broadcast(np.ndarray low, np.ndarray high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - Array path for smaller integer types - - This path is simpler since the high value in the open interval [low, high) - must be in-range for the next larger type, uint64. Here we case to - this type for checking and the recast to int32 when producing the - random integers. - """ - cdef uint32_t rng, last_rng, off, val, mask, out_val, is_open - cdef uint32_t buf - cdef uint32_t *out_data - cdef uint64_t low_v, high_v - cdef np.ndarray low_arr, high_arr, out_arr - cdef np.npy_intp i, cnt - cdef np.broadcast it - cdef int buf_rem = 0 - - # Array path - is_open = not closed - low_arr = <np.ndarray>low - high_arr = <np.ndarray>high - if np.any(np.less(low_arr, -0x80000000LL)): - raise ValueError('low is out of bounds for int32') - if closed: - high_comp = np.greater_equal - low_high_comp = np.greater - else: - high_comp = np.greater - low_high_comp = np.greater_equal - - if np.any(high_comp(high_arr, 0x80000000LL)): - raise ValueError('high is out of bounds for int32') - if np.any(low_high_comp(low_arr, high_arr)): - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - low_arr = <np.ndarray>np.PyArray_FROM_OTF(low, np.NPY_INT64, np.NPY_ALIGNED | np.NPY_FORCECAST) - high_arr = <np.ndarray>np.PyArray_FROM_OTF(high, np.NPY_INT64, np.NPY_ALIGNED | np.NPY_FORCECAST) - - if size is not None: - out_arr = <np.ndarray>np.empty(size, np.int32) - else: - it = np.PyArray_MultiIterNew2(low_arr, high_arr) - out_arr = <np.ndarray>np.empty(it.shape, np.int32) - - it = np.PyArray_MultiIterNew3(low_arr, high_arr, out_arr) - out_data = <uint32_t *>np.PyArray_DATA(out_arr) - cnt = np.PyArray_SIZE(out_arr) - mask = last_rng = 0 - with lock, nogil: - for i in range(cnt): - low_v = (<uint64_t*>np.PyArray_MultiIter_DATA(it, 0))[0] - high_v = (<uint64_t*>np.PyArray_MultiIter_DATA(it, 1))[0] - # Subtract 1 since generator produces values on the closed int [off, off+rng] - rng = <uint32_t>((high_v - is_open) - low_v) - off = <uint32_t>(<uint64_t>low_v) - - if rng != last_rng: - # Smallest bit mask >= max - mask = <uint32_t>_gen_mask(rng) - - out_data[i] = random_buffered_bounded_uint32(state, off, rng, mask, use_masked, &buf_rem, &buf) - - np.PyArray_MultiIter_NEXT(it) - return out_arr - -cdef object _rand_int16_broadcast(np.ndarray low, np.ndarray high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - Array path for smaller integer types - - This path is simpler since the high value in the open interval [low, high) - must be in-range for the next larger type, uint32. Here we case to - this type for checking and the recast to int16 when producing the - random integers. - """ - cdef uint16_t rng, last_rng, off, val, mask, out_val, is_open - cdef uint32_t buf - cdef uint16_t *out_data - cdef uint32_t low_v, high_v - cdef np.ndarray low_arr, high_arr, out_arr - cdef np.npy_intp i, cnt - cdef np.broadcast it - cdef int buf_rem = 0 - - # Array path - is_open = not closed - low_arr = <np.ndarray>low - high_arr = <np.ndarray>high - if np.any(np.less(low_arr, -0x8000LL)): - raise ValueError('low is out of bounds for int16') - if closed: - high_comp = np.greater_equal - low_high_comp = np.greater - else: - high_comp = np.greater - low_high_comp = np.greater_equal - - if np.any(high_comp(high_arr, 0x8000LL)): - raise ValueError('high is out of bounds for int16') - if np.any(low_high_comp(low_arr, high_arr)): - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - low_arr = <np.ndarray>np.PyArray_FROM_OTF(low, np.NPY_INT32, np.NPY_ALIGNED | np.NPY_FORCECAST) - high_arr = <np.ndarray>np.PyArray_FROM_OTF(high, np.NPY_INT32, np.NPY_ALIGNED | np.NPY_FORCECAST) - - if size is not None: - out_arr = <np.ndarray>np.empty(size, np.int16) - else: - it = np.PyArray_MultiIterNew2(low_arr, high_arr) - out_arr = <np.ndarray>np.empty(it.shape, np.int16) - - it = np.PyArray_MultiIterNew3(low_arr, high_arr, out_arr) - out_data = <uint16_t *>np.PyArray_DATA(out_arr) - cnt = np.PyArray_SIZE(out_arr) - mask = last_rng = 0 - with lock, nogil: - for i in range(cnt): - low_v = (<uint32_t*>np.PyArray_MultiIter_DATA(it, 0))[0] - high_v = (<uint32_t*>np.PyArray_MultiIter_DATA(it, 1))[0] - # Subtract 1 since generator produces values on the closed int [off, off+rng] - rng = <uint16_t>((high_v - is_open) - low_v) - off = <uint16_t>(<uint32_t>low_v) - - if rng != last_rng: - # Smallest bit mask >= max - mask = <uint16_t>_gen_mask(rng) - - out_data[i] = random_buffered_bounded_uint16(state, off, rng, mask, use_masked, &buf_rem, &buf) - - np.PyArray_MultiIter_NEXT(it) - return out_arr - -cdef object _rand_int8_broadcast(np.ndarray low, np.ndarray high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - Array path for smaller integer types - - This path is simpler since the high value in the open interval [low, high) - must be in-range for the next larger type, uint16. Here we case to - this type for checking and the recast to int8 when producing the - random integers. - """ - cdef uint8_t rng, last_rng, off, val, mask, out_val, is_open - cdef uint32_t buf - cdef uint8_t *out_data - cdef uint16_t low_v, high_v - cdef np.ndarray low_arr, high_arr, out_arr - cdef np.npy_intp i, cnt - cdef np.broadcast it - cdef int buf_rem = 0 - - # Array path - is_open = not closed - low_arr = <np.ndarray>low - high_arr = <np.ndarray>high - if np.any(np.less(low_arr, -0x80LL)): - raise ValueError('low is out of bounds for int8') - if closed: - high_comp = np.greater_equal - low_high_comp = np.greater - else: - high_comp = np.greater - low_high_comp = np.greater_equal - - if np.any(high_comp(high_arr, 0x80LL)): - raise ValueError('high is out of bounds for int8') - if np.any(low_high_comp(low_arr, high_arr)): - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - low_arr = <np.ndarray>np.PyArray_FROM_OTF(low, np.NPY_INT16, np.NPY_ALIGNED | np.NPY_FORCECAST) - high_arr = <np.ndarray>np.PyArray_FROM_OTF(high, np.NPY_INT16, np.NPY_ALIGNED | np.NPY_FORCECAST) - - if size is not None: - out_arr = <np.ndarray>np.empty(size, np.int8) - else: - it = np.PyArray_MultiIterNew2(low_arr, high_arr) - out_arr = <np.ndarray>np.empty(it.shape, np.int8) - - it = np.PyArray_MultiIterNew3(low_arr, high_arr, out_arr) - out_data = <uint8_t *>np.PyArray_DATA(out_arr) - cnt = np.PyArray_SIZE(out_arr) - mask = last_rng = 0 - with lock, nogil: - for i in range(cnt): - low_v = (<uint16_t*>np.PyArray_MultiIter_DATA(it, 0))[0] - high_v = (<uint16_t*>np.PyArray_MultiIter_DATA(it, 1))[0] - # Subtract 1 since generator produces values on the closed int [off, off+rng] - rng = <uint8_t>((high_v - is_open) - low_v) - off = <uint8_t>(<uint16_t>low_v) - - if rng != last_rng: - # Smallest bit mask >= max - mask = <uint8_t>_gen_mask(rng) - - out_data[i] = random_buffered_bounded_uint8(state, off, rng, mask, use_masked, &buf_rem, &buf) - - np.PyArray_MultiIter_NEXT(it) - return out_arr - - -cdef object _rand_uint64_broadcast(object low, object high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - Array path for 64-bit integer types - - Requires special treatment since the high value can be out-of-range for - the largest (64 bit) integer type since the generator is specified on the - interval [low,high). - - The internal generator does not have this issue since it generates from - the closes interval [low, high-1] and high-1 is always in range for the - 64 bit integer type. - """ - - cdef np.ndarray low_arr, high_arr, out_arr, highm1_arr - cdef np.npy_intp i, cnt, n - cdef np.broadcast it - cdef object closed_upper - cdef uint64_t *out_data - cdef uint64_t *highm1_data - cdef uint64_t low_v, high_v - cdef uint64_t rng, last_rng, val, mask, off, out_val - - low_arr = <np.ndarray>low - high_arr = <np.ndarray>high - - if np.any(np.less(low_arr, 0x0ULL)): - raise ValueError('low is out of bounds for uint64') - dt = high_arr.dtype - if closed or np.issubdtype(dt, np.integer): - # Avoid object dtype path if already an integer - high_lower_comp = np.less if closed else np.less_equal - if np.any(high_lower_comp(high_arr, 0x0ULL)): - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - high_m1 = high_arr if closed else high_arr - dt.type(1) - if np.any(np.greater(high_m1, 0xFFFFFFFFFFFFFFFFULL)): - raise ValueError('high is out of bounds for uint64') - highm1_arr = <np.ndarray>np.PyArray_FROM_OTF(high_m1, np.NPY_UINT64, np.NPY_ALIGNED | np.NPY_FORCECAST) - else: - # If input is object or a floating type - highm1_arr = <np.ndarray>np.empty_like(high_arr, dtype=np.uint64) - highm1_data = <uint64_t *>np.PyArray_DATA(highm1_arr) - cnt = np.PyArray_SIZE(high_arr) - flat = high_arr.flat - for i in range(cnt): - # Subtract 1 since generator produces values on the closed int [off, off+rng] - closed_upper = int(flat[i]) - 1 - if closed_upper > 0xFFFFFFFFFFFFFFFFULL: - raise ValueError('high is out of bounds for uint64') - if closed_upper < 0x0ULL: - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - highm1_data[i] = <uint64_t>closed_upper - - if np.any(np.greater(low_arr, highm1_arr)): - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - high_arr = highm1_arr - low_arr = <np.ndarray>np.PyArray_FROM_OTF(low, np.NPY_UINT64, np.NPY_ALIGNED | np.NPY_FORCECAST) - - if size is not None: - out_arr = <np.ndarray>np.empty(size, np.uint64) - else: - it = np.PyArray_MultiIterNew2(low_arr, high_arr) - out_arr = <np.ndarray>np.empty(it.shape, np.uint64) - - it = np.PyArray_MultiIterNew3(low_arr, high_arr, out_arr) - out_data = <uint64_t *>np.PyArray_DATA(out_arr) - n = np.PyArray_SIZE(out_arr) - mask = last_rng = 0 - with lock, nogil: - for i in range(n): - low_v = (<uint64_t*>np.PyArray_MultiIter_DATA(it, 0))[0] - high_v = (<uint64_t*>np.PyArray_MultiIter_DATA(it, 1))[0] - # Generator produces values on the closed int [off, off+rng], -1 subtracted above - rng = <uint64_t>(high_v - low_v) - off = <uint64_t>(<uint64_t>low_v) - - if rng != last_rng: - mask = _gen_mask(rng) - out_data[i] = random_bounded_uint64(state, off, rng, mask, use_masked) - - np.PyArray_MultiIter_NEXT(it) - - return out_arr - -cdef object _rand_int64_broadcast(object low, object high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - Array path for 64-bit integer types - - Requires special treatment since the high value can be out-of-range for - the largest (64 bit) integer type since the generator is specified on the - interval [low,high). - - The internal generator does not have this issue since it generates from - the closes interval [low, high-1] and high-1 is always in range for the - 64 bit integer type. - """ - - cdef np.ndarray low_arr, high_arr, out_arr, highm1_arr - cdef np.npy_intp i, cnt, n - cdef np.broadcast it - cdef object closed_upper - cdef uint64_t *out_data - cdef int64_t *highm1_data - cdef int64_t low_v, high_v - cdef uint64_t rng, last_rng, val, mask, off, out_val - - low_arr = <np.ndarray>low - high_arr = <np.ndarray>high - - if np.any(np.less(low_arr, -0x8000000000000000LL)): - raise ValueError('low is out of bounds for int64') - dt = high_arr.dtype - if closed or np.issubdtype(dt, np.integer): - # Avoid object dtype path if already an integer - high_lower_comp = np.less if closed else np.less_equal - if np.any(high_lower_comp(high_arr, -0x8000000000000000LL)): - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - high_m1 = high_arr if closed else high_arr - dt.type(1) - if np.any(np.greater(high_m1, 0x7FFFFFFFFFFFFFFFLL)): - raise ValueError('high is out of bounds for int64') - highm1_arr = <np.ndarray>np.PyArray_FROM_OTF(high_m1, np.NPY_INT64, np.NPY_ALIGNED | np.NPY_FORCECAST) - else: - # If input is object or a floating type - highm1_arr = <np.ndarray>np.empty_like(high_arr, dtype=np.int64) - highm1_data = <int64_t *>np.PyArray_DATA(highm1_arr) - cnt = np.PyArray_SIZE(high_arr) - flat = high_arr.flat - for i in range(cnt): - # Subtract 1 since generator produces values on the closed int [off, off+rng] - closed_upper = int(flat[i]) - 1 - if closed_upper > 0x7FFFFFFFFFFFFFFFLL: - raise ValueError('high is out of bounds for int64') - if closed_upper < -0x8000000000000000LL: - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - highm1_data[i] = <int64_t>closed_upper - - if np.any(np.greater(low_arr, highm1_arr)): - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - high_arr = highm1_arr - low_arr = <np.ndarray>np.PyArray_FROM_OTF(low, np.NPY_INT64, np.NPY_ALIGNED | np.NPY_FORCECAST) - - if size is not None: - out_arr = <np.ndarray>np.empty(size, np.int64) - else: - it = np.PyArray_MultiIterNew2(low_arr, high_arr) - out_arr = <np.ndarray>np.empty(it.shape, np.int64) - - it = np.PyArray_MultiIterNew3(low_arr, high_arr, out_arr) - out_data = <uint64_t *>np.PyArray_DATA(out_arr) - n = np.PyArray_SIZE(out_arr) - mask = last_rng = 0 - with lock, nogil: - for i in range(n): - low_v = (<int64_t*>np.PyArray_MultiIter_DATA(it, 0))[0] - high_v = (<int64_t*>np.PyArray_MultiIter_DATA(it, 1))[0] - # Generator produces values on the closed int [off, off+rng], -1 subtracted above - rng = <uint64_t>(high_v - low_v) - off = <uint64_t>(<int64_t>low_v) - - if rng != last_rng: - mask = _gen_mask(rng) - out_data[i] = random_bounded_uint64(state, off, rng, mask, use_masked) - - np.PyArray_MultiIter_NEXT(it) - - return out_arr - - -cdef object _rand_uint64(object low, object high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - _rand_uint64(low, high, size, use_masked, *state, lock) - - Return random np.uint64 integers from `low` (inclusive) to `high` (exclusive). - - Return random integers from the "discrete uniform" distribution in the - interval [`low`, `high`). If `high` is None (the default), - then results are from [0, `low`). On entry the arguments are presumed - to have been validated for size and order for the np.uint64 type. - - Parameters - ---------- - low : int or array-like - Lowest (signed) integer to be drawn from the distribution (unless - ``high=None``, in which case this parameter is the *highest* such - integer). - high : int or array-like - If provided, one above the largest (signed) integer to be drawn from the - distribution (see above for behavior if ``high=None``). - size : int or tuple of ints - 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. - use_masked : bool - If True then rejection sampling with a range mask is used else Lemire's algorithm is used. - closed : bool - If True then sample from [low, high]. If False, sample [low, high) - state : bit generator - Bit generator state to use in the core random number generators - lock : threading.Lock - Lock to prevent multiple using a single generator simultaneously - - Returns - ------- - out : python scalar or ndarray of np.uint64 - `size`-shaped array of random integers from the appropriate - distribution, or a single such random int if `size` not provided. - - Notes - ----- - The internal integer generator produces values from the closed - interval [low, high-(not closed)]. This requires some care since - high can be out-of-range for uint64. The scalar path leaves - integers as Python integers until the 1 has been subtracted to - avoid needing to cast to a larger type. - """ - cdef np.ndarray out_arr, low_arr, high_arr - cdef uint64_t rng, off, out_val - cdef uint64_t *out_data - cdef np.npy_intp i, n, cnt - - if size is not None: - if (np.prod(size) == 0): - return np.empty(size, dtype=np.uint64) - - low_arr = <np.ndarray>np.array(low, copy=False) - high_arr = <np.ndarray>np.array(high, copy=False) - low_ndim = np.PyArray_NDIM(low_arr) - high_ndim = np.PyArray_NDIM(high_arr) - if ((low_ndim == 0 or (low_ndim == 1 and low_arr.size == 1 and size is not None)) and - (high_ndim == 0 or (high_ndim == 1 and high_arr.size == 1 and size is not None))): - low = int(low_arr) - high = int(high_arr) - # Subtract 1 since internal generator produces on closed interval [low, high] - if not closed: - high -= 1 - - if low < 0x0ULL: - raise ValueError("low is out of bounds for uint64") - if high > 0xFFFFFFFFFFFFFFFFULL: - raise ValueError("high is out of bounds for uint64") - if low > high: # -1 already subtracted, closed interval - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - rng = <uint64_t>(high - low) - off = <uint64_t>(<uint64_t>low) - if size is None: - with lock: - random_bounded_uint64_fill(state, off, rng, 1, use_masked, &out_val) - return np.uint64(<uint64_t>out_val) - else: - out_arr = <np.ndarray>np.empty(size, np.uint64) - cnt = np.PyArray_SIZE(out_arr) - out_data = <uint64_t *>np.PyArray_DATA(out_arr) - with lock, nogil: - random_bounded_uint64_fill(state, off, rng, cnt, use_masked, out_data) - return out_arr - return _rand_uint64_broadcast(low_arr, high_arr, size, use_masked, closed, state, lock) - -cdef object _rand_uint32(object low, object high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - _rand_uint32(low, high, size, use_masked, *state, lock) - - Return random np.uint32 integers from `low` (inclusive) to `high` (exclusive). - - Return random integers from the "discrete uniform" distribution in the - interval [`low`, `high`). If `high` is None (the default), - then results are from [0, `low`). On entry the arguments are presumed - to have been validated for size and order for the np.uint32 type. - - Parameters - ---------- - low : int or array-like - Lowest (signed) integer to be drawn from the distribution (unless - ``high=None``, in which case this parameter is the *highest* such - integer). - high : int or array-like - If provided, one above the largest (signed) integer to be drawn from the - distribution (see above for behavior if ``high=None``). - size : int or tuple of ints - 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. - use_masked : bool - If True then rejection sampling with a range mask is used else Lemire's algorithm is used. - closed : bool - If True then sample from [low, high]. If False, sample [low, high) - state : bit generator - Bit generator state to use in the core random number generators - lock : threading.Lock - Lock to prevent multiple using a single generator simultaneously - - Returns - ------- - out : python scalar or ndarray of np.uint32 - `size`-shaped array of random integers from the appropriate - distribution, or a single such random int if `size` not provided. - - Notes - ----- - The internal integer generator produces values from the closed - interval [low, high-(not closed)]. This requires some care since - high can be out-of-range for uint32. The scalar path leaves - integers as Python integers until the 1 has been subtracted to - avoid needing to cast to a larger type. - """ - cdef np.ndarray out_arr, low_arr, high_arr - cdef uint32_t rng, off, out_val - cdef uint32_t *out_data - cdef np.npy_intp i, n, cnt - - if size is not None: - if (np.prod(size) == 0): - return np.empty(size, dtype=np.uint32) - - low_arr = <np.ndarray>np.array(low, copy=False) - high_arr = <np.ndarray>np.array(high, copy=False) - low_ndim = np.PyArray_NDIM(low_arr) - high_ndim = np.PyArray_NDIM(high_arr) - if ((low_ndim == 0 or (low_ndim == 1 and low_arr.size == 1 and size is not None)) and - (high_ndim == 0 or (high_ndim == 1 and high_arr.size == 1 and size is not None))): - low = int(low_arr) - high = int(high_arr) - # Subtract 1 since internal generator produces on closed interval [low, high] - if not closed: - high -= 1 - - if low < 0x0UL: - raise ValueError("low is out of bounds for uint32") - if high > 0XFFFFFFFFUL: - raise ValueError("high is out of bounds for uint32") - if low > high: # -1 already subtracted, closed interval - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - rng = <uint32_t>(high - low) - off = <uint32_t>(<uint32_t>low) - if size is None: - with lock: - random_bounded_uint32_fill(state, off, rng, 1, use_masked, &out_val) - return np.uint32(<uint32_t>out_val) - else: - out_arr = <np.ndarray>np.empty(size, np.uint32) - cnt = np.PyArray_SIZE(out_arr) - out_data = <uint32_t *>np.PyArray_DATA(out_arr) - with lock, nogil: - random_bounded_uint32_fill(state, off, rng, cnt, use_masked, out_data) - return out_arr - return _rand_uint32_broadcast(low_arr, high_arr, size, use_masked, closed, state, lock) - -cdef object _rand_uint16(object low, object high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - _rand_uint16(low, high, size, use_masked, *state, lock) - - Return random np.uint16 integers from `low` (inclusive) to `high` (exclusive). - - Return random integers from the "discrete uniform" distribution in the - interval [`low`, `high`). If `high` is None (the default), - then results are from [0, `low`). On entry the arguments are presumed - to have been validated for size and order for the np.uint16 type. - - Parameters - ---------- - low : int or array-like - Lowest (signed) integer to be drawn from the distribution (unless - ``high=None``, in which case this parameter is the *highest* such - integer). - high : int or array-like - If provided, one above the largest (signed) integer to be drawn from the - distribution (see above for behavior if ``high=None``). - size : int or tuple of ints - 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. - use_masked : bool - If True then rejection sampling with a range mask is used else Lemire's algorithm is used. - closed : bool - If True then sample from [low, high]. If False, sample [low, high) - state : bit generator - Bit generator state to use in the core random number generators - lock : threading.Lock - Lock to prevent multiple using a single generator simultaneously - - Returns - ------- - out : python scalar or ndarray of np.uint16 - `size`-shaped array of random integers from the appropriate - distribution, or a single such random int if `size` not provided. - - Notes - ----- - The internal integer generator produces values from the closed - interval [low, high-(not closed)]. This requires some care since - high can be out-of-range for uint16. The scalar path leaves - integers as Python integers until the 1 has been subtracted to - avoid needing to cast to a larger type. - """ - cdef np.ndarray out_arr, low_arr, high_arr - cdef uint16_t rng, off, out_val - cdef uint16_t *out_data - cdef np.npy_intp i, n, cnt - - if size is not None: - if (np.prod(size) == 0): - return np.empty(size, dtype=np.uint16) - - low_arr = <np.ndarray>np.array(low, copy=False) - high_arr = <np.ndarray>np.array(high, copy=False) - low_ndim = np.PyArray_NDIM(low_arr) - high_ndim = np.PyArray_NDIM(high_arr) - if ((low_ndim == 0 or (low_ndim == 1 and low_arr.size == 1 and size is not None)) and - (high_ndim == 0 or (high_ndim == 1 and high_arr.size == 1 and size is not None))): - low = int(low_arr) - high = int(high_arr) - # Subtract 1 since internal generator produces on closed interval [low, high] - if not closed: - high -= 1 - - if low < 0x0UL: - raise ValueError("low is out of bounds for uint16") - if high > 0XFFFFUL: - raise ValueError("high is out of bounds for uint16") - if low > high: # -1 already subtracted, closed interval - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - rng = <uint16_t>(high - low) - off = <uint16_t>(<uint16_t>low) - if size is None: - with lock: - random_bounded_uint16_fill(state, off, rng, 1, use_masked, &out_val) - return np.uint16(<uint16_t>out_val) - else: - out_arr = <np.ndarray>np.empty(size, np.uint16) - cnt = np.PyArray_SIZE(out_arr) - out_data = <uint16_t *>np.PyArray_DATA(out_arr) - with lock, nogil: - random_bounded_uint16_fill(state, off, rng, cnt, use_masked, out_data) - return out_arr - return _rand_uint16_broadcast(low_arr, high_arr, size, use_masked, closed, state, lock) - -cdef object _rand_uint8(object low, object high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - _rand_uint8(low, high, size, use_masked, *state, lock) - - Return random np.uint8 integers from `low` (inclusive) to `high` (exclusive). - - Return random integers from the "discrete uniform" distribution in the - interval [`low`, `high`). If `high` is None (the default), - then results are from [0, `low`). On entry the arguments are presumed - to have been validated for size and order for the np.uint8 type. - - Parameters - ---------- - low : int or array-like - Lowest (signed) integer to be drawn from the distribution (unless - ``high=None``, in which case this parameter is the *highest* such - integer). - high : int or array-like - If provided, one above the largest (signed) integer to be drawn from the - distribution (see above for behavior if ``high=None``). - size : int or tuple of ints - 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. - use_masked : bool - If True then rejection sampling with a range mask is used else Lemire's algorithm is used. - closed : bool - If True then sample from [low, high]. If False, sample [low, high) - state : bit generator - Bit generator state to use in the core random number generators - lock : threading.Lock - Lock to prevent multiple using a single generator simultaneously - - Returns - ------- - out : python scalar or ndarray of np.uint8 - `size`-shaped array of random integers from the appropriate - distribution, or a single such random int if `size` not provided. - - Notes - ----- - The internal integer generator produces values from the closed - interval [low, high-(not closed)]. This requires some care since - high can be out-of-range for uint8. The scalar path leaves - integers as Python integers until the 1 has been subtracted to - avoid needing to cast to a larger type. - """ - cdef np.ndarray out_arr, low_arr, high_arr - cdef uint8_t rng, off, out_val - cdef uint8_t *out_data - cdef np.npy_intp i, n, cnt - - if size is not None: - if (np.prod(size) == 0): - return np.empty(size, dtype=np.uint8) - - low_arr = <np.ndarray>np.array(low, copy=False) - high_arr = <np.ndarray>np.array(high, copy=False) - low_ndim = np.PyArray_NDIM(low_arr) - high_ndim = np.PyArray_NDIM(high_arr) - if ((low_ndim == 0 or (low_ndim == 1 and low_arr.size == 1 and size is not None)) and - (high_ndim == 0 or (high_ndim == 1 and high_arr.size == 1 and size is not None))): - low = int(low_arr) - high = int(high_arr) - # Subtract 1 since internal generator produces on closed interval [low, high] - if not closed: - high -= 1 - - if low < 0x0UL: - raise ValueError("low is out of bounds for uint8") - if high > 0XFFUL: - raise ValueError("high is out of bounds for uint8") - if low > high: # -1 already subtracted, closed interval - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - rng = <uint8_t>(high - low) - off = <uint8_t>(<uint8_t>low) - if size is None: - with lock: - random_bounded_uint8_fill(state, off, rng, 1, use_masked, &out_val) - return np.uint8(<uint8_t>out_val) - else: - out_arr = <np.ndarray>np.empty(size, np.uint8) - cnt = np.PyArray_SIZE(out_arr) - out_data = <uint8_t *>np.PyArray_DATA(out_arr) - with lock, nogil: - random_bounded_uint8_fill(state, off, rng, cnt, use_masked, out_data) - return out_arr - return _rand_uint8_broadcast(low_arr, high_arr, size, use_masked, closed, state, lock) - -cdef object _rand_bool(object low, object high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - _rand_bool(low, high, size, use_masked, *state, lock) - - Return random np.bool integers from `low` (inclusive) to `high` (exclusive). - - Return random integers from the "discrete uniform" distribution in the - interval [`low`, `high`). If `high` is None (the default), - then results are from [0, `low`). On entry the arguments are presumed - to have been validated for size and order for the np.bool type. - - Parameters - ---------- - low : int or array-like - Lowest (signed) integer to be drawn from the distribution (unless - ``high=None``, in which case this parameter is the *highest* such - integer). - high : int or array-like - If provided, one above the largest (signed) integer to be drawn from the - distribution (see above for behavior if ``high=None``). - size : int or tuple of ints - 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. - use_masked : bool - If True then rejection sampling with a range mask is used else Lemire's algorithm is used. - closed : bool - If True then sample from [low, high]. If False, sample [low, high) - state : bit generator - Bit generator state to use in the core random number generators - lock : threading.Lock - Lock to prevent multiple using a single generator simultaneously - - Returns - ------- - out : python scalar or ndarray of np.bool - `size`-shaped array of random integers from the appropriate - distribution, or a single such random int if `size` not provided. - - Notes - ----- - The internal integer generator produces values from the closed - interval [low, high-(not closed)]. This requires some care since - high can be out-of-range for bool. The scalar path leaves - integers as Python integers until the 1 has been subtracted to - avoid needing to cast to a larger type. - """ - cdef np.ndarray out_arr, low_arr, high_arr - cdef bool_t rng, off, out_val - cdef bool_t *out_data - cdef np.npy_intp i, n, cnt - - if size is not None: - if (np.prod(size) == 0): - return np.empty(size, dtype=np.bool) - - low_arr = <np.ndarray>np.array(low, copy=False) - high_arr = <np.ndarray>np.array(high, copy=False) - low_ndim = np.PyArray_NDIM(low_arr) - high_ndim = np.PyArray_NDIM(high_arr) - if ((low_ndim == 0 or (low_ndim == 1 and low_arr.size == 1 and size is not None)) and - (high_ndim == 0 or (high_ndim == 1 and high_arr.size == 1 and size is not None))): - low = int(low_arr) - high = int(high_arr) - # Subtract 1 since internal generator produces on closed interval [low, high] - if not closed: - high -= 1 - - if low < 0x0UL: - raise ValueError("low is out of bounds for bool") - if high > 0x1UL: - raise ValueError("high is out of bounds for bool") - if low > high: # -1 already subtracted, closed interval - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - rng = <bool_t>(high - low) - off = <bool_t>(<bool_t>low) - if size is None: - with lock: - random_bounded_bool_fill(state, off, rng, 1, use_masked, &out_val) - return np.bool_(<bool_t>out_val) - else: - out_arr = <np.ndarray>np.empty(size, np.bool) - cnt = np.PyArray_SIZE(out_arr) - out_data = <bool_t *>np.PyArray_DATA(out_arr) - with lock, nogil: - random_bounded_bool_fill(state, off, rng, cnt, use_masked, out_data) - return out_arr - return _rand_bool_broadcast(low_arr, high_arr, size, use_masked, closed, state, lock) - -cdef object _rand_int64(object low, object high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - _rand_int64(low, high, size, use_masked, *state, lock) - - Return random np.int64 integers from `low` (inclusive) to `high` (exclusive). - - Return random integers from the "discrete uniform" distribution in the - interval [`low`, `high`). If `high` is None (the default), - then results are from [0, `low`). On entry the arguments are presumed - to have been validated for size and order for the np.int64 type. - - Parameters - ---------- - low : int or array-like - Lowest (signed) integer to be drawn from the distribution (unless - ``high=None``, in which case this parameter is the *highest* such - integer). - high : int or array-like - If provided, one above the largest (signed) integer to be drawn from the - distribution (see above for behavior if ``high=None``). - size : int or tuple of ints - 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. - use_masked : bool - If True then rejection sampling with a range mask is used else Lemire's algorithm is used. - closed : bool - If True then sample from [low, high]. If False, sample [low, high) - state : bit generator - Bit generator state to use in the core random number generators - lock : threading.Lock - Lock to prevent multiple using a single generator simultaneously - - Returns - ------- - out : python scalar or ndarray of np.int64 - `size`-shaped array of random integers from the appropriate - distribution, or a single such random int if `size` not provided. - - Notes - ----- - The internal integer generator produces values from the closed - interval [low, high-(not closed)]. This requires some care since - high can be out-of-range for uint64. The scalar path leaves - integers as Python integers until the 1 has been subtracted to - avoid needing to cast to a larger type. - """ - cdef np.ndarray out_arr, low_arr, high_arr - cdef uint64_t rng, off, out_val - cdef uint64_t *out_data - cdef np.npy_intp i, n, cnt - - if size is not None: - if (np.prod(size) == 0): - return np.empty(size, dtype=np.int64) - - low_arr = <np.ndarray>np.array(low, copy=False) - high_arr = <np.ndarray>np.array(high, copy=False) - low_ndim = np.PyArray_NDIM(low_arr) - high_ndim = np.PyArray_NDIM(high_arr) - if ((low_ndim == 0 or (low_ndim == 1 and low_arr.size == 1 and size is not None)) and - (high_ndim == 0 or (high_ndim == 1 and high_arr.size == 1 and size is not None))): - low = int(low_arr) - high = int(high_arr) - # Subtract 1 since internal generator produces on closed interval [low, high] - if not closed: - high -= 1 - - if low < -0x8000000000000000LL: - raise ValueError("low is out of bounds for int64") - if high > 0x7FFFFFFFFFFFFFFFL: - raise ValueError("high is out of bounds for int64") - if low > high: # -1 already subtracted, closed interval - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - rng = <uint64_t>(high - low) - off = <uint64_t>(<int64_t>low) - if size is None: - with lock: - random_bounded_uint64_fill(state, off, rng, 1, use_masked, &out_val) - return np.int64(<int64_t>out_val) - else: - out_arr = <np.ndarray>np.empty(size, np.int64) - cnt = np.PyArray_SIZE(out_arr) - out_data = <uint64_t *>np.PyArray_DATA(out_arr) - with lock, nogil: - random_bounded_uint64_fill(state, off, rng, cnt, use_masked, out_data) - return out_arr - return _rand_int64_broadcast(low_arr, high_arr, size, use_masked, closed, state, lock) - -cdef object _rand_int32(object low, object high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - _rand_int32(low, high, size, use_masked, *state, lock) - - Return random np.int32 integers from `low` (inclusive) to `high` (exclusive). - - Return random integers from the "discrete uniform" distribution in the - interval [`low`, `high`). If `high` is None (the default), - then results are from [0, `low`). On entry the arguments are presumed - to have been validated for size and order for the np.int32 type. - - Parameters - ---------- - low : int or array-like - Lowest (signed) integer to be drawn from the distribution (unless - ``high=None``, in which case this parameter is the *highest* such - integer). - high : int or array-like - If provided, one above the largest (signed) integer to be drawn from the - distribution (see above for behavior if ``high=None``). - size : int or tuple of ints - 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. - use_masked : bool - If True then rejection sampling with a range mask is used else Lemire's algorithm is used. - closed : bool - If True then sample from [low, high]. If False, sample [low, high) - state : bit generator - Bit generator state to use in the core random number generators - lock : threading.Lock - Lock to prevent multiple using a single generator simultaneously - - Returns - ------- - out : python scalar or ndarray of np.int32 - `size`-shaped array of random integers from the appropriate - distribution, or a single such random int if `size` not provided. - - Notes - ----- - The internal integer generator produces values from the closed - interval [low, high-(not closed)]. This requires some care since - high can be out-of-range for uint32. The scalar path leaves - integers as Python integers until the 1 has been subtracted to - avoid needing to cast to a larger type. - """ - cdef np.ndarray out_arr, low_arr, high_arr - cdef uint32_t rng, off, out_val - cdef uint32_t *out_data - cdef np.npy_intp i, n, cnt - - if size is not None: - if (np.prod(size) == 0): - return np.empty(size, dtype=np.int32) - - low_arr = <np.ndarray>np.array(low, copy=False) - high_arr = <np.ndarray>np.array(high, copy=False) - low_ndim = np.PyArray_NDIM(low_arr) - high_ndim = np.PyArray_NDIM(high_arr) - if ((low_ndim == 0 or (low_ndim == 1 and low_arr.size == 1 and size is not None)) and - (high_ndim == 0 or (high_ndim == 1 and high_arr.size == 1 and size is not None))): - low = int(low_arr) - high = int(high_arr) - # Subtract 1 since internal generator produces on closed interval [low, high] - if not closed: - high -= 1 - - if low < -0x80000000L: - raise ValueError("low is out of bounds for int32") - if high > 0x7FFFFFFFL: - raise ValueError("high is out of bounds for int32") - if low > high: # -1 already subtracted, closed interval - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - rng = <uint32_t>(high - low) - off = <uint32_t>(<int32_t>low) - if size is None: - with lock: - random_bounded_uint32_fill(state, off, rng, 1, use_masked, &out_val) - return np.int32(<int32_t>out_val) - else: - out_arr = <np.ndarray>np.empty(size, np.int32) - cnt = np.PyArray_SIZE(out_arr) - out_data = <uint32_t *>np.PyArray_DATA(out_arr) - with lock, nogil: - random_bounded_uint32_fill(state, off, rng, cnt, use_masked, out_data) - return out_arr - return _rand_int32_broadcast(low_arr, high_arr, size, use_masked, closed, state, lock) - -cdef object _rand_int16(object low, object high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - _rand_int16(low, high, size, use_masked, *state, lock) - - Return random np.int16 integers from `low` (inclusive) to `high` (exclusive). - - Return random integers from the "discrete uniform" distribution in the - interval [`low`, `high`). If `high` is None (the default), - then results are from [0, `low`). On entry the arguments are presumed - to have been validated for size and order for the np.int16 type. - - Parameters - ---------- - low : int or array-like - Lowest (signed) integer to be drawn from the distribution (unless - ``high=None``, in which case this parameter is the *highest* such - integer). - high : int or array-like - If provided, one above the largest (signed) integer to be drawn from the - distribution (see above for behavior if ``high=None``). - size : int or tuple of ints - 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. - use_masked : bool - If True then rejection sampling with a range mask is used else Lemire's algorithm is used. - closed : bool - If True then sample from [low, high]. If False, sample [low, high) - state : bit generator - Bit generator state to use in the core random number generators - lock : threading.Lock - Lock to prevent multiple using a single generator simultaneously - - Returns - ------- - out : python scalar or ndarray of np.int16 - `size`-shaped array of random integers from the appropriate - distribution, or a single such random int if `size` not provided. - - Notes - ----- - The internal integer generator produces values from the closed - interval [low, high-(not closed)]. This requires some care since - high can be out-of-range for uint16. The scalar path leaves - integers as Python integers until the 1 has been subtracted to - avoid needing to cast to a larger type. - """ - cdef np.ndarray out_arr, low_arr, high_arr - cdef uint16_t rng, off, out_val - cdef uint16_t *out_data - cdef np.npy_intp i, n, cnt - - if size is not None: - if (np.prod(size) == 0): - return np.empty(size, dtype=np.int16) - - low_arr = <np.ndarray>np.array(low, copy=False) - high_arr = <np.ndarray>np.array(high, copy=False) - low_ndim = np.PyArray_NDIM(low_arr) - high_ndim = np.PyArray_NDIM(high_arr) - if ((low_ndim == 0 or (low_ndim == 1 and low_arr.size == 1 and size is not None)) and - (high_ndim == 0 or (high_ndim == 1 and high_arr.size == 1 and size is not None))): - low = int(low_arr) - high = int(high_arr) - # Subtract 1 since internal generator produces on closed interval [low, high] - if not closed: - high -= 1 - - if low < -0x8000L: - raise ValueError("low is out of bounds for int16") - if high > 0x7FFFL: - raise ValueError("high is out of bounds for int16") - if low > high: # -1 already subtracted, closed interval - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - rng = <uint16_t>(high - low) - off = <uint16_t>(<int16_t>low) - if size is None: - with lock: - random_bounded_uint16_fill(state, off, rng, 1, use_masked, &out_val) - return np.int16(<int16_t>out_val) - else: - out_arr = <np.ndarray>np.empty(size, np.int16) - cnt = np.PyArray_SIZE(out_arr) - out_data = <uint16_t *>np.PyArray_DATA(out_arr) - with lock, nogil: - random_bounded_uint16_fill(state, off, rng, cnt, use_masked, out_data) - return out_arr - return _rand_int16_broadcast(low_arr, high_arr, size, use_masked, closed, state, lock) - -cdef object _rand_int8(object low, object high, object size, - bint use_masked, bint closed, - bitgen_t *state, object lock): - """ - _rand_int8(low, high, size, use_masked, *state, lock) - - Return random np.int8 integers from `low` (inclusive) to `high` (exclusive). - - Return random integers from the "discrete uniform" distribution in the - interval [`low`, `high`). If `high` is None (the default), - then results are from [0, `low`). On entry the arguments are presumed - to have been validated for size and order for the np.int8 type. - - Parameters - ---------- - low : int or array-like - Lowest (signed) integer to be drawn from the distribution (unless - ``high=None``, in which case this parameter is the *highest* such - integer). - high : int or array-like - If provided, one above the largest (signed) integer to be drawn from the - distribution (see above for behavior if ``high=None``). - size : int or tuple of ints - 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. - use_masked : bool - If True then rejection sampling with a range mask is used else Lemire's algorithm is used. - closed : bool - If True then sample from [low, high]. If False, sample [low, high) - state : bit generator - Bit generator state to use in the core random number generators - lock : threading.Lock - Lock to prevent multiple using a single generator simultaneously - - Returns - ------- - out : python scalar or ndarray of np.int8 - `size`-shaped array of random integers from the appropriate - distribution, or a single such random int if `size` not provided. - - Notes - ----- - The internal integer generator produces values from the closed - interval [low, high-(not closed)]. This requires some care since - high can be out-of-range for uint8. The scalar path leaves - integers as Python integers until the 1 has been subtracted to - avoid needing to cast to a larger type. - """ - cdef np.ndarray out_arr, low_arr, high_arr - cdef uint8_t rng, off, out_val - cdef uint8_t *out_data - cdef np.npy_intp i, n, cnt - - if size is not None: - if (np.prod(size) == 0): - return np.empty(size, dtype=np.int8) - - low_arr = <np.ndarray>np.array(low, copy=False) - high_arr = <np.ndarray>np.array(high, copy=False) - low_ndim = np.PyArray_NDIM(low_arr) - high_ndim = np.PyArray_NDIM(high_arr) - if ((low_ndim == 0 or (low_ndim == 1 and low_arr.size == 1 and size is not None)) and - (high_ndim == 0 or (high_ndim == 1 and high_arr.size == 1 and size is not None))): - low = int(low_arr) - high = int(high_arr) - # Subtract 1 since internal generator produces on closed interval [low, high] - if not closed: - high -= 1 - - if low < -0x80L: - raise ValueError("low is out of bounds for int8") - if high > 0x7FL: - raise ValueError("high is out of bounds for int8") - if low > high: # -1 already subtracted, closed interval - comp = '>' if closed else '>=' - raise ValueError('low {comp} high'.format(comp=comp)) - - rng = <uint8_t>(high - low) - off = <uint8_t>(<int8_t>low) - if size is None: - with lock: - random_bounded_uint8_fill(state, off, rng, 1, use_masked, &out_val) - return np.int8(<int8_t>out_val) - else: - out_arr = <np.ndarray>np.empty(size, np.int8) - cnt = np.PyArray_SIZE(out_arr) - out_data = <uint8_t *>np.PyArray_DATA(out_arr) - with lock, nogil: - random_bounded_uint8_fill(state, off, rng, cnt, use_masked, out_data) - return out_arr - return _rand_int8_broadcast(low_arr, high_arr, size, use_masked, closed, state, lock) diff --git a/numpy/random/_bounded_integers.pyx.in b/numpy/random/_bounded_integers.pyx.in index 47cb13b3a..c0068dab2 100644 --- a/numpy/random/_bounded_integers.pyx.in +++ b/numpy/random/_bounded_integers.pyx.in @@ -191,7 +191,7 @@ cdef object _rand_{{nptype}}_broadcast(object low, object high, object size, highm1_arr = <np.ndarray>np.PyArray_FROM_OTF(high_m1, np.{{npctype}}, np.NPY_ALIGNED | np.NPY_FORCECAST) else: # If input is object or a floating type - highm1_arr = <np.ndarray>np.empty_like(high_arr, dtype=np.{{nptype}}) + highm1_arr = <np.ndarray>np.empty_like(high_arr, dtype=np.{{otype}}) highm1_data = <{{nptype}}_t *>np.PyArray_DATA(highm1_arr) cnt = np.PyArray_SIZE(high_arr) flat = high_arr.flat @@ -213,10 +213,10 @@ cdef object _rand_{{nptype}}_broadcast(object low, object high, object size, low_arr = <np.ndarray>np.PyArray_FROM_OTF(low, np.{{npctype}}, np.NPY_ALIGNED | np.NPY_FORCECAST) if size is not None: - out_arr = <np.ndarray>np.empty(size, np.{{nptype}}) + out_arr = <np.ndarray>np.empty(size, np.{{otype}}) else: it = np.PyArray_MultiIterNew2(low_arr, high_arr) - out_arr = <np.ndarray>np.empty(it.shape, np.{{nptype}}) + out_arr = <np.ndarray>np.empty(it.shape, np.{{otype}}) it = np.PyArray_MultiIterNew3(low_arr, high_arr, out_arr) out_data = <uint64_t *>np.PyArray_DATA(out_arr) @@ -258,12 +258,12 @@ cdef object _rand_{{nptype}}(object low, object high, object size, """ _rand_{{nptype}}(low, high, size, use_masked, *state, lock) - Return random np.{{nptype}} integers from `low` (inclusive) to `high` (exclusive). + Return random `np.{{otype}}` integers from `low` (inclusive) to `high` (exclusive). Return random integers from the "discrete uniform" distribution in the interval [`low`, `high`). If `high` is None (the default), then results are from [0, `low`). On entry the arguments are presumed - to have been validated for size and order for the np.{{nptype}} type. + to have been validated for size and order for the `np.{{otype}}` type. Parameters ---------- @@ -289,7 +289,7 @@ cdef object _rand_{{nptype}}(object low, object high, object size, Returns ------- - out : python scalar or ndarray of np.{{nptype}} + out : python scalar or ndarray of np.{{otype}} `size`-shaped array of random integers from the appropriate distribution, or a single such random int if `size` not provided. @@ -308,7 +308,7 @@ cdef object _rand_{{nptype}}(object low, object high, object size, if size is not None: if (np.prod(size) == 0): - return np.empty(size, dtype=np.{{nptype}}) + return np.empty(size, dtype=np.{{otype}}) low_arr = <np.ndarray>np.array(low, copy=False) high_arr = <np.ndarray>np.array(high, copy=False) @@ -337,7 +337,7 @@ cdef object _rand_{{nptype}}(object low, object high, object size, random_bounded_{{utype}}_fill(state, off, rng, 1, use_masked, &out_val) return np.{{otype}}(<{{nptype}}_t>out_val) else: - out_arr = <np.ndarray>np.empty(size, np.{{nptype}}) + out_arr = <np.ndarray>np.empty(size, np.{{otype}}) cnt = np.PyArray_SIZE(out_arr) out_data = <{{utype}}_t *>np.PyArray_DATA(out_arr) with lock, nogil: diff --git a/numpy/random/_generator.pyx b/numpy/random/_generator.pyx index 4b012af2f..b6c222cc0 100644 --- a/numpy/random/_generator.pyx +++ b/numpy/random/_generator.pyx @@ -502,7 +502,7 @@ cdef class Generator: Desired dtype of the result. All dtypes are determined by their name, i.e., 'int64', 'int', etc, so byteorder is not available and a specific precision may have different C types depending - on the platform. The default value is 'np.int'. + on the platform. The default value is `np.int_`. endpoint : bool, optional If true, sample from the interval [low, high] instead of the default [low, high) @@ -595,7 +595,7 @@ cdef class Generator: elif key == 'bool': ret = _rand_bool(low, high, size, _masked, endpoint, &self._bitgen, self.lock) - if size is None and dtype in (np.bool, np.int, np.long): + if size is None and dtype in (bool, int, np.compat.long): if np.array(ret).shape == (): return dtype(ret) return ret diff --git a/numpy/random/mtrand.pyx b/numpy/random/mtrand.pyx index 683a771cc..b21607282 100644 --- a/numpy/random/mtrand.pyx +++ b/numpy/random/mtrand.pyx @@ -555,7 +555,7 @@ cdef class RandomState: tomaxint(size=None) Return a sample of uniformly distributed random integers in the interval - [0, ``np.iinfo(np.int).max``]. The np.int type translates to the C long + [0, ``np.iinfo(np.int_).max``]. The `np.int_` type translates to the C long integer type and its precision is platform dependent. Parameters @@ -584,7 +584,7 @@ cdef class RandomState: [ 739731006, 1947757578]], [[1871712945, 752307660], [1601631370, 1479324245]]]) - >>> rs.tomaxint((2,2,2)) < np.iinfo(np.int).max + >>> rs.tomaxint((2,2,2)) < np.iinfo(np.int_).max array([[[ True, True], [ True, True]], [[ True, True], @@ -636,7 +636,7 @@ cdef class RandomState: Desired dtype of the result. All dtypes are determined by their name, i.e., 'int64', 'int', etc, so byteorder is not available and a specific precision may have different C types depending - on the platform. The default value is 'np.int'. + on the platform. The default value is `np.int_`. .. versionadded:: 1.11.0 @@ -724,7 +724,7 @@ cdef class RandomState: elif key == 'bool': ret = _rand_bool(low, high, size, _masked, _endpoint, &self._bitgen, self.lock) - if size is None and dtype in (np.bool, np.int, np.long): + if size is None and dtype in (bool, int, np.compat.long): if np.array(ret).shape == (): return dtype(ret) return ret @@ -1165,11 +1165,11 @@ cdef class RandomState: """ random_integers(low, high=None, size=None) - Random integers of type np.int between `low` and `high`, inclusive. + Random integers of type `np.int_` between `low` and `high`, inclusive. - Return random integers of type np.int from the "discrete uniform" + Return random integers of type `np.int_` from the "discrete uniform" distribution in the closed interval [`low`, `high`]. If `high` is - None (the default), then results are from [1, `low`]. The np.int + None (the default), then results are from [1, `low`]. The `np.int_` type translates to the C long integer type and its precision is platform dependent. diff --git a/numpy/random/tests/test_generator_mt19937.py b/numpy/random/tests/test_generator_mt19937.py index d85de6b6d..d835f16bd 100644 --- a/numpy/random/tests/test_generator_mt19937.py +++ b/numpy/random/tests/test_generator_mt19937.py @@ -494,9 +494,8 @@ class TestIntegers(object): def test_repeatability_broadcasting(self, endpoint): for dt in self.itype: - lbnd = 0 if dt in (np.bool, bool, np.bool_) else np.iinfo(dt).min - ubnd = 2 if dt in ( - np.bool, bool, np.bool_) else np.iinfo(dt).max + 1 + lbnd = 0 if dt in (bool, np.bool_) else np.iinfo(dt).min + ubnd = 2 if dt in (bool, np.bool_) else np.iinfo(dt).max + 1 ubnd = ubnd - 1 if endpoint else ubnd # view as little endian for hash @@ -535,8 +534,8 @@ class TestIntegers(object): assert_raises(ValueError, random.integers, low_a, high_a, endpoint=endpoint, dtype=dtype) - low_o = np.array([[low]*10], dtype=np.object) - high_o = np.array([high] * 10, dtype=np.object) + low_o = np.array([[low]*10], dtype=object) + high_o = np.array([high] * 10, dtype=object) assert_raises(ValueError, random.integers, low_o, high, endpoint=endpoint, dtype=dtype) assert_raises(ValueError, random.integers, low, high_o, @@ -578,7 +577,7 @@ class TestIntegers(object): sample = self.rfunc(lbnd, ubnd, endpoint=endpoint, dtype=dt) assert_equal(sample.dtype, dt) - for dt in (bool, int, np.long): + for dt in (bool, int, np.compat.long): lbnd = 0 if dt is bool else np.iinfo(dt).min ubnd = 2 if dt is bool else np.iinfo(dt).max + 1 ubnd = ubnd - 1 if endpoint else ubnd @@ -2220,7 +2219,7 @@ class TestSingleEltArrayInput(object): assert_equal(out.shape, self.tgtShape) def test_integers(self, endpoint): - itype = [np.bool, np.int8, np.uint8, np.int16, np.uint16, + itype = [np.bool_, np.int8, np.uint8, np.int16, np.uint16, np.int32, np.uint32, np.int64, np.uint64] func = random.integers high = np.array([1]) diff --git a/numpy/random/tests/test_random.py b/numpy/random/tests/test_random.py index 37bd121f3..2e2ecedf8 100644 --- a/numpy/random/tests/test_random.py +++ b/numpy/random/tests/test_random.py @@ -269,7 +269,7 @@ class TestRandint(object): sample = self.rfunc(lbnd, ubnd, dtype=dt) assert_equal(sample.dtype, np.dtype(dt)) - for dt in (bool, int, np.long): + for dt in (bool, int, np.compat.long): lbnd = 0 if dt is bool else np.iinfo(dt).min ubnd = 2 if dt is bool else np.iinfo(dt).max + 1 diff --git a/numpy/random/tests/test_randomstate.py b/numpy/random/tests/test_randomstate.py index 5131f1839..c12b685ad 100644 --- a/numpy/random/tests/test_randomstate.py +++ b/numpy/random/tests/test_randomstate.py @@ -229,7 +229,7 @@ class TestSetState(object): new_state = ('Unknown', ) + state[1:] assert_raises(ValueError, self.random_state.set_state, new_state) assert_raises(TypeError, self.random_state.set_state, - np.array(new_state, dtype=np.object)) + np.array(new_state, dtype=object)) state = self.random_state.get_state(legacy=False) del state['bit_generator'] assert_raises(ValueError, self.random_state.set_state, state) @@ -382,7 +382,7 @@ class TestRandint(object): sample = self.rfunc(lbnd, ubnd, dtype=dt) assert_equal(sample.dtype, np.dtype(dt)) - for dt in (bool, int, np.long): + for dt in (bool, int, np.compat.long): lbnd = 0 if dt is bool else np.iinfo(dt).min ubnd = 2 if dt is bool else np.iinfo(dt).max + 1 @@ -455,7 +455,7 @@ class TestRandomDist(object): random.seed(self.seed) rs = random.RandomState(self.seed) actual = rs.tomaxint(size=(3, 2)) - if np.iinfo(np.int).max == 2147483647: + if np.iinfo(int).max == 2147483647: desired = np.array([[1328851649, 731237375], [1270502067, 320041495], [1908433478, 499156889]], dtype=np.int64) diff --git a/numpy/random/tests/test_smoke.py b/numpy/random/tests/test_smoke.py index 6e641b5f4..58ef6a09a 100644 --- a/numpy/random/tests/test_smoke.py +++ b/numpy/random/tests/test_smoke.py @@ -8,7 +8,7 @@ from numpy.testing import assert_equal, assert_, assert_array_equal from numpy.random import (Generator, MT19937, PCG64, Philox, SFC64) @pytest.fixture(scope='module', - params=(np.bool, np.int8, np.int16, np.int32, np.int64, + params=(np.bool_, np.int8, np.int16, np.int32, np.int64, np.uint8, np.uint16, np.uint32, np.uint64)) def dtype(request): return request.param @@ -655,7 +655,7 @@ class RNG(object): rg.standard_gamma(1.0, out=existing[::3]) def test_integers_broadcast(self, dtype): - if dtype == np.bool: + if dtype == np.bool_: upper = 2 lower = 0 else: @@ -672,7 +672,7 @@ class RNG(object): assert_equal(a, c) self._reset_state() d = self.rg.integers(np.array( - [lower] * 10), np.array([upper], dtype=np.object), size=10, + [lower] * 10), np.array([upper], dtype=object), size=10, dtype=dtype) assert_equal(a, d) self._reset_state() @@ -701,7 +701,7 @@ class RNG(object): assert out.shape == (1,) def test_integers_broadcast_errors(self, dtype): - if dtype == np.bool: + if dtype == np.bool_: upper = 2 lower = 0 else: |