summaryrefslogtreecommitdiff
path: root/numpy/core/src
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/core/src')
-rw-r--r--numpy/core/src/arraymethods.c100
-rw-r--r--numpy/core/src/arrayobject.c11
-rw-r--r--numpy/core/src/multiarraymodule.c131
-rw-r--r--numpy/core/src/scalartypes.inc.src9
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, &copy,
- 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,