[c++] Interpolacja Newtona

0

Witam! zająłem się problemem interpolacji newtona i napisałem taki oto kod:
Niestety cos nie działa, nie wiem gdzie popełniłem błąd, mógłby ktos sprawdzic i pomóc??

#include <iostream>


using namespace std;


int silnia (int n) 
{
	if (n<0)
		return 0;

	if (n==0 || n==1)
		return 1;

	return silnia(n-1)*n;
}

double interpolacja_Newtona(int n, double x, double xn[], double yn[])
{
	double iloczyn;
	double y = 0.0;

	for(int i = 1; i < n; i++)
	{
		for(int j = 0; j < (n-i); j++)
		{
			yn[j] = yn[j+1] - yn[j];
		}
		iloczyn = 1;
		for(int j = 0; j < i; j++)
		{
			iloczyn = iloczyn * (x - xn[j]);
		}
		y += (yn[0]*iloczyn)/(silnia(i));
	}
	return y;
}

int main(int argc, char *argv[])
{	
	int n;
	cout << "Podaj liczbe rownan: " ;
	cin >> n;
	double *xn = new double[n];
	double *yn = new double[n];

	
	for(int i = 0; i < n; i++)
	{
		cout << "Podaj wartosc wspolzednej x(" << i << "): " ;
		cin >> xn[i]; 
		cout << "Podaj wartosc wspolzednej y(" << i << "): " ;
		cin >> yn[i];
	}


	double x;
	cout << "Podaj punkt w ktorym policzona zostanie wartosc funkcji: ";
	cin >> x;
	cout << endl;

        cout << "Wartosc funkcji w punkcie dla interpolacji newtona " << x << " wynosi "<< interpolacja_Newtona(n, x, xn, yn) << endl;

	

	system("pause");
}
0

cos nie działa

Ale co!?
Powiedz, co dokładnie nie działa.

0

Oczywiście że nie działa, bo spałeś na zajęciach z metod numerycznych (albo właśnie śpisz). Liczenie w ten sposób jak to robisz szeregu to zbrodnia. Czemu liczysz za każdym razem silnię od nowa? o_O Przecież skoro znasz silnia(x) to silnia(x+1) to jest silnia(x)*(x+1)...
Poza tym wiesz że silnia to jest szybko rosnąca funkcja i że w C++ w long long przechowasz nie więcej niż 21! (a w incie jeszcze mniej...)

0

czyli jak to mam napisac?

0

Przy interpolacji twoje zadanie sprowadza sie do wyliczenia wspolczynnikow funkcji, a kiedy juz je masz mozesz liczyc wartosci funkcji w punkcie za pomoca np. schematu hornera. Majac dany 1 wezel na poczatku mozesz przyblizyc funkcje wielomianem stopnia n-1 czyli zerowego. Algorytm jest wziety z wzoru ogolnego, Wyliczasz sobie fi i alfa, i mozesz liczyc wartosc funkcji.

Silnia akurat jest tu kompletnie nie potrzebna.

0

ok, mam teraz pytanie techniczne: musze napisac program o temacie interpolacja lagrangea/newtona.
napisałem to tak:

czy jest dobrze?
[code]#include <iostream>

using namespace std;

double interpolacja_Lagrangea(int n, double x, double xn[], double yn[])
{

double t, y = 0.0;

for (int i = 0; i < n; i++)
{
	t = 1.0;

	for (int j = 0; j < n; j++)
	{
		if (i != j) 
		{
			t = t * ((x-xn[j])/(xn[i] - xn[j]));
		}
	}
	y += t * yn[i];

}
return y;

}

int main(int argc, char *argv[])
{
int n;
cout << "Podaj liczbe rownan: " ;
cin >> n;
double *xn = new double[n];
double *yn = new double[n];

for(int i = 0; i < n; i++)
{
	cout << "Podaj wartosc wspolzednej x(" << i << "): " ;
	cin >> xn[i]; 
	cout << "Podaj wartosc wspolzednej y(" << i << "): " ;
	cin >> yn[i];
}


double x;
cout << "Podaj punkt w ktorym policzona zostanie wartosc funkcji: ";
cin >> x;
cout << endl;


	for (int i = 0; i<n; i++)
{
	cout << "x (" << i << ")= " << xn[i] << "\t\t" << "y(" << i  << ") = " << yn[i] << endl;
}


cout << "Wartosc funkcji w punkcie dla interpolacji lagrangea " << x << " wynosi "<< interpolacja_Lagrangea(n, x, xn, yn) << endl;





system("pause");

}
[/code]

0

Bardzo latwo mozesz sobie sprawdzic sam czy dobrze interpoluje. Wprowadz punkty, bedziesz wiedzial jak ta funkcja mniej wiecej wyglada i jakie wartosci powinny byc w danych pkt. Najprosciej na jakiejs liniowe/kwadratowej sprawdzic.

1 użytkowników online, w tym zalogowanych: 0, gości: 1