函数逼近——(Newton)牛顿插值法 | 北太天元

Lagrange 插值

  • 优点:容易得到,公式紧凑

  • 不足:当增删节点时,计算需重新进行

解决方案:采用新的基函数,逐次生成多项式。 下面介绍 Newton 插值

一、 Newton插值

已知 n + 1 n+1 n+1 个不同的样本点 ( x i , y i ) , i = 0 , 1 , 2 , … , n (x_i,y_i),i=0,1,2,\dots,n (xi,yi),i=0,1,2,,n
n n n 次Newton插值多项式
N n ( x ) = C 0 ϕ 0 ( x ) + C 1 ϕ 1 ( x ) + ⋯ + C n ϕ n ( x ) N_n(x) = C_0\phi_0(x)+C_1\phi_1(x)+\dots+C_n\phi_n(x) Nn(x)=C0ϕ0(x)+C1ϕ1(x)++Cnϕn(x)
其使用的基函数如下:

  • ϕ 0 ( x ) = 1 \phi_0(x) = 1 ϕ0(x)=1
  • ϕ 1 ( x ) = ( x − x 0 ) \phi_1(x) = (x-x_0) ϕ1(x)=(xx0)
  • ϕ 2 ( x ) = ( x − x 0 ) ( x − x 1 ) \phi_2(x) = (x-x_0)(x-x_1) ϕ2(x)=(xx0)(xx1)
  • ⋮ \vdots
  • ϕ n ( x ) = ( x − x 0 ) ( x − x 1 ) ⋯ ( x − x n − 1 ) \phi_n(x) = (x-x_0)(x-x_1)\cdots(x-x_{n-1}) ϕn(x)=(xx0)(xx1)(xxn1)

基函数应满足

( ϕ 0 ( x 0 ) 0 ⋯ 0 ϕ 0 ( x 1 ) ϕ 1 ( x 1 ) ⋯ 0 ⋮ ⋮ ⋮ ϕ 0 ( x n ) ϕ 1 ( x n ) ⋯ ϕ n ( x n ) ) ( C 0 C 1 ⋮ C n ) = ( y 0 y 1 ⋮ y n ) \begin{pmatrix} \phi_0(x_0) & 0 &\cdots&0\\ \phi_0(x_1) & \phi_1(x_1) &\cdots&0\\ \vdots & \vdots & &\vdots\\ \phi_0(x_n) & \phi_1(x_n) &\cdots&\phi_n(x_n)\\ \end{pmatrix} \begin{pmatrix} C_0\\C_1\\\vdots\\C_n \end{pmatrix}=\begin{pmatrix} y_0\\y_1\\\vdots\\y_n \end{pmatrix} ϕ0(x0)ϕ0(x1)ϕ0(xn)0ϕ1(x1)ϕ1(xn)00ϕn(xn) C0C1Cn = y0y1yn

解这个方程组,可以得到 C 0 , C 1 , … , C n C_0,C_1,\dots, C_n C0,C1,,Cn

结合差商的定义

C 0 = f ( x 0 ) , C 1 = f [ x 0 , x 1 ] , C 2 = f [ x 0 , x 1 , x 2 ] , … , C n = f [ x 0 , x 1 , x 2 , … , x n ] C_0 = f(x_0),C_1 = f[x_0,x_1],C_2 = f[x_0,x_1,x_2],\dots ,C_n = f[x_0,x_1,x_2,\dots,x_n] C0=f(x0),C1=f[x0,x1],C2=f[x0,x1,x2],,Cn=f[x0,x1,x2,,xn]

N n ( x ) = f ( x 0 ) + f [ x 0 , x 1 ] ( x − x 0 ) + ⋯ + f [ x 0 , x 1 , ⋯   , x n ] ( x − x 0 ) ( x − x 1 ) ⋯ ( x − x n − 1 ) N_n(x) = f(x_0)+ f[x_0,x_1](x-x_0)+\cdots+f[x_0,x_1,\cdots,x_n](x-x_0)(x-x_1)\cdots(x-x_{n-1}) Nn(x)=f(x0)+f[x0,x1](xx0)++f[x0,x1,,xn](xx0)(xx1)(xxn1)

其中,差商可由差商表进行计算,

x i f [ x i ] f [ x i , x i + 1 ] f [ x i , x i + 1 , x i + 2 ] f [ x i , x i + 1 , x i + 2 , x i + 3 ] ⋯ x 0 f [ x 0 ] x 1 f [ x 1 ] f [ x 0 , x 1 ] x 2 f [ x 2 ] f [ x 1 , x 2 ] f [ x 0 , x 1 , x 2 ] x 3 f [ x 3 ] f [ x 2 , x 3 ] f [ x 1 , x 2 , x 3 ] f [ x 0 , x 1 , x 2 , x 3 ] ⋯ \begin{array}{c|ccccc} x_i & f[x_i] & f[x_i,x_{i+1}] & f[x_i,x_{i+1},x_{i+2}] & f[x_i,x_{i+1},x_{i+2},x_{i+3}] & \cdots\\ \hline x_0 & f[x_0] \\ x_1 & f[x_1] & f[x_0,x_1] \\ x_2 & f[x_2] & f[x_1,x_2] & f[x_0,x_1,x_2] \\ x_3 & f[x_3] & f[x_2,x_3] & f[x_1,x_2,x_3] & f[x_0,x_1,x_2,x_3] \\ \cdots\\ \end{array} xix0x1x2x3f[xi]f[x0]f[x1]f[x2]f[x3]f[xi,xi+1]f[x0,x1]f[x1,x2]f[x2,x3]f[xi,xi+1,xi+2]f[x0,x1,x2]f[x1,x2,x3]f[xi,xi+1,xi+2,xi+3]f[x0,x1,x2,x3]

二、算法的简单介绍

💖 Newton 插值 (这里只强调差商表对计算的节省)

输入:

  • n + 1 n+1 n+1 个样本点的横纵坐标分别构成的向量 x 0 , y 0 x0,y0 x0,y0
  • 目标近似点 x x x

输出:

  • 近似点的值 y y y

实现步骤

  1. 步骤 1 1 1: 计算差商表,用矩阵 D D D表示,有 n n n 行, n + 1 n+1 n+1

x 0 f [ x 0 ] x 1 f [ x 1 ] f [ x 0 , x 1 ] x 2 f [ x 2 ] f [ x 1 , x 2 ] f [ x 0 , x 1 , x 2 ] x 3 f [ x 3 ] f [ x 2 , x 3 ] f [ x 1 , x 2 , x 3 ] f [ x 0 , x 1 , x 2 , x 3 ] ⋯ \begin{array}{cccccc} x_0 & f[x_0] \\ x_1 & f[x_1] & f[x_0,x_1] \\ x_2 & f[x_2] & f[x_1,x_2] & f[x_0,x_1,x_2] \\ x_3 & f[x_3] & f[x_2,x_3] & f[x_1,x_2,x_3] & f[x_0,x_1,x_2,x_3] \\ \cdots\\ \end{array} x0x1x2x3f[x0]f[x1]f[x2]f[x3]f[x0,x1]f[x1,x2]f[x2,x3]f[x0,x1,x2]f[x1,x2,x3]f[x0,x1,x2,x3]

  1. 步骤 2 2 2: 计算基函数 ϕ i ( x ) \phi_i(x) ϕi(x)
  2. 步骤 3 3 3:
    N n ( x ) = f ( x 0 ) + f [ x 0 , x 1 ] ( x − x 0 ) + ⋯ + f [ x 0 , x 1 , ⋯   , x n ] ( x − x 0 ) ( x − x 1 ) ⋯ ( x − x n − 1 ) N_n(x)=f(x_0)+ f[x_0,x_1](x-x_0)+\cdots+f[x_0,x_1,\cdots,x_n](x-x_0)(x-x_1)\cdots(x-x_{n-1}) Nn(x)=f(x0)+f[x0,x1](xx0)++f[x0,x1,,xn](xx0)(xx1)(xxn1)

三、北太天元源程序

计算差商表

function [D] = divided_differences(x0,y0,c)
% Newton插值中用到的差商计算
% Input: 互异样本点构成的向量 (横) x0, (纵) y0, c:控制列循环的次数
% Output: 差商表 D
%   Version:            1.0
%   last modified:      04/01/2024
n = length(x0);
D = zeros(n,n+1); 
D(:,1) = x0 ;D(:,2) = y0;
if nargin < 3
    c = n+1;
end
% 列循环
for k = 3:1:c  
    % 行循环
    for i =k-1:1:n 
        D(i,k) = D(i,k-1) - D(i-1,k-1);
        D(i,k) = D(i,k)/(x0(i)-x0(i-(k-2)));
        %D   % 取消注释 D 可以观察每次的变化
    end
end
end

将上述代码保存为 divided_differences.m 文件。

Newton插值

function [N,D] = Newton_interp(x0,y0,x)
% Newton 插值法 插值逼近
% Input: 样本点构成的向量x0 (升序), (纵) y0 
%        x0,y0 是行向量
%        x  
% Output: N 插值结果 , D 差商表
%   Version:            1.0
%   last modified:      04/01/2024
n = length(x0);
D = divided_differences(x0,y0);
D_need = diag(D(:,2:n+1)); % 列
% 表示基函数
n1 = length(x);
for k = 1:1:n1
    xjx = [1,x(k)-x0(1:n-1)]; 
    for i = 2:length(xjx)
        xjx(i) = xjx(i)*xjx(i-1);
    end
    N(k) = xjx * D_need;
end
end

将上述代码保存为 Newton_interp.m 文件。

四、简单实现一下

例子1

%% 测试差商计算 
clc;clear;
x0 = [0.4 0.5 0.6 0.7 0.8];
y0 = [-0.916291 -0.693147 -0.510826 -0.357765 -0.223143];
D =divided_differences(x0,y0,4)

其中计算差商表函数中的 c ,控制着算到第 c-2 阶差商

所得差商表,第1列是 x0,第2列 为 y0,第3列为一阶差商,第4列为二阶差商

c = 3 时

D =

0.4000   -0.9163    0.0000    0.0000    0.0000    0.0000
0.5000   -0.6931    2.2314    0.0000    0.0000    0.0000
0.6000   -0.5108    1.8232    0.0000    0.0000    0.0000
0.7000   -0.3578    1.5306    0.0000    0.0000    0.0000
0.8000   -0.2231    1.3462    0.0000    0.0000    0.0000
c = 4时:

D =

0.4000   -0.9163    0.0000    0.0000    0.0000    0.0000
0.5000   -0.6931    2.2314    0.0000    0.0000    0.0000
0.6000   -0.5108    1.8232   -2.0412    0.0000    0.0000
0.7000   -0.3578    1.5306   -1.4630    0.0000    0.0000
0.8000   -0.2231    1.3462   -0.9220    0.0000    0.0000
c 不填时

D =

0.4000   -0.9163    0.0000    0.0000    0.0000    0.0000
0.5000   -0.6931    2.2314    0.0000    0.0000    0.0000
0.6000   -0.5108    1.8232   -2.0412    0.0000    0.0000
0.7000   -0.3578    1.5306   -1.4630    1.9272    0.0000
0.8000   -0.2231    1.3462   -0.9220    1.8035   -0.3092

通过c的控制,我们可以只算到我们想要的第几阶差商。

例子2

对 sin(x) 做Newton插值逼近

%%
clc;clear all;
x0 = linspace(0,15,15);
y0 = sin(x0);
x= linspace(0,15,100);
y = sin(x);
[s,M] = Newton_interp(x0,y0,x);
plot(x,y,'r');
hold on
    plot(x,s,'b');
    plot(x0,y0,'o');
    hold off
    legend('sin(x)','N(x)');

运行后得到
在这里插入图片描述

最后小结

这次写的Newton插值代码只强调了差商计算表对计算的一些简便之处,对于一组相同的样本点 x 0 , y 0 x0,y0 x0,y0,不同的近似点x,有一张共用的差商计算表,从而节省一定的计算量。

如果是在原有样本点的基础上添加新的样本点,需要注意将其的横坐标按升序重新排列,再结合旧的差商表,节省计算量的同时计算出新的差商表,这里不再进行探讨,如果有兴趣的话,可以自己实现一下。

  • 37
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

折木_phi

谢谢前辈的鼓励,我会继续加油的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值