计算方法上机实验报告——拉格朗日插值问题
一、方法原理
n次拉格朗日插值多项式为:Ln(x)=y0l0(x)+y1l1(x)+y2l2(x)+…+ynln(x) n=1时,称为线性插值,L1(x)=y0(x-x1)/(x0-x1)+y1(x-x0)/(x1-x0)=y0+(y1-x0)(x-x0)/(x1-x0) n=2时,称为二次插值或抛物线插值,精度相对高些
L2(x)=y0(x-x1)(x-x2)/(x0-x1)/(x0-x2)+y1(x-x0)(x-x2)/(x1-x0)/(x1-x
2)+y2(x-x0)(x-x1)/(x2-x0)/(x2-x1)
二、主要思路
使用线性方程组求系数构造插值公式相对复杂,可改用构造方法来插值。
对节点xi(i=0,1,…,n)中任一点xk(0<=k<=n)作一n次多项式lk(xk),使它在该点上取值为1,而在其余点xi(i=0,1,…,k-1,k+1,…,n)上为0,则插值多项式为Ln(x)=y0l0(x)+y1l1(x)+y2l2(x)+…+ynln(x)
上式表明:n个点xi(i=0,1,…,k-1,k+1,…,n)都是lk(x)的零点。
可求得lk
三.计算方法及过程:1.输入节点的个数n
2.输入各个节点的横纵坐标
3.输入插值点
4.调用函数,返回z
函数语句与形参说明
程序源代码如下:
形参与函数类型
参数意义
intn
节点的个数
doublex[n](double*x)
存放n个节点的值
doubley[n](double*y)
存放n个节点相对应的函数值
doublep
指定插值点的值
doublefun()
函数返回一个双精度实型函数值,即插值点p处的近似函数值
#include<iostream>
#include<math.h>
usingnamespacestd;
#defineN100
doublefun(double*x,double*y,intn,doublep);
voidmain()
{inti,n;
cout<<"输入节点的个数n:";
cin>>n;
doublex[N],y[N],p;
cout<<"pleaseinputxiangliangx="<<endl;
for(i=0;i<n;i++)cin>>x[i];
cout<<"pleaseinputxiangliangy="<<endl;
for(i=0;i<n;i++)cin>>y[i];
cout<<"pleaseinputLagelangrichazhiJieDianp="<<endl;
cin>>p;
cout<<"TheAnswer="<<fun(x,y,n,p)<<endl;
system("pause");}
doublefun(doublex[],doubley[],intn,doublep)
{doublez=0,s=1.0;
intk=0,i=0;
doubleL[N];
while(k<n)
{if(k==0)
{for(i=1;i<n;i++)s=s*(p-x[i])/(x[0]-x[i]);
L[0]=s*y[0];
k=k+1;}
else
{s=1.0;
for(i=0;i<=k-1;i++)s=s*((p-x[i])/(x[k]-x[i]));
for(i=k+1;i<n;i++)s=s*((p-x[i])/(x[k]-x[i]));
L[k]=s*y[k];
k++;}
}
for(i=0;i<n;i++)z=z+L[i];
returnz;
}
四.运行结果测试:
五.实验分析
n=2时,为一次插值,即线性插值
n=3时,为二次插值,即抛物线插值
n=1,此时只有一个节点,插值点的值就是该节点的函数值
n<1时,结果都是返回0的;这里做了n=0和n=-7两种情况
3<n<100时,也都有相应的答案
常用的是线性插值和抛物线插值,显然,抛物线精度相对高些
n次插值多项式Ln(x)通常是次数为n的多项式,特殊情况可能次数小于n.例如:通过三点的二次插值多项式L2(x),如果三点共线,则y=L2(x)就是一条直线,而不是抛物线,这时L2(x)是一次式。
拟合曲线光顺性差。