Lagrange插值多项式,公式结构紧凑,理论分析方便,但插值节点增减时全部插值及函数均要随之变换,实际计算不方便。借此引入牛顿插值公式。
均差表计算公式:
均差表
xi | f(xi) | 一阶均差 | 二阶均差 | ... | n阶均差 |
x0 | f(x0) | ... | |||
x1 | f(x1) | f[x0,x1] | ... | ||
x2 | f(x2) | f[x1,x2] | f[x0,x1,x2] | ... | |
. | . | . | . | ... | . |
xn | f(xn) | f[x(n-1),xn] | f[x(n-2),x(n-1),xn] | ... | f[x0,x1,..,xn] |
程序思路
程序包括了三个模块:赋值、求解以及输出模块
这一次将着重介绍输出均差表的输出模块。在这一次的编写程序中,有一个新奇点的是在输出模块中实现了下三角的表格输出。使用循环嵌套,第一个执行的循环将完成表格的横向输出,第二个执行的循环将完成纵向输出。从均差表中可以看出第一行只有一个f(x0),第二行有f(x1)、f[x0,x1],以此类推到第n行有n个。这就要求每次执行外层的循环一次后到执行内层循环时,内层循环的次数将加一。符合这种关系的循环判断变量就是外层循环的递增变量i,所以内层循环的循环判断变量是与i有关。
for (int i = 1; i <= n; i++)//
{
cout << x[i] << " ";
for (int j = 0; j <= i - 1; j++)
{
cout << F[j][i - j] << " ";
}
cout << endl;//第一行输出完后,换行继续输出下一行
}//两个for循环构成下三角形输出。
附上实现程序(Visual Studio 2019)
#include <iostream>
#include <iomanip>
double x[100];//定义式样点的x值
double F[100][100];//定义各阶均差值
double xk;//定义插入点xk值
double Fk;//定义插入点xk对应的Fk函数值
void func_F(int n);//调用求各阶均差值函数
double func_Fk(int n);//调用求xk插值点的函数值
int main()
{
using namespace std;
int n;
cout << "式样点个数" << endl;
cin >> n;
for (int i = 1; i <= n; i++)
{
cout << "x" << i << "和" << "f" << i << endl;
cin >> x[i] >> F[0][i];
}
cout << "输入求解点xk" << endl;
cin >> xk;//赋值模块
func_F(n);//调用求各阶均差值函数
func_Fk(n);//调用求xk插值点的函数值
cout << "*********输出结果*********" << endl;
cout << "********牛顿均差表********" << endl;
cout << setiosflags(ios::fixed) << setprecision(3);//输出结果保留3位小数
for (int i = 1; i <= n; i++)//
{
cout << x[i] << " ";
for (int j = 0; j <= i - 1; j++)
{
cout << F[j][i - j] << " ";
}
cout << endl;//第一行输出完后,换行继续输出下一行
}//两个for循环构成下三角形输出。
cout << endl;
cout << "xk对应的函数值Fk为:" << Fk;
return 0;
}
void func_F(int n)//调用求各阶均差值函数
{
for (int i = 1; i <= n - 1; i++)
{
for (int j = 1; j <= n - i; j++)
{
F[i][j] = (F[i - 1][j + 1] - F[i - 1][j]) / (x[j + i] - x[j]);
}
}
}
double func_Fk(int n)//调用求xk插值点的函数值
{
double w = 1;
Fk = F[0][1];
for (int i = 1; i <= n - 1; i++)
{
w *= xk - x[i];
Fk += w * F[i][1];
}
return Fk;
}
例题
1 | 2 | 3 | 4 |
0 | 2 | 2 | 5 |
求f(2.5)的牛顿插值:
不足
这次程序还有一些不足,并不能把每一列的数据靠左对齐,上面的截图是一种特殊情况。列与列之间的空间是通过cout << " ";这输出空格的形式得出的,但是当前面的数据的长度与上一行不同时,将会导致每一列的数据不对齐。