摘要
给定平面上n+1个不同的数据点则满足条件
的n次拉格朗日插值多项式
:
是存在唯一的。若式
,且
充分光滑,则当
时,有误差估计
前言
利用拉格朗日插值多项式
求
的近似值
程序设计流程
开始 输入(xi,yi),n i=0,1,2,…,n L=0 i=0 xl=1 xl=xxjxixj*xl j=0,1,…,i-1,i+1,…,n L=L+xl*yi i=i+1 i=n? 是 输出y 结束 拉格朗日插值框图
否
问题1 (1)
N = 5时,程序运行如下:
TestLag(inline('1./(1+x.^2)'), -5, 5, 5, 0.75:4.75); 将区间[-5,5]分为了5段 计算插值的点 xi =
0.7500 1.7500 2.7500 3.7500 4.7500 计算出的插值 yi =
0.9054 0.5258 0.0096 -0.3568 -0.1595 插值点处函数值 yFact =
0.6400 0.2462 0.1168 0.0664 0.0424 计算误差 err =
-0.2654 -0.2796 0.1072 0.4232 0.2020
N = 10时,程序运行如下:
TestLag(inline('1./(1+x.^2)'), -5, 5, 10, 0.75:4.75); 将区间[-5,5]分为了10段 计算插值的点 xi =
0.7500 1.7500 2.7500 3.7500 4.7500 计算出的插值 yi =
0.6907 0.2330 0.1122 0.1084 -0.2360 插值点处函数值 yFact =
0.6400 0.2462 0.1168 0.0664 0.0424 计算误差 err =
-0.0507 0.0132 0.0045 -0.0420 0.2785
N = 20时,程序运行如下:
TestLag(inline('1./(1+x.^2)'), -5, 5, 20, 0.75:4.75); 将区间[-5,5]分为了20段 计算插值的点 xi =
0.7500 1.7500 2.7500 3.7500 4.7500 计算出的插值 yi =
0.6413 0.2491 0.1282 0.1903 6.4150 插值点处函数值 yFact =
0.6400 0.2462 0.1168 0.0664 0.0424 计算误差 err =
-0.0013 -0.0029 -0.0114 -0.1239 -6.3726
问题1 (2)
N = 5时,程序运行如下:
TestLag(inline('exp(x)'), -1, 1, 5, [-0.95 -0.05 0.05 0.95]); 将区间[-1,1]分为了5段 计算插值的点 xi =
-0.9500 -0.0500 0.0500 0.9500 计算出的插值 yi =
0.3863 0.9513 1.0512 2.5863 插值点处函数值 yFact =
0.3867 0.9512 1.0513 2.5857 计算误差 err = 1.0e-003 *
0.4471 -0.1051 0.1069 -0.6129
N = 10时,程序运行如下:
TestLag(inline('exp(x)'), -1, 1, 10, [-0.95 -0.05 0.05 0.95]); 将区间[-1,1]分为了10段 计算插值的点 xi =
-0.9500 -0.0500 0.0500 0.9500
计算出的插值 yi =
0.3867 0.9512 1.0513 2.5857 插值点处函数值 yFact =
0.3867 0.9512 1.0513 2.5857 计算误差 err = 1.0e-008 *
-0.3126 -0.0055 -0.0055 -0.3714
N = 20时,程序运行如下:
TestLag(inline('exp(x)'), -1, 1, 20, [-0.95 -0.05 0.05 0.95]); 将区间[-1,1]分为了20段 计算插值的点 xi =
-0.9500 -0.0500 0.0500 0.9500 计算出的插值 yi =
0.3867 0.9512 1.0513 2.5857 插值点处函数值 yFact =
0.3867 0.9512 1.0513 2.5857 计算误差 err = 1.0e-012 *
0.7339 0 -0.0002 -0.5671
问题2 (1)
N = 5时,程序运行如下:
TestLag(inline('1./(1+x.^2)'), -1, 1, 5, [-0.95 -0.05 0.05 0.95]); 将区间[-1,1]分为了5段 计算插值的点 xi =
-0.9500 -0.0500 0.0500 0.9500
计算出的插值 yi =
0.5136 0.9978 0.9978 0.5136 插值点处函数值 yFact =
0.5256 0.9975 0.9975 0.5256 计算误差 err =
0.0121 -0.0002 -0.0002 0.0121
N = 10时,程序运行如下:
TestLag(inline('1./(1+x.^2)'), -1, 1, 10, [-0.95 -0.05 0.05 0.95]); 将区间[-1,1]分为了10段 计算插值的点 xi =
-0.9500 -0.0500 0.0500 0.9500 计算出的插值 yi =
0.5243 0.9975 0.9975 0.5243 插值点处函数值 yFact =
0.5256 0.9975 0.9975 0.5256 计算误差 err =
0.0014 0.0000 0.0000 0.0014
N = 20时,程序运行如下:
TestLag(inline('1./(1+x.^2)'), -1, 1, 20, [-0.95 -0.05 0.05 0.95]); 将区间[-1,1]分为了20段 计算插值的点 xi =
-0.9500 -0.0500 0.0500 0.9500 计算出的插值 yi =
0.5256 0.9975 0.9975 0.5256 插值点处函数值 yFact =
0.5256 0.9975 0.9975 0.5256 计算误差 err = 1.0e-005 *
-0.7023 0.0000 0.0000 -0.7023
实验2 (2)
N = 5时,程序运行如下:
TestLag(inline('exp(x)'), -5, 5, 5, [-4.75 -0.25 0.25 4.75]); 将区间[-5,5]分为了5段 计算插值的点 xi =
-4.7500 -0.2500 0.2500 4.7500
计算出的插值 yi =
-1.9321 1.4275 0.5882 123.7146 插值点处函数值 yFact =
0.0087 0.7788 1.2840 115.5843 计算误差 err =
1.9408 -0.6487 0.6958 -8.1303
N = 10时,程序运行如下:
TestLag(inline('exp(x)'), -5, 5, 10, [-4.75 -0.25 0.25 4.75]); 将区间[-5,5]分为了10段 计算插值的点 xi =
-4.7500 -0.2500 0.2500 4.7500 计算出的插值 yi =
0.0425 0.7796 1.2848 115.6630 插值点处函数值 yFact =
0.0087 0.7788 1.2840 115.5843 计算误差 err =
-0.0339 -0.0008 -0.0008 -0.0788
N = 20时,程序运行如下:
TestLag(inline('exp(x)'), -5, 5, 20, [-4.75 -0.25 0.25 4.75]); 将区间[-5,5]分为了20段 计算插值的点 xi =
-4.7500 -0.2500 0.2500 4.7500 计算出的插值 yi =
0.0087 0.7788 1.2840 115.5843 插值点处函数值 yFact =
0.0087 0.7788 1.2840 115.5843 计算误差 err = 1.0e-007 *
-0.0914 0.0000 0.0000 -0.1434
问题3 (1)
N =5时,程序运行如下:
TestLag2(inline('1./(1+x.^2)'), -1, 1, 5, [-0.95 -0.05 0.05 0.95]); 将区间[-1,1]分为了5段 计算插值的点 xi =
-0.9500 -0.0500 0.0500 0.9500
计算出的插值 yi =
0.5254 0.9978 0.9978 0.5254 插值点处函数值 yFact =
0.5256 0.9975 0.9975 0.5256 计算误差 err = 1.0e-003 *
0.2071 -0.3011 -0.3011 0.2071
N =10时,程序运行如下:
TestLag2(inline('1./(1+x.^2)'), -1, 1, 10, [-0.95 -0.05 0.05 0.95]); 将区间[-1,1]分为了10段 计算插值的点 xi =
-0.9500 -0.0500 0.0500 0.9500 计算出的插值 yi =
0.5255 0.9972 0.9972 0.5255 插值点处函数值 yFact =
0.5256 0.9975 0.9975 0.5256 计算误差 err = 1.0e-003 *
0.1562 0.2603 0.2603 0.1562
N =20时,程序运行如下:
TestLag2(inline('1./(1+x.^2)'), -1, 1, 20, [-0.95 -0.05 0.05 0.95]); 将区间[-1,1]分为了20段 计算插值的点 xi =
-0.9500 -0.0500 0.0500 0.9500 计算出的插值 yi =
0.5256 0.9975 0.9975 0.5256 插值点处函数值 yFact =
0.5256 0.9975 0.9975 0.5256 计算误差 err = 1.0e-007 *
0.2318 0.2381 0.2381 0.2318
问题3 (2)
N =5时,程序运行如下:
TestLag2(inline('exp(x)'), -1, 1, 5, [-0.95 -0.05 0.05 0.95]); 将区间[-1,1]分为了5段 计算插值的点 xi =
-0.9500 -0.0500 0.0500 0.9500
计算出的插值 yi =
0.3867 0.9514 1.0511 2.5857 插值点处函数值 yFact =
0.3867 0.9512 1.0513 2.5857 计算误差 err = 1.0e-003 *
0.0079 -0.1317 0.1339 -0.0108
N =10时,程序运行如下:
TestLag2(inline('exp(x)'), -1, 1, 10, [-0.95 -0.05 0.05 0.95]); 将区间[-1,1]分为了10段 计算插值的点 xi =
-0.9500 -0.0500 0.0500 0.9500 计算出的插值 yi =
0.3867 0.9512 1.0513 2.5857 插值点处函数值 yFact =
0.3867 0.9512 1.0513 2.5857 计算误差 err = 1.0e-009 *
-0.5045 -0.4791 -0.4835 -0.5994
N =20时,程序运行如下:
TestLag2(inline('exp(x)'), -1, 1, 20, [-0.95 -0.05 0.05 0.95]); 将区间[-1,1]分为了20段 计算插值的点 xi =
-0.9500 -0.0500 0.0500 0.9500 计算出的插值 yi =
0.3867 0.9512 1.0513 2.5857 插值点处函数值 yFact =
0.3867 0.9512 1.0513 2.5857 计算误差 err = 1.0e-015 *
0.1665 0.3331 -0.4441 -0.8882
问题4
(1) 程序运行如下:
TestLag3([1 4 9], [5 50 115 185]) 计算插值的点 xi = 5 50 115 185 计算出的插值 yi =
2.2667 -20.2333 -171.9000 -492.7333 插值点处函数值 yFact =
2.2361 7.0711 10.7238 13.6015 计算误差 err =
-0.0306 27.3044 182.6238 506.3348 (2) 程序运行如下:
TestLag3([36 49 64], [5 50 115 185]) 计算插值的点 xi = 5 50 115 185
计算出的插值 yi =
3.1158 7.0718 10.1670 10.0388 插值点处函数值 yFact =
2.2361 7.0711 10.7238 13.6015 计算误差 err =
-0.8797 -0.0007 0.5568 3.5626 (3) 程序运行如下:
TestLag3([100 121 144], [5 50 115 185]) 计算插值的点 xi = 5 50 115 185
计算出的插值 yi =
4.4391 7.2850 10.7228 13.5357 插值点处函数值 yFact =
2.2361 7.0711 10.7238 13.6015 计算误差 err =
-2.2030 -0.2139 0.0010 0.0658 (4) 程序运行如下:
TestLag3([169 196 225], [5 50 115 185]) 计算插值的点 xi = 5 50 115 185 计算出的插值 yi =
5.4972 7.8001 10.8005 13.6006 插值点处函数值 yFact =
2.2361 7.0711 10.7238 13.6015 计算误差 err =
-3.2611 -0.7291 -0.0767 0.0009
实验所用函数
function yh = LagInterp(x, y, xh) % LagInterp 计算拉格朗日插值 %
% Synopsis: yh = LagInterp(x, y, xh) %
% Input: x = 一维向量,将要做插值x的值 % y = 一维向量,将要做插值y的值
% xh = 数值或一维向量,计算插值的位置,支持计算一列xh的值 %
% Output: yh = 数值或一维向量,通过计算插值的位置算出的插值 if min(size(x)) > 1 | min(size(y)) > 1 %判断x,y是否为一维向量 error('x,y must be vectors!'); elseif length(x) ~= length(y) %判断x,y是否有同样多的元素 error('x and y must agree!'); end
yh = zeros(size(xh)); L = zeros(length(x) - 1); for j = 1:length(xh) for i = 1:length(x) xCal = x; xCal(i) = [];
%prod(xh(j) - xCal)/prod(x(i) - xCal)为拉格朗日基函数
L(i) = prod(xh(j) - xCal)/prod(x(i) - xCal); yh(j) = yh(j) + L(i) * y(i); %yh = sum(L(i) * y(i)) end
end
function TestLag(fx, a, b, n, xi) % TestLag 实验题目1 1,2 %
% Synopsis: TestLag(fun, a, b, n, xi) %
% Input: fx = 用来验证插值计算准确率的函数 % a,b = 节点选取上下限
% n = 多项式次数,固定区间[-a,b]分段数 % xi = 要计算插值的点
x = linspace(a, b, n); y = feval(fx, x);
yi = LagInterp(x, y, xi); yFact = feval(fx, xi); err = yFact - yi;
fprintf('将区间[%d,%d]分为了%d段\\n', a, b, n); fprintf('计算插值的点 xi =\\n'); disp(xi);
fprintf('计算出的插值 yi =\\n'); disp(yi);
fprintf('插值点处函数值 yFact =\\n'); disp(yFact);
fprintf('计算误差 err =\\n'); disp(err);
function TestLag2(fx, a, b, n, xi) % TestLag2 实验题目1 3 %
% Synopsis: TestLag2(fun, a, b, n, xi) %
% Input: fx = 用来验证插值计算准确率的函数 % a,b = 节点选取上下限
% n = 多项式次数,固定区间[-a,b]分段数 % xi = 要计算插值的点
x = zeros(1,n); for k = 1:n
x(k) = cos( (2*k-1)*pi/(2*n) ); %构造非等距节点 end
y = feval(fx, x);
yi = LagInterp(x, y, xi); yFact = feval(fx, xi); err = yFact - yi;
fprintf('将区间[%d,%d]分为了%d段\\n', a, b, n); fprintf('计算插值的点 xi =\\n'); disp(xi);
fprintf('计算出的插值 yi =\\n'); disp(yi);
fprintf('插值点处函数值 yFact =\\n'); disp(yFact);
fprintf('计算误差 err =\\n'); disp(err);
function TestLag3(x, xi) % TestLag3 实验题目1 4 %
% Synopsis: TestLag3(fun, a, b, n, xi) %
% Input: x = 构造Lagrange插值的节点 % xi = 要计算插值的点 fx = inline('sqrt(x)'); y = feval(fx, x);
yi = LagInterp(x, y, xi); yFact = feval(fx, xi); err = yFact - yi;
fprintf('计算插值的点 disp(xi);
fprintf('计算出的插值 disp(yi);
fprintf('插值点处函数值 disp(yFact);
fprintf('计算误差 disp(err);
xi =\\n'); yi =\\n'); yFact =\\n'); err =\\n');
思考题
1. 拉格朗日插值多项式的次数并不是越大越好,根据定义,插值式可以在节点处与实际函
数匹配,但不能保证在节点之间很好的逼近实际函数。这个现象就是多项式摆动——Runge现象,有时多项式摆动可以通过谨慎选择基础函数的取样点来减小。通常采用分段插值可以很好的消除多项式摆动现象。
2. 在分段段数相同的情况下,插值区间越大,误差越大。原因是大部分情况下,相对于比
较大的区间,函数在比较小的区间上的函数值变化较缓和,因此即使出现摆动也不会偏离原函数太大。
3. 第一问中已经提到多项式摆动可以通过谨慎选择基础函数的取样点来减小。我们来看下
的分布和
的图像:
可以看出,
的分布是两端密集中间稀疏,
的趋势是两边陡峭中间平缓,函数变化
陡峭时节点增多正好可以增加插值的准确性。
4. 一般来说,内插时插值收敛于实际函数,一旦超出内插的范围,插值函数会发散,且离
插值区间越远外推误差越大。使用不用的插值方法在同一点外推的值也会相差很多,这说明外推本身就存在很大的不确定性。
因篇幅问题不能全部显示,请点此查看更多更全内容