哈工大计算方法实验拉格朗日.docx
《哈工大计算方法实验拉格朗日.docx》由会员分享,可在线阅读,更多相关《哈工大计算方法实验拉格朗日.docx(18页珍藏版)》请在冰豆网上搜索。
哈工大计算方法实验拉格朗日
实验题目1Lagrange插值
摘要
给定平面上n+1个不同的数据点
:
则满足条件
的n次拉格朗日插值多项式
是存在唯一的。
若
,且
充分光滑,则当
时,有误差估计式
前言
利用拉格朗日插值多项式
求
的近似值
程序设计流程
问题1
(1)
N=5时,程序运行如下:
TestLag(inline('1./(1+x.^2)'),-5,5,5,:
;
将区间[-5,5]分为了5段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
N=10时,程序运行如下:
TestLag(inline('1./(1+x.^2)'),-5,5,10,:
;
将区间[-5,5]分为了10段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
N=20时,程序运行如下:
TestLag(inline('1./(1+x.^2)'),-5,5,20,:
;
将区间[-5,5]分为了20段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
问题1
(2)
N=5时,程序运行如下:
TestLag(inline('exp(x)'),-1,1,5,[]);
将区间[-1,1]分为了5段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
*
N=10时,程序运行如下:
TestLag(inline('exp(x)'),-1,1,10,[]);
将区间[-1,1]分为了10段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
*
N=20时,程序运行如下:
TestLag(inline('exp(x)'),-1,1,20,[]);
将区间[-1,1]分为了20段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
*
0
问题2
(1)
N=5时,程序运行如下:
TestLag(inline('1./(1+x.^2)'),-1,1,5,[]);
将区间[-1,1]分为了5段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
N=10时,程序运行如下:
TestLag(inline('1./(1+x.^2)'),-1,1,10,[]);
将区间[-1,1]分为了10段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
N=20时,程序运行如下:
TestLag(inline('1./(1+x.^2)'),-1,1,20,[]);
将区间[-1,1]分为了20段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
*
实验2
(2)
N=5时,程序运行如下:
TestLag(inline('exp(x)'),-5,5,5,[]);
将区间[-5,5]分为了5段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
N=10时,程序运行如下:
TestLag(inline('exp(x)'),-5,5,10,[]);
将区间[-5,5]分为了10段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
N=20时,程序运行如下:
TestLag(inline('exp(x)'),-5,5,20,[]);
将区间[-5,5]分为了20段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
*
问题3
(1)
N=5时,程序运行如下:
TestLag2(inline('1./(1+x.^2)'),-1,1,5,[]);
将区间[-1,1]分为了5段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
*
N=10时,程序运行如下:
TestLag2(inline('1./(1+x.^2)'),-1,1,10,[]);
将区间[-1,1]分为了10段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
*
N=20时,程序运行如下:
TestLag2(inline('1./(1+x.^2)'),-1,1,20,[]);
将区间[-1,1]分为了20段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
*
问题3
(2)
N=5时,程序运行如下:
TestLag2(inline('exp(x)'),-1,1,5,[]);
将区间[-1,1]分为了5段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
*
N=10时,程序运行如下:
TestLag2(inline('exp(x)'),-1,1,10,[]);
将区间[-1,1]分为了10段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
*
N=20时,程序运行如下:
TestLag2(inline('exp(x)'),-1,1,20,[]);
将区间[-1,1]分为了20段
计算插值的点xi=
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
*
问题4
(1)程序运行如下:
TestLag3([149],[550115185])
计算插值的点xi=
550115185
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
(2)程序运行如下:
TestLag3([364964],[550115185])
计算插值的点xi=
550115185
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
(3)程序运行如下:
TestLag3([100121144],[550115185])
计算插值的点xi=
550115185
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
(4)程序运行如下:
TestLag3([169196225],[550115185])
计算插值的点xi=
550115185
计算出的插值yi=
插值点处函数值yFact=
计算误差err=
实验所用函数
functionyh=LagInterp(x,y,xh)
%LagInterp计算拉格朗日插值
%
%Synopsis:
yh=LagInterp(x,y,xh)
%
%Input:
x=一维向量,将要做插值x的值
%y=一维向量,将要做插值y的值
%xh=数值或一维向量,计算插值的位置,支持计算一列xh的值
%
%Output:
yh=数值或一维向量,通过计算插值的位置算出的插值
ifmin(size(x))>1|min(size(y))>1%判断x,y是否为一维向量
error('x,ymustbevectors!
');
elseiflength(x)~=length(y)%判断x,y是否有同样多的元素
error('xandymustagree!
');
end
yh=zeros(size(xh));
L=zeros(length(x)-1);
forj=1:
length(xh)
fori=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
functionTestLag(fx,a,b,n,xi)
%TestLag实验题目11,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);
functionTestLag2(fx,a,b,n,xi)
%TestLag2实验题目13
%
%Synopsis:
TestLag2(fun,a,b,n,xi)
%
%Input:
fx=用来验证插值计算准确率的函数
%a,b=节点选取上下限
%n=多项式次数,固定区间[-a,b]分段数
%xi=要计算插值的点
x=zeros(1,n);
fork=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);
functionTestLag3(x,xi)
%TestLag3实验题目14
%
%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('计算插值的点xi=\n');
disp(xi);
fprintf('计算出的插值yi=\n');
disp(yi);
fprintf('插值点处函数值yFact=\n');
disp(yFact);
fprintf('计算误差err=\n');
disp(err);
思考题
1.拉格朗日插值多项式的次数并不是越大越好,根据定义,插值式可以在节点处与实际函数匹配,但不能保证在节点之间很好的逼近实际函数。
这个现象就是多项式摆动——Runge现象,有时多项式摆动可以通过谨慎选择基础函数的取样点来减小。
通常采用分段插值可以很好的消除多项式摆动现象。
2.在分段段数相同的情况下,插值区间越大,误差越大。
原因是大部分情况下,相对于比较大的区间,函数在比较小的区间上的函数值变化较缓和,因此即使出现摆动也不会偏离原函数太大。
3.第一问中已经提到多项式摆动可以通过谨慎选择基础函数的取样点来减小。
我们来看下
的分布和
的图像:
可以看出,
的分布是两端密集中间稀疏,
的趋势是两边陡峭中间平缓,函数变化陡峭时节点增多正好可以增加插值的准确性。
4.一般来说,内插时插值收敛于实际函数,一旦超出内插的范围,插值函数会发散,且离插值区间越远外推误差越大。
使用不用的插值方法在同一点外推的值也会相差很多,这说明外推本身就存在很大的不确定性。