diff options
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/arrayprint.py | 11 | ||||
-rw-r--r-- | numpy/core/include/numpy/ndarrayobject.h | 2 | ||||
-rw-r--r-- | numpy/core/src/multiarray/ctors.c | 30 | ||||
-rw-r--r-- | numpy/core/src/multiarray/datetime.c | 239 | ||||
-rw-r--r-- | numpy/core/src/umath/scalarmath.c.src | 60 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 13 | ||||
-rw-r--r-- | numpy/distutils/command/build_src.py | 8 | ||||
-rw-r--r-- | numpy/random/generator.pyx | 6 | ||||
-rw-r--r-- | numpy/random/tests/test_generator_mt19937.py | 9 |
9 files changed, 171 insertions, 207 deletions
diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py index b1310a737..233d139fd 100644 --- a/numpy/core/arrayprint.py +++ b/numpy/core/arrayprint.py @@ -200,6 +200,8 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None, ----- `formatter` is always reset with a call to `set_printoptions`. + Use `printoptions` as a context manager to set the values temporarily. + Examples -------- Floating point precision can be set: @@ -236,9 +238,16 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None, To put back the default options, you can use: - >>> np.set_printoptions(edgeitems=3,infstr='inf', + >>> np.set_printoptions(edgeitems=3, infstr='inf', ... linewidth=75, nanstr='nan', precision=8, ... suppress=False, threshold=1000, formatter=None) + + Also to temporarily override options, use `printoptions` as a context manager: + + >>> with np.printoptions(precision=2, suppress=True, threshold=5): + ... np.linspace(0, 10, 10) + array([ 0. , 1.11, 2.22, ..., 7.78, 8.89, 10. ]) + """ legacy = kwarg.pop('legacy', None) if kwarg: diff --git a/numpy/core/include/numpy/ndarrayobject.h b/numpy/core/include/numpy/ndarrayobject.h index 2cc7ced35..95e9cb060 100644 --- a/numpy/core/include/numpy/ndarrayobject.h +++ b/numpy/core/include/numpy/ndarrayobject.h @@ -23,7 +23,7 @@ extern "C" { /* C-API that requires previous API to be defined */ -#define PyArray_DescrCheck(op) (((PyObject*)(op))->ob_type==&PyArrayDescr_Type) +#define PyArray_DescrCheck(op) PyObject_TypeCheck(op, &PyArrayDescr_Type) #define PyArray_Check(op) PyObject_TypeCheck(op, &PyArray_Type) #define PyArray_CheckExact(op) (((PyObject*)(op))->ob_type == &PyArray_Type) diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index ba5121306..5174bd889 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -3580,6 +3580,7 @@ array_fromfile_binary(FILE *fp, PyArray_Descr *dtype, npy_intp num, size_t *nrea { PyArrayObject *r; npy_off_t start, numbytes; + int elsize; if (num < 0) { int fail = 0; @@ -3606,16 +3607,21 @@ array_fromfile_binary(FILE *fp, PyArray_Descr *dtype, npy_intp num, size_t *nrea } num = numbytes / dtype->elsize; } + + /* + * Array creation may move sub-array dimensions from the dtype to array + * dimensions, so we need to use the original element size when reading. + */ + elsize = dtype->elsize; + r = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, dtype, 1, &num, NULL, NULL, 0, NULL); if (r == NULL) { return NULL; } - /* In some cases NewFromDescr can replace the dtype, so fetch new one */ - dtype = PyArray_DESCR(r); NPY_BEGIN_ALLOW_THREADS; - *nread = fread(PyArray_DATA(r), dtype->elsize, num, fp); + *nread = fread(PyArray_DATA(r), elsize, num, fp); NPY_END_ALLOW_THREADS; return r; } @@ -3642,14 +3648,19 @@ array_from_text(PyArray_Descr *dtype, npy_intp num, char *sep, size_t *nread, size = (num >= 0) ? num : FROM_BUFFER_SIZE; + /* + * Array creation may move sub-array dimensions from the dtype to array + * dimensions, so we need to use the original dtype when reading. + */ + Py_INCREF(dtype); + r = (PyArrayObject *) PyArray_NewFromDescr(&PyArray_Type, dtype, 1, &size, NULL, NULL, 0, NULL); if (r == NULL) { + Py_DECREF(dtype); return NULL; } - /* In some cases NewFromDescr can replace the dtype, so fetch new one */ - dtype = PyArray_DESCR(r); clean_sep = swab_separator(sep); if (clean_sep == NULL) { @@ -3710,6 +3721,7 @@ array_from_text(PyArray_Descr *dtype, npy_intp num, char *sep, size_t *nread, if (PyErr_Occurred()) { /* If an error is already set (unlikely), do not create new one */ Py_DECREF(r); + Py_DECREF(dtype); return NULL; } /* 2019-09-12, NumPy 1.18 */ @@ -3721,6 +3733,7 @@ array_from_text(PyArray_Descr *dtype, npy_intp num, char *sep, size_t *nread, } fail: + Py_DECREF(dtype); if (err == 1) { PyErr_NoMemory(); } @@ -3986,6 +3999,11 @@ PyArray_FromString(char *data, npy_intp slen, PyArray_Descr *dtype, return NULL; } } + /* + * NewFromDescr may replace dtype to absorb subarray shape + * into the array, so get size beforehand. + */ + npy_intp size_to_copy = num*dtype->elsize; ret = (PyArrayObject *) PyArray_NewFromDescr(&PyArray_Type, dtype, 1, &num, NULL, NULL, @@ -3993,7 +4011,7 @@ PyArray_FromString(char *data, npy_intp slen, PyArray_Descr *dtype, if (ret == NULL) { return NULL; } - memcpy(PyArray_DATA(ret), data, num*dtype->elsize); + memcpy(PyArray_DATA(ret), data, size_to_copy); } else { /* read from character-based string */ diff --git a/numpy/core/src/multiarray/datetime.c b/numpy/core/src/multiarray/datetime.c index 82e046ca1..d21bb9776 100644 --- a/numpy/core/src/multiarray/datetime.c +++ b/numpy/core/src/multiarray/datetime.c @@ -27,6 +27,40 @@ #include "datetime_strings.h" /* + * Computes the python `ret, d = divmod(d, unit)`. + * + * Note that GCC is smart enough at -O2 to eliminate the `if(*d < 0)` branch + * for subsequent calls to this command - it is able to deduce that `*d >= 0`. + */ +static inline +npy_int64 extract_unit_64(npy_int64 *d, npy_int64 unit) { + assert(unit > 0); + npy_int64 div = *d / unit; + npy_int64 mod = *d % unit; + if (mod < 0) { + mod += unit; + div -= 1; + } + assert(mod >= 0); + *d = mod; + return div; +} + +static inline +npy_int32 extract_unit_32(npy_int32 *d, npy_int32 unit) { + assert(unit > 0); + npy_int32 div = *d / unit; + npy_int32 mod = *d % unit; + if (mod < 0) { + mod += unit; + div -= 1; + } + assert(mod >= 0); + *d = mod; + return div; +} + +/* * Imports the PyDateTime functions so we can create these objects. * This is called during module initialization */ @@ -160,17 +194,7 @@ days_to_yearsdays(npy_int64 *days_) npy_int64 year; /* Break down the 400 year cycle to get the year and day within the year */ - if (days >= 0) { - year = 400 * (days / days_per_400years); - days = days % days_per_400years; - } - else { - year = 400 * ((days - (days_per_400years - 1)) / days_per_400years); - days = days % days_per_400years; - if (days < 0) { - days += days_per_400years; - } - } + year = 400 * extract_unit_64(&days, days_per_400years); /* Work out the year/day within the 400 year cycle */ if (days >= 366) { @@ -411,26 +435,6 @@ PyArray_TimedeltaStructToTimedelta( } /* - * Computes the python `ret, d = divmod(d, unit)`. - * - * Note that GCC is smart enough at -O2 to eliminate the `if(*d < 0)` branch - * for subsequent calls to this command - it is able to deduce that `*d >= 0`. - */ -static inline -npy_int64 extract_unit(npy_datetime *d, npy_datetime unit) { - assert(unit > 0); - npy_int64 div = *d / unit; - npy_int64 mod = *d % unit; - if (mod < 0) { - mod += unit; - div -= 1; - } - assert(mod >= 0); - *d = mod; - return div; -} - -/* * Converts a datetime based on the given metadata into a datetimestruct */ NPY_NO_EXPORT int @@ -438,7 +442,7 @@ convert_datetime_to_datetimestruct(PyArray_DatetimeMetaData *meta, npy_datetime dt, npy_datetimestruct *out) { - npy_int64 perday; + npy_int64 days; /* Initialize the output to all zeros */ memset(out, 0, sizeof(npy_datetimestruct)); @@ -473,7 +477,7 @@ convert_datetime_to_datetimestruct(PyArray_DatetimeMetaData *meta, break; case NPY_FR_M: - out->year = 1970 + extract_unit(&dt, 12); + out->year = 1970 + extract_unit_64(&dt, 12); out->month = dt + 1; break; @@ -487,73 +491,67 @@ convert_datetime_to_datetimestruct(PyArray_DatetimeMetaData *meta, break; case NPY_FR_h: - perday = 24LL; - - set_datetimestruct_days(extract_unit(&dt, perday), out); + days = extract_unit_64(&dt, 24LL); + set_datetimestruct_days(days, out); out->hour = (int)dt; break; case NPY_FR_m: - perday = 24LL * 60; - - set_datetimestruct_days(extract_unit(&dt, perday), out); - out->hour = (int)extract_unit(&dt, 60); - out->min = (int)dt; + days = extract_unit_64(&dt, 60LL*24); + set_datetimestruct_days(days, out); + out->hour = (int)extract_unit_64(&dt, 60LL); + out->min = (int)dt; break; case NPY_FR_s: - perday = 24LL * 60 * 60; - - set_datetimestruct_days(extract_unit(&dt, perday), out); - out->hour = (int)extract_unit(&dt, 60*60); - out->min = (int)extract_unit(&dt, 60); + days = extract_unit_64(&dt, 60LL*60*24); + set_datetimestruct_days(days, out); + out->hour = (int)extract_unit_64(&dt, 60LL*60); + out->min = (int)extract_unit_64(&dt, 60LL); out->sec = (int)dt; break; case NPY_FR_ms: - perday = 24LL * 60 * 60 * 1000; - - set_datetimestruct_days(extract_unit(&dt, perday), out); - out->hour = (int)extract_unit(&dt, 1000LL*60*60); - out->min = (int)extract_unit(&dt, 1000LL*60); - out->sec = (int)extract_unit(&dt, 1000LL); + days = extract_unit_64(&dt, 1000LL*60*60*24); + set_datetimestruct_days(days, out); + out->hour = (int)extract_unit_64(&dt, 1000LL*60*60); + out->min = (int)extract_unit_64(&dt, 1000LL*60); + out->sec = (int)extract_unit_64(&dt, 1000LL); out->us = (int)(dt * 1000); break; case NPY_FR_us: - perday = 24LL * 60LL * 60LL * 1000LL * 1000LL; - set_datetimestruct_days(extract_unit(&dt, perday), out); - out->hour = (int)extract_unit(&dt, 1000LL*1000*60*60); - out->min = (int)extract_unit(&dt, 1000LL*1000*60); - out->sec = (int)extract_unit(&dt, 1000LL*1000); + days = extract_unit_64(&dt, 1000LL*1000*60*60*24); + set_datetimestruct_days(days, out); + out->hour = (int)extract_unit_64(&dt, 1000LL*1000*60*60); + out->min = (int)extract_unit_64(&dt, 1000LL*1000*60); + out->sec = (int)extract_unit_64(&dt, 1000LL*1000); out->us = (int)dt; break; case NPY_FR_ns: - perday = 24LL * 60LL * 60LL * 1000LL * 1000LL * 1000LL; - - set_datetimestruct_days(extract_unit(&dt, perday), out); - out->hour = (int)extract_unit(&dt, 1000LL*1000*1000*60*60); - out->min = (int)extract_unit(&dt, 1000LL*1000*1000*60); - out->sec = (int)extract_unit(&dt, 1000LL*1000*1000); - out->us = (int)extract_unit(&dt, 1000LL); + days = extract_unit_64(&dt, 1000LL*1000*1000*60*60*24); + set_datetimestruct_days(days, out); + out->hour = (int)extract_unit_64(&dt, 1000LL*1000*1000*60*60); + out->min = (int)extract_unit_64(&dt, 1000LL*1000*1000*60); + out->sec = (int)extract_unit_64(&dt, 1000LL*1000*1000); + out->us = (int)extract_unit_64(&dt, 1000LL); out->ps = (int)(dt * 1000); break; case NPY_FR_ps: - perday = 24LL * 60 * 60 * 1000 * 1000 * 1000 * 1000; - - set_datetimestruct_days(extract_unit(&dt, perday), out); - out->hour = (int)extract_unit(&dt, 1000LL*1000*1000*1000*60*60); - out->min = (int)extract_unit(&dt, 1000LL*1000*1000*1000*60); - out->sec = (int)extract_unit(&dt, 1000LL*1000*1000*1000); - out->us = (int)extract_unit(&dt, 1000LL*1000); + days = extract_unit_64(&dt, 1000LL*1000*1000*1000*60*60*24); + set_datetimestruct_days(days, out); + out->hour = (int)extract_unit_64(&dt, 1000LL*1000*1000*1000*60*60); + out->min = (int)extract_unit_64(&dt, 1000LL*1000*1000*1000*60); + out->sec = (int)extract_unit_64(&dt, 1000LL*1000*1000*1000); + out->us = (int)extract_unit_64(&dt, 1000LL*1000); out->ps = (int)(dt); break; case NPY_FR_fs: /* entire range is only +- 2.6 hours */ - out->hour = (int)extract_unit(&dt, 1000LL*1000*1000*1000*1000*60*60); + out->hour = (int)extract_unit_64(&dt, 1000LL*1000*1000*1000*1000*60*60); if (out->hour < 0) { out->year = 1969; out->month = 12; @@ -561,16 +559,16 @@ convert_datetime_to_datetimestruct(PyArray_DatetimeMetaData *meta, out->hour += 24; assert(out->hour >= 0); } - out->min = (int)extract_unit(&dt, 1000LL*1000*1000*1000*1000*60); - out->sec = (int)extract_unit(&dt, 1000LL*1000*1000*1000*1000); - out->us = (int)extract_unit(&dt, 1000LL*1000*1000); - out->ps = (int)extract_unit(&dt, 1000LL); + out->min = (int)extract_unit_64(&dt, 1000LL*1000*1000*1000*1000*60); + out->sec = (int)extract_unit_64(&dt, 1000LL*1000*1000*1000*1000); + out->us = (int)extract_unit_64(&dt, 1000LL*1000*1000); + out->ps = (int)extract_unit_64(&dt, 1000LL); out->as = (int)(dt * 1000); break; case NPY_FR_as: /* entire range is only +- 9.2 seconds */ - out->sec = (int)extract_unit(&dt, 1000LL*1000*1000*1000*1000*1000); + out->sec = (int)extract_unit_64(&dt, 1000LL*1000*1000*1000*1000*1000); if (out->sec < 0) { out->year = 1969; out->month = 12; @@ -580,8 +578,8 @@ convert_datetime_to_datetimestruct(PyArray_DatetimeMetaData *meta, out->sec += 60; assert(out->sec >= 0); } - out->us = (int)extract_unit(&dt, 1000LL*1000*1000*1000); - out->ps = (int)extract_unit(&dt, 1000LL*1000); + out->us = (int)extract_unit_64(&dt, 1000LL*1000*1000*1000); + out->ps = (int)extract_unit_64(&dt, 1000LL*1000); out->as = (int)dt; break; @@ -2017,20 +2015,8 @@ add_seconds_to_datetimestruct(npy_datetimestruct *dts, int seconds) int minutes; dts->sec += seconds; - if (dts->sec < 0) { - minutes = dts->sec / 60; - dts->sec = dts->sec % 60; - if (dts->sec < 0) { - --minutes; - dts->sec += 60; - } - add_minutes_to_datetimestruct(dts, minutes); - } - else if (dts->sec >= 60) { - minutes = dts->sec / 60; - dts->sec = dts->sec % 60; - add_minutes_to_datetimestruct(dts, minutes); - } + minutes = extract_unit_32(&dts->sec, 60); + add_minutes_to_datetimestruct(dts, minutes); } /* @@ -2042,28 +2028,13 @@ add_minutes_to_datetimestruct(npy_datetimestruct *dts, int minutes) { int isleap; - /* MINUTES */ dts->min += minutes; - while (dts->min < 0) { - dts->min += 60; - dts->hour--; - } - while (dts->min >= 60) { - dts->min -= 60; - dts->hour++; - } - /* HOURS */ - while (dts->hour < 0) { - dts->hour += 24; - dts->day--; - } - while (dts->hour >= 24) { - dts->hour -= 24; - dts->day++; - } + /* propagate invalid minutes into hour and day changes */ + dts->hour += extract_unit_32(&dts->min, 60); + dts->day += extract_unit_32(&dts->hour, 24); - /* DAYS */ + /* propagate invalid days into month and year changes */ if (dts->day < 1) { dts->month--; if (dts->month < 1) { @@ -2890,7 +2861,6 @@ convert_datetime_to_pyobject(npy_datetime dt, PyArray_DatetimeMetaData *meta) NPY_NO_EXPORT PyObject * convert_timedelta_to_pyobject(npy_timedelta td, PyArray_DatetimeMetaData *meta) { - PyObject *ret = NULL; npy_timedelta value; int days = 0, seconds = 0, useconds = 0; @@ -2920,54 +2890,47 @@ convert_timedelta_to_pyobject(npy_timedelta td, PyArray_DatetimeMetaData *meta) /* Convert to days/seconds/useconds */ switch (meta->base) { case NPY_FR_W: - value *= 7; + days = value * 7; break; case NPY_FR_D: + days = value; break; case NPY_FR_h: - seconds = (int)((value % 24) * (60*60)); - value = value / 24; + days = extract_unit_64(&value, 24ULL); + seconds = value*60*60; break; case NPY_FR_m: - seconds = (int)(value % (24*60)) * 60; - value = value / (24*60); + days = extract_unit_64(&value, 60ULL*24); + seconds = value*60; break; case NPY_FR_s: - seconds = (int)(value % (24*60*60)); - value = value / (24*60*60); + days = extract_unit_64(&value, 60ULL*60*24); + seconds = value; break; case NPY_FR_ms: - useconds = (int)(value % 1000) * 1000; - value = value / 1000; - seconds = (int)(value % (24*60*60)); - value = value / (24*60*60); + days = extract_unit_64(&value, 1000ULL*60*60*24); + seconds = extract_unit_64(&value, 1000ULL); + useconds = value*1000; break; case NPY_FR_us: - useconds = (int)(value % (1000*1000)); - value = value / (1000*1000); - seconds = (int)(value % (24*60*60)); - value = value / (24*60*60); + days = extract_unit_64(&value, 1000ULL*1000*60*60*24); + seconds = extract_unit_64(&value, 1000ULL*1000); + useconds = value; break; default: + // unreachable, handled by the `if` above + assert(NPY_FALSE); break; } /* - * 'value' represents days, and seconds/useconds are filled. - * * If it would overflow the datetime.timedelta days, return a raw int */ - if (value < -999999999 || value > 999999999) { + if (days < -999999999 || days > 999999999) { return PyLong_FromLongLong(td); } else { - days = (int)value; - ret = PyDelta_FromDSU(days, seconds, useconds); - if (ret == NULL) { - return NULL; - } + return PyDelta_FromDSU(days, seconds, useconds); } - - return ret; } /* diff --git a/numpy/core/src/umath/scalarmath.c.src b/numpy/core/src/umath/scalarmath.c.src index 9cce0b7f0..d5d8d659b 100644 --- a/numpy/core/src/umath/scalarmath.c.src +++ b/numpy/core/src/umath/scalarmath.c.src @@ -406,21 +406,22 @@ half_ctype_divmod(npy_half a, npy_half b, npy_half *out1, npy_half *out2) { /**begin repeat * #name = float, double, longdouble# * #type = npy_float, npy_double, npy_longdouble# + * #c = f,,l# */ -static npy_@name@ (*_basic_@name@_pow)(@type@ a, @type@ b); static void @name@_ctype_power(@type@ a, @type@ b, @type@ *out) { - *out = _basic_@name@_pow(a, b); + *out = npy_pow@c@(a, b); } + /**end repeat**/ static void half_ctype_power(npy_half a, npy_half b, npy_half *out) { const npy_float af = npy_half_to_float(a); const npy_float bf = npy_half_to_float(b); - const npy_float outf = _basic_float_pow(af,bf); + const npy_float outf = npy_powf(af,bf); *out = npy_float_to_half(outf); } @@ -477,14 +478,10 @@ static void } /**end repeat**/ -/* - * Get the nc_powf, nc_pow, and nc_powl functions from - * the data area of the power ufunc in umathmodule. - */ - /**begin repeat * #name = cfloat, cdouble, clongdouble# * #type = npy_cfloat, npy_cdouble, npy_clongdouble# + * #c = f,,l# */ static void @name@_ctype_positive(@type@ a, @type@ *out) @@ -493,12 +490,10 @@ static void out->imag = a.imag; } -static void (*_basic_@name@_pow)(@type@ *, @type@ *, @type@ *); - static void @name@_ctype_power(@type@ a, @type@ b, @type@ *out) { - _basic_@name@_pow(&a, &b, out); + *out = npy_cpow@c@(a, b); } /**end repeat**/ @@ -1680,52 +1675,9 @@ add_scalarmath(void) /**end repeat**/ } -static int -get_functions(PyObject * mm) -{ - PyObject *obj; - void **funcdata; - char *signatures; - int i, j; - int ret = -1; - - /* Get the nc_pow functions */ - /* Get the pow functions */ - obj = PyObject_GetAttrString(mm, "power"); - if (obj == NULL) { - goto fail; - } - funcdata = ((PyUFuncObject *)obj)->data; - signatures = ((PyUFuncObject *)obj)->types; - - i = 0; - j = 0; - while (signatures[i] != NPY_FLOAT) { - i += 3; - j++; - } - _basic_float_pow = funcdata[j]; - _basic_double_pow = funcdata[j + 1]; - _basic_longdouble_pow = funcdata[j + 2]; - _basic_cfloat_pow = funcdata[j + 3]; - _basic_cdouble_pow = funcdata[j + 4]; - _basic_clongdouble_pow = funcdata[j + 5]; - Py_DECREF(obj); - - return ret = 0; - - fail: - Py_DECREF(mm); - return ret; -} - NPY_NO_EXPORT int initscalarmath(PyObject * m) { - if (get_functions(m) < 0) { - return -1; - } - add_scalarmath(); return 0; diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 88db357b2..9b124f603 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -5023,6 +5023,19 @@ class TestIO(object): self.test_tofile_sep() self.test_tofile_format() + def test_fromfile_subarray_binary(self): + # Test subarray dtypes which are absorbed into the shape + x = np.arange(24, dtype="i4").reshape(2, 3, 4) + x.tofile(self.filename) + res = np.fromfile(self.filename, dtype="(3,4)i4") + assert_array_equal(x, res) + + x_str = x.tobytes() + with assert_warns(DeprecationWarning): + # binary fromstring is deprecated + res = np.fromstring(x_str, dtype="(3,4)i4") + assert_array_equal(x, res) + class TestFromBuffer(object): @pytest.mark.parametrize('byteorder', ['<', '>']) diff --git a/numpy/distutils/command/build_src.py b/numpy/distutils/command/build_src.py index af8cec08a..3e0522c5f 100644 --- a/numpy/distutils/command/build_src.py +++ b/numpy/distutils/command/build_src.py @@ -53,12 +53,12 @@ class build_src(build_ext.build_ext): ('inplace', 'i', "ignore build-lib and put compiled extensions into the source " + "directory alongside your pure Python modules"), - ('verbose', 'v', + ('verbose-cfg', None, "change logging level from WARN to INFO which will show all " + "compiler output") ] - boolean_options = ['force', 'inplace', 'verbose'] + boolean_options = ['force', 'inplace', 'verbose-cfg'] help_options = [] @@ -79,7 +79,7 @@ class build_src(build_ext.build_ext): self.swig_opts = None self.swig_cpp = None self.swig = None - self.verbose = None + self.verbose_cfg = None def finalize_options(self): self.set_undefined_options('build', @@ -370,7 +370,7 @@ class build_src(build_ext.build_ext): +name.split('.')[:-1])) self.mkpath(build_dir) - if self.verbose: + if self.verbose_cfg: new_level = log.INFO else: new_level = log.WARN diff --git a/numpy/random/generator.pyx b/numpy/random/generator.pyx index 37ac57c06..df7485a97 100644 --- a/numpy/random/generator.pyx +++ b/numpy/random/generator.pyx @@ -3786,7 +3786,7 @@ cdef class Generator: # Shuffling and permutations: def shuffle(self, object x, axis=0): """ - shuffle(x) + shuffle(x, axis=0) Modify a sequence in-place by shuffling its contents. @@ -3858,7 +3858,7 @@ cdef class Generator: x = np.swapaxes(x, 0, axis) buf = np.empty_like(x[0, ...]) with self.lock: - for i in reversed(range(1, n)): + for i in reversed(range(1, len(x))): j = random_interval(&self._bitgen, i) if i == j: # i == j is not needed and memcpy is undefined. @@ -3928,7 +3928,7 @@ cdef class Generator: def permutation(self, object x, axis=0): """ - permutation(x) + permutation(x, axis=0) Randomly permute a sequence, or return a permuted range. diff --git a/numpy/random/tests/test_generator_mt19937.py b/numpy/random/tests/test_generator_mt19937.py index 20bc10cd0..391c33c1a 100644 --- a/numpy/random/tests/test_generator_mt19937.py +++ b/numpy/random/tests/test_generator_mt19937.py @@ -746,6 +746,15 @@ class TestRandomDist(object): random.shuffle(actual, axis=-1) assert_array_equal(actual, desired) + def test_shuffle_axis_nonsquare(self): + y1 = np.arange(20).reshape(2, 10) + y2 = y1.copy() + random = Generator(MT19937(self.seed)) + random.shuffle(y1, axis=1) + random = Generator(MT19937(self.seed)) + random.shuffle(y2.T) + assert_array_equal(y1, y2) + def test_shuffle_masked(self): # gh-3263 a = np.ma.masked_values(np.reshape(range(20), (5, 4)) % 3 - 1, -1) |