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

numpy-svn@scip... numpy-svn@scip...
Mon Mar 26 15:40:04 CDT 2007


Author: oliphant
Date: 2007-03-26 15:40:01 -0500 (Mon, 26 Mar 2007)
New Revision: 3600

Modified:
   trunk/numpy/core/src/multiarraymodule.c
   trunk/numpy/core/src/ufuncobject.c
Log:
Fix scalar coercion rules between different basic kinds.

Modified: trunk/numpy/core/src/multiarraymodule.c
===================================================================
--- trunk/numpy/core/src/multiarraymodule.c	2007-03-26 19:23:04 UTC (rev 3599)
+++ trunk/numpy/core/src/multiarraymodule.c	2007-03-26 20:40:01 UTC (rev 3600)
@@ -1926,7 +1926,7 @@
 	PyObject *otmp;
 	PyArray_Descr *intype=NULL, *stype=NULL;
 	PyArray_Descr *newtype=NULL;
-	NPY_SCALARKIND scalarkind;
+	NPY_SCALARKIND scalarkind, intypekind;
 
 	*retn = n = PySequence_Length(op);
 	if (PyErr_Occurred()) {*retn = 0; return NULL;}
@@ -1960,6 +1960,8 @@
 			Py_XDECREF(intype);
 			intype = newtype;
 			mps[i] = NULL;
+                        intypekind = PyArray_ScalarKind(intype->type_num,
+                                                        NULL);
 		}
 		else {
 			newtype = PyArray_DescrFromObject(otmp, stype);
@@ -1967,13 +1969,6 @@
 			stype = newtype;
 			scalarkind = PyArray_ScalarKind(newtype->type_num,
 							NULL);
-			if (intype && \
-			    !PyArray_CanCoerceScalar(newtype->type_num,
-						     intype->type_num,
-						     scalarkind)) {
-				Py_XDECREF(intype);
-				intype = stype;
-			}
 			mps[i] = (PyArrayObject *)Py_None;
 			Py_INCREF(Py_None);
 		}
@@ -1988,6 +1983,23 @@
 			mps[i] = NULL;
 		}
 	}
+        else if (intypekind != scalarkind) { \
+                /* we need to upconvert to type that
+                   handles both intype and stype
+                   and don't forcecast the scalars.
+                */
+                
+                if (!PyArray_CanCoerceScalar(stype->type_num,
+                                             intype->type_num,
+                                             scalarkind)) {
+                        Py_XDECREF(intype);
+                        intype = stype;
+                }
+                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;

Modified: trunk/numpy/core/src/ufuncobject.c
===================================================================
--- trunk/numpy/core/src/ufuncobject.c	2007-03-26 19:23:04 UTC (rev 3599)
+++ trunk/numpy/core/src/ufuncobject.c	2007-03-26 20:40:01 UTC (rev 3600)
@@ -1118,8 +1118,10 @@
         int nargs, i;
         int arg_types[NPY_MAXARGS];
 	PyArray_SCALARKIND scalars[NPY_MAXARGS];
+        PyArray_SCALARKIND kindof, new;
 	PyUFuncObject *self=loop->ufunc;
 	Bool allscalars=TRUE;
+        Bool samekind=TRUE;
 	PyTypeObject *subtype=&PyArray_Type;
         PyObject *context=NULL;
         PyObject *obj;
@@ -1160,11 +1162,18 @@
 		   at this point
 		*/
 		if (mps[i]->nd > 0) {
-			scalars[i] = PyArray_NOSCALAR;
+                        scalars[i] = PyArray_NOSCALAR;
 			allscalars=FALSE;
+                        new = PyArray_ScalarKind(arg_types[i], NULL);
 		}
-		else scalars[i] = PyArray_ScalarKind(arg_types[i], &(mps[i]));
-
+		else {
+                        scalars[i] = PyArray_ScalarKind(arg_types[i], &(mps[i]));
+                        new = scalars[i];
+                }
+                if (i==0) kindof=new;
+                else if (kindof != new) {
+                        samekind=FALSE;
+                }
         }
 
         if (flexible && !object) {
@@ -1172,13 +1181,15 @@
                 return nargs;
         }
 
-	/* If everything is a scalar, then use normal coercion rules */
-	if (allscalars) {
+	/* If everything is a scalar, or scalars mixed with arrays of different kinds
+           then use normal coercion rules */
+	if (allscalars || !samekind) {
 		for (i=0; i<self->nin; i++) {
 			scalars[i] = PyArray_NOSCALAR;
 		}
 	}
 
+
         /* Select an appropriate function for these argument types. */
         if (select_types(loop->ufunc, arg_types, &(loop->function),
                          &(loop->funcdata), scalars, typetup) == -1)



More information about the Numpy-svn mailing list