diff options
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/code_generators/cversions.py | 4 | ||||
-rw-r--r-- | numpy/core/code_generators/cversions.txt | 2 | ||||
-rw-r--r-- | numpy/core/code_generators/numpy_api.py | 3 | ||||
-rw-r--r-- | numpy/core/fromnumeric.py | 2 | ||||
-rw-r--r-- | numpy/core/setup_common.py | 5 | ||||
-rw-r--r-- | numpy/core/src/multiarray/convert.c | 9 | ||||
-rw-r--r-- | numpy/core/src/umath/struct_ufunc_test.c.src | 8 | ||||
-rw-r--r-- | numpy/core/src/umath/ufunc_object.c | 49 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 8 | ||||
-rw-r--r-- | numpy/core/tests/test_umath.py | 15 |
10 files changed, 86 insertions, 19 deletions
diff --git a/numpy/core/code_generators/cversions.py b/numpy/core/code_generators/cversions.py index 5ce0757c8..840251aa8 100644 --- a/numpy/core/code_generators/cversions.py +++ b/numpy/core/code_generators/cversions.py @@ -7,8 +7,8 @@ from __future__ import division, absolute_import, print_function from os.path import dirname -from .genapi import fullapi_hash -from . import numpy_api +from genapi import fullapi_hash +import numpy_api if __name__ == '__main__': diff --git a/numpy/core/code_generators/cversions.txt b/numpy/core/code_generators/cversions.txt index 5de3d5dc2..24d376ac6 100644 --- a/numpy/core/code_generators/cversions.txt +++ b/numpy/core/code_generators/cversions.txt @@ -15,3 +15,5 @@ 0x00000007 = e396ba3912dcf052eaee1b0b203a7724 # Version 8 Added interface to MapIterObject 0x00000008 = 17321775fc884de0b1eda478cd61c74b +# Version 9 Added interface for partition functions. +0x00000009 = f99a02b75bd60205d1afe1eed080fd53 diff --git a/numpy/core/code_generators/numpy_api.py b/numpy/core/code_generators/numpy_api.py index 134d6199e..ad9ee3eec 100644 --- a/numpy/core/code_generators/numpy_api.py +++ b/numpy/core/code_generators/numpy_api.py @@ -339,6 +339,7 @@ multiarray_funcs_api = { 'PyArray_Partition': 296, 'PyArray_ArgPartition': 297, 'PyArray_SelectkindConverter': 298, + # End 1.8 API } ufunc_types_api = { @@ -388,7 +389,9 @@ ufunc_funcs_api = { # End 1.6 API 'PyUFunc_DefaultTypeResolver': 39, 'PyUFunc_ValidateCasting': 40, + # End 1.7 API 'PyUFunc_RegisterLoopForDescr': 41, + # End 1.8 API } # List of all the dicts which define the C API diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 3ed1c13b0..9d7c226fc 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1303,7 +1303,7 @@ def ravel(a, order='C'): Returns ------- 1d_array : ndarray - Output of the same dtype as `a`, and of shape ``(a.size(),)``. + Output of the same dtype as `a`, and of shape ``(a.size,)``. See Also -------- diff --git a/numpy/core/setup_common.py b/numpy/core/setup_common.py index 9a630225d..7f0ad8bfe 100644 --- a/numpy/core/setup_common.py +++ b/numpy/core/setup_common.py @@ -31,7 +31,10 @@ C_ABI_VERSION = 0x01000009 # without breaking binary compatibility. In this case, only the C_API_VERSION # (*not* C_ABI_VERSION) would be increased. Whenever binary compatibility is # broken, both C_API_VERSION and C_ABI_VERSION should be increased. -C_API_VERSION = 0x00000008 +# +# 0x00000008 - 1.7.x +# 0x00000009 - 1.8.x +C_API_VERSION = 0x00000009 class MismatchCAPIWarning(Warning): pass diff --git a/numpy/core/src/multiarray/convert.c b/numpy/core/src/multiarray/convert.c index e3dd78b9f..62b9034c2 100644 --- a/numpy/core/src/multiarray/convert.c +++ b/numpy/core/src/multiarray/convert.c @@ -413,7 +413,14 @@ PyArray_FillWithScalar(PyArrayObject *arr, PyObject *obj) else { PyArrayObject *src_arr; - src_arr = (PyArrayObject *)PyArray_FromAny(obj, NULL, 0, 0, 0, NULL); + /** + * The dtype of the destination is used when converting + * from the pyobject, so that for example a tuple gets + * recognized as a struct scalar of the required type. + */ + Py_INCREF(PyArray_DTYPE(arr)); + src_arr = (PyArrayObject *)PyArray_FromAny(obj, + PyArray_DTYPE(arr), 0, 0, 0, NULL); if (src_arr == NULL) { return -1; } diff --git a/numpy/core/src/umath/struct_ufunc_test.c.src b/numpy/core/src/umath/struct_ufunc_test.c.src index 4bd24559f..517925570 100644 --- a/numpy/core/src/umath/struct_ufunc_test.c.src +++ b/numpy/core/src/umath/struct_ufunc_test.c.src @@ -29,7 +29,7 @@ static void add_uint64_triplet(char **args, npy_intp *dimensions, npy_intp is2=steps[1]; npy_intp os=steps[2]; npy_intp n=dimensions[0]; - uint64_t *x, *y, *z; + npy_uint64 *x, *y, *z; char *i1=args[0]; char *i2=args[1]; @@ -37,9 +37,9 @@ static void add_uint64_triplet(char **args, npy_intp *dimensions, for (i = 0; i < n; i++) { - x = (uint64_t*)i1; - y = (uint64_t*)i2; - z = (uint64_t*)op; + x = (npy_uint64*)i1; + y = (npy_uint64*)i2; + z = (npy_uint64*)op; z[0] = x[0] + y[0]; z[1] = x[1] + y[1]; diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c index bea15c65c..7ec5b977f 100644 --- a/numpy/core/src/umath/ufunc_object.c +++ b/numpy/core/src/umath/ufunc_object.c @@ -753,7 +753,7 @@ static int get_ufunc_arguments(PyUFuncObject *ufunc, /* Get input arguments */ for (i = 0; i < nin; ++i) { obj = PyTuple_GET_ITEM(args, i); - + if (PyArray_Check(obj)) { out_op[i] = (PyArrayObject *)PyArray_FromArray(obj,NULL,0); } @@ -1236,10 +1236,10 @@ iterator_loop(PyUFuncObject *ufunc, for (i = 0; i < nin; ++i) { op_flags[i] = NPY_ITER_READONLY | NPY_ITER_ALIGNED; - /* + /* * If READWRITE flag has been set for this operand, * then clear default READONLY flag - */ + */ op_flags[i] |= ufunc->op_flags[i]; if (op_flags[i] & (NPY_ITER_READWRITE | NPY_ITER_WRITEONLY)) { op_flags[i] &= ~NPY_ITER_READONLY; @@ -1541,10 +1541,10 @@ execute_fancy_ufunc_loop(PyUFuncObject *ufunc, op_flags[i] = default_op_in_flags | NPY_ITER_READONLY | NPY_ITER_ALIGNED; - /* + /* * If READWRITE flag has been set for this operand, * then clear default READONLY flag - */ + */ op_flags[i] |= ufunc->op_flags[i]; if (op_flags[i] & (NPY_ITER_READWRITE | NPY_ITER_WRITEONLY)) { op_flags[i] &= ~NPY_ITER_READONLY; @@ -2037,10 +2037,10 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc, op_flags[i] = NPY_ITER_READONLY | NPY_ITER_COPY | NPY_ITER_ALIGNED; - /* + /* * If READWRITE flag has been set for this operand, * then clear default READONLY flag - */ + */ op_flags[i] |= ufunc->op_flags[i]; if (op_flags[i] & (NPY_ITER_READWRITE | NPY_ITER_WRITEONLY)) { op_flags[i] &= ~NPY_ITER_READONLY; @@ -3337,12 +3337,40 @@ PyUFunc_Reduceat(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *ind, op[1] = arr; op[2] = ind; - /* Likewise with accumulate, must do UPDATEIFCOPY */ if (out != NULL || ndim > 1 || !PyArray_ISALIGNED(arr) || !PyArray_EquivTypes(op_dtypes[0], PyArray_DESCR(arr))) { need_outer_iterator = 1; } + /* Special case when the index array's size is zero */ + if (ind_size == 0) { + if (out == NULL) { + npy_intp out_shape[NPY_MAXDIMS]; + memcpy(out_shape, PyArray_SHAPE(arr), + PyArray_NDIM(arr) * NPY_SIZEOF_INTP); + out_shape[axis] = 0; + Py_INCREF(op_dtypes[0]); + op[0] = out = (PyArrayObject *)PyArray_NewFromDescr( + &PyArray_Type, op_dtypes[0], + PyArray_NDIM(arr), out_shape, NULL, NULL, + 0, NULL); + if (out == NULL) { + goto fail; + } + } + else { + /* Allow any zero-sized output array in this case */ + if (PyArray_SIZE(out) != 0) { + PyErr_SetString(PyExc_ValueError, + "output operand shape for reduceat is " + "incompatible with index array of shape (0,)"); + goto fail; + } + } + + goto finish; + } + if (need_outer_iterator) { npy_uint32 flags = NPY_ITER_ZEROSIZE_OK| NPY_ITER_REFS_OK| @@ -3350,7 +3378,8 @@ PyUFunc_Reduceat(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *ind, /* * The way reduceat is set up, we can't do buffering, - * so make a copy instead when necessary. + * so make a copy instead when necessary using + * the UPDATEIFCOPY flag */ /* The per-operand flags for the outer loop */ @@ -4488,7 +4517,7 @@ PyUFunc_RegisterLoopForDescr(PyUFuncObject *ufunc, arg_typenums[i] = user_dtype->type_num; } } - + result = PyUFunc_RegisterLoopForType(ufunc, user_dtype->type_num, function, arg_typenums, data); diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 19806bd76..b7235d05f 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -164,9 +164,17 @@ class TestAttributes(TestCase): y[...] = 1 assert_equal(x,y) + def test_fill_struct_array(self): + # Filling from a scalar x = array([(0,0.0), (1,1.0)], dtype='i4,f8') x.fill(x[0]) assert_equal(x['f1'][1], x['f1'][0]) + # Filling from a tuple that can be converted + # to a scalar + x = np.zeros(2, dtype=[('a', 'f8'), ('b', 'i4')]) + x.fill((3.5, -2)) + assert_array_equal(x['a'], [3.5, 3.5]) + assert_array_equal(x['b'], [-2, -2]) class TestAssignment(TestCase): def test_assignment_broadcasting(self): diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py index c2304a748..b2d47d052 100644 --- a/numpy/core/tests/test_umath.py +++ b/numpy/core/tests/test_umath.py @@ -1263,6 +1263,21 @@ def test_reduceat(): np.setbufsize(np.UFUNC_BUFSIZE_DEFAULT) assert_array_almost_equal(h1, h2) +def test_reduceat_empty(): + """Reduceat should work with empty arrays""" + indices = np.array([], 'i4') + x = np.array([], 'f8') + result = np.add.reduceat(x, indices) + assert_equal(result.dtype, x.dtype) + assert_equal(result.shape, (0,)) + # Another case with a slightly different zero-sized shape + x = np.ones((5,2)) + result = np.add.reduceat(x, [], axis=0) + assert_equal(result.dtype, x.dtype) + assert_equal(result.shape, (0, 2)) + result = np.add.reduceat(x, [], axis=1) + assert_equal(result.dtype, x.dtype) + assert_equal(result.shape, (5, 0)) def test_complex_nan_comparisons(): nans = [complex(np.nan, 0), complex(0, np.nan), complex(np.nan, np.nan)] |