diff options
Diffstat (limited to 'numpy/lib/src')
-rw-r--r-- | numpy/lib/src/_compiled_base.c | 148 |
1 files changed, 86 insertions, 62 deletions
diff --git a/numpy/lib/src/_compiled_base.c b/numpy/lib/src/_compiled_base.c index 328fc2d14..a461613e3 100644 --- a/numpy/lib/src/_compiled_base.c +++ b/numpy/lib/src/_compiled_base.c @@ -60,29 +60,44 @@ decr_slot_right_(double x, double * bins, npy_intp lbins) return 0; } -/** +/* * Returns -1 if the array is monotonic decreasing, * +1 if the array is monotonic increasing, * and 0 if the array is not monotonic. */ static int -check_array_monotonic(double * a, int lena) +check_array_monotonic(const double *a, npy_int lena) { - int i; + npy_intp i; + double next; + double last = a[0]; + + /* Skip repeated values at the beginning of the array */ + for (i = 1; (i < lena) && (a[i] == last); i++); + + if (i == lena) { + /* all bin edges hold the same value */ + return 1; + } - if (a [0] <= a [1]) { - /* possibly monotonic increasing */ - for (i = 1; i < lena - 1; i ++) { - if (a [i] > a [i + 1]) { + next = a[i]; + if (last < next) { + /* Possibly monotonic increasing */ + for (i += 1; i < lena; i++) { + last = next; + next = a[i]; + if (last > next) { return 0; } } return 1; } else { - /* possibly monotonic decreasing */ - for (i = 1; i < lena - 1; i ++) { - if (a [i] < a [i + 1]) { + /* last > next, possibly monotonic decreasing */ + for (i += 1; i < lena; i++) { + last = next; + next = a[i]; + if (last < next) { return 0; } } @@ -90,39 +105,26 @@ check_array_monotonic(double * a, int lena) } } - - -/* find the index of the maximum element of an integer array */ -static npy_intp -mxx (npy_intp *i , npy_intp len) +/* Find the minimum and maximum of an integer array */ +static void +minmax(const npy_intp *data, npy_intp data_len, npy_intp *mn, npy_intp *mx) { - npy_intp mx = 0, max = i[0]; - npy_intp j; + npy_intp min = *data; + npy_intp max = *data; - for ( j = 1; j < len; j ++ ) { - if ( i [j] > max ) { - max = i [j]; - mx = j; + while (--data_len) { + const npy_intp val = *(++data); + if (val < min) { + min = val; + } + else if (val > max) { + max = val; } } - return mx; -} -/* find the index of the minimum element of an integer array */ -static npy_intp -mnx (npy_intp *i , npy_intp len) -{ - npy_intp mn = 0, min = i [0]; - npy_intp j; - - for ( j = 1; j < len; j ++ ) - if ( i [j] < min ) - {min = i [j]; - mn = j;} - return mn; + *mn = min; + *mx = max; } - - /* * arr_bincount is registered as bincount. * @@ -142,7 +144,7 @@ arr_bincount(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwds) PyArray_Descr *type; PyObject *list = NULL, *weight=Py_None, *mlength=Py_None; PyArrayObject *lst=NULL, *ans=NULL, *wts=NULL; - npy_intp *numbers, *ians, len , mxi, mni, ans_size, minlength; + npy_intp *numbers, *ians, len , mx, mn, ans_size, minlength; int i; double *weights , *dans; static char *kwlist[] = {"list", "weights", "minlength", NULL}; @@ -159,14 +161,22 @@ arr_bincount(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwds) len = PyArray_SIZE(lst); type = PyArray_DescrFromType(NPY_INTP); - /* handle empty list */ - if (len < 1) { - if (mlength == Py_None) { - minlength = 0; - } - else if (!(minlength = PyArray_PyIntAsIntp(mlength))) { + if (mlength == Py_None) { + minlength = 0; + } + else { + minlength = PyArray_PyIntAsIntp(mlength); + if (minlength <= 0) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "minlength must be positive"); + } goto fail; } + } + + /* handle empty list */ + if (len == 0) { if (!(ans = (PyArrayObject *)PyArray_Zeros(1, &minlength, type, 0))){ goto fail; } @@ -175,24 +185,14 @@ arr_bincount(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwds) } numbers = (npy_intp *) PyArray_DATA(lst); - mxi = mxx(numbers, len); - mni = mnx(numbers, len); - if (numbers[mni] < 0) { + minmax(numbers, len, &mn, &mx); + if (mn < 0) { PyErr_SetString(PyExc_ValueError, "The first argument of bincount must be non-negative"); goto fail; } - ans_size = numbers [mxi] + 1; + ans_size = mx + 1; if (mlength != Py_None) { - if (!(minlength = PyArray_PyIntAsIntp(mlength))) { - goto fail; - } - if (minlength <= 0) { - /* superfluous, but may catch incorrect usage */ - PyErr_SetString(PyExc_ValueError, - "minlength must be positive"); - goto fail; - } if (ans_size < minlength) { ans_size = minlength; } @@ -680,8 +680,15 @@ arr_interp(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwdict) slopes[i] = (dy[i + 1] - dy[i])/(dx[i + 1] - dx[i]); } for (i = 0; i < lenx; i++) { - npy_intp j = binary_search(dz[i], dx, lenxp); + const double x = dz[i]; + npy_intp j; + if (npy_isnan(x)) { + dres[i] = x; + continue; + } + + j = binary_search(x, dx, lenxp); if (j == -1) { dres[i] = lval; } @@ -692,7 +699,7 @@ arr_interp(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwdict) dres[i] = rval; } else { - dres[i] = slopes[j]*(dz[i] - dx[j]) + dy[j]; + dres[i] = slopes[j]*(x - dx[j]) + dy[j]; } } NPY_END_ALLOW_THREADS; @@ -701,8 +708,15 @@ arr_interp(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwdict) else { NPY_BEGIN_ALLOW_THREADS; for (i = 0; i < lenx; i++) { - npy_intp j = binary_search(dz[i], dx, lenxp); + const double x = dz[i]; + npy_intp j; + + if (npy_isnan(x)) { + dres[i] = x; + continue; + } + j = binary_search(x, dx, lenxp); if (j == -1) { dres[i] = lval; } @@ -713,8 +727,8 @@ arr_interp(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwdict) dres[i] = rval; } else { - double slope = (dy[j + 1] - dy[j])/(dx[j + 1] - dx[j]); - dres[i] = slope*(dz[i] - dx[j]) + dy[j]; + const double slope = (dy[j + 1] - dy[j])/(dx[j + 1] - dx[j]); + dres[i] = slope*(x - dx[j]) + dy[j]; } } NPY_END_ALLOW_THREADS; @@ -1402,6 +1416,9 @@ _packbits( void *In, npy_intp out_Nm1; int maxi, remain, nonzero, j; char *outptr,*inptr; + NPY_BEGIN_THREADS_DEF; + + NPY_BEGIN_THREADS_THRESHOLDED(out_N); outptr = Out; /* pointer to output buffer */ inptr = In; /* pointer to input buffer */ @@ -1436,6 +1453,8 @@ _packbits( void *In, *outptr = build; outptr += out_stride; } + + NPY_END_THREADS; return; } @@ -1453,6 +1472,9 @@ _unpackbits(void *In, unsigned char mask; int i, index; char *inptr, *outptr; + NPY_BEGIN_THREADS_DEF; + + NPY_BEGIN_THREADS_THRESHOLDED(in_N); outptr = Out; inptr = In; @@ -1465,6 +1487,8 @@ _unpackbits(void *In, } inptr += in_stride; } + + NPY_END_THREADS; return; } |