1.2. Интерполяционные формулы для равноотстоящих узлов
Если значения функции заданы в точкахс постоянным положительным шагом, то часто используется интерполяционный многочлен Ньютона для интерполяции вперед
,(1.10)
где , а конечные разности, носящие названия нисходящих разностей, находят из соотношений
,
.
Интерполяционный многочлен (1.10) удобно использовать при работе в начале таблицы значений функции и для экстраполяции левее точки .
Интерполяционный многочлен с узлами где, имеет вид
(1.11)
и называется интерполяционным многочленом Ньютона для интерполяции назад. Его удобно использовать при интерполяции в конце таблицы и для экстраполяции правее точки . Входящие в выражение (1.11) значения конечных восходящих разностей находят из соотношений
,
...........................................................
.
Если при заданном в таблице значений функциис шагомимеется достаточное число узлов с каждой стороны от, то целесообразно узлы интерполяциивыбрать так, чтобы точкаоказалась как можно ближе к середине минимального отрезка, содержащего узлы. При этом обычно в качествеберется ближайший кузел, затем запринимается ближайший кузел, расположенный с противоположной отстороны, чем. Следующие узлы назначаются поочередно с разных сторон оти должны быть расположены как можно ближе к. Одной из возможных схем интерполяции в этом случае является схема Стирлинга с интерполяционным многочленом вида
В этом выражении учитывается, что дано нечетное число значений функции, где. Обычно эту формулу целесообразно использовать при.
x1 = 0.8110; x2=0.3770; x3=1.5480
i |
X[i] |
Y[i] |
0 |
0.2680 |
-0. 1950 |
1 |
0.4290 |
-0. 0480 |
2 |
0.5910 |
0. 0110 |
3 |
0.7520 |
0. 0100 |
4 |
0.9130 |
-0. 0280 |
5 |
1.0740 |
-0. 0770 |
6 |
1.2360 |
-0. 1130 |
7 |
1.3970 |
-0. 1090 |
8 |
1.5580 |
-0. 0410 |
9 |
1.7190 |
0. 1140 |
10 |
1.8810 |
0. 3870 |
Номер метода |
X | ||
X1=0.8110 |
X2=0.3770 |
X3=1.5480 | |
1 |
-0.001109 |
-0.082118 |
-0.046795 |
2 |
-0.001125 |
-0.082093 |
-0.046782 |
3 |
-0.001103 |
-0.082157 |
-0.046726 |
Тексты программ:
Lab9.cpp
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
double Ln (double x, double *X, double *Y, int N);
double P (int first, int last, double *X, double x);
double div_sub (int first, int last, double *X, double* Y);
FILE *data;
void main()
{
clrscr();
int N,i;
double *X, *Y, x;
float tmp;
data=fopen("data.txt","r");
fscanf(data,"%d",&N);
X=new double [N+1];
Y=new double [N+1];
for (i=0; i<=N; i++)
{fscanf(data,"%f",&tmp);
X[i]=tmp;}
for (i=0; i<=N; i++)
{fscanf(data,"%f",&tmp);
Y[i]=tmp;}
printf("\nInput x: ");
scanf("%f",&tmp);
x=tmp;
printf("\nf(x)=%f",Ln(x,X,Y,N));
getch();
}
double Ln (double x, double *X, double *Y, int N)
{
double sum=0;
int i;
for (i=1; i<=N; i++)
sum+=P(0,i-1,X,x)*div_sub(0,i,X,Y);
sum+=Y[0];
return sum;
}
double P (int first, int last, double *X, double x)
{
double p=1;
int i;
for (i=first; i<=last; i++)
p*=(x-X[i]);
return p;
}
double div_sub (int first, int last, double *X, double* Y)
{
if (first != last) return (div_sub(first+1,last,X,Y)-div_sub(first,last-1,X,Y))/(X[last]-X[first]);
else return Y[first];
}
lab10.cpp
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
double Ln_Back (double x, double *X, double *Y, double *X0, double *Y0, int N);
double P (int first, int last, int sign);
double nabla (int power, int index, double *Y);
double delta (int power, int index, double *Y);
long factorial (int x);
double Ln_Forward (double x, double *X, double *Y, double *X0, double *Y0, int N);
double Ln_Stirl (double x, double *X, double *Y, double *X0, double *Y0, int N);
FILE *data;
double q;
void main()
{
clrscr();
char keyhit;
int N,i;
double *X, *Y, *X0, *Y0, x;
float tmp;
data=fopen("data.txt","r");
fscanf(data,"%d",&N);
X=new double [N+1];
Y=new double [N+1];
X0=new double [N+1];
Y0=new double [N+1];
for (i=0; i<=N; i++)
{fscanf(data,"%f",&tmp);
X0[i]=tmp;}
for (i=0; i<=N; i++)
{fscanf(data,"%f",&tmp);
Y0[i]=tmp;}
printf("\nInput x: ");
scanf("%f",&tmp);
x=tmp;
sel:
printf("\n1-Forward interpolation\n2-Backward interpolation\n3-Stirlinf's method");
keyhit=getch();
switch (keyhit)
{
case 49: printf("\nf(x)=%f",Ln_Forward (x,X,Y,X0,Y0,N));break;
case 50: printf("\nf(x)=%f",Ln_Back (x,X,Y,X0,Y0,N));break;
case 51: printf("\nf(x)=%f",Ln_Stirl (x,X,Y,X0,Y0,N));break;
default: goto sel;
};
getch();
}
double Ln_Back (double x, double *X, double *Y, double *X0, double *Y0, int N)
{
double sum=0;
int i;
for (i=0; i<=N; i++)
{X[i]=X0[N-i];
Y[i]=Y0[N-i];
}
q=(x-X[0])/fabs(X[1]-X[0]);
for (i=1; i<=N; i++)
sum+=P(0,i-1,1)*nabla(i,0,Y)/factorial(i);
sum+=Y[0];
return sum;
}
double P (int first, int last, int sign)
{
double p=1;
int i;
for (i=first; i<=last; i++)
p*=(q+sign*i);
return p;
}
double nabla (int power, int index, double *Y)
{return delta(power,index-power, Y);}
double delta (int power, int index, double *Y)
{if (power!=1) return delta(power-1, index+1, Y)-delta(power-1, index, Y);
else return Y[abs(index+1)]-Y[abs(index)];
}
long factorial (int x)
{long p=1;
int i;
for (i=1; i<=x; i++)
p*=i;
return p;
}
double Ln_Forward (double x, double *X, double *Y, double *X0, double *Y0, int N)
{
double sum=0;
int i;
for (i=0; i<=N; i++)
{X[i]=X0[i];
Y[i]=Y0[i];
}
q=(x-X[0])/fabs(X[1]-X[0]);
for (i=1; i<=N; i++)
sum+=P(0,i-1,-1)*delta(i,0,Y)/factorial(i);
sum+=Y[0];
return sum;
}
double Ln_Stirl (double x, double *X, double *Y, double *X0, double *Y0, int N)
{return (Ln_Forward (x,X,Y,X0,Y0,N)+Ln_Back (x,X,Y,X0,Y0,N))/2;}