-
Notifications
You must be signed in to change notification settings - Fork 24
new polynomial_fit module
#145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| polynomial_fit | ||
| ============== | ||
|
|
||
| .. automodule:: pynumdiff.polynomial_fit | ||
| :members: |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,5 @@ | ||
| evaluate | ||
| ======== | ||
|
|
||
| .. currentmodule:: pynumdiff.utils.evaluate | ||
|
|
||
| .. automodule:: pynumdiff.utils.evaluate | ||
| :members: | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,5 @@ | ||
| simulate | ||
| ======== | ||
|
|
||
| .. currentmodule:: pynumdiff.utils.simulate | ||
|
|
||
| .. automodule:: pynumdiff.utils.simulate | ||
| :members: |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,5 @@ | ||
| utility | ||
| ======= | ||
|
|
||
| .. currentmodule:: pynumdiff.utils.utility | ||
|
|
||
| .. automodule:: pynumdiff.utils.utility | ||
| :members: |
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,10 @@ | ||
| """Import useful functions from all modules | ||
| """ | ||
| from pynumdiff._version import __version__ | ||
| from pynumdiff.finite_difference import first_order, second_order, fourth_order | ||
| from pynumdiff.smooth_finite_difference import mediandiff, meandiff, gaussiandiff,\ | ||
| friedrichsdiff, butterdiff, splinediff | ||
| from pynumdiff.total_variation_regularization import iterative_velocity, velocity,\ | ||
| acceleration, jerk, smooth_acceleration, jerk_sliding | ||
| from pynumdiff.linear_model import lineardiff, polydiff, spectraldiff, savgoldiff | ||
| from pynumdiff.kalman_smooth import constant_velocity, constant_acceleration, constant_jerk,\ | ||
| known_dynamics | ||
| from ._version import __version__ | ||
|
|
||
| from .finite_difference import finitediff, first_order, second_order, fourth_order | ||
| from .smooth_finite_difference import meandiff, mediandiff, gaussiandiff, friedrichsdiff, butterdiff | ||
| from .polynomial_fit import splinediff, polydiff, savgoldiff | ||
| from .total_variation_regularization import tvrdiff, velocity, acceleration, jerk, iterative_velocity, smooth_acceleration, jerk_sliding | ||
| from .kalman_smooth import rts_const_deriv, constant_velocity, constant_acceleration, constant_jerk, known_dynamics | ||
| from .linear_model import spectraldiff, lineardiff |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,3 @@ | ||
| """This module implements some common finite difference schemes | ||
| """ | ||
| from ._finite_difference import finite_difference, first_order, second_order, fourth_order | ||
| from ._finite_difference import finitediff, first_order, second_order, fourth_order |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,115 +1,25 @@ | ||
| import copy, math, logging, scipy | ||
| import math, scipy | ||
| import numpy as np | ||
| from warnings import warn | ||
|
|
||
| from pynumdiff.finite_difference import first_order as finite_difference | ||
| from pynumdiff.finite_difference import second_order as finite_difference | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A last case where the former-first-order-which-was-actually-second-order was still being imported as first order, which is now properly first order. I haven't been checking on lineardiff as closely, so this slipped through. |
||
| from pynumdiff.polynomial_fit import savgoldiff as _savgoldiff # patch through | ||
| from pynumdiff.polynomial_fit import polydiff as _polydiff # patch through | ||
| from pynumdiff.utils import utility | ||
|
|
||
| try: import cvxpy | ||
| except ImportError: pass | ||
|
|
||
|
|
||
| ######################### | ||
| # Savitzky-Golay filter # | ||
| ######################### | ||
| def savgoldiff(x, dt, params=None, options=None, poly_order=None, window_size=None, smoothing_win=None): | ||
| """Use the Savitzky-Golay to smooth the data and calculate the first derivative. It uses | ||
| scipy.signal.savgol_filter. The Savitzky-Golay is very similar to the sliding polynomial fit, | ||
| but slightly noisier, and much faster. | ||
| def savgoldiff(*args, **kwargs): | ||
| warn("`savgoldiff` has moved to `polynomial_fit.savgoldiff` and will be removed from " | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just a common pattern to make the functions still importable from the old place, for backwards compatibility. |
||
| + "`linear_model` in a future release.", DeprecationWarning) | ||
| return _savgoldiff(*args, **kwargs) | ||
|
|
||
| :param np.array[float] x: data to differentiate | ||
| :param float dt: step size | ||
| :param list params: (**deprecated**, prefer :code:`poly_order`, :code:`window_size`, and :code:`smoothing_win`) | ||
| :param dict options: (**deprecated**) | ||
| :param int poly_order: order of the polynomial | ||
| :param int window_size: size of the sliding window, must be odd (if not, 1 is added) | ||
| :param int smoothing_win: size of the window used for gaussian smoothing, a good default is | ||
| window_size, but smaller for high frequnecy data | ||
|
|
||
| :return: tuple[np.array, np.array] of\n | ||
| - **x_hat** -- estimated (smoothed) x | ||
| - **dxdt_hat** -- estimated derivative of x | ||
| """ | ||
| if params != None: # Warning to support old interface for a while. Remove these lines along with params in a future release. | ||
| warn("`params` and `options` parameters will be removed in a future version. Use `poly_order`, " + | ||
| "`window_size`, and `smoothing_win` instead.", DeprecationWarning) | ||
| poly_order, window_size, smoothing_win = params | ||
| elif poly_order == None or window_size == None or smoothing_win == None: | ||
| raise ValueError("`poly_order`, `window_size`, and `smoothing_win` must be given.") | ||
|
|
||
| window_size = np.clip(window_size, poly_order + 1, len(x)-1) | ||
| if window_size % 2 == 0: | ||
| window_size += 1 # window_size needs to be odd | ||
| warn("Kernel window size should be odd. Added 1 to length.") | ||
| smoothing_win = min(smoothing_win, len(x)-1) | ||
|
|
||
| dxdt_hat = scipy.signal.savgol_filter(x, window_size, poly_order, deriv=1)/dt | ||
|
|
||
| kernel = utility.gaussian_kernel(smoothing_win) | ||
| dxdt_hat = utility.convolutional_smoother(dxdt_hat, kernel) | ||
|
|
||
| x_hat = utility.integrate_dxdt_hat(dxdt_hat, dt) | ||
| x0 = utility.estimate_integration_constant(x, x_hat) | ||
| x_hat = x_hat + x0 | ||
|
|
||
| return x_hat, dxdt_hat | ||
|
|
||
|
|
||
| ###################### | ||
| # Polynomial fitting # | ||
| ###################### | ||
| def polydiff(x, dt, params=None, options=None, poly_order=None, window_size=None, step_size=1, | ||
| kernel='friedrichs'): | ||
| """Fit polynomials to the data, and differentiate the polynomials. | ||
|
|
||
| :param np.array[float] x: data to differentiate | ||
| :param float dt: step size | ||
| :param list[int] params: (**deprecated**, prefer :code:`poly_order` and :code:`window_size`) | ||
| :param dict options: (**deprecated**, prefer :code:`step_size` and :code:`kernel`) | ||
| a dictionary consisting of {'sliding': (bool), 'step_size': (int), 'kernel_name': (str)} | ||
| :param int poly_order: order of the polynomial | ||
| :param int window_size: size of the sliding window, if not given no sliding | ||
| :param int step_size: step size for sliding | ||
| :param str kernel: name of kernel to use for weighting and smoothing windows ('gaussian' or 'friedrichs') | ||
|
|
||
| :return: tuple[np.array, np.array] of\n | ||
| - **x_hat** -- estimated (smoothed) x | ||
| - **dxdt_hat** -- estimated derivative of x | ||
| """ | ||
| if params != None: | ||
| warn("`params` and `options` parameters will be removed in a future version. Use `poly_order` " + | ||
| "and `window_size` instead.", DeprecationWarning) | ||
| poly_order = params[0] | ||
| if len(params) > 1: window_size = params[1] | ||
| if options != None: | ||
| if 'sliding' in options and not options['sliding']: window_size = None | ||
| if 'step_size' in options: step_size = options['step_size'] | ||
| if 'kernel_name' in options: kernel = options['kernel_name'] | ||
| elif poly_order == None or window_size == None: | ||
| raise ValueError("`poly_order` and `window_size` must be given.") | ||
|
|
||
| if window_size < poly_order*3: | ||
| window_size = poly_order*3+1 | ||
| if window_size % 2 == 0: | ||
| window_size += 1 | ||
| warn("Kernel window size should be odd. Added 1 to length.") | ||
|
|
||
| def _polydiff(x, dt, poly_order, weights=None): | ||
| t = np.arange(len(x))*dt | ||
|
|
||
| r = np.polyfit(t, x, poly_order, w=weights) # polyfit returns highest order first | ||
| dr = np.polyder(r) # power rule already implemented for us | ||
|
|
||
| dxdt_hat = np.polyval(dr, t) # evaluate the derivative and original polynomials at points t | ||
| x_hat = np.polyval(r, t) # smoothed x | ||
|
|
||
| return x_hat, dxdt_hat | ||
|
|
||
| if not window_size: | ||
| return _polydiff(x, dt, poly_order) | ||
|
|
||
| kernel = {'gaussian':utility.gaussian_kernel, 'friedrichs':utility.friedrichs_kernel}[kernel](window_size) | ||
| return utility.slide_function(_polydiff, x, dt, kernel, poly_order, stride=step_size, pass_weights=True) | ||
| def polydiff(*args, **kwargs): | ||
| warn("`polydiff` has moved to `polynomial_fit.polydiff` and will be removed from " | ||
| + "`linear_model` in a future release.", DeprecationWarning) | ||
| return _polydiff(*args, **kwargs) | ||
|
|
||
|
|
||
| ############### | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| """Find a smooth fit with some kind of polynomials, and then take derivative. | ||
| """ | ||
| from ._polynomial_fit import splinediff, polydiff, savgoldiff | ||
|
|
||
| __all__ = ['splinediff', 'polydiff', 'savgoldiff'] # So automodule from the .rst finds them |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is redundant with automobile.