mathnet-filtering
mathnet-filtering copied to clipboard
Lowpass filter response with example application
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:
The lowpass filter response is below:
The bandpass filter response is below:
The bandpass with narrow band is below:
All the signals involved in this test application are below:
Any advice regarding the response of the lowpass filter is appreciated.
Attached is the Source Code and VS2019 example application for your reference.
Thanks
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
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
Dear @cdrnet, Will this issue be fixed? @SOCMarcel correctly described root cause and proposed the fix.
Can we get a fix for this?