IIR filtering problem


Hi There!

I’m trying to use the IIR filters from the Math.NET filtering library, but regardless of what I’m trying to do they all seem unstable.

Here’s what I’m trying to do:

Coefficients = MathNet.Filtering.IIR.IirCoefficients.LowPass(samplingRate, cutoff, Bandwidth)
The generated coefficients are:

First off all I have no idea what Bandwidth is, I think it is supposed to be the bandwidth between the corner frequencies so in the case of a LowPass filter I think Bandwidth = cutoff, at least thats what I’m using right now.

I have a stochastic signa which is sampled with 10 kHz. I acquire a buffer of 1000 samples per sampling (so I get 1000 samples every 100 ms).

I’d like to low pass filter this signal using the calculated coefficients, but when I do this:

var filter = New MathNet.Filtering.IIR.OnlineIirFilter(Coefficients);
var filtered= filter.ProcessSamples(Buffer);

the filtered variable contains something unresembling the filtered signal.

Any idea what’s causing the filter to become unstable? No matter what cutoff frequency I use it is always unstable

(Asouth) #2

I’m having this same issue. It looks the the problem is with the IIR coefficients themselves, bascially plotting them in MATLAB using freqz, doesn’t reveal a magnitude reponse that anywhere near reseambles a fillter with the expected cutoffs etc. it does work FIR though. It might be if you calculate your IIR coefficents elsewhere an then order with numerator followed by denominator in an array and pass this to the OnlineIirFilter it will work/

(Tobias Glaubach) #3

I looked into the implementation and figured out, that the method signatures work with frequency input parameters, which is counter intuitive for users (like me) familiar with scipy, octave or MATLAB.

I also find the Signatures a bit obscure, not well documentet (missing examples) and also found that there are no unit tests at all for the IIR and FIR classes.

From my own implementation I found a way to call the method like that:

var samplingFrequency = 100;  // in Hertz
var bandwidth = 10;           // in Hertz
var cutoff = 5;               // in Hertz
var ab = IirCoefficients.LowPass(samplingFrequency, cutoff, bandwidth);

var nHalf = ab.Length / 2;
var den= new double[nHalf];
var num= new double[nHalf];
Array.Copy(ab, den, nHalf);
Array.Copy(ab, nHalf, num, 0, nHalf);

After that num and den are the Lowpass coefficients.

(Tobias Glaubach) #4

as for the actual algorithm, that is beeing used by the method I did some testing by variying the inputs and plotting the bode plots for the results. I varied bandwidth from 0…100 in steps of 20 as well as as cutoff with the same stepping.

The graphs are here (blue beeing magniture in dB, green beeing phase in radiants):

Then I tried to set bandwidth and cutoff equal, since a bandwidth does not really make sense for a lowpass filter. When plotting from 0 to 100 Hz with 25 steps, one gets the results below:

They are all lowpass filters, but I can not really see any meaningful way, how the cutoff and bandwidth parameters influence to the frequencies shown in the bode plots.

Anyone any hints?

I will open a github issue for that, in the next hour or so.

(Tobias Glaubach) #5

Issue here: