ar1st0crat / NWaves

.NET DSP library with a lot of audio processing functions
MIT License
453 stars 71 forks source link

Does Savitzky-Golay filter calculate correct results? #35

Closed ToGoOrNotToGo closed 3 years ago

ToGoOrNotToGo commented 3 years ago

I am testing the Savitzky-Golay filter. The filter implementation looks very simplified. Or how were the coefficients calculated? Does the filter calculate correct results? In the example below, the filter is supposed to remove the noise. However, more is removed:

var signal = Enumerable.Range(0, 100).Select(x => (float)System.Math.Sin(x * 0.1)); var random = new Random(); var noise = Enumerable.Range(0, 100).Select(_ => (float)random.NextDouble() * 0.01f); var noisySignal = signal.Zip(noise, (x, y) => x + y).ToArray(); var filteredSignal = new SavitzkyGolayFilter(5, 1).ApplyFilterDirectly(new DiscreteSignal(1, noisySignal));

ar1st0crat commented 3 years ago

Hi,

I took coefficients from precomputed tables (like here) and then I did a double-check - I compared the coeffs with sciPy results. The coeffs are always the same, so I've just coded these tables, instead of coding a lot of linear algebra stuff.

As for filtering results, they should be correct, since SavitzkyGolayFilter is just an FIR filter. You can see the frequency response and other filter characteristics in DemoForms app:

image

Btw, ApplyFilterDirectly() method is slower than the recommended ApplyTo() method. It's one of those older methods I added for DSP learners (for their understanding of difference equations), and the suffix Directly means that the difference equation is coded as-is, without any optimizations.

ToGoOrNotToGo commented 3 years ago

Thank you for your explanation! Yes it looks good. However, it depends on the filter settings. First I was confused because I set 'deriv' to 1.

Interesting if there is a filter parameter estimaten method...

ar1st0crat commented 3 years ago

However, it depends on the filter settings

What depends? Filter length (kernel size) is the only parameter, and filter coefficients (kernel) are same for each particular length. Regardless of this length, the filter will act as a smoothing filter similar to moving average (polynomial fit, deriv=0), or a smoothing differentiator (deriv = 1,2).

Interesting if there is a filter parameter estimaten method

Do you mean how the filter coefficients are calculated? There's a description in wikipedia, section 'Derivation of convolution coefficients'. But I simply hard-coded these coefficients for kernel sizes up to 35.

If you mean if there's a way to find 'the best' filter length, then maybe it's the subject of other research. For example, I found this paper.

Anyway, back to your initial question:

Does Savitzky-Golay filter calculate correct results?

The answer is positive - the results are correct.

ToGoOrNotToGo commented 3 years ago

What depends?

I mean the "derivative" property. It has a huge impact on the result. But I'm starting to understand this property ;-)

If you mean if there's a way to find 'the best' filter length, then maybe it's the subject of other research. For example, I found this paper.

That's what I mean. Thanks for the link!