diff options
author | Stefan van der Walt <sjvdwalt@gmail.com> | 2012-11-06 17:00:07 -0800 |
---|---|---|
committer | Stefan van der Walt <sjvdwalt@gmail.com> | 2012-11-06 17:00:07 -0800 |
commit | 93be7c0ca93735faac3c9b03b6844a4f9ed90d71 (patch) | |
tree | 519002533ffee8c930e0bd8354633991796fb633 /numpy | |
parent | 526b7647ad3e0c295340e7b85593364eeadc5686 (diff) | |
parent | 0d275f114e49ef5f9569832be2743aa85c4bb4e1 (diff) | |
download | numpy-93be7c0ca93735faac3c9b03b6844a4f9ed90d71.tar.gz |
Merge pull request #2702 from seberg/issue2700
BUG: Reshape of 0-sized arrays failed to work without copy.
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/src/multiarray/shape.c | 136 | ||||
-rw-r--r-- | numpy/core/tests/test_regression.py | 5 |
2 files changed, 46 insertions, 95 deletions
diff --git a/numpy/core/src/multiarray/shape.c b/numpy/core/src/multiarray/shape.c index 6da07e4cd..482166598 100644 --- a/numpy/core/src/multiarray/shape.c +++ b/numpy/core/src/multiarray/shape.c @@ -18,10 +18,6 @@ #include "shape.h" static int -_check_ones(PyArrayObject *self, int newnd, - npy_intp* newdims, npy_intp *strides); - -static int _fix_unknown_dimension(PyArray_Dims *newshape, npy_intp s_original); static int @@ -187,6 +183,11 @@ PyArray_Newshape(PyArrayObject *self, PyArray_Dims *newdims, if (order == NPY_ANYORDER) { order = PyArray_ISFORTRAN(self); } + else if (order == NPY_KEEPORDER) { + PyErr_SetString(PyExc_ValueError, + "order 'K' is not permitted for reshaping"); + return NULL; + } /* Quick check to make sure anything actually needs to be done */ if (ndim == PyArray_NDIM(self)) { same = NPY_TRUE; @@ -203,68 +204,48 @@ PyArray_Newshape(PyArrayObject *self, PyArray_Dims *newdims, } /* - * Returns a pointer to an appropriate strides array - * if all we are doing is inserting ones into the shape, - * or removing ones from the shape - * or doing a combination of the two - * In this case we don't need to do anything but update strides and - * dimensions. So, we can handle non single-segment cases. + * fix any -1 dimensions and check new-dimensions against old size */ - i = _check_ones(self, ndim, dimensions, newstrides); - if (i == 0) { - strides = newstrides; + if (_fix_unknown_dimension(newdims, PyArray_SIZE(self)) < 0) { + return NULL; } - flags = PyArray_FLAGS(self); - - if (strides == NULL) { - /* - * we are really re-shaping not just adding ones to the shape somewhere - * fix any -1 dimensions and check new-dimensions against old size - */ - if (_fix_unknown_dimension(newdims, PyArray_SIZE(self)) < 0) { - return NULL; + /* + * sometimes we have to create a new copy of the array + * in order to get the right orientation and + * because we can't just re-use the buffer with the + * data in the order it is in. + */ + if ((order == NPY_CORDER && !PyArray_IS_C_CONTIGUOUS(self)) || + (order == NPY_FORTRANORDER && !PyArray_IS_F_CONTIGUOUS(self))) { + int success = 0; + success = _attempt_nocopy_reshape(self, ndim, dimensions, + newstrides, order); + if (success) { + /* no need to copy the array after all */ + strides = newstrides; } - /* - * sometimes we have to create a new copy of the array - * in order to get the right orientation and - * because we can't just re-use the buffer with the - * data in the order it is in. - */ - if (!(PyArray_ISONESEGMENT(self)) || - (((PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS) && - order == NPY_FORTRANORDER) || - (PyArray_CHKFLAGS(self, NPY_ARRAY_F_CONTIGUOUS) && - order == NPY_CORDER)) && (PyArray_NDIM(self) > 1))) { - int success = 0; - success = _attempt_nocopy_reshape(self, ndim, dimensions, - newstrides, order); - if (success) { - /* no need to copy the array after all */ - strides = newstrides; - } - else { - PyObject *newcopy; - newcopy = PyArray_NewCopy(self, order); - if (newcopy == NULL) { - return NULL; - } - incref = NPY_FALSE; - self = (PyArrayObject *)newcopy; + else { + PyObject *newcopy; + newcopy = PyArray_NewCopy(self, order); + if (newcopy == NULL) { + return NULL; } + incref = NPY_FALSE; + self = (PyArrayObject *)newcopy; } + } + /* We always have to interpret the contiguous buffer correctly */ - /* We always have to interpret the contiguous buffer correctly */ - - /* Make sure the flags argument is set. */ - if (ndim > 1) { - if (order == NPY_FORTRANORDER) { - flags &= ~NPY_ARRAY_C_CONTIGUOUS; - flags |= NPY_ARRAY_F_CONTIGUOUS; - } - else { - flags &= ~NPY_ARRAY_F_CONTIGUOUS; - flags |= NPY_ARRAY_C_CONTIGUOUS; - } + /* Make sure the flags argument is set. */ + flags = PyArray_FLAGS(self); + if (ndim > 1) { + if (order == NPY_FORTRANORDER) { + flags &= ~NPY_ARRAY_C_CONTIGUOUS; + flags |= NPY_ARRAY_F_CONTIGUOUS; + } + else { + flags &= ~NPY_ARRAY_F_CONTIGUOUS; + flags |= NPY_ARRAY_C_CONTIGUOUS; } } @@ -319,41 +300,6 @@ PyArray_Reshape(PyArrayObject *self, PyObject *shape) return ret; } -/* inserts 0 for strides where dimension will be 1 */ -static int -_check_ones(PyArrayObject *self, int newnd, - npy_intp* newdims, npy_intp *strides) -{ - int nd; - npy_intp *dims; - npy_bool done=NPY_FALSE; - int j, k; - - nd = PyArray_NDIM(self); - dims = PyArray_DIMS(self); - - for (k = 0, j = 0; !done && (j < nd || k < newnd);) { - if ((j<nd) && (k<newnd) && (newdims[k] == dims[j])) { - strides[k] = PyArray_STRIDES(self)[j]; - j++; - k++; - } - else if ((k < newnd) && (newdims[k] == 1)) { - strides[k] = 0; - k++; - } - else if ((j<nd) && (dims[j] == 1)) { - j++; - } - else { - done = NPY_TRUE; - } - } - if (done) { - return -1; - } - return 0; -} static void _putzero(char *optr, PyObject *zero, PyArray_Descr *dtype) diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index f46a7ddcf..0f268fce8 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -521,6 +521,11 @@ class TestRegression(TestCase): a = np.lib.stride_tricks.as_strided(a, shape=(5,), strides=(0,)) assert_(a.reshape(5,1).strides[0] == 0) + def test_reshape_zero_size(self, level=rlevel): + """Github Issue #2700, setting shape failed for 0-sized arrays""" + a = np.ones((0,2)) + a.shape = (-1,2) + def test_repeat_discont(self, level=rlevel): """Ticket #352""" a = np.arange(12).reshape(4,3)[:,2] |