mkauba Opublikowano 15 Listopada 2009 Zgłoś Opublikowano 15 Listopada 2009 Witam, Mam do napisania program w C obliczający wartość funkcji sqrt(x+1) poprzez rozwinięcie w szereg Taylora wokół punktu zero (szereg Maclaurina), a następnie porównujący wynik z funkcja biblioteczna. Po rozwinięciu tego w ten szereg otrzymujemy zerowy wyraz 1, drugi - 1/2x^2, trzeci - (-1/8x^2) itd... I tak tworze wzór rekurencyjny na następny wyraz ciągu ((1,5-n)*x)/n. A kod wygląda tak: #include <stdio.h>#include <math.h>float main(float x, int liczba){printf("Witaj. Program oblicza wartosc funkcji sqrt(x+1) poprzez rozwiniecie w szereg Taylora. Podaj wartosc x.\n");scanf("%f",&x);printf("Podaj liczbe wyrazow szeregu.\n");scanf("%d",&liczba);float sum;float licznik = x;float mianownik = 2.0;int i; for (i=1;i<liczba;i++) { sum=licznik/mianownik; licznik*(1.5-i)*x; mianownik*i; }printf("%f\n",sum+1);return 0; Tylko program podaje zawsze zły wynik. Może mi ktoś powiedzieć gdzie tu jest błąd, bo ja już nie mam pomysłów? Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
kfgz Opublikowano 15 Listopada 2009 Zgłoś Opublikowano 15 Listopada 2009 Słabo u Ciebie z matematyką, z programowaniem z resztą też nie najlepiej. Może później coś skrobnę. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
mkauba Opublikowano 15 Listopada 2009 Zgłoś Opublikowano 15 Listopada 2009 To, że z programowaniem też nie najlepiej to wiem, bo proszę o pomoc. A z matematyką nie widzę problemów. Więc może zamiast bezcelowych uwag napiszesz coś co będzie odpowiedzią na moje pytanie? Z góry dziękuję. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
kfgz Opublikowano 15 Listopada 2009 Zgłoś Opublikowano 15 Listopada 2009 (edytowane) Dobra, przepraszam za matmę. Progs niedługo będzie gotowy. Tylko się Hornerem pobawię ;) EDIT: Jakoś tak to z grubsza wygląda #include <stdio.h>#include <math.h>#define rozmiar_tab 100double pochodna_tab[rozmiar_tab];//Obliczenie poszczególnych pochodnych dla x = 0void pochodna(int k) { double potega_pocz = 0.5; double y = 1.0; int i; for (i = 0; i < k; i++, potega_pocz--) { pochodna_tab[i] = potega_pocz * y; y = pochodna_tab[i]; }}int main() { int liczba = 5; double x = 1.0, suma = 0; double wsp_wiel[rozmiar_tab]; double mianownik = 1.0; printf("Witaj. Program oblicza wartość funkcji sqrt(x+1)\n"); printf("poprzez rozwinięcie w szereg Maclaurina. \n\nPodaj wartość x "); scanf("%lf", &x); printf("\nPodaj liczbę wyrazów szeregu "); scanf("%d", &liczba); int i; pochodna(liczba); //Obliczenie wyrazów szeregu (bez x'ów w potęgach) for (i = 0; i < liczba; i++) { mianownik *= (i + 1); wsp_wiel[i] = pochodna_tab[i] / mianownik; } //Obliczenie wartości wielomianu wg schematu Hornera suma = wsp_wiel[liczba - 1]; for (i = liczba - 2; i >= 0; i--) suma = suma * x + wsp_wiel[i]; suma *= x; printf("Szereg Maclaurina %f\n", suma + 1.0); printf("Funkcja biblioteczna %f\n", sqrt(x + 1.0)); return 0;} Edytowane 15 Listopada 2009 przez Dj_AnT Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
mkauba Opublikowano 15 Listopada 2009 Zgłoś Opublikowano 15 Listopada 2009 Dzięki. Tylko przy próbie kompilacji występuje błąd w 13 linijce. 'for' loop initial declaration used outside C99 mode. Pomysł co z tym zrobić? Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
kfgz Opublikowano 15 Listopada 2009 Zgłoś Opublikowano 15 Listopada 2009 (edytowane) Zastosowałem dwie poprawki 1. Dotyczącą błędu kompilacji. 2. Obliczeniową (dodałem suma *= x;) co by wynik był dokładniejszy ;) EDIT: Jednak się pospieszyłem. Edytowane 15 Listopada 2009 przez Dj_AnT Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
mkauba Opublikowano 15 Listopada 2009 Zgłoś Opublikowano 15 Listopada 2009 (edytowane) Spoko. Dzięki wielkie. A mój program wygląda tak. #include <stdio.h>#include <math.h>float main(float x, int liczba){printf("Witaj. Program oblicza wartosc funkcji sqrt(x+1) poprzez rozwiniecie w szereg Taylora. \n\nPodaj wartosc x.\n");scanf("%f",&x);printf("Podaj liczbe wyrazow szeregu.\n");scanf("%d",&liczba);float sum;float licznik = x;float mianownik = 2.0;int i; for (i=1;i<liczba;i++) { sum += licznik/mianownik; licznik *= (1.5-i)*x; mianownik *= i; }printf("Szereg Taylora %f\n",sum+1);printf("Porownanie z funkcja biblioteczna %f\n", sqrt(x+1.0));return 0;}I też działa. :wink: Byłbym Ci wdzięczny za jakąś uwagę. <_< Edytowane 15 Listopada 2009 przez mkauba Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
kfgz Opublikowano 15 Listopada 2009 Zgłoś Opublikowano 15 Listopada 2009 Mój działa lepiej ;) A tak na marginesie to main nie powinna być typu float oraz parametry x i liczba też powinny stamtąd zniknąć. Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
mkauba Opublikowano 18 Listopada 2009 Zgłoś Opublikowano 18 Listopada 2009 A wiesz moze jakby wyglądał ten program dla otoczenia wokół dowolnego punktu? Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
kfgz Opublikowano 18 Listopada 2009 Zgłoś Opublikowano 18 Listopada 2009 (edytowane) Mniej więcej tak #include <stdio.h>#include <math.h>#define rozmiar_tab 100double pochodna_tab[rozmiar_tab];//Obliczenie poszczególnych pochodnych dla x = x0void pochodna(int k, double x0) { double potega_pocz = 0.5; double y = 1.0; int i; for (i = 0; i < k; i++) { pochodna_tab[i] = potega_pocz * y; potega_pocz--; y = pochodna_tab[i]; pochodna_tab[i] *= pow((x0 + 1.0), potega_pocz); }}int main() { int liczba = 40; double x = 3, suma = 0; double wsp_wiel[rozmiar_tab]; double mianownik = 1.0; // x0 - otoczenie punktu double x0 = 0; printf("Witaj. Program oblicza wartość funkcji sqrt(x+1)\n"); printf("poprzez rozwinięcie w szereg Maclaurina. \n\nPodaj wartość x "); scanf("%lf", &x); printf("\nPodaj punkt otoczenia "); scanf("%lf", &x0); printf("\nPodaj liczbę wyrazów szeregu "); scanf("%d", &liczba); int i; pochodna(liczba, x0); //Obliczenie wyrazów szeregu (bez x'ów w potęgach) for (i = 0; i < liczba; i++) { mianownik *= (i + 1); wsp_wiel[i] = pochodna_tab[i] / mianownik; } //Obliczenie wartości wielomianu wg schematu Hornera suma = wsp_wiel[liczba - 1]; for (i = liczba - 2; i >= 0; i--) suma = suma * (x - x0) + wsp_wiel[i]; suma *= (x - x0); printf("Szereg Maclaurina %lf\n", suma + sqrt(1.0 + x0)); printf("Funkcja biblioteczna %lf\n", sqrt(x + 1.0)); return 0;} Edytowane 18 Listopada 2009 przez Dj_AnT Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
mkauba Opublikowano 18 Listopada 2009 Zgłoś Opublikowano 18 Listopada 2009 Dzięki wielkie. To teraz tylko usiąść i zrozumieć jak on liczy. To siadam do roboty. :angry: Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
kfgz Opublikowano 18 Listopada 2009 Zgłoś Opublikowano 18 Listopada 2009 (edytowane) Jednak będę musiał trochę poprawek wprowadzić bo za daleko na skróty poszedłem w ostatnim kodzie. EDIT: Kod poprawiony. Co do analizy sprawa jest prosta. Jeśli chodzi o funkcję pochodna to bierzesz do ręki długopis. Zaczynasz od funkcji (x + 1) ^ 0.5 i liczysz kolejne pochodne bo to właśnie do tego ta funkcja służy (jest odzwierciedleniem wersji kartkowo-długopisowej ;)). Silnia jest wyrażona jako mianownik. Od razu jest w tej pętli obliczany iloraz fn(x0)/n!, gdzie n to kolejna pochodna. Na koniec Horner w niecodziennym wydaniu ;) żeby szybko policzyć sumę (x-x0)^n*fn(x0)/n! Edytowane 18 Listopada 2009 przez Dj_AnT Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
mkauba Opublikowano 18 Listopada 2009 Zgłoś Opublikowano 18 Listopada 2009 (edytowane) Dobra, dzięki wielkie. :) Edytowane 18 Listopada 2009 przez mkauba Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...
kfgz Opublikowano 18 Listopada 2009 Zgłoś Opublikowano 18 Listopada 2009 (edytowane) Jeśli chodzi o mój kod to pójście na łatwiznę oznaczało błąd w obliczeniu pochodnej bo nie było wykonywane potęgowanie. Dla x0 = 0 (1+x0=1) potęgowanie jest zbędne ale dla każdej innej wartości już nie z wiadomej przyczyny. Edytowane 18 Listopada 2009 przez Dj_AnT Cytuj Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach Więcej opcji udostępniania...