summaryrefslogtreecommitdiff
path: root/numpy/core/src
diff options
context:
space:
mode:
authorTravis Oliphant <oliphant@enthought.com>2007-03-30 23:47:39 +0000
committerTravis Oliphant <oliphant@enthought.com>2007-03-30 23:47:39 +0000
commite784b53e64e22bb4a1a65853505b74d774716cc2 (patch)
treedd60be8f0456741f8cb5d83ca7433521f3e9766c /numpy/core/src
parent72dea1afaeea8deab2fccb599fba2c7f1f811af3 (diff)
downloadnumpy-e784b53e64e22bb4a1a65853505b74d774716cc2.tar.gz
Add tests for clipping. Also some good tests on choose and convert_tocommontype. Fix some mixed-type problems. Fix problems with clipping. More to be done to close ticket #425
Diffstat (limited to 'numpy/core/src')
-rw-r--r--numpy/core/src/arrayobject.c14
-rw-r--r--numpy/core/src/arraytypes.inc.src12
-rw-r--r--numpy/core/src/multiarraymodule.c85
3 files changed, 74 insertions, 37 deletions
diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c
index 5a5747b1f..4de6bd3be 100644
--- a/numpy/core/src/arrayobject.c
+++ b/numpy/core/src/arrayobject.c
@@ -10389,6 +10389,7 @@ PyArray_MultiIterNew(int n, ...)
PyErr_Format(PyExc_ValueError,
"Need between 2 and (%d) " \
"array objects (inclusive).", NPY_MAXARGS);
+ return NULL;
}
/* fprintf(stderr, "multi new...");*/
@@ -11972,6 +11973,17 @@ arrayflags_print(PyArrayFlagsObject *self)
}
+static int
+arrayflags_compare(PyArrayFlagsObject *self, PyArrayFlagsObject *other)
+{
+ if (self->flags == other->flags)
+ return 0;
+ else if (self->flags < other->flags)
+ return -1;
+ else
+ return 1;
+}
+
static PyMappingMethods arrayflags_as_mapping = {
#if PY_VERSION_HEX >= 0x02050000
(lenfunc)NULL, /*mp_length*/
@@ -12009,7 +12021,7 @@ static PyTypeObject PyArrayFlags_Type = {
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
- 0, /* tp_compare */
+ (cmpfunc)arrayflags_compare, /* tp_compare */
(reprfunc)arrayflags_print, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
diff --git a/numpy/core/src/arraytypes.inc.src b/numpy/core/src/arraytypes.inc.src
index 4872a73ca..1e32e1361 100644
--- a/numpy/core/src/arraytypes.inc.src
+++ b/numpy/core/src/arraytypes.inc.src
@@ -2069,7 +2069,7 @@ static void
@type@ max_val, min_val;
max_val = *max;
- min_val = *min;
+ min_val = *min;
for (i = 0; i < ni; i++) {
if (in[i] < min_val) {
@@ -2093,14 +2093,14 @@ static void
register npy_intp i;
@type@ max_val, min_val;
- max_val = *max;
min_val = *min;
-
+ max_val = *max;
+
for (i = 0; i < ni; i++) {
- if (PyArray_CLT(in[i], max_val)) {
- out[i] = max_val;
+ if (PyArray_CLT(in[i], min_val)) {
+ out[i] = min_val;
} else if (PyArray_CGT(in[i], max_val)) {
- out[i] = max_val;
+ out[i] = max_val;
}
}
return;
diff --git a/numpy/core/src/multiarraymodule.c b/numpy/core/src/multiarraymodule.c
index c4f48ff60..2b826ec1e 100644
--- a/numpy/core/src/multiarraymodule.c
+++ b/numpy/core/src/multiarraymodule.c
@@ -1145,7 +1145,7 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o
PyArrayObject *maxa=NULL;
PyArrayObject *mina=NULL;
PyArrayObject *newout=NULL, *newin=NULL;
- PyArray_Descr *indescr;
+ PyArray_Descr *indescr, *newdescr;
PyObject *zero;
func = self->descr->f->fastclip;
@@ -1155,20 +1155,40 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o
/* Use the fast scalar clip function */
- if (PyArray_ISNOTSWAPPED(self)) {
- indescr = PyArray_DescrNewByteorder(self->descr, '=');
- if (indescr == NULL) goto fail;
+ /* First we need to figure out the correct type */
+ indescr = PyArray_DescrFromObject(min, NULL);
+ if (indescr == NULL) return NULL;
+ newdescr = PyArray_DescrFromObject(max, indescr);
+ Py_DECREF(indescr);
+
+ if (newdescr == NULL) return NULL;
+ /* Use the scalar descriptor only if it is of a bigger
+ KIND than the input array (and then find the
+ type that matches both).
+ */
+ if (PyArray_ScalarKind(newdescr->type_num, NULL) >
+ PyArray_ScalarKind(self->descr->type_num, NULL)) {
+ indescr = _array_small_type(newdescr, self->descr);
+ func = indescr->f->fastclip;
}
- else {
+ else {
indescr = self->descr;
Py_INCREF(indescr);
}
+ Py_DECREF(newdescr);
+
+ if (!PyDataType_ISNOTSWAPPED(indescr)) {
+ PyArray_Descr *descr2;
+ descr2 = PyArray_DescrNewByteorder(indescr, '=');
+ Py_DECREF(indescr);
+ if (descr2 == NULL) goto fail;
+ indescr = descr2;
+ }
/* Convert max to an array */
maxa = (NPY_AO *)PyArray_FromAny(max, indescr, 0, 0,
NPY_DEFAULT, NULL);
if (maxa == NULL) return NULL;
- Py_INCREF(indescr);
/* If we are unsigned, then make sure min is not <0 */
@@ -1197,6 +1217,7 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o
}
/* Convert min to an array */
+ Py_INCREF(indescr);
mina = (NPY_AO *)PyArray_FromAny(min, indescr, 0, 0,
NPY_DEFAULT, NULL);
Py_DECREF(min);
@@ -1206,7 +1227,7 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o
/* Check to see if input is single-segment, aligned,
and in native byteorder */
if (PyArray_ISONESEGMENT(self) && PyArray_CHKFLAGS(self, ALIGNED) &&
- PyArray_ISNOTSWAPPED(self))
+ PyArray_ISNOTSWAPPED(self) && (self->descr == indescr))
ingood = 1;
if (!ingood) {
@@ -1223,8 +1244,10 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o
}
/* At this point, newin is a single-segment, aligned, and correct
- byte-order array if ingood == 0, then it is a copy, otherwise,
- it is the input
+ byte-order array of the correct type
+
+ if ingood == 0, then it is a copy, otherwise,
+ it is the original input.
*/
/* If we have already made a copy of the data, then use
@@ -1254,8 +1277,8 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o
outgood = 1;
}
if (!outgood && PyArray_ISONESEGMENT(out) &&
- PyArray_CHKFLAGS(out, ALIGNED) &&
- PyArray_ISNOTSWAPPED(out)) {
+ PyArray_CHKFLAGS(out, ALIGNED) && PyArray_ISNOTSWAPPED(out) &&
+ PyArray_EquivTypes(out->descr, indescr)) {
outgood = 1;
}
@@ -1263,20 +1286,12 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o
/* Create one, now */
if (!outgood) {
int oflags;
- PyArray_Descr *odescr;
if (PyArray_ISFORTRAN(out))
- oflags = NPY_FARRAY | NPY_UPDATEIFCOPY;
+ oflags = NPY_FARRAY;
else
- oflags = NPY_CARRAY | NPY_UPDATEIFCOPY;
- if (PyArray_ISNOTSWAPPED(out)) {
- odescr = PyArray_DescrNewByteorder(out->descr, '=');
- if (odescr == NULL) goto fail;
- }
- else {
- odescr = out->descr;
- Py_INCREF(odescr);
- }
- newout = (NPY_AO*)PyArray_FromArray(out, odescr, oflags);
+ oflags = NPY_CARRAY;
+ oflags |= NPY_UPDATEIFCOPY | NPY_FORCECAST;
+ newout = (NPY_AO*)PyArray_FromArray(out, indescr, oflags);
if (newout == NULL) goto fail;
}
else {
@@ -1284,6 +1299,13 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o
Py_INCREF(newout);
}
+ /* make sure the shape of the output array is the same */
+ if (!PyArray_SAMESHAPE(newin, newout)) {
+ PyErr_SetString(PyExc_ValueError, "clip: Output array must have the"
+ "same shape as the input.");
+ goto fail;
+ }
+
if (newout->data != newin->data) {
memcpy(newout->data, newin->data, PyArray_NBYTES(newin));
}
@@ -1305,6 +1327,7 @@ PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *o
Py_XDECREF(maxa);
Py_XDECREF(mina);
Py_XDECREF(newin);
+ PyArray_XDECREF_ERR(newout);
return NULL;
}
@@ -2130,19 +2153,21 @@ PyArray_ConvertToCommonType(PyObject *op, int *retn)
handles both intype and stype
and don't forcecast the scalars.
*/
-
+
if (!PyArray_CanCoerceScalar(stype->type_num,
intype->type_num,
scalarkind)) {
+ newtype = _array_small_type(intype, stype);
Py_XDECREF(intype);
- intype = stype;
- Py_INCREF(stype);
+ intype = newtype;
}
for (i=0; i<n; i++) {
Py_XDECREF(mps[i]);
mps[i] = NULL;
}
}
+
+
/* Make sure all arrays are actual array objects. */
for(i=0; i<n; i++) {
int flags = CARRAY;
@@ -2217,25 +2242,23 @@ PyArray_Choose(PyArrayObject *ip, PyObject *op, PyArrayObject *ret,
sizes[i] = PyArray_NBYTES(mps[i]);
}
- Py_INCREF(mps[0]->descr);
if (!ret) {
+ Py_INCREF(mps[0]->descr);
ret = (PyArrayObject *)PyArray_NewFromDescr(ap->ob_type,
mps[0]->descr,
ap->nd,
ap->dimensions,
NULL, NULL, 0,
(PyObject *)ap);
- if (ret == NULL) goto fail;
}
else {
PyArrayObject *obj;
- int flags = NPY_CARRAY | NPY_UPDATEIFCOPY;
+ int flags = NPY_CARRAY | NPY_UPDATEIFCOPY | NPY_FORCECAST;
if (PyArray_SIZE(ret) != PyArray_SIZE(ap)) {
PyErr_SetString(PyExc_TypeError,
"invalid shape for output array.");
ret = NULL;
- Py_DECREF(mps[0]->descr);
goto fail;
}
if (clipmode == NPY_RAISE) {
@@ -2245,12 +2268,14 @@ PyArray_Choose(PyArrayObject *ip, PyObject *op, PyArrayObject *ret,
*/
flags |= NPY_ENSURECOPY;
}
+ Py_INCREF(mps[0]->descr);
obj = (PyArrayObject *)PyArray_FromArray(ret, mps[0]->descr,
flags);
if (obj != ret) copyret = 1;
ret = obj;
}
+ if (ret == NULL) goto fail;
elsize = ret->descr->elsize;
m = PyArray_SIZE(ret);
self_data = (intp *)ap->data;