Source code for sg_filter
# -*- coding: utf-8 -*-
"""
A module that implements the useful Savitzky–Golay filter.
See http://en.wikipedia.org/wiki/Savitzky%E2%80%93Golay_smoothing_filter .
"""
from math import *
from numpy import *
[docs]def calc_coeff(num_points, pol_degree, diff_order=0):
""" Calculates filter coefficients for symmetric Savitzky–Golay filter.
see: http://www.nrbook.com/a/bookcpdf/c14-8.pdf
:param num_points: means that 2*num_points+1 values contribute to the smoother.
:type num_points: int.
:param pol_degree: is degree of fitting polynomial
:type pol_degree: int.
:param diff_order: is degree of implicit differentiation.
0 means that filter results in smoothing of function.
1 means that filter results in smoothing the first derivative of function.
:type diff_order: int.
:returns: numpy.array -- The coefficients for the Savitzky–Golay filter.
"""
# Setup interpolation matrix. You might use other interpolation
# points and maybe other functions than monomials.
x = arange(-num_points, num_points+1, dtype=int)
monom = lambda x, deg : pow(x, deg)
A = zeros((2*num_points+1, pol_degree+1), float)
for i in range(2*num_points+1):
for j in range(pol_degree+1):
A[i,j] = monom(x[i], j)
# calculate diff_order-th row of inv(A^T A)
ATA = dot(A.transpose(), A)
rhs = zeros((pol_degree+1,), float)
rhs[diff_order] = (-1)**diff_order
wvec = linalg.solve(ATA, rhs)
# calculate filter-coefficients
coeff = dot(A, wvec)
return coeff
[docs]def smooth(signal, coeff):
""" Applies coefficients calculated by :py:func:`calc_coeff` to signal. """
N = (size(coeff)-1)/2
res = convolve(signal, coeff)
return res[N:-N]
if __name__ == "__main__":
print "Sample run to demonstrate the SG Filter"
x=arange(0, 10., .1)
y=sin(x)
coeff = calc_coeff(5, 2, diff_order=1)
yPrime=smooth(y, coeff)
# calibrate due to unknown correction factor:
N = len(x)
dy =cos(x) # exakt
corrfac = dy[N/2]/yPrime[N/2]
import pylab
pylab.plot(x,y)
pylab.plot(x,corrfac*yPrime)
pylab.show()