对于一系列互不相等的 x 0 , x 1 , ⋯ , x n x_0,x_1,\cdots,x_n x0,x1,⋯,xn,有差商定义如下:
f [ x i , x j ] = f ( x i ) − f ( x j ) x i − x j ( i ≠ j , i , j = 0 , 1 , ⋯ , n ) f[x_i,x_j]=\frac{f(x_i)-f(x_j)}{x_i-x_j}(i\neq j,i,j=0,1,\cdots,n) f[xi,xj]=xi−xjf(xi)−f(xj)(i=j,i,j=0,1,⋯,n)
称此为 f ( x ) f(x) f(x)在 x i , x j x_i,x_j xi,xj处的一阶差商,又称
f ( x i , x j , x k ) = f [ x i , x j ] − f [ x j , x k ] x i − x k f(x_i,x_j,x_k)=\frac{f[x_i,x_j]-f[x_j,x_k]}{x_i-x_k} f(xi,xj,xk)=xi−xkf[xi,xj]−f[xj,xk]
为 f ( x ) f(x) f(x)在 x i , x j , x k x_i,x_j,x_k xi,xj,xk处的二阶差商。
因此可以得到n阶差商的定义:
f [ x 0 , x 1 , ⋯ , x n ] = f [ x 0 , x 1 , ⋯ , x n − 1 ] − f [ x 1 , x 2 , ⋯ , x n ] x 0 − x n f[x_0,x_1,\cdots,x_n]=\frac{f[x_0,x_1,\cdots,x_{n-1}]-f[x_1,x_2,\cdots,x_n]}{x_0-x_n} f[x0,x1,⋯,xn]=x0−xnf[x0,x1,⋯,xn−1]−f[x1,x2,⋯,xn]
差商的计算方法如下:
与拉格朗日插值法不同,如果需要增加插值点,拉格朗日插值法需要重新计算所有插值点的值,重新计算基函数,而牛顿插值法只需要重附上一项即可,不需要重新计算。
牛顿插值法需要利用到差商,其插值公式如下:
N n ( x ) = f ( x 0 ) + f [ x 0 , x 1 ] ∗ ( x − x 0 ) + f [ x 0 , x 1 , x 2 ] ∗ ( x − x 0 ) ( x − x 1 ) + f [ x 0 , x 1 , x 2 , x 3 ] ∗ ( x − x 0 ) ( x − x 1 ) ( x − x 2 ) + ⋯ + f [ x 0 , x 1 , ⋯ , x n ] ∗ ( x − x 0 ) ( x − x 1 ) ⋯ ( x − x n − 1 ) \begin{aligned} N_n(x)=&f(x_0)+f[x_0,x_1]*(x-x_0)+f[x_0,x_1,x_2]*(x-x_0)(x-x_1)+\\&f[x_0,x_1,x_2,x_3]*(x-x_0)(x-x_1)(x-x_2)+\cdots +\\&f[x_0,x_1,\cdots,x_n]*(x-x_0)(x-x_1)\cdots(x-x_{n-1}) \end{aligned} Nn(x)=f(x0)+f[x0,x1]∗(x−x0)+f[x0,x1,x2]∗(x−x0)(x−x1)+f[x0,x1,x2,x3]∗(x−x0)(x−x1)(x−x2)+⋯+f[x0,x1,⋯,xn]∗(x−x0)(x−x1)⋯(x−xn−1)
//牛顿插值法
#include
#include
//求差商
void poor_quotient(double *xi,double *yi,double *Ni,int n)
{
double **a_temp=new double*[n];
for (int i=0; i < n;i++)
{
a_temp[i]=new double[n];
a_temp[i][0]=yi[i];
}
for (int j = 1; j < n;j++)
{
for (int i=j; i < n;i++)
{
a_temp[i][j]=(a_temp[i][j-1]-a_temp[i-1][j-1])/(xi[i]-xi[i-j]);
}
}
for (int i = 0; i < n; i++)
{
Ni[i] = a_temp[i][i];
}
for (int i = 0; i < n;i++)
{
delete[] a_temp[i];
}
delete[] a_temp;
}
double Newton(double *Ni,double *xi,double x,int n)
{
double result =Ni[0];
double temp = 1.0f;
for (int i = 1;i>n;
double error[3]={0.0f,0.0f,0.0f};//误差评价
double *x = new double [n];
double *y = new double [n];
double *Ni = new double [n];
double a=3, b=10;//定义插值区间
//生成插值数据
for (int i = 0;i error[0])
{
error[0] = fabs(y_temp - y_temp2);
// std::cout << y_temp2 << std::endl;
}
error[1] += fabs((y_temp - y_temp2) / y_temp);
error[2] += ((y_temp - y_temp2)) * ((y_temp - y_temp2));
}
//err[0]得到的是在区间内最大的误差
//err[1]得到的是平均最大相对误差
//err[2]是均方根误差
error[1] = error[1]/100;
error[2] = sqrt(error[2]/100);
for(int i = 0;i < 3;i++)
{
std::cout<<"误差"<