MathNet.Filtering Bandpass parameters

4.7k Views Asked by At

I'm trying to use MathNet filters to apply a band pass filter to a signal; I'm using the MathNet.Filtering.OnlineFiter.CreateBandpass(..) method, to be precise.

The problem is, I'm not getting the expected results and I'm getting confused by the method's parameters. I've got a signal sampled at 1Khz, and I want to remove everything outside the 4 to 6 Hz range. What is the correct way to call the method CreateBandpass(..)?


Edit

This is the code, as requested in a comment:

OnlineFilter bandPass = CreateBandpass(ImpulseResponse.Finite, samplingRate, 3, 7);
postProcessedData = bandPass.ProcessSamples(preProcessedData);

The source is a sinewave at exactly 5 Hz with some relatively high frequency noise (like 30-70 hz); the amplitude of the signal is around 20 peak-peak, centred at 0 (so -10 to +10). The filtered signal is a sinewave at 5 Hz with no noise and an amplitude, peak-peak, of 2.1


P.S.

This happens too with a test wave, by the way. If a generate a pure sinewave (whatever the frequency) and filter it around its frequency, I obtain a sinewave of the same frequency and a totally unrelated amplitude. On the other hand if I FFT (still using MathNet) the wave and remove the components I'm not interested into, I can then rebuild the wave at the expected amplitude and totally clean from noise.

1

There are 1 best solutions below

1
On

If your signal is at 5Hz and your noise at 30-70Hz, you don't really need a bandpass filter, a lowpass will do it. Also, some attenuation is expected, although in your case is a little excessive, and the reason is... your filter is too narrow. Either use a lowpass with cutoff frequency of, let's say 10Hz, or a bandpass with low/high cutoff of 0-10Hz. The sample below shows a comparison between these options. Notice that, not surprisingly, the lowpass and bandpass filter results, with the same 10Hz bandwidth, are an exact match, as expected.

enter image description here

    //signal + noise
    double fs = 1000; //sampling rate
    double fw = 5; //signal frequency
    double fn = 50; //noise frequency
    double n = 5; //number of periods to show
    double A = 10; //signal amplitude
    double N = 1; //noise amplitude
    int size = (int)(n * fs / fw); //sample size

    var t = Enumerable.Range(1, size).Select(p => p * 1 / fs).ToArray();
    var y = t.Select(p => (A * Math.Sin(2 * pi * fw * p)) + (N * Math.Sin(2 * pi * fn * p))).ToArray(); //Original

    //lowpass filter
    double fc = 10; //cutoff frequency
    var lowpass = OnlineFirFilter.CreateLowpass(ImpulseResponse.Finite, fs, fc);

    //bandpass filter
    double fc1 = 0; //low cutoff frequency
    double fc2 = 10; //high cutoff frequency
    var bandpass = OnlineFirFilter.CreateBandpass(ImpulseResponse.Finite, fs, fc1, fc2);

    //narrow bandpass filter
    fc1 = 3; //low cutoff frequency
    fc2 = 7; //high cutoff frequency
    var bandpassnarrow = OnlineFirFilter.CreateBandpass(ImpulseResponse.Finite, fs, fc1, fc2);

    double[] yf1 = lowpass.ProcessSamples(y); //Lowpass
    double[] yf2 = bandpass.ProcessSamples(y); //Bandpass
    double[] yf3 = bandpassnarrow.ProcessSamples(y); //Bandpass Narrow