Witam. Napisałem "program" który ma wyznaczać wielomian interpolacyjny, wszystko jest ok, gdy liczba węzłów nie przekracza ok. 35 natomiast gdy użytkownik podaje liczbę większą np 50 na jednym z krańców przedziału dzieją się dziwne rzeczy, zamieszczam mój kod. Proszę o pomoc, jakąś wskazówkę co robię źle, interpolacja metodą Newtona na węzłach równoodległych i Czebyszewa. Do rysowania wykresów używam gnuplota.
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cmath>
#include "gnuplot_i.hpp"
#define GNUPLOT_PATH "D:\\programs\\gnuplot\\bin"
using namespace std;
int rozmiar = 0;
struct element
{
double x, y;
};
double Newton (element* el, int rozmiar, double x)
{
double wynik = el[0].y;
double *a = new double [rozmiar];
for (int i=0; i<rozmiar; i++)
a[i] = el[i].y;
for (int i=1; i<rozmiar; i++)
for (int j=0; j<i; j++)
a[i] = (a[i]-a[j])/(el[i].x-el[j].x);
for (int i=1; i<rozmiar; i++)
{
double f = 1.0;
for (int j=0; j<i; j++)
f *= x - el[j].x;
wynik += a[i]*f;
}
delete [] a;
return wynik;
}
double fun1 (double x)
{
return 0.05*x*x*x*x*x-1.4416*x*x*x*x+15.5666*x*x*x-77.8583*x*x+178.6833*x-149;
}
double fun2 (double x)
{
return 1/(x*x+1);
}
element* Odczyt (string nazwa)
{
element *tab;
ifstream plik (nazwa.c_str());
if (plik.good())
{
plik >> rozmiar;
tab = new element [rozmiar];
for (int i=0; i<rozmiar; i++)
plik >> tab[i].x >> tab[i].y;
}
else exit;
return tab;
}
void Gnu3 (double a, double b, double(* fun)(double), element* tab, int rozmiar/*, double(* fun2)(element*, int, double)*/)
{
ofstream plik;
plik.open("numerki.dat");
if(plik.is_open())
{
for (double i=a; i<b; i=i+0.01)
{
plik.width(5);
plik.fill(' ');
plik<<left<<i<<" "<<fun(i)<<endl;
}
plik.close();
}
else exit;
ofstream plik2;
plik2.open("numerki2.dat");
if(plik2.is_open())
{
for (double i=a; i<b; i=i+0.01)
{
plik2.width(5);
plik2.fill(' ');
plik2<<left<<i<<" "<<Newton(tab,rozmiar,i)<<endl;
}
plik.close();
}
else exit;
system("\"\"D:\\programs\\gnuplot\\bin\\gnuplot.exe\" -p -e \"plot 'tabik.txt','numerki.dat' with lines,'numerki2.dat' with lines\"\"");
}
void Rowne (double a, double b, int ile_wezlow, double(* fun)(double))
{
double odleglosc = (b-a)/(ile_wezlow-1);
ofstream avaritia;
avaritia.open("tab.txt");
if (avaritia.is_open())
{
avaritia <<ile_wezlow<<"\n";
for (double i=a; i<=b; i=i+odleglosc)
{
avaritia <<i<<" "<<fun(i)<<"\n";
}
avaritia.close();
}
else exit;
ofstream wezly;
wezly.open("tabik.txt");
if (wezly.is_open())
{
for (double i=a; i<=b; i=i+odleglosc)
wezly <<i<<" "<<fun(i)<<"\n";
wezly.close();
}
else exit;
}
void Czebyszew (double a, double b, int n, double(* fun)(double))
{
double *tab = new double [n];
if (n%2==1)
{
tab[n/2]=((a+b)+(b-a)*cos((2.0*n/2+1.0)/(n+1)*M_PI/2.0))/2.0;
for (int i=0; i<n/2; i++)
tab[i]=((a+b)+(b-a)*cos((2.0*i+1.0)/(n+1)*M_PI/2.0))/2.0;
for (int i=n/2+1; i<n; i++)
tab[i]=((a+b)+(b-a)*cos((2.0*(i+1.0)+1.0)/(n+1)*M_PI/2.0))/2.0;
}
else
{
for (int i=0; i<n/2; i++)
tab[i]=((a+b)+(b-a)*cos((2.0*i+1.0)/(n+1)*M_PI/2.0))/2.0;
for (int i=n/2; i<n; i++)
tab[i]=((a+b)+(b-a)*cos((2.0*(i+1.0)+1.0)/(n+1)*M_PI/2.0))/2.0;
}
ofstream avaritia;
avaritia.open("tab.txt");
if (avaritia.is_open())
{
avaritia<<n<<"\n";
for (int i=0; i<n; i++)
{
avaritia<<tab[i]<<" "<<fun(tab[i])<<"\n";
}
avaritia.close();
}
else exit;
ofstream wezly;
wezly.open("tabik.txt");
if (wezly.is_open())
{
for (int i=0; i<n; i++)
wezly <<tab[i]<<" "<<fun(tab[i])<<"\n";
wezly.close();
}
else exit;
delete [] tab;
}
int main()
{
double a,b;
int ile_wezlow;
int wybor_funkcji;
int wybor_metody;
cout << "Wybor funkcji" << endl;
cout << "1: 0.05x^3-1.4416x^4+15.5666x^3-77.8583x^2+178.6833x-149"<<endl;
cout << "2: 1/(x^2+1)"<<endl;
cout <<endl<<"Wybierz funkcje: ";
cin >> wybor_funkcji;
switch (wybor_funkcji)
{
case 1:
{
cout <<endl<<"Przedzial" << endl;
cout << "a: ";
cin >> a;
cout << "b: ";
cin >> b;
cout <<endl<< "Podaj liczbe wezlow: ";
cin >> ile_wezlow;
cout <<endl<< "Metoda"<<endl;
cout << "1 - Rownoodlegle"<<endl;
cout << "2 - Czebyszewa"<<endl;
cout <<endl<< "Wybierz metode: ";
cin >> wybor_metody;
switch (wybor_metody)
{
case 1:
{
Rowne(a,b,ile_wezlow, fun1);
element *A = Odczyt("tab.txt");
Gnu3(a,b,fun1,A,rozmiar/*,Newton*/);
delete [] A;
}
break;
case 2:
{
Czebyszew(a,b,ile_wezlow,fun1);
element *A = Odczyt("tab.txt");
Gnu3(a,b,fun1,A,rozmiar/*,Newton*/);
delete [] A;
}
break;
}
}
break;
case 2:
{
cout <<endl<< "Przedzial" << endl;
cout << "a: ";
cin >> a;
cout << "b: ";
cin >> b;
cout <<endl<< "Podaj liczbe wezlow: ";
cin >> ile_wezlow;
cout <<endl<< "Metoda"<<endl;
cout << "1 - Rownoodlegle"<<endl;
cout << "2 - Czebyszewa"<<endl;
cout <<endl<< "Wybierz metode: ";
cin >> wybor_metody;
switch (wybor_metody)
{
case 1:
{
Rowne(a,b,ile_wezlow, fun2);
element *A = Odczyt("tab.txt");
Gnu3(a,b,fun2,A,rozmiar/*,Newton*/);
delete [] A;
}
break;
case 2:
{
Czebyszew(a,b,ile_wezlow,fun2);
element *A = Odczyt("tab.txt");
Gnu3(a,b,fun2,A,rozmiar/*,Newton*/);
delete [] A;
}
break;
}
}
break;
}
return 0;
}
- 7bd92cf796.png (160 KB) - ściągnięć: 229