不添加不必要极值的插值方法

发布于 2021-01-29 15:00:32

这个问题既是编程的一半,也是数学的一半。我想通过一条曲线对点集进行插值,而又不添加不必要的极值,而这些极值保持“接近线性插值”,同时保持一条看起来平滑的曲线。我知道这种表述是模糊的,但是我希望通过一个例子可以使它更加清楚。让我们看一下下面的代码和结果:

#! /usr/bin/python

import numpy as np
from scipy.interpolate import interp1d
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.spines['left'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position('zero')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')

list_points=[(-3,0.1),(-2,0.15),(0,4),(2,-6),(4,-2),(7,-0.15),(8,-0.1)]
(xp,yp)=zip(*list_points)
fun=interp1d(xp,yp,kind='cubic')

xc=np.linspace(min(xp),max(xp),300)

plt.plot(xp,yp,'o',color='black',ms=5)
plt.plot(xc,fun(xc))
fun2=interp1d(xp,yp,kind='linear')
plt.plot(xc,fun2(xc))

plt.show()

插补

我本来希望只有两个极值(大约x〜0和x〜2)的插值,而这里我们有5个极值。如果我们要求他们手工绘制一条平滑曲线的点,这就是大多数人会画的图。有没有一种方法可以达到这个目的(在python中)。

更新:请注意,xfig的内容很接近(称为“近似样条图”),其不便之处在于曲线不能精确地通过指定点。我希望曲线能精确地通过指定点,但是如果没有人知道更好的解决方案,我会欢迎使用xfig方法。

关注者
0
被浏览
69
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    虽然不完全相同(?),但您的问题与类似,因此相同的答案可能会很有用。您可以尝试单调插值器。该PchipInterpolator类(您可以通过它的短别名参考pchip)中scipy.interpolate都可以使用。这是脚本的一个版本,pchip其中包含使用include创建的曲线:

    import numpy as np
    from scipy.interpolate import interp1d, pchip
    import matplotlib.pyplot as plt
    
    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)
    ax.spines['left'].set_position('zero')
    ax.spines['right'].set_color('none')
    ax.spines['bottom'].set_position('zero')
    ax.spines['top'].set_color('none')
    ax.xaxis.set_ticks_position('bottom')
    ax.yaxis.set_ticks_position('left')
    
    list_points = [(-3,0.1),(-2,0.15),(0,4),(2,-6),(4,-2),(7,-0.15),(8,-0.1)]
    (xp,yp) = zip(*list_points)
    fun = interp1d(xp,yp,kind='cubic')
    
    xc = np.linspace(min(xp),max(xp),300)
    
    plt.plot(xp,yp,'o',color='black',ms=5)
    plt.plot(xc,fun(xc))
    fun2 = interp1d(xp,yp,kind='linear')
    plt.plot(xc,fun2(xc))
    
    p = pchip(xp, yp)
    plt.plot(xc, p(xc), 'r', linewidth=3, alpha=0.6)
    
    plt.show()
    

    它生成的图如下所示。

    • 黑点:原始数据
    • 绿线:线性插值
    • 蓝线:三次样条插值
    • 红线:pchip插值

    情节



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看