[Numpy-svn] r3145 - trunk/numpy/core/src

numpy-svn at scipy.org numpy-svn at scipy.org
Wed Sep 13 16:16:01 EDT 2006


Author: oliphant
Date: 2006-09-13 15:15:39 -0500 (Wed, 13 Sep 2006)
New Revision: 3145

Modified:
   trunk/numpy/core/src/arraymethods.c
   trunk/numpy/core/src/ufuncobject.c
Log:
Allow .item(<index>) for fast selection of Python scalars from a numpy array.  Re-name a few confusing constants in ufuncobject.c

Modified: trunk/numpy/core/src/arraymethods.c
===================================================================
--- trunk/numpy/core/src/arraymethods.c	2006-09-12 00:38:39 UTC (rev 3144)
+++ trunk/numpy/core/src/arraymethods.c	2006-09-13 20:15:39 UTC (rev 3145)
@@ -452,14 +452,86 @@
 
 static PyObject *
 array_toscalar(PyArrayObject *self, PyObject *args) {
-        if (!PyArg_ParseTuple(args, "")) return NULL;
-	if (self->nd == 0 || PyArray_SIZE(self) == 1)
-		return self->descr->f->getitem(self->data, self);
-	else {
-		PyErr_SetString(PyExc_ValueError, "can only convert an"	\
-				" array of size 1 to Python scalar.");
-		return NULL;
-	}
+        int n, nd;
+        n = PyTuple_GET_SIZE(args);
+        
+        if (n==1) {
+                PyObject *obj;
+                obj = PyTuple_GET_ITEM(args, 0);
+                if (PyTuple_Check(obj)) {
+                        args = obj;
+                        n = PyTuple_GET_SIZE(args);
+                }
+        }
+        
+        if (n==0) {
+                if (self->nd == 0 || PyArray_SIZE(self) == 1)
+                        return self->descr->f->getitem(self->data, self);
+                else {
+                        PyErr_SetString(PyExc_ValueError, 
+                                        "can only convert an array "    \
+                                        " of size 1 to a Python scalar");
+                        return NULL;
+                }
+        }
+        else if (n != self->nd && (n > 1 || self->nd==0)) {
+                PyErr_SetString(PyExc_ValueError, 
+                                "incorrect number of indices for "      \
+                                "array");
+                return NULL;
+        }
+        else if (n==1) { /* allows for flat getting as well as 1-d case */
+                intp value, loc, index, factor;
+                intp factors[MAX_DIMS];
+                value = PyArray_PyIntAsIntp(PyTuple_GET_ITEM(args, 0));
+                if (error_converting(value)) {
+                        PyErr_SetString(PyExc_ValueError, "invalid integer");
+                        return NULL;
+                }
+                if (value >= PyArray_SIZE(self)) {
+                        PyErr_SetString(PyExc_ValueError, 
+                                        "index out of bounds");
+                        return NULL;
+                }
+                if (self->nd == 1) {
+                        return self->descr->f->getitem(self->data + value, 
+                                                       self);
+                }
+                nd = self->nd;
+                factor = 1;
+                while (nd--) {
+                        factors[nd] = factor;
+                        factor *= self->dimensions[nd];
+                }
+                loc = 0;
+                for (nd=0; nd < self->nd; nd++) {
+                        index = value / factors[nd];
+                        value = value % factors[nd];
+                        loc += self->strides[nd]*index;
+                }
+                
+                return self->descr->f->getitem(self->data + loc,
+                                               self);
+                
+        }
+        else {
+                intp loc, index[MAX_DIMS];
+                nd = PyArray_IntpFromSequence(args, index, MAX_DIMS);
+                if (nd < n) return NULL;
+                loc = 0;
+                while (nd--) {
+                        if (index[nd] < 0) 
+                                index[nd] += self->dimensions[nd];
+                        if (index[nd] < 0 || 
+                            index[nd] >= self->dimensions[nd]) {
+                                PyErr_SetString(PyExc_ValueError, 
+                                                "index out of bounds");
+                                return NULL;
+                        }
+                        loc += self->strides[nd]*index[nd];
+                }
+                return self->descr->f->getitem(self->data + loc, self);
+        }
 }
 
 

Modified: trunk/numpy/core/src/ufuncobject.c
===================================================================
--- trunk/numpy/core/src/ufuncobject.c	2006-09-12 00:38:39 UTC (rev 3144)
+++ trunk/numpy/core/src/ufuncobject.c	2006-09-13 20:15:39 UTC (rev 3145)
@@ -578,9 +578,9 @@
 
 
 #define NO_UFUNCLOOP        0
-#define ZERODIM_REDUCELOOP  0
+#define ZERO_EL_REDUCELOOP  0
 #define ONE_UFUNCLOOP       1
-#define ONEDIM_REDUCELOOP   1
+#define ONE_EL_REDUCELOOP   1
 #define NOBUFFER_UFUNCLOOP  2
 #define NOBUFFER_REDUCELOOP 2
 #define BUFFER_UFUNCLOOP  3
@@ -1832,12 +1832,12 @@
 	aar = *arr;
 
         if (loop->N == 0) {
-                loop->meth = ZERODIM_REDUCELOOP;
+                loop->meth = ZERO_EL_REDUCELOOP;
         }
         else if (PyArray_ISBEHAVED_RO(aar) &&		\
                  otype == (aar)->descr->type_num) {
 		if (loop->N == 1) {
-			loop->meth = ONEDIM_REDUCELOOP;
+			loop->meth = ONE_EL_REDUCELOOP;
 		}
 		else {
 			loop->meth = NOBUFFER_UFUNCLOOP;
@@ -1856,7 +1856,7 @@
         else
                 loop->obj = 0;
 
-        if (loop->meth == ZERODIM_REDUCELOOP) {
+        if (loop->meth == ZERO_EL_REDUCELOOP) {
                 idarr = _getidentity(self, otype, str);
                 if (idarr == NULL) goto fail;
                 if (idarr->descr->elsize > UFUNC_MAXIDENTITY) {
@@ -1913,10 +1913,10 @@
                         outsize = PyArray_MultiplyList(loop_i, aar->nd);
                 }
 		if (ind_size == 0) {
-			loop->meth = ZERODIM_REDUCELOOP;
+			loop->meth = ZERO_EL_REDUCELOOP;
 			return loop;
 		}
-		if (loop->meth == ONEDIM_REDUCELOOP)
+		if (loop->meth == ONE_EL_REDUCELOOP)
 			loop->meth = NOBUFFER_REDUCELOOP;
 		break;
 	}
@@ -1938,7 +1938,7 @@
         loop->outsize = loop->ret->descr->elsize;
         loop->bufptr[1] = loop->ret->data;
 
-	if (loop->meth == ZERODIM_REDUCELOOP) {
+	if (loop->meth == ZERO_EL_REDUCELOOP) {
 		loop->size = PyArray_SIZE(loop->ret);
 		return loop;
 	}
@@ -1946,7 +1946,7 @@
 	loop->it = (PyArrayIterObject *)PyArray_IterNew((PyObject *)aar);
         if (loop->it == NULL) return NULL;
 
-	if (loop->meth == ONEDIM_REDUCELOOP) {
+	if (loop->meth == ONE_EL_REDUCELOOP) {
 		loop->size = loop->it->size;
 		return loop;
 	}
@@ -2046,7 +2046,7 @@
 
         NPY_LOOP_BEGIN_THREADS
         switch(loop->meth) {
-        case ZERODIM_REDUCELOOP:
+        case ZERO_EL_REDUCELOOP:
 		/* fprintf(stderr, "ZERO..%d\n", loop->size); */
 		for(i=0; i<loop->size; i++) {
 			if (loop->obj) Py_INCREF(*((PyObject **)loop->idptr));
@@ -2054,7 +2054,7 @@
 			loop->bufptr[1] += loop->outsize;
 		}
                 break;
-        case ONEDIM_REDUCELOOP:
+        case ONE_EL_REDUCELOOP:
 		/*fprintf(stderr, "ONEDIM..%d\n", loop->size); */
                 while(loop->index < loop->size) {
 			if (loop->obj)
@@ -2189,7 +2189,7 @@
 
 	NPY_LOOP_BEGIN_THREADS
         switch(loop->meth) {
-        case ZERODIM_REDUCELOOP: /* Accumulate */
+        case ZERO_EL_REDUCELOOP: /* Accumulate */
 		/* fprintf(stderr, "ZERO..%d\n", loop->size); */
 		for(i=0; i<loop->size; i++) {
 			if (loop->obj)
@@ -2198,7 +2198,7 @@
 			loop->bufptr[1] += loop->outsize;
 		}
                 break;
-        case ONEDIM_REDUCELOOP: /* Accumulate */
+        case ONE_EL_REDUCELOOP: /* Accumulate */
 		/* fprintf(stderr, "ONEDIM..%d\n", loop->size); */
                 while(loop->index < loop->size) {
 			if (loop->obj)
@@ -2369,7 +2369,7 @@
 	NPY_LOOP_BEGIN_THREADS
 	switch(loop->meth) {
 	/* zero-length index -- return array immediately */
-	case ZERODIM_REDUCELOOP:
+	case ZERO_EL_REDUCELOOP:
 		/* fprintf(stderr, "ZERO..\n"); */
 		break;
 	/* NOBUFFER -- behaved array and same type */




More information about the Numpy-svn mailing list