mathnet-filtering icon indicating copy to clipboard operation
mathnet-filtering copied to clipboard

Lowpass filter response with example application

Open hulaomr opened this issue 4 years ago • 4 comments

Hello,

Using the following example (with release 0.7.0 from NuGet), the low pass filter has a unexpected response.

` 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 = 1; //signal amplitude double N = 0.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 * Math.PI * fw * p)) + (N * Math.Sin(2 * Math.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 `

The original signal (plus noise) is on the following chart:

image

The lowpass filter response is below:

image

The bandpass filter response is below:

image

The bandpass with narrow band is below:

image

All the signals involved in this test application are below:

image

Any advice regarding the response of the lowpass filter is appreciated.

Attached is the Source Code and VS2019 example application for your reference.

Thanks

FilterExample.zip

hulaomr avatar May 30 '20 14:05 hulaomr

Hello,

as far as I unterstand the source code (https://github.com/mathnet/mathnet-filtering/blob/master/src/Filtering/OnlineFilter.cs, https://github.com/mathnet/mathnet-filtering/blob/master/src/Filtering/FIR/FirCoefficients.cs) there seems to be an issue with CreateLowpass(ImpulseResponse mode, double sampleRate, double cutoffRate, int order) since the update from version 0.5 (which I'm still using) to 0.6, still existing in 0.7:

In case of passed mode ImpulseResponse.Finite the following code is executed: double[] c = FirCoefficients.LowPass(sampleRate, cutoffRate, order >> 1); return new OnlineFirFilter(c); Yet as you can see in the history (probably corresponding to version change from 0.5 to 0.6) the signature of FirCoefficients.LowPass(...) changed from public static double[] LowPass(double samplingRate, double cutoff, int halforder = 0) to public static double[] LowPass(double samplingRate, double cutoff, double dcGain = 1.0, int halforder = 0)

So from my point of view the order parameter from CreateLowpass(...) gets now passed as dcGain to FirCoefficients.LowPass(...) instead of halforder which results in incorrect coefficients.

Kind regards. Marcel

SOCMarcel avatar Jun 12 '20 13:06 SOCMarcel

Dear @SOCMarcel, Thanks for your feedback and analysis description. Appreciated. I will take a look and test the 0.5 version. Perhaps, according with my needs, I don't need newer version. Regards

hulaomr avatar Jun 12 '20 20:06 hulaomr

Dear @cdrnet, Will this issue be fixed? @SOCMarcel correctly described root cause and proposed the fix.

23W avatar Feb 05 '23 16:02 23W

Can we get a fix for this?

mitja-p avatar Jun 02 '23 08:06 mitja-p