Skocz do zawartości
mkauba

[c] Obliczanie Wartosci Funkcji Sqrt(x+1)

Rekomendowane odpowiedzi

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?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

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 przez Dj_AnT

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

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 przez Dj_AnT

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

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 przez mkauba

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

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 przez Dj_AnT

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

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 przez Dj_AnT

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

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 przez Dj_AnT

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie


×
×
  • Dodaj nową pozycję...