From 2d69b480bae8f9045a6c9876e55f6d1a3216b05f Mon Sep 17 00:00:00 2001 From: Stefan van der Walt Date: Fri, 18 Apr 2008 12:43:33 +0000 Subject: Fast implementation of take [patch by Eric Firing]. --- numpy/core/src/arraytypes.inc.src | 89 ++++++++++++++++++++++++++++++++++++++- numpy/core/src/multiarraymodule.c | 46 ++++++++++++-------- 2 files changed, 116 insertions(+), 19 deletions(-) (limited to 'numpy/core/src') diff --git a/numpy/core/src/arraytypes.inc.src b/numpy/core/src/arraytypes.inc.src index 8e8633d72..26b8a5010 100644 --- a/numpy/core/src/arraytypes.inc.src +++ b/numpy/core/src/arraytypes.inc.src @@ -2179,6 +2179,89 @@ static void #define OBJECT_fastputmask NULL + +/************************ + * Fast take functions + *************************/ + +/**begin repeat +#name=BOOL,BYTE, UBYTE, SHORT, USHORT, INT, UINT, LONG, ULONG, LONGLONG, ULONGLONG, FLOAT, DOUBLE, LONGDOUBLE,CFLOAT, CDOUBLE, CLONGDOUBLE# +#type= Bool, byte, ubyte, short, ushort, int, uint, long, ulong, longlong, ulonglong, float, double, longdouble,cfloat, cdouble, clongdouble# +*/ +static int +@name@_fasttake(@type@ *dest, @type@ *src, intp *indarray, + intp nindarray, intp n_outer, + intp m_middle, intp nelem, + NPY_CLIPMODE clipmode) +{ + intp i, j, k, tmp; + + switch(clipmode) { + case NPY_RAISE: + for(i=0; i= nindarray)) { + PyErr_SetString(PyExc_IndexError, + "index out of range "\ + "for array"); + return 1; + } + if (nelem == 1) *dest++ = *(src+tmp); + else { + for(k=0; k= nindarray) + while (tmp >= nindarray) + tmp -= nindarray; + if (nelem == 1) *dest++ = *(src+tmp); + else { + for(k=0; k= nindarray) + tmp = nindarray-1; + if (nelem == 1) *dest++ = *(src+tmp); + else { + for(k=0; kdata; if (maxa != NULL) max_data = maxa->data; - + func(newin->data, PyArray_SIZE(newin), min_data, max_data, newout->data); @@ -3107,10 +3107,10 @@ PyArray_SearchSorted(PyArrayObject *op1, PyObject *op2, NPY_SEARCHSIDE side) NPY_BEGIN_THREADS_DEF dtype = PyArray_DescrFromObject((PyObject *)op2, op1->descr); - + /* need ap1 as contiguous array and of right type */ Py_INCREF(dtype); - ap1 = (PyArrayObject *)PyArray_FromAny((PyObject *)op1, dtype, + ap1 = (PyArrayObject *)PyArray_FromAny((PyObject *)op1, dtype, 1, 1, NPY_DEFAULT, NULL); if (ap1 == NULL) { @@ -3746,10 +3746,10 @@ PyArray_ArgMax(PyArrayObject *op, int axis, PyArrayObject *out) op = ap; } - /* Will get native-byte order contiguous copy. + /* Will get native-byte order contiguous copy. */ ap = (PyArrayObject *)\ - PyArray_ContiguousFromAny((PyObject *)op, + PyArray_ContiguousFromAny((PyObject *)op, op->descr->type_num, 1, 0); Py_DECREF(op); @@ -3824,11 +3824,13 @@ static PyObject * PyArray_TakeFrom(PyArrayObject *self0, PyObject *indices0, int axis, PyArrayObject *ret, NPY_CLIPMODE clipmode) { + PyArray_FastTakeFunc *func; PyArrayObject *self, *indices; - intp nd, i, j, n, m, max_item, tmp, chunk; + intp nd, i, j, n, m, max_item, tmp, chunk, nelem; intp shape[MAX_DIMS]; char *src, *dest; int copyret=0; + int err; indices = NULL; self = (PyAO *)_check_axis(self0, &axis, CARRAY); @@ -3892,10 +3894,14 @@ PyArray_TakeFrom(PyArrayObject *self0, PyObject *indices0, int axis, } max_item = self->dimensions[axis]; + nelem = chunk; chunk = chunk * ret->descr->elsize; src = self->data; dest = ret->data; + func = self->descr->f->fasttake; + if (func == NULL) { + switch(clipmode) { case NPY_RAISE: for(i=0; idata), + max_item, n, m, nelem, clipmode); + if (err) goto fail; + } PyArray_INCREF(ret); @@ -5666,7 +5678,7 @@ _array_fromobject(PyObject *ignored, PyObject *args, PyObject *kws) Py_XDECREF(type); return NULL; } - + /* fast exit if simple call */ if ((subok && PyArray_Check(op)) || @@ -5787,7 +5799,7 @@ array_empty(PyObject *ignored, PyObject *args, PyObject *kwds) return NULL; } -/* This function is needed for supporting Pickles of +/* This function is needed for supporting Pickles of numpy scalar objects. */ static PyObject * @@ -6363,7 +6375,7 @@ PyArray_FromFile(FILE *fp, PyArray_Descr *dtype, intp num, char *sep) */ if ((tmp == NULL) || (nread == 0)) { Py_DECREF(ret); - return PyErr_NoMemory(); + return PyErr_NoMemory(); } ret->data = tmp; PyArray_DIM(ret,0) = nread; @@ -6433,7 +6445,7 @@ PyArray_FromIter(PyObject *obj, PyArray_Descr *dtype, intp count) if ((elsize=dtype->elsize) == 0) { PyErr_SetString(PyExc_ValueError, "Must specify length "\ "when using variable-size data-type."); - goto done; + goto done; } /* We would need to alter the memory RENEW code to decrement any @@ -7126,7 +7138,7 @@ array_can_cast_safely(PyObject *dummy, PyObject *args, PyObject *kwds) retobj = (ret ? Py_True : Py_False); Py_INCREF(retobj); - finish: + finish: Py_XDECREF(d1); Py_XDECREF(d2); return retobj; -- cgit v1.2.1