Rēzeknes Augstskola
Inženieru fakultāte
Datorzinātņu un matemātikas katedra
Praktiskais darbs Nr.5
Interpolācija, izmantojot Ņūtona interpolācijas formulas
Autors
Dienas nodaļas
Inženiera programmētāja specialitātes
2.kursa studente
********
*************
Docētājs
Docents ________________ ***********
I. Darba uzdevums
Izmantojot Ņūtona interpolācijas formulas, noteikt funkcijas vērtības pie dotajām argumentu vērtībām. Izvadīt galīgo diferenču tabulu, aprēķinātās funkcijas vērtības un attiecīgos atlikuma locekļus kļūdas novērtēšanai. Tabulāros datus ievadīt no faila.
7.variants
x3,03,13,23,33,43,53,63,73,8
y3,0934,3465,7667,3679,15811,14913,34915,76518,401
1.Organizēt datu ievadi no faila (t.i., pieprasīt no lietotāja faila nosaukumu, pārbaudīt, vai fails eksistē, nolasīt masīvus x[i] un y[i]).
2.Pieprasīt no lietotāja elementu skaita ievadi.
3.Radīt dinamiskos masīvus: x[i] un y[i] vērtību uzglabāšanai, kā arī divdimensiju matricu ar mainīgu rindas garuma izmēru diferenču tabulas uzglabāšanai un apstrādei.
4.Datu kontrolei izvadīt uz ekrāna no faila iegūtos datus.
4.Aprēķināt vērtību h pēc formulas: h=| x[1]-x[0] |
5.Aizpildīt diferenču tabulas pirmo kolonnu ar y[i] vērtībām.
6.Sākot no otrās kolonnas aizpildīt diferenču tabulu ar izrēķinātajām vērtībām. Pirmās kārtas diferences aprēķina pēc formulas:
Otrās kārtas diferences aprēķina:
Aizpildīt arī pārējo augstāko kārtu diferences, kuras aprēķina pēc formulas:
, kur n – diferences kārta, i – diferences numurs;
6.Izvadīt diferenču tabulu uz ekrāna.
7.Pārbaudīt, vai ievadītā argumenta vērtība atrodas tuvāk intervāla sākumam vai beigām:
7.1.Ja vērtība atrodas tuvāk intervāla sākumam, tad izmanto 1. Ņūtona interpolācijas formulu;
7.2.Ja vērtība atrodas tuvāk intervāla beigām, tad izmanto 2. Ņūtona interpolācijas formulu.
8.Izvēlētajai interpolācijas formulai aprēķina koeficientu q –
8.1. , ja izmanto 1. Ņūtona interpolācijas formulu;
8.2. , ja izmanto 2. Ņūtona interpolācijas formulu;
Kur x – argumenta vērtība, kurai aprēķina funkcijas y vērtību; x0 – intervāla sākuma vērtība; xk – intervāla beigu vērtība; h=xi+1–xi – argumenta x maiņas solis.
9. Aprēķina funkcijas vērtību pēc formulas –
9.1. Ja izmanto 1. Ņūtona interpolācijas formulu:
9.2. Ja izmanto 2. Ņūtona interpolācijas formulu:
10. Nosaka risinājuma kļūdu pēc atlikuma locekļa -
10.1Ja izmanto I Ņūtona interpolācijas formulu
11.Aizvērt failu, nodzēst radītos dinamiskos masīvus.
12.Izvadīt uz ekrāna iegūto funkcijas rezultātu un risinājuma kļūdu.
13.Pieprasīt no lietotāja atkārtotu programmas palaišanu, piekrišanas gadījumā atgriezties uz punktu 1., pretējā gadījumā pabeigt programmas darbību.
IV. Programma
# include <iostream.h>
# include <conio.h>
# include <math.h>
# include <iomanip.h>
# include <fstream.h>
using namespace std;
int main () {
bool choice;
char name[256];
double temp,R,f,q,mid,h,arg;
int p,i,j,k,size,fakt;
ifstream in;
Repeat:
clrscr();
cout<<endl<<"No kaada faila nolasiit datus? : "; cin>>name;
in.open(name);
if (in.fail())
{
cout << "Paarbaudiet faila nosaukumu!" << endl;
exit(1);
}
cout<<endl<<"Cik elementu? : "; cin>>size;
clrscr();
double *x = new double[size];
double *y = new double[size];
double* *diferences = new double* [size];
for(i=0; i<2; i++)
{
for(k=0; k<size; k++)
{
if(i==0)in>>x[k];
else in>>y[k];
}
}
for (i=0; i<size; i++) cout<<x[i]<<"t"; cout<<endl;
for (i=0; i<size; i++) cout<<y[i]<<"t"; cout<<endl; cout<<endl;
h=fabs(x[1]-x[0]);
for (i=0; i<size; i++) diferences[i]=new double[size-i];
for (i=0; i<size; i++)
//aizpilda diferenču tabulas nulto kolonnu ar y vērtībām
{
diferences[i][0]=y[i];
}
for (j=1; j<size; j++)
{
for (i=0; i<=size-j-1; i++)
{
diferences[i][j]=diferences[i+1][j-1]-diferences[i][j-1];
}
}
cout.setf(ios::fixed);
cout.precision(5);
for (i=0; i<size; i++)
{
for (j=0; j<=size-i-1; j++)
cout<<setw(10)<<diferences[i][j];
cout<<endl;
}
mid=fabs((x[0]+x[size-1])/2);
cout<<endl<<"Ievadiet argumentu: "; cin>>arg;
if (mid>arg) //ja meklējamā vērtība tuvāk sākumam
{ //izmantojam pirmo Ņūtona interpolācijas formulu
q=(arg-x[0])/h;
f=diferences[0][0];
temp=q;
fakt=1;
for (i=1; i<size; i++)
{
fakt=fakt*i;
R = temp*diferences[0][i]/fakt;
f = f + R;
temp=temp*(q-i);
}
}
else //ja meklējamā vērtība tuvāk beigām
{ //izmantojam otro Ņūtona interpolācijas formulu
q=(arg-x[size-1])/h;
f = y[size-1];
temp=q;
fakt=1;
for (i=1; i<size; i++)
{
fakt=fakt*i;
R = temp*diferences[size-i-1][i]/fakt;
f = f + R;
temp=temp*(q+i);
}
}
in.close();
delete []x;
delete []y;
do
{
delete[]diferences[size-1];
size--;
}
while(size>0);
delete[]diferences;
cout.precision(7);
cout<<endl<<"Funkcijas veertiiba ir: "<<f;
cout.setf(ios::scientific, ios::floatfield);
cout<<endl<<"Precizitaate ir: "<<R;
cout<<endl<<"Reekjinaat veelreiz? (1-yes / 0-no)"; cin>>choice;
if (choice==TRUE) goto Repeat;
getch();
return 0;
}
Kontrolpiemēram es izvēlējos šādu sakarības starp x un y tabulu:
X05101520
Y613912
Lai pārbaudītu, vai programma pareizi strādā, rēķinot gan ar pirmo, gan ar otro Ņūtona interpolācijas metodēm, es izvēlējos divas x vērtības, kurām jāaprēķina funkcijas vērtība: 2 un 19.
yy2y3y4y
6-57-3-4
124-7
36-3
93
12
h = 5 – 0 = 5
1) x = 2
„Ar roku” rēķinātais:
q = (2-0)/5 = 2/5 = 0,4
y(x) = 6 + 0,4•(-5) + 7•0,4•(-0,6)/2! + (-3)•0,4•(-0,6) •(-1,6)/3! + (-4) •0,4•(-0,6) •(-1,6) •(-2,6)/4! = 6 – 2 – 0,84 – 0,192 + 0,1664 = 3,1344
Programma uzrādīja šādus rezultātus:
6-57-3-4
124-7
36-3
93
12
Funkcijas veertiiba ir: 3.1344000
Precizitaate ir: 1.6640000e-01
2) x = 19
„Ar roku” rēķinātais:
q = (19-20)/5 = -1/5 = -0,2
y(x) = 12 + 3•(-0,2) + (-3)•(-0,2)•(0,8)/2! + (-7)•(-0,2)•(0,8)•(1,8)/3! + (-4)•(-0,2)•(0,8)•(1,8)•(2,8)/4! = 12 – 0,6 + 0,24 + 0,336 + 0,1344 = 12,1101
Programma uzrādīja šādus rezultātus:
6-57-3-4
124-7
36-3
93
12
Funkcijas veertiiba ir: 12.1104000
Precizitaate ir: 1.3440000e-01
x=2
6.00000 -5.00000 7.00000 -3.00000 -4.00000
1.00000 2.00000 4.00000 -7.00000
3.00000 6.00000 -3.00000
9.00000 3.00000
12.00000
Funkcijas veertiiba ir: 3.1344000
Precizitaate ir: 1.6640000e-01
x=19
6.00000 -5.00000 7.00000 -3.00000 -4.00000
1.00000 2.00000 4.00000 -7.00000
3.00000 6.00000 -3.00000
9.00000 3.00000
12.00000
Funkcijas veertiiba ir: 12.1104000
Precizitaate ir: 1.3440000e-01
Kontrolpiemērā „ar roku” rēķinātais pilnīgi sakrita ar programmas iegūtajiem rezultātiem abos gadījumos, kad argumenta x vērtība bija intervāla sākumā un beigās, no kā var secināt, ka programma darbojas korekti.
Neērtības radīja tas, ka uzdevuma noteikumos netika prasīta palīgfunkciju veidošana, kas ļoti atvieglotu programmas rakstīšanas procesu – piemēram, funkcija, kas izskaitļo faktoriālu.
Programma tika optimizēta vairākkārtējai datu ievadei, jo lietotājam ir jāievada vismaz divas vērtības – intervāla sākumā un beigās.
Diemžēl programma ir nepilnīga, jo tā precīzi atrod tikai argumenta vērtības, kuras ir tuvas intervāla robežu vērtībām.
Sandra Lobazova
25.04.2006.