I have been able to interpolate values successfully from linear values ofx to sine-like values ofy.
However - I am struggling to interpolate the other way - from nonlinear values ofy to linear values ofx.
The below is a toy example
import matplotlib.pylab as pltfrom scipy import interpolate#create 100 x valuesx = np.linspace(-np.pi, np.pi, 100)#create 100 values of y where y= sin(x)y=np.sin(x)#learn function to map y from xf = interpolate.interp1d(x, y)With new values of linearx
xnew = np.array([-1,1])I get correctly interpolated values of nonlineary
ynew = f(xnew)print(ynew) array([-0.84114583, 0.84114583])The problem comes when I try and interpolate values ofx fromy.
I create a new function, the reverse of f:
f2 = interpolate.interp1d(y,x,kind='cubic')I put in values of y that I successfully interpolated before
ynew=np.array([-0.84114583, 0.84114583])I am expecting to get the original values ofx [-1, 1]
But I get:
array([-1.57328791, 1.57328791])I have tried putting in other values for the 'kind' parameter with no luck and am not sure if I have got the wrong approach here. Thanks for your help
2 Answers2
I guess the problem raises from the fact, thatx is not a function ofy, since for an arbitraryy value there may be more than onex value found.
Take a look at a truncated range of data.Whenx ranges from 0 tonp.pi/2, then for everyy value there is a uniquex value.In this case the snippet below works as expected.
>>> import numpy as np>>> from scipy import interpolate>>> x = np.linspace(0, np.pi / 2, 100)>>> y = np.sin(x)>>> f = interpolate.interp1d(x, y)>>> f([0, 0.1, 0.3, 0.5])array([0. , 0.09983071, 0.29551713, 0.47941047])>>> f2 = interpolate.interp1d(y, x)>>> f2([0, 0.09983071, 0.29551713, 0.47941047])array([0. , 0.1 , 0.3 , 0.50000001])1 Comment
Maxim provided the reason for this behavior. This interpolation is a class designed to work for functions. In your case,y=arcsin(x) is only in a limited interval a function. This leads to interesting phenomena in the interpolation routine that interpolates to the nearest y-value which in the case of thearcsin() function is not necessarily the next value in the x-y curve but maybe several periods away. An illustration:
import numpy as npimport matplotlib.pylab as pltfrom scipy import interpolatexmin=-np.pixmax=np.pifig, axes = plt.subplots(3, 3, figsize=(15, 10))for i, fac in enumerate([2, 1, 0.5]): x = np.linspace(xmin * fac, xmax*fac, 100) y=np.sin(x) #x->y f = interpolate.interp1d(x, y) x_fit = np.linspace(xmin*fac, xmax*fac, 1000) y_fit = f(x_fit) axes[i][0].plot(x_fit, y_fit) axes[i][0].set_ylabel(f"sin period {fac}") if not i: axes[i][0].set_title(label="interpolation x->y") #y->x f2 = interpolate.interp1d(y, x) y2_fit = np.linspace(.99 * min(y), .99 * max(y), 1000) x2_fit = f2(y2_fit) axes[i][1].plot(x2_fit, y2_fit) if not i: axes[i][1].set_title(label="interpolation y->x") #y->x with cubic interpolation f3 = interpolate.interp1d(y, x, kind="cubic") y3_fit = np.linspace(.99 * min(y), .99 * max(y), 1000) x3_fit = f3(y3_fit) axes[i][2].plot(x3_fit, y3_fit) if not i: axes[i][2].set_title(label="cubic interpolation y->x") plt.show()As you can see, the interpolation works along the ordered list of y-values (as you instructed it to), and this works particularly badly with cubic interpolation.
Comments
Explore related questions
See similar questions with these tags.

