[Numpy-svn] r3616 - in trunk/numpy/core: include/numpy src

numpy-svn@scip... numpy-svn@scip...
Fri Mar 30 00:10:17 CDT 2007


Author: oliphant
Date: 2007-03-30 00:09:53 -0500 (Fri, 30 Mar 2007)
New Revision: 3616

Modified:
   trunk/numpy/core/include/numpy/ndarrayobject.h
   trunk/numpy/core/src/arrayobject.c
   trunk/numpy/core/src/arraytypes.inc.src
   trunk/numpy/core/src/multiarraymodule.c
Log:
Make a fastclip function (adapted from ticket #425 and fix conjugate method to use ufunc when complex matrix

Modified: trunk/numpy/core/include/numpy/ndarrayobject.h
===================================================================
--- trunk/numpy/core/include/numpy/ndarrayobject.h	2007-03-29 21:37:58 UTC (rev 3615)
+++ trunk/numpy/core/include/numpy/ndarrayobject.h	2007-03-30 05:09:53 UTC (rev 3616)
@@ -1040,6 +1040,9 @@
 
 typedef int (PyArray_ScalarKindFunc)(void *);
 
+typedef void (PyArray_FastClipFunc)(void *in, npy_intp n_in, void *min,
+                                    void *max, void *out);
+
 typedef struct {
         npy_intp *ptr;
         int len;
@@ -1115,8 +1118,7 @@
         int **cancastscalarkindto;
         int *cancastto;
 
-        int listpickle;           /* Unused */
-
+        PyArray_FastClipFunc *fastclip;
 } PyArray_ArrFuncs;
 
 #define NPY_ITEM_REFCOUNT   0x01  /* The item must be reference counted
@@ -1317,8 +1319,17 @@
 
 #define PyArray_MAX(a,b) (((a)>(b))?(a):(b))
 #define PyArray_MIN(a,b) (((a)<(b))?(a):(b))
+#define PyArray_CLT(p,q) ((((p).real==(q).real) ? ((p).imag < (q).imag) : \
+                               ((p).real < (q).real)))
+#define PyArray_CGT(p,q) ((((p).real==(q).real) ? ((p).imag > (q).imag) : \
+                               ((p).real > (q).real)))
+#define PyArray_CLE(p,q) ((((p).real==(q).real) ? ((p).imag <= (q).imag) : \
+                               ((p).real <= (q).real)))
+#define PyArray_CGE(p,q) ((((p).real==(q).real) ? ((p).imag >= (q).imag) : \
+                               ((p).real >= (q).real)))
+#define PyArray_CEQ(p,q) (((p).real==(q).real) && ((p).imag == (q).imag))
+#define PyArray_CNE(p,q) (((p).real!=(q).real) || ((p).imag != (q).imag))
 
-
 /*
  * C API:  consists of Macros and functions.  The MACROS are defined here.
  */

Modified: trunk/numpy/core/src/arrayobject.c
===================================================================
--- trunk/numpy/core/src/arrayobject.c	2007-03-29 21:37:58 UTC (rev 3615)
+++ trunk/numpy/core/src/arrayobject.c	2007-03-30 05:09:53 UTC (rev 3616)
@@ -3167,7 +3167,8 @@
                 *ceil,
                 *maximum,
                 *minimum,
-                *rint;
+                *rint,
+                *conjugate;
 } NumericOps;
 
 static NumericOps n_ops; /* NB: static objects inlitialized to zero */
@@ -3224,6 +3225,7 @@
         SET(maximum);
         SET(minimum);
         SET(rint);
+        SET(conjugate);
         return 0;
 }
 
@@ -3273,6 +3275,7 @@
         GET(maximum);
         GET(minimum);
         GET(rint);
+        GET(conjugate);
         return dict;
 
  fail:

Modified: trunk/numpy/core/src/arraytypes.inc.src
===================================================================
--- trunk/numpy/core/src/arraytypes.inc.src	2007-03-29 21:37:58 UTC (rev 3615)
+++ trunk/numpy/core/src/arraytypes.inc.src	2007-03-30 05:09:53 UTC (rev 3616)
@@ -2053,6 +2053,63 @@
 /**end repeat**/
 
 
+
+/************************ 
+ * Fast clip functions 
+ *************************/ 
+ 
+/**begin repeat 
+#name=BOOL,BYTE, UBYTE, SHORT, USHORT, INT, UINT, LONG, ULONG, LONGLONG, ULONGLONG, FLOAT, DOUBLE, LONGDOUBLE# 
+#type= Bool, byte, ubyte, short, ushort, int, uint, long, ulong, longlong, ulonglong, float, double, longdouble# 
+*/ 
+static void
+@name@_fastclip(@type@ *in, intp ni, @type@ *min, @type@ *max, @type@ *out)
+{ 
+        register npy_intp i; 
+        @type@ max_val, min_val;
+        
+        max_val = *max;
+        min_val = *min;        
+  
+        for (i = 0; i < ni; i++) {   
+                if (in[i] < min_val) { 
+                        out[i]   = min_val; 
+                } else if (in[i] > max_val) { 
+                        out[i]   = max_val; 
+                } 
+        } 
+        
+        return;
+} 
+/**end repeat**/ 
+
+/**begin repeat 
+#name=CFLOAT, CDOUBLE, CLONGDOUBLE# 
+#type= cfloat, cdouble, clongdouble# 
+*/ 
+static void
+@name@_fastclip(@type@ *in, intp ni, @type@ *min, @type@ *max, @type@ *out) 
+{ 
+        register npy_intp i; 
+        @type@ max_val, min_val;
+        
+        max_val = *max;
+        min_val = *min;
+ 
+        for (i = 0; i < ni; i++) {   
+                if (PyArray_CLT(in[i], max_val)) { 
+                        out[i]   = max_val; 
+                } else if (PyArray_CGT(in[i], max_val)) { 
+                        out[i]   = max_val; 
+                } 
+        }         
+        return;
+} 
+ 
+/**end repeat**/ 
+
+#define OBJECT_fastclip NULL
+
 #define _ALIGN(type) offsetof(struct {char c; type v;},v)
 
 /* Disable harmless compiler warning "4116: unnamed type definition in
@@ -2117,7 +2174,7 @@
         (PyArray_ScalarKindFunc*)NULL,
         NULL,
         NULL,
-        0
+        (PyArray_FastClipFunc *)NULL
 };
 
 static PyArray_Descr @from@_Descr = {
@@ -2194,7 +2251,7 @@
         (PyArray_ScalarKindFunc*)NULL,
         NULL,
         NULL,
-        0,
+        (PyArray_FastClipFunc*)@from@_fastclip
 };
 
 static PyArray_Descr @from@_Descr = {

Modified: trunk/numpy/core/src/multiarraymodule.c
===================================================================
--- trunk/numpy/core/src/multiarraymodule.c	2007-03-29 21:37:58 UTC (rev 3615)
+++ trunk/numpy/core/src/multiarraymodule.c	2007-03-30 05:09:53 UTC (rev 3616)
@@ -1100,11 +1100,8 @@
 
 }
 
-/*MULTIARRAY_API
- Clip
-*/
 static PyObject *
-PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *out)
+_slow_array_clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *out)
 {
 	PyObject *selector=NULL, *newtup=NULL, *ret=NULL;
 	PyObject *res1=NULL, *res2=NULL, *res3=NULL;
@@ -1137,10 +1134,141 @@
 	return ret;
 }
 
-/* Why doesn't this just call the ufunc?
-   All we need to do is add it to the list of needed ufuncs.
- */
+/*MULTIARRAY_API
+ Clip
+*/
+static PyObject *
+PyArray_Clip(PyArrayObject *self, PyObject *min, PyObject *max, PyArrayObject *out)
+{
+        PyArray_FastClipFunc *func;
+        int outgood=0, ingood=0;                
+        PyArrayObject *maxa=NULL;
+        PyArrayObject *mina=NULL;
+        PyArrayObject *newout=NULL, *newin=NULL;
+        PyArray_Descr *indescr;
 
+        func = self->descr->f->fastclip;
+        if (func == NULL || !PyArray_CheckAnyScalar(min) || 
+            !PyArray_CheckAnyScalar(max))
+                return _slow_array_clip(self, min, max, out);
+
+        /* Use the fast scalar clip function */
+
+        if (PyArray_ISNOTSWAPPED(self)) {
+                indescr = PyArray_DescrNewByteorder(self->descr, '=');
+                if (indescr == NULL) goto fail;
+        }
+        else { 
+                indescr = self->descr;
+                Py_INCREF(indescr);
+        }
+
+        maxa = (NPY_AO *)PyArray_FromAny(max, indescr, 0, 0, 
+                                         NPY_DEFAULT, NULL);
+        if (maxa == NULL) return NULL;
+        Py_INCREF(indescr);
+        mina = (NPY_AO *)PyArray_FromAny(min, indescr, 0, 0, 
+                                         NPY_DEFAULT, NULL);
+        if (mina == NULL) goto fail;
+        
+        if (PyArray_ISONESEGMENT(self) && PyArray_CHKFLAGS(self, ALIGNED) &&
+            PyArray_ISNOTSWAPPED(self)) 
+                ingood = 1;
+
+        if (!ingood) {
+                int flags;
+                if (PyArray_ISFORTRAN(self)) flags = NPY_FARRAY;
+                else flags = NPY_CARRAY;
+                Py_INCREF(indescr);
+                newin = (NPY_AO *)PyArray_FromArray(self, indescr, flags);
+                if (newin == NULL) goto fail;
+        }
+        else {
+                newin = self;
+                Py_INCREF(newin);
+        }
+
+        /* If we have already made a copy of the data, then use 
+           that as the output array
+        */
+        if (out == NULL && !ingood) {
+                out = newin;
+        }
+
+        /* Now, we know newin is a usable array for fastclip,
+           we need to make sure the output array is available
+           and usable */
+        if (out == NULL) {
+                Py_INCREF(indescr);
+                out = (NPY_AO*)PyArray_NewFromDescr(self->ob_type,
+						    indescr, self->nd, 
+                                                    self->dimensions,
+						    NULL, NULL,
+						    PyArray_ISFORTRAN(self),
+                                                    NULL);
+                if (out == NULL) goto fail;
+                outgood = 1;
+        }
+        /* Input is good at this point */
+        if (out == newin) {
+                outgood = 1;
+        }
+        if (!outgood && PyArray_ISONESEGMENT(out) && 
+            PyArray_CHKFLAGS(out, ALIGNED) && 
+            PyArray_ISNOTSWAPPED(out)) {
+                outgood = 1;
+        }
+
+        /* Do we still not have a suitable output array? */
+        /* Create one, now */
+        if (!outgood) {
+                int oflags;
+                PyArray_Descr *odescr;
+                if (PyArray_ISFORTRAN(out)) 
+                        oflags = NPY_FARRAY | NPY_UPDATEIFCOPY;
+                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);
+                if (newout == NULL) goto fail;
+        }
+        else {
+                newout = out;
+                Py_INCREF(newout);
+        }
+
+        if (newout->data != newin->data) {
+                memcpy(newout->data, newin->data, PyArray_NBYTES(newin));
+        }
+        
+        /* Now we can call the fast-clip function */
+
+        func(newin->data, PyArray_SIZE(newin), mina->data, maxa->data,
+             newout->data);
+        
+        /* Clean up temporary variables */
+        Py_DECREF(mina);
+        Py_DECREF(maxa);
+        Py_DECREF(newin);
+        /* Copy back into out if out was not already a nice array. */
+        Py_DECREF(newout);
+        return (PyObject *)out;
+        
+ fail:
+        Py_XDECREF(maxa);
+        Py_XDECREF(mina);
+        Py_XDECREF(newin);
+        return NULL;
+}
+
+
 /*MULTIARRAY_API
  Conjugate
 */
@@ -1148,41 +1276,15 @@
 PyArray_Conjugate(PyArrayObject *self, PyArrayObject *out)
 {
 	if (PyArray_ISCOMPLEX(self)) {
-		PyObject *new;
-		intp size, i;
-		/* Make a copy */
-                new = PyArray_NewCopy(self, -1);
-                if (new==NULL) return NULL;
-		size = PyArray_SIZE(new);
-		if (self->descr->type_num == PyArray_CFLOAT) {
-			cfloat *dptr = (cfloat *) PyArray_DATA(new);
-			for (i=0; i<size; i++) {
-				dptr->imag = -dptr->imag;
-				dptr++;
-			}
-		}
-		else if (self->descr->type_num == PyArray_CDOUBLE) {
-			cdouble *dptr = (cdouble *)PyArray_DATA(new);
-			for (i=0; i<size; i++) {
-				dptr->imag = -dptr->imag;
-				dptr++;
-			}
-		}
-		else if (self->descr->type_num == PyArray_CLONGDOUBLE) {
-			clongdouble *dptr = (clongdouble *)PyArray_DATA(new);
-			for (i=0; i<size; i++) {
-				dptr->imag = -dptr->imag;
-				dptr++;
-			}
-		}
-                if (out) {
-                        if (PyArray_CopyAnyInto(out, (PyArrayObject *)new)<0)
-                                return NULL;
-                        Py_INCREF(out);
-                        Py_DECREF(new);
-                        return (PyObject *)out;
+                if (out == NULL) {
+                        return PyArray_GenericUnaryFunction(self, 
+                                                            n_ops.conjugate);
                 }
-		return new;
+                else {
+                        return PyArray_GenericBinaryFunction(self, 
+                                                             (PyObject *)out,
+                                                             n_ops.conjugate);
+                }
 	}
 	else {
                 PyArrayObject *ret;
@@ -1926,7 +2028,7 @@
 	PyObject *otmp;
 	PyArray_Descr *intype=NULL, *stype=NULL;
 	PyArray_Descr *newtype=NULL;
-	NPY_SCALARKIND scalarkind, intypekind;
+	NPY_SCALARKIND scalarkind=NPY_NOSCALAR, intypekind=NPY_NOSCALAR;
 
 	*retn = n = PySequence_Length(op);
 	if (PyErr_Occurred()) {*retn = 0; return NULL;}



More information about the Numpy-svn mailing list