summaryrefslogtreecommitdiff
path: root/numpy/core/src/multiarraymodule.c
diff options
context:
space:
mode:
authorTravis Oliphant <oliphant@enthought.com>2006-03-21 05:21:43 +0000
committerTravis Oliphant <oliphant@enthought.com>2006-03-21 05:21:43 +0000
commitcdbcee59fbe407dcfa3a81fc18f95eca4e8ec6c4 (patch)
treeeb824394b6eeb3f6f02cebc63ad17a36828c2dae /numpy/core/src/multiarraymodule.c
parentcd5f36dc87fd462bc0391a3f7e13036bf1ad3c40 (diff)
downloadnumpy-cdbcee59fbe407dcfa3a81fc18f95eca4e8ec6c4.tar.gz
Fix reshape to always interpret as C-contiguous unless fortran=True is given or fortran=None and array is already fortran array.
Diffstat (limited to 'numpy/core/src/multiarraymodule.c')
-rw-r--r--numpy/core/src/multiarraymodule.c131
1 files changed, 105 insertions, 26 deletions
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)