summaryrefslogtreecommitdiff
path: root/numpy/core/src
diff options
context:
space:
mode:
authorTravis Oliphant <oliphant@enthought.com>2006-10-23 22:03:14 +0000
committerTravis Oliphant <oliphant@enthought.com>2006-10-23 22:03:14 +0000
commit440a2627ac7d15de4b765279ce7546e66ddfa780 (patch)
tree1517c4f08f6ba2a0d12ad0dfd44d7140a0ff4c18 /numpy/core/src
parentce92c890b685c9a3c2d75f2265763f2226fd884b (diff)
downloadnumpy-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.c3
-rw-r--r--numpy/core/src/arraytypes.inc.src67
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 **********************************/