diff options
author | Travis Oliphant <oliphant@enthought.com> | 2006-10-23 22:03:14 +0000 |
---|---|---|
committer | Travis Oliphant <oliphant@enthought.com> | 2006-10-23 22:03:14 +0000 |
commit | 440a2627ac7d15de4b765279ce7546e66ddfa780 (patch) | |
tree | 1517c4f08f6ba2a0d12ad0dfd44d7140a0ff4c18 /numpy/core/src | |
parent | ce92c890b685c9a3c2d75f2265763f2226fd884b (diff) | |
download | numpy-440a2627ac7d15de4b765279ce7546e66ddfa780.tar.gz |
Add ability to sort arrays with fields defined more intelligently.
Diffstat (limited to 'numpy/core/src')
-rw-r--r-- | numpy/core/src/arrayobject.c | 3 | ||||
-rw-r--r-- | numpy/core/src/arraytypes.inc.src | 67 |
2 files changed, 63 insertions, 7 deletions
diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index 45983e84d..2aea422ae 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -5881,7 +5881,8 @@ array_shape_set(PyArrayObject *self, PyObject *val) 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; } diff --git a/numpy/core/src/arraytypes.inc.src b/numpy/core/src/arraytypes.inc.src index acb936ede..963038619 100644 --- a/numpy/core/src/arraytypes.inc.src +++ b/numpy/core/src/arraytypes.inc.src @@ -1667,18 +1667,73 @@ UNICODE_compare(register PyArray_UCS4 *ip1, register PyArray_UCS4 *ip2, 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 **********************************/ |