Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Trovare lo zero di una funzione
Forum - C/C++ - Trovare lo zero di una funzione

Avatar
Puffetta (Normal User)
Rookie


Messaggi: 21
Iscritto: 29/11/2009

Segnala al moderatore
Postato alle 17:32
Mercoledì, 13/01/2010
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#

  1. /*Scrivere un programma C++ che realizza il metodo di bisezione, il metodo di Newton e il metodo della secante e utilizzarlo per
  2. approssimare entro la tolleranza acquisita da tastiera le radici di alcune equazioni non lineari.*/
  3.  
  4. #include<stdio.h>
  5. #include<stdlib.h>
  6. #include<math.h>
  7.  
  8. double f(double, int);
  9. int leggif();
  10. int leggimet();
  11. void METODO1(int);
  12. double bisezione(double, double, double, double, int, int);
  13. void METODO2(int);
  14. double fp(double, int);
  15. double newton(double, double, int, int &, int);
  16. void METODO3(int);
  17. double secanti(double, double, double, double, double, int, int);
  18.  
  19. main()
  20. {
  21.       int contr, metodo;
  22.      
  23.       contr=leggif();
  24.      
  25.       metodo=leggimet();
  26.      
  27.       if(metodo==1)
  28.                   METODO1(contr);
  29.      
  30.       else if(metodo==2)        
  31.                   METODO2(contr);
  32.      
  33.       else if(metodo==3)        
  34.                   METODO3(contr);
  35.                  
  36.       else if(metodo==4)
  37.                  {
  38.                         METODO1(contr);
  39.                        
  40.                         METODO2(contr);
  41.                        
  42.                         METODO3(contr);
  43.                  }      
  44.      
  45.       system("PAUSE");
  46.       return 0;      
  47. }
  48.  
  49. int leggif()
  50. {
  51.     int a;
  52.    
  53.     printf("\n\n Di quali tra le funzioni 1-2-3-4-5-6-7 voglio conoscere gli zeri?\n funzione n.");
  54.     scanf("%d", &a);
  55.    
  56.     return a;
  57. }
  58.  
  59. double f(double t, int contr)
  60. {      
  61.        if(contr==1)
  62.                    return(t*t-2);
  63.                    
  64.        else if(contr==2)
  65.                    return(t*t*t-2);
  66.        
  67.        else if(contr==3)
  68.                    return((t*t*t)-2*(t*t)+3*t-4);
  69.        
  70.        else if(contr==4)
  71.                     return((t*t*t*t*t)-6*(t*t*t)+3);
  72.        
  73.        else if(contr==5)
  74.                    return(1-2*t*exp(-t/2));
  75.        
  76.        else if(contr==6)
  77.                    return(t-exp(-t*t));
  78.                    
  79.        else if(contr==7)
  80.                    return(log(t)+t);
  81. }
  82.  
  83. int leggimet()
  84. {
  85.     int c;
  86.    
  87.     printf("\n\n Per trovare gli zeri di una funzione ci sono vari metodi");
  88.     printf("\n\n Per scegliere il metodo di bisezione digita il numero 1");
  89.     printf("\n\n Per scegliere il metodo di Newton digita il numero 2");
  90.     printf("\n\n Per scegliere il metodo delle secanti digita il numero 3");
  91.     printf("\n\n Per scegliere tutti i metodi di risoluzioni digita il numero 4");
  92.     printf("\n\n Quale metodo vuoi usare per trovare gli zeri della funzione?     ");
  93.     scanf("%d", &c);
  94.    
  95.     return c;
  96. }
  97.  
  98. void METODO1(int contr)
  99. {
  100.      double a, b, c, fa, fb;
  101.      
  102.      printf("\n\n Qual'e' il valore di a?");
  103.      scanf("%lf", &a);
  104.      
  105.      printf("\n Qual'e' il valore di b?");
  106.      scanf("%lf", &b);
  107.      
  108.      fa=f(a, contr);
  109.      
  110.      fb=f(b, contr);
  111.      
  112.      if(fa*fb>0)
  113.                  {
  114.                      printf("\n La radice non si trova in questo intervallo\n");
  115.                      return;
  116.                  }
  117.      
  118.      else if(fa==0)
  119.                  {
  120.                      printf("\n Lo zero della funzione è l'estremo a, cioè c=a=%lf\n", a);
  121.                      return;
  122.                  }
  123.      
  124.       else if(fb==0)
  125.                  {
  126.                      printf("\n Lo zero della funzione è l'estremo b, cioè c=b=%lf\n", b);
  127.                      return;
  128.                  }
  129.      
  130.       else if(fa*fb<0)
  131.                  {
  132.                       double eps; int k;
  133.                      
  134.                       printf("\n Inserisci il valore della tolleranza eps=");
  135.                       scanf("%lf", &eps);
  136.                      
  137.                       printf("\n In quante iterazioni si deve raggiungere il risultato? k=");
  138.                       scanf("%d", &k);
  139.                      
  140.                       c=bisezione(a, b, fa, fb, k, contr);
  141.                      
  142.                       printf("\n\n Lo zero della funzione calcolato mediante il metodo della bisezione e' uguale a x=%1.16f\n", c);
  143.                  }
  144.      
  145.       return;
  146. }
  147.  
  148. double bisezione(double a, double b, double fa, double fb, int k, int contr)
  149. {
  150.        double c, fc;
  151.        
  152.        for(int i=1; i<=k; i++)
  153.                {
  154.                     c=a+(b-a)/2;//1°funzione sbagliata
  155.                    
  156.                     fc=f(c, contr);
  157.                    
  158.                     if(fa*fc<0)
  159.                           {
  160.                                b=c;
  161.                                
  162.                                fb=fc;
  163.                           }
  164.                    
  165.                     else if(fc==0)
  166.                           {
  167.                                printf("\n\n La radice e' uguale a c, cioe' vale c=%.16f\n\n", c);
  168.                                return 0;
  169.                           }
  170.                     else if(fa*fc>0)
  171.                           {
  172.                                 a=c;
  173.                                
  174.                                 fa=fc;
  175.                           }
  176.                }
  177.        
  178.        return c;      
  179. }
  180.  
  181. void METODO2(int contr)
  182. {
  183.        double xk, fx, fpx, x, delta, toll; int nmax, n=1;
  184.        
  185.        printf("\n\n Inserire un numero reale    xk=");
  186.        scanf("%lf", &xk);
  187.      
  188.        printf("\n Inserire il limite di precisione    toll=");
  189.        scanf("%lf", &toll);
  190.      
  191.        printf("\n Quante iterazioni al massimo posso fare?    n=");
  192.        scanf("%d", &nmax);
  193.        
  194.        x=newton(xk,toll, nmax, n, contr);
  195.        
  196.        printf("\n\n La radice e' uguale a x=%1.16f\n\n", x);
  197.      
  198.        printf("\n Il numero di iterate fatte e' uguale a %d\n\n", n);
  199.        
  200.        return;
  201. }
  202.  
  203. double newton(double xk, double toll, int k,int & n, int contr)
  204. {
  205.      double fxk, fpxk, delta;
  206.      
  207.      do
  208.        {    
  209.             fxk=f(xk, contr);
  210.              
  211.             fpxk=fp(xk, contr);
  212.              
  213.             delta=fxk/fpxk;
  214.              
  215.             xk -= delta;
  216.              
  217.             n++;          
  218.        }
  219.      while(((delta+fabs(fxk))<toll)||(n<k));
  220.      
  221.      return xk;    
  222. }
  223.  
  224. double fp(double x, int contr)
  225. {
  226.        if(contr==1)
  227.                    return (2*x);
  228.                    
  229.        else if(contr==2)
  230.                    return (2*(x*x));
  231.        
  232.        else if(contr==3)
  233.                    return(3*x*x-4*x+3);
  234.        
  235.        else if(contr==4)
  236.                    return(5*x*x*x*x-18*x*x);
  237.        
  238.        else if(contr==5)
  239.                    return((x*exp(-x/2))-(2*exp(-x/2)));
  240.        
  241.        else if(contr==6)
  242.                    return(1+2*x*exp(-x*x));
  243.                    
  244.        else if(contr==7)
  245.                    return((1/x)+1);
  246. }
  247.  
  248.  
  249.  
  250. void METODO3(int contr)
  251. {
  252.       double x0, x1, f0, f1, x, toll; int k;
  253.      
  254.       printf("\n\n Inserire il valore   x0=");
  255.       scanf("%lf", &x0);
  256.      
  257.       printf("\n\n Inserire il valore   x1=");
  258.       scanf("%lf", &x1);
  259.      
  260.       printf("\n Inserisci il valore della tolleranza   toll=");
  261.       scanf("%lf", &toll);
  262.                      
  263.       printf("\n In quante iterazioni si deve raggiungere il risultato? k=");
  264.       scanf("%d", &k);
  265.      
  266.       f0=f(x0, contr);
  267.      
  268.       f1=f(x1, contr);
  269.      
  270.       x=secanti(x0, x1, f0, f1, toll, k, contr);
  271.      
  272.       printf("\n La radice trovata con il metodo delle secanti e' uguale a x=%1.16f\n", x);
  273.      
  274.       return;
  275. }
  276.  
  277. double secanti(double x0, double x1, double f0, double f1, double toll, int k, int contr)
  278. {
  279.        double x, fx, delta; int cont=0;// cont mi permette di controllare il numero delle iterate
  280.        
  281.        do
  282.          {
  283.               x=x1-(f1*(x1-x0)/(f1-f0));//calcola x n+1 e successivamente f(x n+1)
  284.          
  285.               fx=f(x, contr);
  286.              
  287.               x1=x;
  288.              
  289.               f1=fx;
  290.              
  291.               delta=fabs(x1-x0);
  292.              
  293.               cont++;
  294.              
  295.          }
  296.        while((delta<toll)||(cont<k));
  297.        
  298.        return x;
  299. }



Scusate ma è veramente importante e non so più che fare:d grazie

PM Quote
Avatar
matteog (Normal User)
Pro


Messaggi: 149
Iscritto: 10/04/2009

Segnala al moderatore
Postato alle 18:49
Mercoledì, 13/01/2010
non si capisce quali sono le funzioni su cui lavora senza conoscerle come faccio a capire cosa devo fare?? posta degli esempi con le varie funzioni e i vari metodi che vedo di risolvere il probelma


matteog
PM Quote
Avatar
lorenzo (Normal User)
Guru


Messaggi: 1178
Iscritto: 15/04/2008

Segnala al moderatore
Postato alle 22:38
Mercoledì, 13/01/2010
a parte il fatto che è C e non C++...comunque la domanda a cui devi rispondere è: prima che mettessi la scelta andava tutto bene?

SI: allora il problema sta nel codice che hai aggiunto, prova a fare il debug controllando i valori che passi alle funzioni.

NO: allora devi ricontrollare le funzioni che hai scritto, sinceramente non ho molta voglia di stare a controllare i tuoi calcoli, prova ad eliminare pezzi di programma e provare ogni metodo separatamente.


"There's no point in being exact about something if you don't even know what you're talking about."

JOHN VON NEUMANN


Siamo italiani NO??
Allora scriviamo in ITALIANO!!!!
PM Quote
Avatar
matteog (Normal User)
Pro


Messaggi: 149
Iscritto: 10/04/2009

Segnala al moderatore
Postato alle 22:40
Mercoledì, 13/01/2010
ho guardato il codice credo siano quei parametri di ritorno ma nn conosco molto bene l'argomento quindi non sò dove mettere le mani forse ti conviene lavorare su tt e tre separatamente e poi unirli in uno solo!


matteog
PM Quote