summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/code_generators/cversions.py4
-rw-r--r--numpy/core/code_generators/cversions.txt2
-rw-r--r--numpy/core/code_generators/numpy_api.py3
-rw-r--r--numpy/core/fromnumeric.py2
-rw-r--r--numpy/core/setup_common.py5
-rw-r--r--numpy/core/src/multiarray/convert.c9
-rw-r--r--numpy/core/src/umath/struct_ufunc_test.c.src8
-rw-r--r--numpy/core/src/umath/ufunc_object.c49
-rw-r--r--numpy/core/tests/test_multiarray.py8
-rw-r--r--numpy/core/tests/test_umath.py15
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)]