Skip to content

FIR with LMS Algorithm

rossGardiner edited this page Mar 31, 2022 · 2 revisions

alt tag

An efficient finite impulse response (FIR) filter class in C++, JAVA wrapper for Android and Python wrapper.

The floating point class offers also adaptive filtering using the least mean square (LMS) or normalised least mean square (NLMS) algorithm.

The least mean square algorithm adjusts the FIR coefficients h_m with the help of an error signal e(n):

h_m(n+1) = h_m(n) + learning_rate * h_m(n) * e(n)

using the function lms_update(e) while performing the filtering with filter().

How to use the filter

  • Construct the Fir filter with all coefficients set to zero: Fir1(nCoeff)
  • Set the learning_rate with the method setLearningRate(learning_rate).
  • Provide the input signal x to the FIR filter and use its standard filter method to filter it.
  • Define your error which needs to be minimised: e = d - y
  • Feed the error back into the filter with the method lms_update(e).

The lmsdemo in the demo directory makes this concept much clearer how to remove artefacts with this method.

alt tag

The above plot shows the filter in action which removes 50Hz noise with the adaptive filter. Learning is very fast and the learning rate here is deliberately kept low to show how it works.

Stability

The FIR filter itself is stable but the error signal changes the filter coefficients which in turn change the error and so on. There is a rule of thumb that the learning rate should be less than the "tap power" of the input signal which is just the sum of all squared values held in the different taps:

learning_rate < 1/getTapInputPower()

That allows an adaptive learning rate which is called "normalised LMS". From my experiments that works in theory but in practise the realtime value of getTapInputPower() can make the algorithm easily unstable because it might suggest infinite learning rates and can fluctuate wildly. A better approach is to keep the learning rate constant and rather control the power of the input signal by, for example, normalising the input signal or limiting it.

See the demo below which removes 50Hz from an ECG which uses a normalised 50Hz signal which guarantees stability by design.

Clone this wiki locally