Constrained circular interpolation in python

My question is similar to the question here . To put it simply, I have a time series angle data that is constrained between [0, 360]. I need to calculate the iteration between dimensions. I am currently using scipy.interpolate.interp1d . To clarify my question, here is an example,

import numpy as np
from scipy import interpolate
data = np.array([[0, 2, 4], [1, 359, 1]]) # first row time index, second row angle measurements
f = interpolate.interp1d(data[0, :], data[1, :], kind='linear', bounds_error=False, fill_value=None)
f([1, 3])

      

this will result in [180., 180.]. However, between time 2 and time 4, the angle changed from 359 to 1, that is, only 2 degrees, and the interpolated value in 3 should have been 0. The angles change in a counterclockwise direction over time.

Finally, my question is as follows,

Is there any standard module I can use to achieve this goal?

Just because I want to avoid custom methods as much as possible!

+7


source to share


2 answers


Just add a 360 Β° padding every time you find there is a jump and go back to the first 360 degrees using the modulo operation. For example:

In [1]: import numpy as np

In [2]: from scipy import interpolate

In [3]: data = np.array([[0, 2, 4, 6, 8], [1, 179, 211, 359, 1]])

In [4]: complement360 = np.rad2deg(np.unwrap(np.deg2rad(data[1])))

In [5]: complement360
Out[5]: array([   1.,  179.,  211.,  359.,  361.])

In [6]: f = interpolate.interp1d(data[0], complement360, kind='linear', bounds_error=False, fill_value=None)

In [7]: f(np.arange(9))
Out[7]: array([   1.,   90.,  179.,  195.,  211.,  285.,  359.,  360.,  361.])

In [8]: f(np.arange(9))%360
Out[8]: array([   1.,   90.,  179.,  195.,  211.,  285.,  359.,    0.,    1.])

      

Note. I've added a few extra values ​​here, since otherwise there is no realistic way to np.unwrap

know in which direction the angle is increasing, and this is probably also how you know it is increasing in this way (the difference between successive values ​​is less than 180 Β° if there is no actual break).



If you do have data from which angular jumps more than 180 Β° between two successive elements, but you know the direction the angles change (like CCW) and that it changes monotonically, then you might find it like this:

In [31]: data = np.array([1, 359, 1, 60, 359, 177, 2])  # mock-data

In [32]: jumps = np.diff(data)<0  # assumptions: angle increases stricly monotonously CCW

In [33]: np.hstack((data[0], data[1:] + np.cumsum(np.sign(d)<0)*360))
Out[33]: array([   1,  359,  361,  420,  719,  897, 1082])

      

+6


source


As of version 1.10.0 numpy.interp takes the period keyword: http://docs.scipy.org/doc/numpy/reference/generated/numpy.interp.html



+2


source







All Articles