拉格朗日多项式插值法 思路详解+详细代码

在数学建模过程中大家经常会使用插值法对数据进行处理,而其中拉格朗日多项式插值法是较为常用到的。
以下是我在学习拉格朗日插值法时通过阅读许多大佬博主的文章时发现,要么只有代码,要么只有理论讲解或者例题,所以我就根据自己的理解总结了这篇笔记。代码附在后面 需求的大家自取即可


插值:求过已知有限个数数据点的近似函数

拟合:已知有限个数据点,求近似函数,不要求过急直数据点,只要求在某种意义下它在这些点上的总偏差最小

拉格朗日多项式插值

插值方法有许多,常用的、基本的有:拉格朗日多项式插值、牛顿插值、分段线插值、Hermite插值和三次样条插值。这里只将一下拉格朗日多项式插值法:

方法应用

通缩点说,已知n+1个点x1,x2,…,xn的函数值,可以使用lagrange插值求出一个n次多项式插值函数f(x),f(x)是接近未知原函数p(x)的函数,根据插值函数f(x)求出p(x)的未知点

具体引入

已知一个未知函数f(x)的三个点(x1,y1)、(x2,y2)、(x3,y3

存在使用一个多项式函数经过这三个点,呈现为一根曲线

因此进行合理假设,此曲线为一个二次多项式

拉格朗日认为可通过三根两次曲线来得到这根二次曲线。

关键

因此假设了三根曲线

第一根曲线f1(x),在x1点处,取值为1,其余两点(x2,y2)、(x3,y3)取值为0

第二根曲线f2(x),在x2点处,取值为1,其余两点(x1,y1)、(x3,y3)取值为0

第三根曲线f3(x),在x3点处,取值为1,其余两点(x1,y1)、(x2,y2)取值为0

所以可得到

y1f1(x)曲线可以保证,在x1处,取值为y1,其余两点取值为0

y2f2(x)曲线可以保证,在x2处,取值为y2,其余两点取值为0

y3f3(x)曲线可以保证,在x3处,取值为y3,其余两点取值为0

可以说这三根曲线就可以组成需要得到的那根二次曲线

那么,f(x)=y1f1(x)+y2f2(x)+y3f3(x)

公式推导

首先假设的三根曲线fi为二次函数

其次需满足
在这里插入图片描述

因此可以得到构造的函数(例如第一根)

​ 零点法
在这里插入图片描述

所以
f 1 ( x ) = ( x − x 2 ) ( x − x 3 ) ( x 1 − x 2 ) ( x 1 − x 3 ) {f_1}\left( x \right) = \frac{{\left( {x - {x_2}} \right)\left( {x - {x_3}} \right)}}{{\left( {{x_1} - {x_2}} \right)\left( {{x_1} - {x_3}} \right)}} f1(x)=(x1x2)(x1x3)(xx2)(xx3)
推广到一般,可得到
f ( x ) = ∑ i = 1 3 y i ⋅ f i ( x ) f\left( x \right) = \sum\limits_{i = 1}^3 {{y_i} \cdot {f_i}\left( x \right)} f(x)=i=13yifi(x)

最终公式

f i ( x ) = ( x − x 0 ) ( x − x 1 ) ⋯ ( x − x i − 1 ) ( x − x i + 1 ) ⋯ ( x − x n ) ( x i − x 0 ) ( x i − x 1 ) ⋯ ( x i − x i − 1 ) ( x i − x i + 1 ) ⋯ ( x i − x n ) {f_i}\left( x \right) = \frac{{\left( {x - {x_0}} \right)\left( {x - {x_1}} \right) \cdots \left( {x - {x_{i - 1}}} \right)\left( {x - {x_{i + 1}}} \right) \cdots \left( {x - {x_n}} \right)}}{{\left( {{x_i} - {x_0}} \right)\left( {{x_i} - {x_1}} \right) \cdots \left( {{x_i} - {x_{i - 1}}} \right)\left( {{x_i} - {x_{i + 1}}} \right) \cdots \left( {{x_i} - {x_n}} \right)}} fi(x)=(xix0)(xix1)(xixi1)(xixi+1)(xixn)(xx0)(xx1)(xxi1)(xxi+1)(xxn)

称为拉格朗日插值基函数
f n ( x ) = ∑ i = 0 n f i ( x ) ⋅ y i {f_n}\left( x \right) = \sum\limits_{i = 0}^n {{f_i}\left( x \right)} \cdot {y_i} fn(x)=i=0nfi(x)yi
为拉格朗日插值多项式公式

公式代码

function y=lagrange(x0,y0,x)
n=length(x0);
m=length(x); 
for i=1:m 
 z=x(i); 
 s=0.0; 
     for k=1:n 
        p=1.0; 
            for j=1:n 
                if j~=k 
                     p=p*(z-x0(j))/(x0(k)-x0(j)); 
                end 
            end 
         s=p*y0(k)+s; 
     end 
  y(i)=s; 
end 


引申

线性插值多项式

f 1 ( x ) = ( x − x 1 ) ( x 0 − x 1 ) ⋅ y 0 + ( x − x 0 ) ( x 1 − x 0 ) ⋅ y 1 {f_1}\left( x \right) = \frac{{\left( {x - {x_1}} \right)}}{{\left( {{x_0} - {x_1}} \right)}} \cdot {y_0} + \frac{{\left( {x - {x_0}} \right)}}{{\left( {{x_1} - {x_0}} \right)}} \cdot {y_1} f1(x)=(x0x1)(xx1)y0+(x1x0)(xx0)y1

代码

function y=sin_L(x0,y0,x1,y1,x)
% sin_L输出sin(x)使用线性插值计算得到的函数值
% 例如: y=sin_T(4,2,9,3,5)
%       y = 
%           2.200
%       R = 
%           6
 
% 以下为判断输入值是否合法的代码
if nargin~=5
    error('请输入线性插值的插值节点和插值点')
end
if ~( isnumeric(x0)&&isnumeric(y0)&&isnumeric(x1)&&isnumeric(y1)&&isnumeric(x) )
    error('输入参数必须是数')
end
 
% 核心计算的代码
y=y0+(y1-y0)*(x-x0)/(x1-x0);
 
% 以下为求解截断误差的代码
syms M2; % 因为sin(x)的二阶导数是本身,所以只需要挑出最大的y值,即可的到M2
if y0>y1
    M2=y0; 
else
    M2=y1;
end
R=M2*abs((x-x0)*(x-x1))/2
end

抛物线插值多项式

f 2 ( x ) = ( x − x 1 ) ⋅ ( x − x 2 ) ( x 0 − x 1 ) ⋅ ( x 0 − x 2 ) ⋅ y 0 + ( x − x 0 ) ( x − x 2 ) ( x 1 − x 0 ) ⋅ ( x 1 − x 2 ) ⋅ y 1 + ( x − x 0 ) ( x − x 1 ) ( x 2 − x 0 ) ⋅ ( x 2 − x 1 ) ⋅ y 2 {f_2}\left( x \right) = \frac{{\left( {x - {x_1}} \right) \cdot \left( {x - {x_2}} \right)}}{{\left( {{x_0} - {x_1}} \right) \cdot \left( {{x_0} - {x_2}} \right)}} \cdot {y_0} + \frac{{\left( {x - {x_0}} \right)\left( {x - {x_2}} \right)}}{{\left( {{x_1} - {x_0}} \right) \cdot \left( {{x_1} - {x_2}} \right)}} \cdot {y_1} + \frac{{\left( {x - {x_0}} \right)\left( {x - {x_1}} \right)}}{{\left( {{x_2} - {x_0}} \right) \cdot \left( {{x_2} - {x_1}} \right)}} \cdot {y_2} f2(x)=(x0x1)(x0x2)(xx1)(xx2)y0+(x1x0)(x1x2)(xx0)(xx2)y1+(x2x0)(x2x1)(xx0)(xx1)y2

代码

function y=sin_T(x0,y0,x1,y1,x2,y2,x)
% sin_T输出sin(x)使用抛物插值计算得到的函数值
% 例如: y=sin_T(1,1,4,2,9,3,5)
%       y = 
%           2.2667
%       R = 
%           1.4408

% 以下为判断输入值是否合法的代码
if nargin~=7
    error('请输入线性插值的插值节点和插值点')
end
if ~( isnumeric(x0)&&isnumeric(y0)&&isnumeric(x1)&&isnumeric(y1)&&isnumeric(x2)&&isnumeric(y2)&&isnumeric(x) )
    error('输入参数必须是数')
end

% 核心计算的代码
y=y0*(x-x1)*(x-x2)/((x0-x1)*(x0-x2))+y1*(x-x0)*(x-x2)/((x1-x0)*(x1-x2))+y2*(x-x0)*(x-x1)/((x2-x0)*(x2-x1));

% 以下为求解截断误差的代码
y_0=cos(x0); % 因为sin(x)的三阶导数是cos(x),那么只要求出x0,x1,x2的cos值,然后去最大即可得到M3
y_1=cos(x1);
y_2=cos(x2);
syms M3;
if y_0>y_1
    M3=y_0;
else
    M3=y_1;
end
if y_2>M3
    M3=y_2;
end
R=M3*abs((x-x0)*(x-x1)*(x-x2))/6
end
  • 32
    点赞
  • 115
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值