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)