diff options
author | Timo Kluck <tkluck@infty.nl> | 2011-12-29 18:42:26 +0100 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2012-04-01 08:20:25 -0600 |
commit | b9576ed22a57cb8c7bf04038c5792bb2b499f390 (patch) | |
tree | 13cafe8b02eab06cba5da24f963c996761a66715 /numpy/lib/src | |
parent | 72185d34170369ec07e8e84ed18d2f6a814e327a (diff) | |
download | numpy-b9576ed22a57cb8c7bf04038c5792bb2b499f390.tar.gz |
ENH: improve interp() speed in some cases.
The interp function was computing slopes for all intervals, even when there
were only a few points to be interpolated. Now it only does so when the
number of interpolation points exceeds the number of sample points.
Diffstat (limited to 'numpy/lib/src')
-rw-r--r-- | numpy/lib/src/_compiled_base.c | 63 |
1 files changed, 44 insertions, 19 deletions
diff --git a/numpy/lib/src/_compiled_base.c b/numpy/lib/src/_compiled_base.c index a66e5da4c..2e290f322 100644 --- a/numpy/lib/src/_compiled_base.c +++ b/numpy/lib/src/_compiled_base.c @@ -537,7 +537,7 @@ arr_interp(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwdict) PyObject *fp, *xp, *x; PyObject *left = NULL, *right = NULL; PyArrayObject *afp = NULL, *axp = NULL, *ax = NULL, *af = NULL; - npy_intp i, lenx, lenxp, indx; + npy_intp i, lenx, lenxp; double lval, rval; double *dy, *dx, *dz, *dres, *slopes; @@ -604,29 +604,54 @@ arr_interp(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwdict) } } - slopes = (double *) PyDataMem_NEW((lenxp - 1)*sizeof(double)); - NPY_BEGIN_ALLOW_THREADS; - for (i = 0; i < lenxp - 1; i++) { - slopes[i] = (dy[i + 1] - dy[i])/(dx[i + 1] - dx[i]); - } - for (i = 0; i < lenx; i++) { - indx = binary_search(dz[i], dx, lenxp); - if (indx == -1) { - dres[i] = lval; - } - else if (indx == lenxp - 1) { - dres[i] = dy[indx]; + /* only pre-calculate slopes if there are relatively few of them. */ + if (lenxp <= lenx) { + slopes = (double *) PyDataMem_NEW((lenxp - 1)*sizeof(double)); + NPY_BEGIN_ALLOW_THREADS; + for (i = 0; i < lenxp - 1; i++) { + slopes[i] = (dy[i + 1] - dy[i])/(dx[i + 1] - dx[i]); } - else if (indx == lenxp) { - dres[i] = rval; + for (i = 0; i < lenx; i++) { + npy_intp j = binary_search(dz[i], dx, lenxp); + + if (j == -1) { + dres[i] = lval; + } + else if (j == lenxp - 1) { + dres[i] = dy[j]; + } + else if (j == lenxp) { + dres[i] = rval; + } + else { + dres[i] = slopes[j]*(dz[i] - dx[j]) + dy[j]; + } } - else { - dres[i] = slopes[indx]*(dz[i] - dx[indx]) + dy[indx]; + NPY_END_ALLOW_THREADS; + PyDataMem_FREE(slopes); + } + else { + NPY_BEGIN_ALLOW_THREADS; + for (i = 0; i < lenx; i++) { + npy_intp j = binary_search(dz[i], dx, lenxp); + + if (j == -1) { + dres[i] = lval; + } + else if (j == lenxp - 1) { + dres[i] = dy[j]; + } + else if (j == lenxp) { + 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]; + } } + NPY_END_ALLOW_THREADS; } - NPY_END_ALLOW_THREADS; - PyDataMem_FREE(slopes); Py_DECREF(afp); Py_DECREF(axp); Py_DECREF(ax); |