2

I want to implement exponential smoothing filter in Python. Currently I calculate:

y[n] = alpha * x[n] + (1 - alpha) * y[n-1],

where x[n] is 'current sample', y[n] is new sample, y[n-1] is previous output sample and alpha is filter parameter.

I do calculation using ordinary Python iteration, as you might imagine, it is painfully slow (like, 10000 data points is already very difficult to get).

Can this calculus be coded using numpy and vector operations?

I'm not sure whether I'm interested in scipy.signal. My primary intention is to study the influence of input vector length and coefficient alpha resolution on accuracy of output.

EDIT: It seems that I did not formulate the question correctly - i'm not interested in this particular solution, but 'this kind of problem'. I'm using this equation as a base, but I add additional treatments to it, in particular rounding and restriction of integer resolution to alpha (coded as two's complement) and y[n] (trimming to specific bit width), so it gives results as good as the resolution of the parameters is (basically emulating hardware behavior). Hence lfilter from scipy is not what I can use for it. On the other hand, proposed Numba seems to be what i'm looking for.

David Belohrad
  • 458
  • 5
  • 19
  • I had that exact problem and I posted a [question in CS SE](https://cs.stackexchange.com/q/73746), then answered myself with the only solution I came up with to do it in a vectorized way, which was using some matrix multiplication. It is more expensive in time and memory, but I was using TensorFlow and it was still faster than looping. If you are using NumPy, I'd recommend you to use Numba for this, you will be able to do it blazing fast and with minimal memory. – jdehesa Feb 12 '19 at 16:04
  • You might consider trading processing time with memory and cache the results, so that the calculating for `y[n-1]` wouldn't be exponentially increased. – r.ook Feb 12 '19 at 16:17
  • Unless you can up with an explicit, non-recursive formula (which doesn't seem your case), you are stuck with recursion. You can increase speed by setting a `y = np.empty(n)` array and fill it with a loop. At least you make memory allocation more efficient (calculation still goes through the `for`). Most posts recommend Numba if you want to increase performance further. – Tarifazo Feb 12 '19 at 17:40
  • See also: https://stackoverflow.com/questions/45970182/recursion-iir-filter-with-scipy-lfilter, https://stackoverflow.com/questions/21336794/python-recursive-vectorization-with-timeseries, https://stackoverflow.com/questions/21391467/can-i-use-numpy-to-speed-this-loop – Warren Weckesser Feb 12 '19 at 18:01

0 Answers0