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

numpy-svn at scipy.org numpy-svn at scipy.org
Mon Oct 23 17:03:22 CDT 2006


Author: oliphant
Date: 2006-10-23 17:03:14 -0500 (Mon, 23 Oct 2006)
New Revision: 3383

Modified:
   trunk/numpy/core/include/numpy/ndarrayobject.h
   trunk/numpy/core/src/arrayobject.c
   trunk/numpy/core/src/arraytypes.inc.src
Log:
Add ability to sort arrays with fields defined more intelligently.

Modified: trunk/numpy/core/include/numpy/ndarrayobject.h
===================================================================
--- trunk/numpy/core/include/numpy/ndarrayobject.h	2006-10-23 20:44:07 UTC (rev 3382)
+++ trunk/numpy/core/include/numpy/ndarrayobject.h	2006-10-23 22:03:14 UTC (rev 3383)
@@ -1634,7 +1634,7 @@
 #define PyDataType_ISUSERDEF(obj) PyTypeNum_ISUSERDEF(((PyArray_Descr*)obj)->type_num)
 #define PyDataType_ISEXTENDED(obj) PyTypeNum_ISEXTENDED(((PyArray_Descr*)obj)->type_num)
 #define PyDataType_ISOBJECT(obj) PyTypeNum_ISOBJECT(((PyArray_Descr*)obj)->type_num)
-#define PyDataType_HASFIELDS(obj) (((PyArray_Descr *)obj)->names)
+#define PyDataType_HASFIELDS(obj) (((PyArray_Descr *)obj)->names != NULL)
 
 #define PyArray_ISBOOL(obj) PyTypeNum_ISBOOL(PyArray_TYPE(obj))
 #define PyArray_ISUNSIGNED(obj) PyTypeNum_ISUNSIGNED(PyArray_TYPE(obj))

Modified: trunk/numpy/core/src/arrayobject.c
===================================================================
--- trunk/numpy/core/src/arrayobject.c	2006-10-23 20:44:07 UTC (rev 3382)
+++ trunk/numpy/core/src/arrayobject.c	2006-10-23 22:03:14 UTC (rev 3383)
@@ -5881,7 +5881,8 @@
         if (PyArray_DATA(ret) != PyArray_DATA(self)) {
                 Py_DECREF(ret);
                 PyErr_SetString(PyExc_AttributeError,
-                                "incompatible shape for a non-contiguous array");
+                                "incompatible shape for a non-contiguous "\
+                                "array");
                 return -1;
         }
 

Modified: trunk/numpy/core/src/arraytypes.inc.src
===================================================================
--- trunk/numpy/core/src/arraytypes.inc.src	2006-10-23 20:44:07 UTC (rev 3382)
+++ trunk/numpy/core/src/arraytypes.inc.src	2006-10-23 22:03:14 UTC (rev 3383)
@@ -1667,18 +1667,73 @@
         return 0;
 }
 
-/* possibly redefine compare in terms of fields and subarrays if any */
-/* this would have to properly align data (if needed for the type)
-   before passing on to the _compare function of sub-fields
+/* If fields are defined, then compare on first field and if equal
+   compare on second field.  Continue until done or comparison results
+   in not_equal. 
 
-   More importantly, it's unclear what is meant by < and > so we really
-   can't implement it correctly.
+   Must align data passed on to sub-comparisons. 
 */
 
 static int
 VOID_compare(char *ip1, char *ip2, PyArrayObject *ap)
 {
-        return STRING_compare(ip1, ip2, ap);
+        PyArray_Descr *descr, *new;
+        PyObject *names, *key;
+        PyObject *tup, *title;
+        char *nip1, *nip2;
+        int i, offset, res=0;
+
+        if (!PyArray_HASFIELDS(ap)) 
+                return STRING_compare(ip1, ip2, ap);
+        
+        descr = ap->descr;
+        /* Compare on the first-field.  If equal, then
+           compare on the second-field, etc.
+        */
+        names = descr->names;
+        for (i=0; i<PyTuple_GET_SIZE(names); i++) {
+                key = PyTuple_GET_ITEM(names, i);
+                tup = PyDict_GetItem(descr->fields, key);
+                if (!PyArg_ParseTuple(tup, "Oi|O", &new, &offset,
+                                      &title)) {
+                        goto finish;
+                }
+                ap->descr = new;
+                nip1 = ip1+offset;
+                nip2 = ip2+offset;
+                if (new->alignment > 1) {
+                        if (((intp)(nip1) % new->alignment) != 0) {
+                                /* create buffer and copy */
+                                nip1 = _pya_malloc(new->elsize);
+                                if (nip1 == NULL) goto finish;
+                                memcpy(nip1, ip1+offset, new->elsize);
+                        }
+                        if (((intp)(nip2) % new->alignment) != 0) {
+                            /* copy data to a buffer */
+                                nip2 = _pya_malloc(new->elsize);
+                                if (nip2 == NULL) {
+                                        if (nip1 != ip1+offset) 
+                                                _pya_free(nip1);
+                                        goto finish;
+                                }
+                                memcpy(nip2, ip2+offset, new->elsize);
+                        }
+                }
+                res = new->f->compare(nip1, nip2, ap);
+                if (new->alignment > 1) {
+                        if (nip1 != ip1+offset) {
+                                _pya_free(nip1);
+                        }
+                        if (nip2 != ip2+offset) {
+                                _pya_free(nip2);
+                        }
+                }
+                if (res != 0) break;
+        }
+
+ finish:
+        ap->descr = descr;
+        return res;
 }
 
 /****************** argfunc **********************************/



More information about the Numpy-svn mailing list