【功能】
给定n个结点(i=0,1,…,n-1)上的函数值y=f(
),用拉格朗日(Lagrange)插值公式计算指定插值点t处的函数近似值z=f(t)。
【方法说明】
在给定的n个结点中自动选择k个结点进行插值,且使指定插值点t位于它们的中间。即选取满足条件的个结点,用n次拉格朗日插值多项式计算插值点t处的函数近似值z=f(t),即
当插值点靠近n个结点所在区间的某端时,选取的结点将少于k个;而当插值点t位于包含n个结点的区间外时,则仅取区间某端的4个结点进行插值。
//【函数程序】
//Lagrange插值
#include <cmath>
#include <iostream>
using namespace std;
//x[n] 存放n个给定的有序结点值
//y[n] 存放n个给定结点上的函数值
//n 给定结点的个数
//t 指定插值点
//函数返回指定插值点t处的函数近似值
double lagrange (double x[], double y[], int n, double t)
{
int i,j,k,m;
double z,s;
z=0.0;
if(n<1) return(z);
if (n==1) {z=y[0];return(z);}
if (n==2) {z=(y[0] *(t-x[1])-y[1]*(t-x[0]))/(x[0]-x[1]); return(z);}
i=0;
//寻找插值点t所在的位置
while((x[i]<t)&&(i<n)) i=i+1;
//取插值区间左端点
k=i-4;
if(k<0)k=0;
//取插值区间右端点
m=i+3;
if(m>n-1) m=n-1;
for(i=k;i<=m;i++)
{
s=1.0;
for (j=k;j<=m;j++)
if(j!=i) s=s*(t-x[j])/(x[i]-x[j]);
z=z+s*y[i];
}
return(z);
}
int main()
{
double t,z;
//x,y表示列表函数的值
//t表示在x位置上插值
//z表示y对应的值
int k;
cout<<"请输入结点的数:";
cin>>k;
cout<<endl;
double *x=new double[k];
cout<<"请输入x的值:";
int i;
for(i=0;i<k;i++)
{
cin>>x[i] ;
}
cout<<endl<<"请输入y的值:";
double *y=new double[k];
for(i=0;i<k;i++)
{
cin>>y[i] ;
}
cout<<endl<<"请输入插值点t的值:";
cin>>t;
z=lagrange(x,y,k,t);
cout <<"t =" <<t <<" z=" <<z<<endl;
return 0;
}
实列演示:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
0.1 | 0.2 | 0.3 | 0.4 | 0.5 | 0.55 | 0.78 | 0.84 | 0.99 | |
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
计算结果为: