[Scipy-tickets] [SciPy] #1706: Error in Cookbook "Savitzky Golay"

SciPy Trac scipy-tickets@scipy....
Tue Aug 7 23:17:54 CDT 2012

#1706: Error in Cookbook "Savitzky Golay"
 Reporter:  thomas.haslwanter        |       Owner:  pv         
     Type:  defect                   |      Status:  new        
 Priority:  normal                   |   Milestone:  Unscheduled
Component:  Documentation            |     Version:  0.10.0     
 Keywords:  Cookbook Savitzky-Golay  |  

Comment(by warren.weckesser):

 I agree--an implementation of the Savitzly-Golay filter should be in
 scipy.  I also noticed some problems with the cookbook code a while ago,
 and starting rewriting it, but I only worked on the 1-d case.  I also
 wanted to break the function down into even simpler functions.  I
 implemented a function that just computes the coefficients of the filter.
 This allows the coefficients to be reused without having to compute them

 Here's the function:
 import numpy as np
 from scipy.linalg import lstsq

 def savitzky_golay_fir(window_length, polyorder, deriv=0):
     """Compute the coefficients for a 1-d Savitzky-Golay FIR filter.

     window_length : input
         The length of the filter (i.e. the number of coefficients).
     polyorder : int
         The order of the polynomial used to fit the samples.
     deriv : int, optional
         The order of the derivative to compute.  This must be a
         nonnegative integer.  The default is 0, which means to filter
         the data without differentiating.

     c : 1-d ndarray
         The filter coefficients.

     Use any convolution function (e.g. numpy.convolve,
     to apply the filter to an array.

     A. Savitzky, M. J. E. Golay, Smoothing and Differentiation of Data by
     Simplified Least Squares Procedures. Analytical Chemistry, 1964, 36
     pp 1627-1639.

     >>> savitzky_golay_fir(5, 2)
     array([-0.08571429,  0.34285714,  0.48571429,  0.34285714,
     >>> savitzky_golay_fir(5, 2, deriv=1)
     array([  2.00000000e-01,   1.00000000e-01,   2.00607895e-16,
             -1.00000000e-01,  -2.00000000e-01])
     k = window_length // 2
     x = np.linspace(-k, k, window_length)
     ord = np.arange(polyorder + 1)
     A = x ** ord[:, np.newaxis]
     y = np.zeros(polyorder + 1)
     y[deriv] = (-1.0) ** deriv
     c = lstsq(A, y)
     return c[0][:,0]

 This could be used in a higher level function that combines computing the
 coefficients with performing the convolution with a given input and
 optionally padding the input.

 It would be nice to have the 2-d version, too (and perhaps an n-d

 I'll work a pull request as soon as a I can (or review a PR if someone
 beats me to it).

Ticket URL: <http://projects.scipy.org/scipy/ticket/1706#comment:3>
SciPy <http://www.scipy.org>
SciPy is open-source software for mathematics, science, and engineering.

More information about the Scipy-tickets mailing list