@@ -50,7 +50,7 @@ def splinediff(x, dt_or_t, params=None, options=None, degree=3, s=None, num_iter
5050
5151
5252def polydiff (x , dt_or_t , params = None , options = None , degree = None , window_size = None , step_size = 1 ,
53- kernel = 'friedrichs' ):
53+ kernel = 'friedrichs' , axis = 0 ):
5454 """Fit polynomials to the data, and differentiate the polynomials.
5555
5656 :param np.array[float] x: data to differentiate. May contain NaN values (missing data); NaNs are excluded from
@@ -64,6 +64,7 @@ def polydiff(x, dt_or_t, params=None, options=None, degree=None, window_size=Non
6464 :param int window_size: size of the sliding window, if not given no sliding
6565 :param int step_size: step size for sliding
6666 :param str kernel: name of kernel to use for weighting and smoothing windows ('gaussian' or 'friedrichs')
67+ :param int axis: data dimension along which differentiation is performed
6768
6869 :return: - **x_hat** (np.array) -- estimated (smoothed) x
6970 - **dxdt_hat** (np.array) -- estimated derivative of x
@@ -80,11 +81,13 @@ def polydiff(x, dt_or_t, params=None, options=None, degree=None, window_size=Non
8081 elif degree is None or window_size is None :
8182 raise ValueError ("`degree` and `window_size` must be given." )
8283
83- if window_size < degree * 3 :
84- window_size = degree * 3 + 1
85- if window_size % 2 == 0 :
86- window_size += 1
87- warn ("Kernel window size should be odd. Added 1 to length." )
84+ if window_size :
85+ if window_size < degree * 3 :
86+ window_size = degree * 3 + 1
87+ if window_size % 2 == 0 :
88+ window_size += 1
89+ warn ("Kernel window size should be odd. Added 1 to length." )
90+ kernel = {'gaussian' :utility .gaussian_kernel , 'friedrichs' :utility .friedrichs_kernel }[kernel ](window_size )
8891
8992 def _polydiff (x , dt_or_t , degree , weights = None ):
9093 t = dt_or_t if not np .isscalar (dt_or_t ) else np .arange (len (x )) * dt_or_t # sample locations
@@ -99,10 +102,13 @@ def _polydiff(x, dt_or_t, degree, weights=None):
99102
100103 return x_hat , dxdt_hat
101104
102- if not window_size : return _polydiff (x , dt_or_t , degree )
103-
104- kernel = {'gaussian' :utility .gaussian_kernel , 'friedrichs' :utility .friedrichs_kernel }[kernel ](window_size )
105- return utility .slide_function (_polydiff , x , dt_or_t , kernel , degree , stride = step_size , pass_weights = True )
105+ x_hat = np .empty_like (x ); dxdt_hat = np .empty_like (x )
106+ for vec_idx in np .ndindex (x .shape [:axis ] + x .shape [axis + 1 :]):
107+ s = vec_idx [:axis ] + (slice (None ),) + vec_idx [axis :]
108+ x_hat [s ], dxdt_hat [s ] = _polydiff (x [s ], dt_or_t , degree ) if not window_size else \
109+ utility .slide_function (_polydiff , x [s ], dt_or_t , kernel , degree , stride = step_size , pass_weights = True )
110+
111+ return x_hat , dxdt_hat
106112
107113
108114def savgoldiff (x , dt , params = None , options = None , degree = None , window_size = None , smoothing_win = None , axis = 0 ):
0 commit comments