Puffetta (Normal User)
Rookie
Messaggi: 21
Iscritto: 29/11/2009
|
Ciao a tutti!!!!!! Ho fatto dei programmi per trovare gli zeri di una funzione mediante i metodi di bisezione, Newton e secanti e funzionavano tutti benissimo. Ora però mi è stato chiesto di fare un programma per trovare gli zeri delle funzioni che permetta all'utente di scegliere quale metodo utilizzare. Ho fatto il codice, solo che ora c'è un problema: i risultati(soprattutto bisezione e secante) non convergono alla soluzione! qualcuno saprebbe dirmi dove ho sbagliato e perchè queste soluzioni non convergono?
Questo è il codice che ho fatto io
Codice sorgente - presumibilmente C# |
/*Scrivere un programma C++ che realizza il metodo di bisezione, il metodo di Newton e il metodo della secante e utilizzarlo per approssimare entro la tolleranza acquisita da tastiera le radici di alcune equazioni non lineari.*/ #include<stdio.h> #include<stdlib.h> #include<math.h> double f(double, int); int leggif(); int leggimet(); void METODO1(int); double bisezione(double, double, double, double, int, int); void METODO2(int); double fp(double, int); double newton(double, double, int, int &, int); void METODO3(int); double secanti(double, double, double, double, double, int, int); main() { int contr, metodo; contr=leggif(); metodo=leggimet(); if(metodo==1) METODO1(contr); else if(metodo==2) METODO2(contr); else if(metodo==3) METODO3(contr); else if(metodo==4) { METODO1(contr); METODO2(contr); METODO3(contr); } system("PAUSE"); return 0; } int leggif() { int a; printf("\n\n Di quali tra le funzioni 1-2-3-4-5-6-7 voglio conoscere gli zeri?\n funzione n."); scanf("%d", &a); return a; } double f(double t, int contr) { if(contr==1) return(t*t-2); else if(contr==2) return(t*t*t-2); else if(contr==3) return((t*t*t)-2*(t*t)+3*t-4); else if(contr==4) return((t*t*t*t*t)-6*(t*t*t)+3); else if(contr==5) return(1-2*t*exp(-t/2)); else if(contr==6) return(t-exp(-t*t)); else if(contr==7) return(log(t)+t); } int leggimet() { int c; printf("\n\n Per trovare gli zeri di una funzione ci sono vari metodi"); printf("\n\n Per scegliere il metodo di bisezione digita il numero 1"); printf("\n\n Per scegliere il metodo di Newton digita il numero 2"); printf("\n\n Per scegliere il metodo delle secanti digita il numero 3"); printf("\n\n Per scegliere tutti i metodi di risoluzioni digita il numero 4"); printf("\n\n Quale metodo vuoi usare per trovare gli zeri della funzione? "); scanf("%d", &c); return c; } void METODO1(int contr) { double a, b, c, fa, fb; printf("\n\n Qual'e' il valore di a?"); scanf("%lf", &a); printf("\n Qual'e' il valore di b?"); scanf("%lf", &b); fa=f(a, contr); fb=f(b, contr); if(fa*fb>0) { printf("\n La radice non si trova in questo intervallo\n"); return; } else if(fa==0) { printf("\n Lo zero della funzione è l'estremo a, cioè c=a=%lf\n", a); return; } else if(fb==0) { printf("\n Lo zero della funzione è l'estremo b, cioè c=b=%lf\n", b); return; } else if(fa*fb<0) { double eps; int k; printf("\n Inserisci il valore della tolleranza eps="); scanf("%lf", &eps); printf("\n In quante iterazioni si deve raggiungere il risultato? k="); scanf("%d", &k); c=bisezione(a, b, fa, fb, k, contr); printf("\n\n Lo zero della funzione calcolato mediante il metodo della bisezione e' uguale a x=%1.16f\n", c); } return; } double bisezione(double a, double b, double fa, double fb, int k, int contr) { double c, fc; for(int i=1; i<=k; i++) { c=a+(b-a)/2;//1°funzione sbagliata fc=f(c, contr); if(fa*fc<0) { b=c; fb=fc; } else if(fc==0) { printf("\n\n La radice e' uguale a c, cioe' vale c=%.16f\n\n", c); return 0; } else if(fa*fc>0) { a=c; fa=fc; } } return c; } void METODO2(int contr) { double xk, fx, fpx, x, delta, toll; int nmax, n=1; printf("\n\n Inserire un numero reale xk="); scanf("%lf", &xk); printf("\n Inserire il limite di precisione toll="); scanf("%lf", &toll); printf("\n Quante iterazioni al massimo posso fare? n="); scanf("%d", &nmax); x=newton(xk,toll, nmax, n, contr); printf("\n\n La radice e' uguale a x=%1.16f\n\n", x); printf("\n Il numero di iterate fatte e' uguale a %d\n\n", n); return; } double newton(double xk, double toll, int k,int & n, int contr) { double fxk, fpxk, delta; do { fxk=f(xk, contr); fpxk=fp(xk, contr); delta=fxk/fpxk; xk -= delta; n++; } while(((delta+fabs(fxk))<toll)||(n<k)); return xk; } double fp(double x, int contr) { if(contr==1) return (2*x); else if(contr==2) return (2*(x*x)); else if(contr==3) return(3*x*x-4*x+3); else if(contr==4) return(5*x*x*x*x-18*x*x); else if(contr==5) return((x*exp(-x/2))-(2*exp(-x/2))); else if(contr==6) return(1+2*x*exp(-x*x)); else if(contr==7) return((1/x)+1); } void METODO3(int contr) { double x0, x1, f0, f1, x, toll; int k; printf("\n\n Inserire il valore x0="); scanf("%lf", &x0); printf("\n\n Inserire il valore x1="); scanf("%lf", &x1); printf("\n Inserisci il valore della tolleranza toll="); scanf("%lf", &toll); printf("\n In quante iterazioni si deve raggiungere il risultato? k="); scanf("%d", &k); f0=f(x0, contr); f1=f(x1, contr); x=secanti(x0, x1, f0, f1, toll, k, contr); printf("\n La radice trovata con il metodo delle secanti e' uguale a x=%1.16f\n", x); return; } double secanti(double x0, double x1, double f0, double f1, double toll, int k, int contr) { double x, fx, delta; int cont=0;// cont mi permette di controllare il numero delle iterate do { x=x1-(f1*(x1-x0)/(f1-f0));//calcola x n+1 e successivamente f(x n+1) fx=f(x, contr); x1=x; f1=fx; delta=fabs(x1-x0); cont++; } while((delta<toll)||(cont<k)); return x; }
|
Scusate ma è veramente importante e non so più che fare grazie
|