diff options
Diffstat (limited to 'numpy/core/src')
-rw-r--r-- | numpy/core/src/arraymethods.c | 100 | ||||
-rw-r--r-- | numpy/core/src/arrayobject.c | 11 | ||||
-rw-r--r-- | numpy/core/src/multiarraymodule.c | 131 | ||||
-rw-r--r-- | numpy/core/src/scalartypes.inc.src | 9 |
4 files changed, 158 insertions, 93 deletions
diff --git a/numpy/core/src/arraymethods.c b/numpy/core/src/arraymethods.c index 8c5edc9c2..9c1715678 100644 --- a/numpy/core/src/arraymethods.c +++ b/numpy/core/src/arraymethods.c @@ -67,36 +67,28 @@ array_putmask(PyArrayObject *self, PyObject *args, PyObject *kwds) return PyArray_PutMask(self, values, mask); } -/* Used to reshape a Fortran Array */ -static void -_reverse_shape(PyArray_Dims *newshape) -{ - int i, n = newshape->len; - intp *ptr = newshape->ptr; - intp *eptr; - intp tmp; - int len = n >> 1; - - eptr = ptr+n-1; - for(i=0; i<len; i++) { - tmp = *eptr; - *eptr-- = *ptr; - *ptr++ = tmp; - } -} - static char doc_reshape[] = \ - "self.reshape(d1, d2, ..., dn) Return a new array from this one. \n" \ - "\n The new array must have the same number of elements as self. "\ + "self.reshape(d1, d2, ..., dn, fortran=False) \n" \ + "Return a new array from this one. \n" \ + "\n The new array must have the same number of elements as self. " \ "Also\n a copy of the data only occurs if necessary."; static PyObject * -array_reshape(PyArrayObject *self, PyObject *args) +array_reshape(PyArrayObject *self, PyObject *args, PyObject *kwds) { PyArray_Dims newshape; - PyObject *ret, *tmp; + PyObject *ret; + PyArray_CONDITION fortran=PyArray_FALSE; int n; + if (kwds != NULL) { + PyObject *ref; + ref = PyDict_GetItemString(kwds, "fortran"); + if (ref == NULL || \ + (PyArray_ConditionConverter(ref, &fortran) == PY_FAIL)) + return NULL; + } + n = PyTuple_Size(args); if (n <= 1) { if (!PyArg_ParseTuple(args, "O&", PyArray_IntpConverter, @@ -116,30 +108,11 @@ array_reshape(PyArrayObject *self, PyObject *args) PyDimMem_FREE(newshape.ptr); return PyArray_Ravel(self, 0); } + + ret = PyArray_Newshape(self, &newshape, fortran); - if ((newshape.len == 0) || PyArray_ISCONTIGUOUS(self)) { - ret = PyArray_Newshape(self, &newshape); - } - else if PyArray_ISFORTRAN(self) { - tmp = PyArray_Transpose(self, NULL); - if (tmp == NULL) goto fail; - _reverse_shape(&newshape); - ret = PyArray_Newshape((PyArrayObject *)tmp, &newshape); - Py_DECREF(tmp); - if (ret == NULL) goto fail; - tmp = PyArray_Transpose((PyArrayObject *)ret, NULL); - Py_DECREF(ret); - if (tmp == NULL) goto fail; - ret = tmp; - } - else { - tmp = PyArray_Copy(self); - if (tmp==NULL) goto fail; - ret = PyArray_Newshape((PyArrayObject *)tmp, &newshape); - Py_DECREF(tmp); - } PyDimMem_FREE(newshape.ptr); - return _ARET(ret); + return ret; fail: PyDimMem_FREE(newshape.ptr); @@ -642,21 +615,22 @@ array_getarray(PyArrayObject *self, PyObject *args) } static char doc_copy[] = "m.copy(|fortran). Return a copy of the array.\n"\ - "If fortran == 0 then the result is contiguous (default). \n"\ - "If fortran > 0 then the result has fortran data order. \n"\ - "If fortran < 0 then the result has fortran data order only if m\n" + "If fortran is false then the result is contiguous (default). \n"\ + "If fortran is true then the result has fortran data order. \n"\ + "If fortran is None then the result has fortran data order only if m\n" " is already in fortran order."; static PyObject * array_copy(PyArrayObject *self, PyObject *args) { - int fortran=0; - if (!PyArg_ParseTuple(args, "|i", &fortran)) return NULL; + PyArray_CONDITION fortran=PyArray_FALSE; + if (!PyArg_ParseTuple(args, "|O&", PyArray_ConditionConverter, + &fortran)) return NULL; return PyArray_NewCopy(self, fortran); } -static char doc_resize[] = "self.resize(new_shape, refcheck=True). "\ +static char doc_resize[] = "self.resize(new_shape, refcheck=True, fortran=False). "\ "Change size and shape of self inplace.\n"\ "\n Array must own its own memory and not be referenced by other " \ "arrays\n Returns None."; @@ -668,6 +642,7 @@ array_resize(PyArrayObject *self, PyObject *args, PyObject *kwds) PyObject *ret; int n; int refcheck = 1; + PyArray_CONDITION fortran=PyArray_DONTCARE; if (kwds != NULL) { PyObject *ref; @@ -678,6 +653,10 @@ array_resize(PyArrayObject *self, PyObject *args, PyObject *kwds) return NULL; } } + ref = PyDict_GetItemString(kwds, "fortran"); + if (ref != NULL || + (PyArray_ConditionConverter(ref, &fortran) == PY_FAIL)) + return NULL; } n = PyTuple_Size(args); if (n <= 1) { @@ -692,9 +671,8 @@ array_resize(PyArrayObject *self, PyObject *args, PyObject *kwds) } return NULL; } - } - - ret = PyArray_Resize(self, &newshape, refcheck); + } + ret = PyArray_Resize(self, &newshape, refcheck, fortran); PyDimMem_FREE(newshape.ptr); if (ret == NULL) return NULL; Py_DECREF(ret); @@ -1465,11 +1443,12 @@ static char doc_flatten[] = "a.flatten([fortran]) return a 1-d array (always cop static PyObject * array_flatten(PyArrayObject *self, PyObject *args) { - int fortran=0; + PyArray_CONDITION fortran=PyArray_FALSE; - if (!PyArg_ParseTuple(args, "|i", &fortran)) return NULL; + if (!PyArg_ParseTuple(args, "|O&", PyArray_ConditionConverter, + &fortran)) return NULL; - return PyArray_Flatten(self, (int) fortran); + return PyArray_Flatten(self, fortran); } static char doc_ravel[] = "a.ravel([fortran]) return a 1-d array (copy only if needed)"; @@ -1477,9 +1456,10 @@ static char doc_ravel[] = "a.ravel([fortran]) return a 1-d array (copy only if n static PyObject * array_ravel(PyArrayObject *self, PyObject *args) { - int fortran=0; - - if (!PyArg_ParseTuple(args, "|i", &fortran)) return NULL; + PyArray_CONDITION fortran=PyArray_FALSE; + + if (!PyArg_ParseTuple(args, "|O&", PyArray_ConditionConverter, + &fortran)) return NULL; return PyArray_Ravel(self, fortran); } @@ -1642,7 +1622,7 @@ static PyMethodDef array_methods[] = { {"argmin", (PyCFunction)array_argmin, METH_VARARGS|METH_KEYWORDS, doc_argmin}, {"reshape", (PyCFunction)array_reshape, - METH_VARARGS, doc_reshape}, + METH_VARARGS|METH_KEYWORDS, doc_reshape}, {"squeeze", (PyCFunction)array_squeeze, METH_VARARGS, doc_squeeze}, {"view", (PyCFunction)array_view, diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index cf14b350e..306cfeae7 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -801,10 +801,11 @@ PyArray_FromDims(int nd, int *d, int type) Copy an array. */ static PyObject * -PyArray_NewCopy(PyArrayObject *m1, int fortran) +PyArray_NewCopy(PyArrayObject *m1, PyArray_CONDITION fortran) { PyArrayObject *ret; - if (fortran < 0) fortran = PyArray_ISFORTRAN(m1); + if (fortran == PyArray_DONTCARE) + fortran = PyArray_ISFORTRAN(m1); Py_INCREF(m1->descr); ret = (PyArrayObject *)PyArray_NewFromDescr(m1->ob_type, @@ -4098,7 +4099,8 @@ PyArray_NewFromDescr(PyTypeObject *subtype, PyArray_Descr *descr, int nd, object. */ static PyObject * -PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int refcheck) +PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int refcheck, + PyArray_CONDITION fortran) { intp oldsize, newsize; int new_nd=newshape->len, k, n, elsize; @@ -4115,6 +4117,9 @@ PyArray_Resize(PyArrayObject *self, PyArray_Dims *newshape, int refcheck) return NULL; } + if (fortran == PyArray_DONTCARE) + fortran = PyArray_FALSE; + newsize = PyArray_MultiplyList(new_dimensions, new_nd); oldsize = PyArray_SIZE(self); diff --git a/numpy/core/src/multiarraymodule.c b/numpy/core/src/multiarraymodule.c index dd65437a7..4e9f774ee 100644 --- a/numpy/core/src/multiarraymodule.c +++ b/numpy/core/src/multiarraymodule.c @@ -175,20 +175,21 @@ PyArray_View(PyArrayObject *self, PyArray_Descr *type, PyTypeObject *pytype) Ravel */ static PyObject * -PyArray_Ravel(PyArrayObject *a, int fortran) +PyArray_Ravel(PyArrayObject *a, PyArray_CONDITION fortran) { PyArray_Dims newdim = {NULL,1}; intp val[1] = {-1}; - if (fortran < 0) fortran = PyArray_ISFORTRAN(a); - + if (fortran == PyArray_DONTCARE) + fortran = PyArray_ISFORTRAN(a); + newdim.ptr = val; if (!fortran && PyArray_ISCONTIGUOUS(a)) { if (a->nd == 1) { Py_INCREF(a); return (PyObject *)a; } - return PyArray_Newshape(a, &newdim); + return PyArray_Newshape(a, &newdim, PyArray_FALSE); } else return PyArray_Flatten(a, fortran); @@ -312,12 +313,13 @@ PyArray_Round(PyArrayObject *a, int decimals) Flatten */ static PyObject * -PyArray_Flatten(PyArrayObject *a, int fortran) +PyArray_Flatten(PyArrayObject *a, PyArray_CONDITION fortran) { PyObject *ret, *new; intp size; - if (fortran < 0) fortran = PyArray_ISFORTRAN(a); + if (fortran == PyArray_DONTCARE) + fortran = PyArray_ISFORTRAN(a); size = PyArray_SIZE(a); Py_INCREF(a->descr); @@ -364,7 +366,7 @@ PyArray_Reshape(PyArrayObject *self, PyObject *shape) PyArray_Dims newdims; if (!PyArray_IntpConverter(shape, &newdims)) return NULL; - ret = PyArray_Newshape(self, &newdims); + ret = PyArray_Newshape(self, &newdims, PyArray_FALSE); PyDimMem_FREE(newdims.ptr); return ret; } @@ -400,14 +402,11 @@ _check_ones(PyArrayObject *self, int newnd, intp* newdims, intp *strides) /* Returns a new array with the new shape from the data - in the old array + in the old array --- uses C-contiguous perspective. */ -/*MULTIARRAY_API - New shape for an array -*/ static PyObject * -PyArray_Newshape(PyArrayObject *self, PyArray_Dims *newdims) +_old_newshape(PyArrayObject *self, PyArray_Dims *newdims) { intp i, s_original, i_unknown, s_known; intp *dimensions = newdims->ptr; @@ -496,6 +495,63 @@ PyArray_Newshape(PyArrayObject *self, PyArray_Dims *newdims) return (PyObject *)ret; } +/* Used to reshape a Fortran Array */ +static void +_reverse_shape(PyArray_Dims *newshape) +{ + int i, n = newshape->len; + intp *ptr = newshape->ptr; + intp *eptr; + intp tmp; + int len = n >> 1; + + eptr = ptr+n-1; + for(i=0; i<len; i++) { + tmp = *eptr; + *eptr-- = *ptr; + *ptr++ = tmp; + } +} + + +/*MULTIARRAY_API + New shape for an array +*/ +static PyObject * +PyArray_Newshape(PyArrayObject *self, PyArray_Dims *newshape, + PyArray_CONDITION fortran) +{ + PyObject *tmp, *ret; + + if (fortran == PyArray_DONTCARE) + fortran = PyArray_ISFORTRAN(self); + + if ((newshape->len == 0) || (PyArray_ISCONTIGUOUS(self) && \ + (fortran != PyArray_TRUE))) { + ret = _old_newshape(self, newshape); + } + else if ((fortran == PyArray_TRUE) && PyArray_ISFORTRAN(self)) { + tmp = PyArray_Transpose(self, NULL); + if (tmp == NULL) return NULL; + _reverse_shape(newshape); + ret = _old_newshape((PyArrayObject *)tmp, newshape); + Py_DECREF(tmp); + if (ret == NULL) return NULL; + tmp = PyArray_Transpose((PyArrayObject *)ret, NULL); + Py_DECREF(ret); + if (tmp == NULL) return NULL; + ret = tmp; + } + else { + tmp = PyArray_Copy(self); + if (tmp==NULL) return NULL; + ret = _old_newshape((PyArrayObject *)tmp, newshape); + Py_DECREF(tmp); + } + + return ret; +} + /* return a new view of the array object with all of its unit-length dimensions squeezed out if needed, otherwise return the same array. @@ -3244,14 +3300,32 @@ PyArray_Converter(PyObject *object, PyObject **address) static int PyArray_BoolConverter(PyObject *object, Bool *val) { - if (PyObject_IsTrue(object)) - *val=TRUE; - else *val=FALSE; - if (PyErr_Occurred()) - return PY_FAIL; - return PY_SUCCEED; + if (PyObject_IsTrue(object)) + *val=TRUE; + else *val=FALSE; + if (PyErr_Occurred()) + return PY_FAIL; + return PY_SUCCEED; } +/*MULTIARRAY_API + Convert an object to true / false +*/ +static int +PyArray_ConditionConverter(PyObject *object, PyArray_CONDITION *val) +{ + + if (object == Py_None) + *val = PyArray_DONTCARE; + else if (PyObject_IsTrue(object)) + *val=PyArray_TRUE; + else *val=PyArray_FALSE; + if (PyErr_Occurred()) + return PY_FAIL; + return PY_SUCCEED; +} + + /*MULTIARRAY_API Typestr converter @@ -4370,14 +4444,14 @@ _array_fromobject(PyObject *ignored, PyObject *args, PyObject *kws) int ndmin=0, nd; PyArray_Descr *type=NULL; PyArray_Descr *oldtype=NULL; - Bool fortran=FALSE; + PyArray_CONDITION fortran=PyArray_DONTCARE; int flags=0; if(!PyArg_ParseTupleAndKeywords(args, kws, "O|O&O&O&O&i", kwd, &op, PyArray_DescrConverter2, &type, PyArray_BoolConverter, ©, - PyArray_BoolConverter, &fortran, + PyArray_ConditionConverter, &fortran, PyArray_BoolConverter, &subok, &ndmin)) return NULL; @@ -4385,7 +4459,8 @@ _array_fromobject(PyObject *ignored, PyObject *args, PyObject *kws) /* fast exit if simple call */ if (PyArray_CheckExact(op)) { if (type==NULL) { - if (!copy && fortran==PyArray_ISFORTRAN(op)) { + if (!copy && (fortran == PyArray_DONTCARE \ + || fortran==PyArray_ISFORTRAN(op))) { Py_INCREF(op); ret = op; goto finish; @@ -4399,7 +4474,8 @@ _array_fromobject(PyObject *ignored, PyObject *args, PyObject *kws) /* One more chance */ oldtype = PyArray_DESCR(op); if (PyArray_EquivTypes(oldtype, type)) { - if (!copy && fortran==PyArray_ISFORTRAN(op)) { + if (!copy && (fortran == PyArray_DONTCARE || \ + fortran==PyArray_ISFORTRAN(op))) { Py_INCREF(op); ret = op; goto finish; @@ -4419,10 +4495,12 @@ _array_fromobject(PyObject *ignored, PyObject *args, PyObject *kws) if (copy) { flags = ENSURECOPY; } - if (fortran) { + if (fortran!=PyArray_FALSE && \ + ((fortran == PyArray_TRUE) || + (PyArray_Check(op) && PyArray_ISFORTRAN(op)))) { flags |= FORTRAN; } - if (!subok) { + if (!subok) { flags |= ENSUREARRAY; } @@ -5421,8 +5499,9 @@ array_arange(PyObject *ignored, PyObject *args, PyObject *kws) { return PyArray_ArangeObj(o_start, o_stop, o_step, typecode); } -/*MULTIARRAY_API - GetNDArrayCVersion +/* +Included at the very first so not auto-grabbed and thus not +labeled. */ static unsigned int PyArray_GetNDArrayCVersion(void) diff --git a/numpy/core/src/scalartypes.inc.src b/numpy/core/src/scalartypes.inc.src index fc253e420..aaa67de0f 100644 --- a/numpy/core/src/scalartypes.inc.src +++ b/numpy/core/src/scalartypes.inc.src @@ -952,7 +952,7 @@ gentype_wraparray(PyObject *scalar, PyObject *args) /**begin repeat -#name=tolist, item, tostring, astype, copy, __deepcopy__, choose, searchsorted, reshape, view, swapaxes, conj, conjugate, nonzero, flatten, ravel, fill, transpose, newbyteorder# +#name=tolist, item, tostring, astype, copy, __deepcopy__, choose, searchsorted, view, swapaxes, conj, conjugate, nonzero, flatten, ravel, fill, transpose, newbyteorder# */ static PyObject * @@ -1011,7 +1011,7 @@ gentype_byteswap(PyObject *self, PyObject *args) /**begin repeat -#name=take, getfield, put, putmask, repeat, tofile, mean, trace, diagonal, clip, std, var, sum, cumsum, prod, cumprod, compress, sort, argsort, round, argmax, argmin, max, min, ptp, any, all, resize# +#name=take, getfield, put, putmask, repeat, tofile, mean, trace, diagonal, clip, std, var, sum, cumsum, prod, cumprod, compress, sort, argsort, round, argmax, argmin, max, min, ptp, any, all, resize, reshape# */ static PyObject * @@ -1186,7 +1186,8 @@ static PyMethodDef gentype_methods[] = { {"setfield", (PyCFunction)gentype_setfield, METH_VARARGS | METH_KEYWORDS, NULL}, {"copy", (PyCFunction)gentype_copy, 1, NULL}, - {"resize", (PyCFunction)gentype_resize, 1, NULL}, + {"resize", (PyCFunction)gentype_resize, + METH_VARARGS|METH_KEYWORDS, NULL}, {"__array__", (PyCFunction)gentype_getarray, 1, doc_getarray}, {"__array_wrap__", (PyCFunction)gentype_wraparray, 1, doc_sc_wraparray}, @@ -1229,7 +1230,7 @@ static PyMethodDef gentype_methods[] = { {"argmin", (PyCFunction)gentype_argmin, METH_VARARGS|METH_KEYWORDS, NULL}, {"reshape", (PyCFunction)gentype_reshape, - METH_VARARGS, NULL}, + METH_VARARGS|METH_KEYWORDS, NULL}, {"squeeze", (PyCFunction)gentype_squeeze, METH_VARARGS, NULL}, {"view", (PyCFunction)gentype_view, |