def filter_savitzky_golay(y, window_size=<NUM_LIT:5>, order=<NUM_LIT:2>, deriv=<NUM_LIT:0>, rate=<NUM_LIT:1>):
try:<EOL><INDENT>window_size = np.abs(np.int(window_size))<EOL>order = np.abs(np.int(order))<EOL><DEDENT>except ValueError:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if window_size % <NUM_LIT:2> != <NUM_LIT:1> or window_size < <NUM_LIT:1>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if window_size < order + <NUM_LIT:2>:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>order_range = range(order + <NUM_LIT:1>)<EOL>half_window = (window_size - <NUM_LIT:1>) // <NUM_LIT:2><EOL>minimum = np.min(y)<EOL>maximum = np.max(y)<EOL>b = np.mat([<EOL>[k ** i for i in order_range]<EOL>for k in range(-half_window, half_window + <NUM_LIT:1>)<EOL>])<EOL>m = np.linalg.pinv(b).A[deriv] * rate ** deriv * math.factorial(deriv)<EOL>firstvals = y[<NUM_LIT:0>] - np.abs(y[<NUM_LIT:1>:half_window+<NUM_LIT:1>][::-<NUM_LIT:1>] - y[<NUM_LIT:0>])<EOL>lastvals = y[-<NUM_LIT:1>] + np.abs(y[-half_window-<NUM_LIT:1>:-<NUM_LIT:1>][::-<NUM_LIT:1>] - y[-<NUM_LIT:1>])<EOL>y = np.concatenate((firstvals, y, lastvals))<EOL>return np.clip(<EOL>np.convolve(m[::-<NUM_LIT:1>], y, mode='<STR_LIT>'),<EOL>minimum,<EOL>maximum,<EOL>)<EOL>
Smooth (and optionally differentiate) with a Savitzky-Golay filter.