微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在线性和非线性值之间进行插值

如何解决在线性和非线性值之间进行插值

我已经能够成功地将值从 x 的线性值插入到 y 的类正弦值。
但是 - 我正在努力插入另一种方式 - 从 y 的非线性值到 x 的线性值。

下面是一个玩具示例

import matplotlib.pylab as plt
from scipy import interpolate
#create 100 x values
x = 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 x
f = interpolate.interp1d(x,y)

使用新的线性值 x

xnew = np.array([-1,1])

我得到了非线性 y 的正确内插值

ynew = f(xnew)
print(ynew)    
array([-0.84114583,0.84114583])

当我尝试从 x 插入 y 的值时出现问题。

我创建了一个函数,f 的反函数

f2 = interpolate.interp1d(y,x,kind='cubic')

我输入了之前成功插入的 y 值

ynew=np.array([-0.84114583,0.84114583])

我希望得到 x [-1,1] 的原始值

但我明白了:

array([-1.57328791,1.57328791])

我尝试为 'kind' 参数输入其他值,但没有成功,我不确定这里是否有错误方法。感谢您的帮助

解决方法

我猜问题出自这样一个事实,即 x 不是 y 的函数,因为对于任意 y 值可能有多个 x找到值。

查看截断的数据范围。 当 x 的范围从 0 到 np.pi/2 时,每个 y 值都有一个唯一的 x 值。 在这种情况下,下面的代码段按预期工作。

>>> 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.47941047])
array([0.,0.50000001])
,

Maxim 提供了这种行为的原因。此插值是一个设计用于函数的类。在您的情况下, y=arcsin(x) 仅在有限区间内是一个函数。这导致插值例程中出现有趣的现象,即插值到最近的 y 值,在 arcsin() 函数的情况下,该值不一定是 x-y 曲线中的下一个值,但可能是几个周期之外的值。一个说明:

import numpy as np
import matplotlib.pylab as plt
from scipy import interpolate
xmin=-np.pi
xmax=np.pi

fig,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,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),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()

enter image description here

如您所见,插值是按照 y 值的有序列表进行的(按照您的指示),这对于三次插值尤其不利。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。