Lagrange插值的核心就是Lagrange公式:
φ(x)=y0l0(x)+y1l1(x)+…+ymlm(x)
其中:
l0(x)= ( x − x 1 ) ( x − x 2 ) . . . ( x − x m ) ( x 0 − x 1 ) ( x 0 − x 2 ) . . . ( x 0 − x m ) \frac{(x-x_1)(x-x_2)...(x-x_m)}{(x_0-x_1)(x_0-x_2)...(x_0-x_m)} (x0−x1)(x0−x2)...(x0−xm)(x−x1)(x−x2)...(x−xm)
l1(x)= ( x − x 0 ) ( x − x 2 ) . . . ( x − x m ) ( x 1 − x 0 ) ( x 1 − x 2 ) . . . ( x 1 − x m ) \frac{(x-x_0)(x-x_2)...(x-x_m)}{(x_1-x_0)(x_1-x_2)...(x_1-x_m)} (x1−x0)(x1−x2)...(x1−xm)(x−x0)(x−x2)...(x−xm)
…
lm(x)= ( x − x 0 ) ( x − x 1 ) . . . ( x − x m − 1 ) ( x m − x 0 ) ( x m − x 2 ) . . . ( x m − x m − 1 ) \frac{(x-x_0)(x-x_1)...(x-x_{m-1})}{(x_m-x_0)(x_m-x_2)...(x_m-x_{m-1})} (xm−x0)(xm−x2)...(xm−xm−1)(x−x0)(x−x1)...(x−xm−1)
举例:
给出
f
(
x
)
=
l
n
x
f(x)=lnx
f(x)=lnx的数值表,分别用2-4次
l
a
g
r
a
n
g
e
lagrange
lagrange插值计算
l
n
(
0.54
)
ln(0.54)
ln(0.54)的近似值。
x | 0.4 | 0.5 | 0.6 | 0.7 | 0.8 |
---|---|---|---|---|---|
l n x lnx lnx | -0.916291 | -0.693147 | -0.510826 | -0.357765 | -0.223144 |
上代码:
#include<iostream>
using namespace std;
const int N = 100;//预先设定最多的插值节点个数
float Lagrange(float arrX[],float arrY[],int n,float x){
float yResult=0.0;//插值后x相应的近似值
float LValue[N];//存放各个插值基函数的函数值
int k,m;//循环变量
float temp1,temp2;//temp1作插值基函数的分子,temp2作插值基函数的分母
for(k=0; k<n; k++)
{
temp1 = 1.0;
temp2 = 1.0;
for(m=0; m<n; m++)
{
if(m==k)
{
continue;
}
temp1 *=(x-arrX[m]);
temp2 *=(arrX[k]-arrX[m]);
}
LValue[k] = temp1/temp2;
}
for(int i=0; i<n; i++)
{
yResult += arrY[i]*LValue[i];//lagrange函数表达式
}
return yResult;
}
int main()
{
float arrX[N],arrY[N];//arrX数组存放插值节点的x值,arrY数组存放相应的函数值
int num;//节点个数
while(cin>>num){//当输入插值节点个数时,进行num-1次插值
cout<<"\n--接下来输入这些插值节点--\n";
for(int i=0; i<num; i++)
{
cout<<"第"<<i+1<<"个节点的X值:";
cin>>arrX[i];
cout<<"第"<<i+1<<"个节点的Y值:";
cin>>arrY[i];
}
float X;
cout<<"\n--请输入待求解的插值节点的X值--\n";
cin>>X;
float Res = Lagrange(arrX,arrY,num,X);
cout<<"\n--插值结果为:"<<Res<<endl;
}
return 0;
}
运行结果:
小注意:n次插值需要n+1个节点。
上面例子要求2-4次插值,对应要分别输入3,4,5个节点。