diff options
author | Travis Oliphant <oliphant@enthought.com> | 2006-12-02 00:35:09 +0000 |
---|---|---|
committer | Travis Oliphant <oliphant@enthought.com> | 2006-12-02 00:35:09 +0000 |
commit | 574fe369112ded91f80502db73022a8fd79d3fe3 (patch) | |
tree | 904b1b27f758c7e5d6c2790a8f5066300f5b5a15 | |
parent | 5898c2c445cb7fe14e2866b34f625e6f95bbf82f (diff) | |
download | numpy-574fe369112ded91f80502db73022a8fd79d3fe3.tar.gz |
Add order keyword to argsort and fix documentation of sort and argsort. Also, fix so that a Python long is passed to mmap instead of an array scalar. Fix setting when using mixed array indices and slice objects by making sure to swap the object in the reverse direction to the swapping that takes place on the MapGet operations.
-rw-r--r-- | numpy/add_newdocs.py | 28 | ||||
-rw-r--r-- | numpy/core/memmap.py | 4 | ||||
-rw-r--r-- | numpy/core/src/arraymethods.c | 36 | ||||
-rw-r--r-- | numpy/core/src/arrayobject.c | 32 | ||||
-rw-r--r-- | numpy/core/src/multiarraymodule.c | 9 |
5 files changed, 81 insertions, 28 deletions
diff --git a/numpy/add_newdocs.py b/numpy/add_newdocs.py index 9cd1c89a5..58940f007 100644 --- a/numpy/add_newdocs.py +++ b/numpy/add_newdocs.py @@ -648,13 +648,19 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('argmin', add_newdoc('numpy.core.multiarray', 'ndarray', ('argsort', - """a.argsort(axis=-1, kind='quicksort') -> indices that sort a along axis. + """a.argsort(axis=-1, kind='quicksort', order=None) -> indices + + Return array of indices that sort a along the given axis. Keyword arguments: - axis -- axis to be indirectly sorted (default -1) - kind -- sorting algorithm (default 'quicksort') - Possible values: 'quicksort', 'mergesort', or 'heapsort' + axis -- axis to be indirectly sorted (default -1) + kind -- sorting algorithm (default 'quicksort') + Possible values: 'quicksort', 'mergesort', or 'heapsort' + order -- If a has fields defined, then the order keyword can be the + field name to sort on or a list (or tuple) of field names + to indicate the order that fields should be used to define + the sort. Returns: array of indices that sort a along the specified axis. @@ -1017,13 +1023,19 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('setflags', add_newdoc('numpy.core.multiarray', 'ndarray', ('sort', - """a.sort(axis=-1, kind='quicksort') -> None. Sort a along the given axis. + """a.sort(axis=-1, kind='quicksort', order=None) -> None. + + Sort a along the given axis. Keyword arguments: - axis -- axis to be sorted (default -1) - kind -- sorting algorithm (default 'quicksort') - Possible values: 'quicksort', 'mergesort', or 'heapsort'. + axis -- axis to be sorted (default -1) + kind -- sorting algorithm (default 'quicksort') + Possible values: 'quicksort', 'mergesort', or 'heapsort'. + order -- If a has fields defined, then the order keyword can be the + field name to sort on or a list (or tuple) of field names + to indicate the order that fields should be used to define + the sort. Returns: None. diff --git a/numpy/core/memmap.py b/numpy/core/memmap.py index 83e9de1ef..d253dabb7 100644 --- a/numpy/core/memmap.py +++ b/numpy/core/memmap.py @@ -17,7 +17,7 @@ mode_equivalents = { class memmap(ndarray): __array_priority__ = -100.0 def __new__(subtype, name, dtype=uint8, mode='r+', offset=0, - shape=None, order=0): + shape=None, order='C'): try: mode = mode_equivalents[mode] except KeyError: @@ -50,7 +50,7 @@ class memmap(ndarray): for k in shape: size *= k - bytes = offset + size*_dbytes + bytes = long(offset + size*_dbytes) if mode == 'w+' or (mode == 'r+' and flen < bytes): fid.seek(bytes-1,0) diff --git a/numpy/core/src/arraymethods.c b/numpy/core/src/arraymethods.c index b48c0c02b..d33fbc70e 100644 --- a/numpy/core/src/arraymethods.c +++ b/numpy/core/src/arraymethods.c @@ -862,12 +862,13 @@ array_sort(PyArrayObject *self, PyObject *args, PyObject *kwds) &order)) return NULL; + if (order == Py_None) order = NULL; if (order != NULL) { PyObject *new_name; saved = self->descr; if (saved->names == NULL) { PyErr_SetString(PyExc_ValueError, "Cannot specify " \ - "order with no fields."); + "order when the array has no fields."); return NULL; } new_name = PyObject_CallMethod(_numpy_internal, "_newnames", @@ -893,13 +894,38 @@ array_argsort(PyArrayObject *self, PyObject *args, PyObject *kwds) { int axis=-1; PyArray_SORTKIND which=PyArray_QUICKSORT; - static char *kwlist[] = {"axis", "kind", NULL}; + PyObject *order=NULL, *res; + PyArray_Descr *newd, *saved=NULL; + static char *kwlist[] = {"axis", "kind", "order", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO&", kwlist, &axis, - PyArray_SortkindConverter, &which)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO&O", kwlist, &axis, + PyArray_SortkindConverter, &which, + &order)) return NULL; - return _ARET(PyArray_ArgSort(self, axis, which)); + if (order == Py_None) order = NULL; + if (order != NULL) { + PyObject *new_name; + saved = self->descr; + if (saved->names == NULL) { + PyErr_SetString(PyExc_ValueError, "Cannot specify " \ + "order when the array has no fields."); + return NULL; + } + new_name = PyObject_CallMethod(_numpy_internal, "_newnames", + "OO", saved, order); + if (new_name == NULL) return NULL; + newd = PyArray_DescrNew(saved); + newd->names = new_name; + self->descr = newd; + } + + res = PyArray_ArgSort(self, axis, which); + if (order != NULL) { + Py_XDECREF(self->descr); + self->descr = saved; + } + return _ARET(res); } static PyObject * diff --git a/numpy/core/src/arrayobject.c b/numpy/core/src/arrayobject.c index 0485e5ad3..ac85fcd23 100644 --- a/numpy/core/src/arrayobject.c +++ b/numpy/core/src/arrayobject.c @@ -2280,10 +2280,10 @@ parse_index(PyArrayObject *self, PyObject *op, } static void -_swap_axes(PyArrayMapIterObject *mit, PyArrayObject **ret) +_swap_axes(PyArrayMapIterObject *mit, PyArrayObject **ret, int getmap) { PyObject *new; - int n1, n2, n3, val; + int n1, n2, n3, val, bnd; int i; PyArray_Dims permute; intp d[MAX_DIMS]; @@ -2308,24 +2308,38 @@ _swap_axes(PyArrayMapIterObject *mit, PyArrayObject **ret) if (new == NULL) return; } - /* tuple for transpose is - (n1,..,n1+n2-1,0,..,n1-1,n1+n2,...,n3-1) + /* Setting and getting need to have different permutations. + On the get we are permuting the returned object, but on + setting we are permuting the object-to-be-set. + The set permutation is the inverse of the get permutation. + */ + + /* For getting the array the tuple for transpose is + (n1,...,n1+n2-1,0,...,n1-1,n1+n2,...,n3-1) n1 is the number of dimensions of the broadcasted index array n2 is the number of dimensions skipped at the - start + start n3 is the number of dimensions of the result */ + + /* For setting the array the tuple for transpose is + (n2,...,n1+n2-1,0,...,n2-1,n1+n2,...n3-1) + */ n1 = mit->iters[0]->nd_m1 + 1; n2 = mit->iteraxes[0]; n3 = mit->nd; - val = n1; + + bnd = (getmap ? n1 : n2); /* use n1 as the boundary if getting + but n2 if setting */ + + val = bnd; i = 0; while(val < n1+n2) permute.ptr[i++] = val++; val = 0; - while(val < n1) + while(val < bnd) permute.ptr[i++] = val++; val = n1+n2; while(val < n3) @@ -2395,7 +2409,7 @@ PyArray_GetMap(PyArrayMapIterObject *mit) /* check for consecutive axes */ if ((mit->subspace != NULL) && (mit->consec)) { if (mit->iteraxes[0] > 0) { /* then we need to swap */ - _swap_axes(mit, &ret); + _swap_axes(mit, &ret, 1); } } return (PyObject *)ret; @@ -2421,7 +2435,7 @@ PyArray_SetMap(PyArrayMapIterObject *mit, PyObject *op) if ((mit->subspace != NULL) && (mit->consec)) { if (mit->iteraxes[0] > 0) { /* then we need to swap */ - _swap_axes(mit, (PyArrayObject **)&arr); + _swap_axes(mit, (PyArrayObject **)&arr, 0); if (arr == NULL) return -1; } } diff --git a/numpy/core/src/multiarraymodule.c b/numpy/core/src/multiarraymodule.c index 037283615..88b063888 100644 --- a/numpy/core/src/multiarraymodule.c +++ b/numpy/core/src/multiarraymodule.c @@ -2181,7 +2181,8 @@ _new_sort(PyArrayObject *op, int axis, NPY_SORTKIND which) swap = !PyArray_ISNOTSWAPPED(op); if (it == NULL) return -1; - BEGIN_THREADS + NPY_BEGIN_THREADS_DESCR(op->descr) + sort = op->descr->f->sort[which]; size = it->size; N = op->dimensions[axis]; @@ -2216,7 +2217,7 @@ _new_sort(PyArrayObject *op, int axis, NPY_SORTKIND which) } } - END_THREADS + NPY_END_THREADS_DESCR(op->descr) Py_DECREF(it); return 0; @@ -2253,7 +2254,7 @@ _new_argsort(PyArrayObject *op, int axis, NPY_SORTKIND which) swap = !PyArray_ISNOTSWAPPED(op); - BEGIN_THREADS + NPY_BEGIN_THREADS_DESCR(op->descr) argsort = op->descr->f->argsort[which]; size = it->size; @@ -2299,7 +2300,7 @@ _new_argsort(PyArrayObject *op, int axis, NPY_SORTKIND which) } } - END_THREADS + NPY_END_THREADS_DESCR(op->descr) Py_DECREF(it); Py_DECREF(rit); |