Jasiek_M Napisano Listopad 13, 2011 Zgłoszenie Share Napisano Listopad 13, 2011 Witam, Napisałem taki o to programik: #include <cstdio> #include <cstdlib> inline double DifProduct(double x,double x0[],int n) { double result; result=1.0; for(int i=0;i<n;++i) result*=(x-x0[i]); return result; } double silnia( double n){ if(n==0){ return 1; }else{ return n*silnia(n-1); } } double potega(double a, double { double wynik = 1; for (int i = b; i > 0; i--) { wynik *= a; } return wynik; } double LagrangeInterp(double x,double x0[],double y0[],int n) { double result,a; a = DifProduct(x,x0,n); n--; // uwaga! zmiejszenie n result = 0.0; for(int i=0;i<=n;++i) { if(x==x0[i]) return y0[i]; result += a*y0[i]/((x-x0[i])*DifProduct(x0[i],x0,i)*DifProduct(x0[i],x0+i+1,n-i)); } return result; } double NewtonInterp(double x, double x0[], double y0[],int n) { int degree = n; double iloczyn; double wynik = 0; double h = x0[1] - x0[0]; double ile; wynik = y0[0]; for(int ile=1;ile<degree;ile++) { for(int j=0;j<(degree-ile);j++) { y0[j] = y0[j+1] - y0[j]; } iloczyn = 1; for(int j=0;j<ile;j++) { iloczyn = iloczyn * (x - x0[j]); } wynik += (y0[0]*iloczyn)/silnia(ile)*potega(h, ile); } return wynik; } int main (void) { int n,i,h; double x; printf ("Podaj ilosc elementow: "); scanf ("%d", &n); double x0[n], y0[n]; for (i = 0; i < n; i++) { printf ("Podaj x[%d]: ", i); scanf ("%f", &x0[i]); printf ("Podaj y[%d]: ", i); scanf ("%f", &y0[i]); } printf ("Podaj wartosc x : "); scanf ("%f", &x); for(int i=0;i<n-1;i++) { if (i==0) { h = x0[i+1] - x0[i]; } else { if (h!=(x0[i+1] - x0[i])) { printf("Roznica miedzy poszczegolnymi X-ami nie jest stala - wybieram metode interpolacji Lagrange`a"); return LagrangeInterp(x,x0,y0,n); } else {printf("Roznica miedzy poszczegolnymi X-ami jest sta³a - wybieram metode interpolacji Newtona");NewtonInterp(x,x0,y0,n);} } } system("pause"); } Niestety wynik jego działania przedstawia się następująco: Wielokrotnie przeczesywałem kod w próbie znalezienia błędu i nic. Niestety sam sobie z tym nie poradzę więc proszę o pomoc lub chociaż naprowadzenie na właściwy trop... Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
Lukasz69 Napisano Listopad 13, 2011 Zgłoszenie Share Napisano Listopad 13, 2011 Oto moje uwagi do programu - może się przydadzą. Jeśli masz jakieś problemy to pisz co otrzymujesz a co powinieneś otrzymać. double silnia( double n){ if(n==0){ return 1; }else{ return n*silnia(n-1); } } Silnia obowiązuje liczby naturalne - double nie reprezentuje liczb naturalnych. Tak na marginesie to nie zaleca się przyrównywania double do 0. double potega(double a, double { double wynik = 1; for (int i = b; i > 0; i--) { wynik *= a; } return wynik; } Literówka w definicji. Pod wynik dałbym jednak 1.0 a nie 1 tak dla bezpieczeństwa(w końcu wynik ma być w double). else { if (h!=(x0[i+1] - x0[i])) { printf("Roznica miedzy poszczegolnymi X-ami nie jest stala - wybieram metode interpolacji Lagrange`a"); return LagrangeInterp(x,x0,y0,n); } else {printf("Roznica miedzy poszczegolnymi X-ami jest sta³a - wybieram metode interpolacji Newtona");NewtonInterp(x,x0,y0,n);} } } system("pause"); } Wstaw drukowanie wyniku na ekran, bo jedynie wynik jest zwracany przez aplikację. Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
thof Napisano Listopad 13, 2011 Zgłoszenie Share Napisano Listopad 13, 2011 Bardzo dobrze, że nie działa. Wstydu nie masz wklejając tu zrzut z CMD 2 Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
Lukasz69 Napisano Listopad 14, 2011 Zgłoszenie Share Napisano Listopad 14, 2011 Bardzo dobrze, że nie działa. Wstydu nie masz wklejając tu zrzut z CMD Może odpalił spod Wine Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
Jasiek_M Napisano Listopad 16, 2011 Autor Zgłoszenie Share Napisano Listopad 16, 2011 Hej, wykonalem wszystkie rady Lukasz69, oto przerobiony kod: #include <cstdio> #include <cstdlib> inline double DifProduct(double x,double x0[],int n) { double result; result=1.0; for(int i=0;i<n;++i) result*=(x-x0[i]); return result; } int silnia( int n){ if(n==0){ return 1; }else{ return n*silnia(n-1); } } double potega(double a, double { double wynik = 1.0; for (int i = b; i > 0; i--) { wynik *= a; } return wynik; } double LagrangeInterp(double x,double x0[],double y0[],int n) { double result,a; a = DifProduct(x,x0,n); n--; // uwaga! zmiejszenie n result = 0.0; for(int i=0;i<=n;++i) { if(x==x0[i]) return y0[i]; result += a*y0[i]/((x-x0[i])*DifProduct(x0[i],x0,i)*DifProduct(x0[i],x0+i+1,n-i)); } printf("Wynik: %f",result); return result; } double NewtonInterp(double x, double x0[], double y0[],int n) { int degree = n; double iloczyn; double wynik = 0; double h = x0[1] - x0[0]; double ile; wynik = y0[0]; for(int ile=1;ile<degree;ile++) { for(int j=0;j<(degree-ile);j++) { y0[j] = y0[j+1] - y0[j]; } iloczyn = 1; for(int j=0;j<ile;j++) { iloczyn = iloczyn * (x - x0[j]); } wynik += (y0[0]*iloczyn)/silnia((int)ile)*potega(h, ile); } printf("Wynik: %f",wynik); return wynik; } int main (void) { int n,i,h; double x; printf ("Podaj ilosc elementow: "); scanf ("%d", &n); double x0[n], y0[n]; for (i = 0; i < n; i++) { printf ("Podaj x[%d]: ", i); scanf ("%f", &x0[i]); printf ("Podaj y[%d]: ", i); scanf ("%f", &y0[i]); } printf ("Podaj wartosc x : "); scanf ("%f", &x); for(int i=0;i<n-1;i++) { if (i==0) { h = x0[i+1] - x0[i]; } else { if (h!=(x0[i+1] - x0[i])) { printf("Roznica miedzy poszczegolnymi X-ami nie jest stala - wybieram metode interpolacji Lagrange`a"); return LagrangeInterp(x,x0,y0,n); } else {printf("Roznica miedzy poszczegolnymi X-ami jest sta³a - wybieram metode interpolacji Newtona");NewtonInterp(x,x0,y0,n);} } } system("pause"); } Wynik pod Windowsem: Wynik pod Linuxem: [Jasiek@Jasiek Programowanie Metdy obliczeniowe]$ ./a.out Podaj ilosc elementow: 6 Podaj x[0]: 0.35 Podaj y[0]: 2.73951 Podaj x[1]: 0.41 Podaj y[1]: 2.30080 Podaj x[2]: 0.47 Podaj y[2]: 1.96864 Podaj x[3]: 0.51 Podaj y[3]: 1.78776 Podaj x[4]: 0.56 Podaj y[4]: 1.59502 Podaj x[5]: 0.64 Podaj y[5]: 1.34310 Podaj wartosc x : 0.526 Roznica miedzy poszczegolnymi X-ami nie jest stala - wybieram metode interpolacji Lagrange`aWynik: -inf[Jasiek@Jasiek Programowanie Metdy obliczeniowe]$ Z Windowsem to przypadek ale mieliscie racje bo CodeBlocks wyrzuca mi takie warningi: /media/621CC8761CC846AF/Programowanie/Metody/1/1/main.cpp|83|warning: format ‘%f’ expects argument of type ‘float*’, but argument 2 has type ‘double*’ [-Wformat]| Nie wiem zbytnio tylko co z tym zrobic-wszedzie pisze ze "%f" moze byc tak samo do float jak i do double... Ehhh normalnie zalamka, nie jestem wstanie tego naprawic a glowie sie i glowie... Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
menth0l Napisano Listopad 17, 2011 Zgłoszenie Share Napisano Listopad 17, 2011 Użyj debugera i zobacz gdzie twój program tworzy wyniki inne od spodziewanych. Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
Jasiek_M Napisano Listopad 17, 2011 Autor Zgłoszenie Share Napisano Listopad 17, 2011 Debbugera uzywalem przy dalszych obliczeniach, ale uzycie go od poczatku faktycznie bylo dobrym pomyslem. Oto po wpisaniu wartosci tablic otrzymujemy taki kwiatek: wartosci tablic "x" i "y" w ogóle nie ulegly zmianie, dodatkowo program widzi dwie zmienne "i"-jedna dobra(wartosc taka jak ilosc przebiegów petli) a druga zainicjowana losowymi wartosciami. Zaraz jade na zajecia i juz raczej nie zdaze sie tym zajac, ale wieczorem spróbuje zobaczyc co moze isc zle... Edit: Pozamiatane, scanf przyjmuje dla double "%lf" zamiast "f". Natrafilem tak po zmudnych poszukiwaniach bo prawie wszedzie pisze ze "%f" odnosi sie i do float i do double... Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
Lukasz69 Napisano Listopad 20, 2011 Zgłoszenie Share Napisano Listopad 20, 2011 Czyli problem tkwil w czytaniu wartosci? Co do zmiennych i to na poczatku programu deklarujesz pierwsza zmienna i - ona ma wartosc losowa(smieci z pamieci), poniewaz nie przypisales jej wartosci. Ogólnie to zmienne typu i, j, x, z, y to nadaja sie co najwyzej do liczników petli - zmienne trzeba nazywac konkretnie. Pózniej wrócisz do kodu i trzeba wiedziec co sie dzieje w programie. Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
jjj Napisano Listopad 26, 2011 Zgłoszenie Share Napisano Listopad 26, 2011 Ja bym metody interpolacji programował albo w oparciu o rozwiązanie układu równań (żeby dowiedzieć się o tablicę współczynników), albo w oparciu o trójkątną tablicę różnic. I szybciej, i dokładniej. Odnośnik do komentarza Udostępnij na innych stronach More sharing options...
Rekomendowane odpowiedzi
Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto
Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.
Zarejestruj nowe konto
Załóż nowe konto. To bardzo proste!
Zarejestruj sięZaloguj się
Posiadasz już konto? Zaloguj się poniżej.
Zaloguj się