【问题标题】:Interpolate between linear and nonlinear values在线性和非线性值之间进行插值
【发布时间】:2021-01-28 09:38:04
【问题描述】:

我已经能够成功地将值从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])

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

我创建了一个新函数,与 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”参数输入其他值,但没有成功,我不确定我是否在这里找到了错误的方法。感谢您的帮助

【问题讨论】:

    标签: python scipy interpolation


    【解决方案1】:

    我想问题是因为x 不是y 的函数,因为对于任意y 值,可能会找到多个x 值。

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

    >>> 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])
    

    【讨论】:

    • 谢谢 - 这是有道理的。想确保我没有完全走错路。我不是数学专家!
    【解决方案2】:

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

    如您所见,插值沿 y 值的有序列表(如您所指示的那样)起作用,而三次插值尤其适用。

    【讨论】:

      猜你喜欢
      • 2020-07-22
      • 2020-04-22
      • 1970-01-01
      • 2017-02-22
      • 2012-11-09
      • 1970-01-01
      • 1970-01-01
      • 2014-01-02
      • 2013-07-27
      相关资源
      最近更新 更多