[SciPy-dev] reimplementation of lfilter
Sturla Molden
sturla at molden.no
Tue Sep 22 02:21:44 EDT 2009
Looking at this atrocious piece of C:
http://svn.scipy.org/svn/scipy/trunk/scipy/signal/lfilter.c.src
I got some inspiration for reusing some of my other C code to
reimplement scipy.signal.lfilter. I basically just had to write
this small C function + a Cython wrapper:
static void lfilter_1d(double *restrict b, double *restrict a,
double *x, double *y, double *zi, npy_intp K, npy_intp N)
{
double Z[K];
double *restrict pz = zi, *restrict z = Z;
register npy_intp n, k;
for (n=0; n<N; n++) {
register double yn, xn = x[n];
yn = y[n] = b[0] * xn + pz[0];
for (k=0; k<K-1; k++)
z[k] = b[k+1] * xn + pz[k+1] - a[k+1]*yn;
z[K-1] = b[K]*xn - a[K]*yn;
double *tmp = pz;
pz = z;
z = tmp;
}
if (pz != zi)
memcpy(zi, pz, K*sizeof(double));
}
Relative speed compared to scipy.signal.lfilter:
One processor:
1D array, 1000000 floats: 150%
2D array, 1000 x 1000 floats, axis=0: 80%
2D array, 1000 x 1000 floats, axis=1: 150%
It is faster than lfilter except for 2D with axis=0. For
2D with axis=1 it is probably faster than lfilter due to
copy-in copy-out optimization. For arrays with more than
one dimension, multithreading helps as well:
Four processors:
1D array, 1000000 floats: 150%
2D array, 1000 x 1000 floats, axis=0: 160%
2D array, 1000 x 1000 floats, axis=1: 250%
Multithreading obviously does not help for filtering single
vector, as there is no work to share.
Some other improvements over signal.lfilter, apart from readable
Cython code:
* GIL is released. The C code is not littered with Python C
API calls that prevents this.
* Filtering can be done in reverse, i.e. no need for fliplr or
flipud for filtering backwards.
* Arrays can be filtered in-place.
* Cleaned up docstring.
Still it only work as a "proof of concept" with double precision
floats. Adding support for other dtypes would be easy, just
replace double with any of:
float
float _Complex
double _Complex
long double
long double _Complex
Regards,
Sturla Molden
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: linear_filter.pyx
URL: <http://mail.python.org/pipermail/scipy-dev/attachments/20090922/f052db95/attachment.ksh>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: _linear_filter.c
URL: <http://mail.python.org/pipermail/scipy-dev/attachments/20090922/f052db95/attachment.c>
More information about the SciPy-Dev
mailing list