C++ approssimazione di funzioni con polinomio di taylor
Ciao a tutti!
Ho dei seri problemi a usare il polinomio di Taylor in un prgramma c++ che deve trovare il valore della funzione a partire dall'approssimazione di Taylor: ad esempio devo trovare il valore di cos(x). come faccio a costruire il polinomio? Io ho pensato a un do while in cui ogni volta incremento di 2 il grado del polinomio in modo tale da avere solo potenze pari, ma come faccio a farmi calcolare il polimonio con tutta la sommatoria?
è importante... grazie
Ho dei seri problemi a usare il polinomio di Taylor in un prgramma c++ che deve trovare il valore della funzione a partire dall'approssimazione di Taylor: ad esempio devo trovare il valore di cos(x). come faccio a costruire il polinomio? Io ho pensato a un do while in cui ogni volta incremento di 2 il grado del polinomio in modo tale da avere solo potenze pari, ma come faccio a farmi calcolare il polimonio con tutta la sommatoria?
è importante... grazie
Risposte
Si tratta di un esercizio? Per calcolare il valore del polinomio, il metodo più naive è quello di fare un ciclo in cui calcoli ogni volta la somma parziale. Ovviamente hai bisogno di una condizione per uscire dal ciclo. In cosa trovi difficoltà esattamente?
L'esercizio è questo. il codice che ho fatto io è questo solo che mi viene sempre e cmq zero come risultato è ciò p impossibile:
/*Scrivere un programma C++ che realizza un'approssimazione polinomiale (facendo uso del polinomio di Taylor con x0=0) della funzione cos(x) che sia accurata entro la tolleranza epsilon acquisita da tastiera. Considerare per il criterio di arresto il modulo dell'errore assoluto.*/ #include <stdio.h> #include<stdlib.h> #include <math.h> double power(double, int); double fattoriale (double, int); main() { float x/*angolo in radianti da inserire*/, eps/*tolleranza*/, app=1/*risultato approssimato*/; int x0=0, n=0;//grado polinomio int sign=1; do { printf("\n CALCOLO DELLA FUNZIONE cos x\n\n"); printf("\n Di quanti radianti e' l'angolo x= "); scanf("%lf", &x); } while((x>0)&&(x<(M_PI)/2)); printf("\n\n Inserire la tolleranza richiesta eps="); scanf("%lf", &eps); do { sign=-sign; app=sign*(app+(power(x, n)/ fattoriale(x, n))); n +=2; } while((fabs(cos(x)-app))<eps); printf("\n Il risultato finale e' cos(x)=%lf \n\n", app); printf("\n La libreria matematica dice cos(x)=%lf\n\n", cos(x)); system("PAUSE"); return 0; } double power (double x, int n) { int i; double p=1; for (i=1; i<=n; ++i) p=p*x; return p; } double fattoriale (double x, int n) { double fattoriale=1; for (int i=1; i<=n; i++) fattoriale=(fattoriale*i); return fattoriale; }
La tua variabile è un float ma tu, in questa riga, stai leggendo un double:
Il metodo corretto è
Lo stesso vale per gli altri scanf e i printf (in cui comunque non servirebbe la l neanche per i double).
C'è una enorme fonte di inefficienza nel tuo codice: calcoli ogni volta il fattoriale e la potenza da zero. Sarebbe infatti sufficiente aggiornare il fattoriale secondo la relazione $(2n)! = (2(n-1))!*(2n*(2n-1))$ e la potenza (pari) secondo la relazione $x^{2n} = x^2x^{2(n-1)}$. Dopodiché la riga
è sbagliata. Il segno dovrebbe infatti essere applicato solo al termine da aggiungere e non a tutto. Ad ogni iterazione stai infatti calcolando $S_n = (-1^n) \sum_{i=0}^{n} \frac{x^{2n}}{(2n)!}$ che non è il coseno. La riga corretta sarebbe infatti:
Scrivi il codice nei tag [ code ] (senza spazi tra code e le parentesi)
scanf("%lf", &x);
Il metodo corretto è
scanf("%f", &x);
Lo stesso vale per gli altri scanf e i printf (in cui comunque non servirebbe la l neanche per i double).
C'è una enorme fonte di inefficienza nel tuo codice: calcoli ogni volta il fattoriale e la potenza da zero. Sarebbe infatti sufficiente aggiornare il fattoriale secondo la relazione $(2n)! = (2(n-1))!*(2n*(2n-1))$ e la potenza (pari) secondo la relazione $x^{2n} = x^2x^{2(n-1)}$. Dopodiché la riga
app=sign*(app+(power(x, n)/ fattoriale(x, n)));
è sbagliata. Il segno dovrebbe infatti essere applicato solo al termine da aggiungere e non a tutto. Ad ogni iterazione stai infatti calcolando $S_n = (-1^n) \sum_{i=0}^{n} \frac{x^{2n}}{(2n)!}$ che non è il coseno. La riga corretta sarebbe infatti:
app += sign * power(x,n) / fattoriale(x,n);
Scrivi il codice nei tag [ code ] (senza spazi tra code e le parentesi)