_______________________________________________________数学建模清风网课笔记
一、插值多项式
也就是说,其实这个多项式是人为规定的,且通过矩阵可以证明在n阶时候的多项式唯一
拉格朗日插值法
公式:,
其中
一般而言不用此类方法,存在弊端,基本了解即可
龙格现象(Runge)
高次插值时,拉格朗日插值多项式结果在两端波动较大,产生明显的震荡
二、分段线性插值
QUESTION:插值时候,次数变高精度下降?引入误差?
A:分段去插值,提高精度
分段二次插值
牛顿插值法(一般也不多用)
与拉格朗日插值的对比:牛顿插值与前n项有关,比如说再加入一个节点,只需要在n阶结果后面加一项即可,计算较为方便;但一样存在龙格现象
埃尔米特插值法(Hermite)
结合分段插值和埃尔米特插值以后
分段三次埃尔米特插值(PCHIP)(重点,较为常用)
三、python代码实现:
主要是引入spciy.interpolate里的各种插值函数
#插值算法
import numpy as np
import matplotlib.pyplot as plt
#import math
from scipy.interpolate import PchipInterpolator #引入三次hermite插值
from scipy.interpolate import lagrange #引入拉格朗日插值,极其不稳定拟合效果较差
from scipy.interpolate import CubicSpline #引入三次样条插值
# 创建x轴数据
x = np.linspace(0, 10, 200)
x_sample = np.linspace(0, 10, 6)
#创建正弦函数
y = np.sin(x)
y_sample = np.sin(x_sample)
f1 = lagrange(x_sample,y_sample)
f2 = PchipInterpolator(x_sample,y_sample)
f3 = CubicSpline(x_sample,y_sample)
# 绘制图形
plt.title('Sin Function Plot')
plt.plot(x_sample, y_sample,'ro',label='sample')
plt.plot(x, y,'b',label='sin')
plt.plot(x,f1(x),'y',label='lagrange')
plt.plot(x,f2(x),'g',label='PCHIP')
plt.plot(x,f3(x),'m',label='CS')
plt.xlabel('x')
plt.ylabel('sin(x)')
plt.legend()
plt.grid(True)
plt.show()
拟合图像效果
(黄色为拉格朗日,绿色为三次埃尔米特插值,品红色为三次样条插值)
四、用于预测
应用场景一:人口预测
年份 | 2009 | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 |
人口数量 | 13345 | 13378 | 13489 | 13588 | 13745 | 13908 | 14100 | 14250 | 14443 | 14780 |
预测2019、2020、2021年度人口数量的python实现:
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import PchipInterpolator #引入三次hermite插值
from scipy.interpolate import lagrange #引入拉格朗日插值,极其不稳定拟合效果较差
from scipy.interpolate import CubicSpline #引入三次样条插值
#预测人口例子
year = np.linspace(2009,2018,10)
year_new = np.linspace(2009,2021,13)
population = [13345,13378,13489,13588,13745,13908,14100,14250,14443,14780]
f1 = PchipInterpolator(year,population)
f2 = CubicSpline(year,population)
f1_new = f1(year_new)
f2_new = f2(year_new)
# 提取2019年到2020年的数据(注意:切片是左闭右开的,所以使用2022来包含2021年的点)
year_slice = year_new[2019-2009:2022-2009] # 因为year_new是从2009开始的,所以索引需要相应调整
f1_slice = f1_new[2019-2009:2022-2009]
f2_slice = f2_new[2019-2009:2022-2009]
#绘制人口图像
plt.plot(year,population,'bo',label='before')
plt.plot(year_slice,f1_slice,'r',label='PchipInterpolator')
plt.plot(year_slice,f2_slice,'g',label='CubicSpline')
plt.plot(year_slice,f1_slice,'r*')
plt.plot(year_slice,f2_slice,'g*')
plt.title('population forecast')
plt.legend()
plt.show()