[Numpy-svn] r3465 - in trunk/numpy: . core core/src

numpy-svn at scipy.org numpy-svn at scipy.org
Fri Dec 1 18:35:17 CST 2006


Author: oliphant
Date: 2006-12-01 18:35:09 -0600 (Fri, 01 Dec 2006)
New Revision: 3465

Modified:
   trunk/numpy/add_newdocs.py
   trunk/numpy/core/memmap.py
   trunk/numpy/core/src/arraymethods.c
   trunk/numpy/core/src/arrayobject.c
   trunk/numpy/core/src/multiarraymodule.c
Log:
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.

Modified: trunk/numpy/add_newdocs.py
===================================================================
--- trunk/numpy/add_newdocs.py	2006-12-01 19:33:05 UTC (rev 3464)
+++ trunk/numpy/add_newdocs.py	2006-12-02 00:35:09 UTC (rev 3465)
@@ -648,13 +648,19 @@
 
 
 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', ('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.
 

Modified: trunk/numpy/core/memmap.py
===================================================================
--- trunk/numpy/core/memmap.py	2006-12-01 19:33:05 UTC (rev 3464)
+++ trunk/numpy/core/memmap.py	2006-12-02 00:35:09 UTC (rev 3465)
@@ -17,7 +17,7 @@
 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 @@
             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)

Modified: trunk/numpy/core/src/arraymethods.c
===================================================================
--- trunk/numpy/core/src/arraymethods.c	2006-12-01 19:33:05 UTC (rev 3464)
+++ trunk/numpy/core/src/arraymethods.c	2006-12-02 00:35:09 UTC (rev 3465)
@@ -862,12 +862,13 @@
                                          &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 @@
 {
 	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 *

Modified: trunk/numpy/core/src/arrayobject.c
===================================================================
--- trunk/numpy/core/src/arrayobject.c	2006-12-01 19:33:05 UTC (rev 3464)
+++ trunk/numpy/core/src/arrayobject.c	2006-12-02 00:35:09 UTC (rev 3465)
@@ -2280,10 +2280,10 @@
 }
 
 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 @@
                 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 @@
         /* 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 @@
 
         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;
                 }
         }

Modified: trunk/numpy/core/src/multiarraymodule.c
===================================================================
--- trunk/numpy/core/src/multiarraymodule.c	2006-12-01 19:33:05 UTC (rev 3464)
+++ trunk/numpy/core/src/multiarraymodule.c	2006-12-02 00:35:09 UTC (rev 3465)
@@ -2181,7 +2181,8 @@
 	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 @@
 		}
 	}
 
-	END_THREADS
+	NPY_END_THREADS_DESCR(op->descr)
 
 	Py_DECREF(it);
 	return 0;
@@ -2253,7 +2254,7 @@
 
 	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 @@
 		}
 	}
 
-	END_THREADS
+	NPY_END_THREADS_DESCR(op->descr)
 
 	Py_DECREF(it);
 	Py_DECREF(rit);



More information about the Numpy-svn mailing list