Recherche d'un zero de la fonction cosinus par dichotomie

Recherche d'un zero de la fonction cosinus par dichotomie - C++ - Programmation

Marsh Posté le 15-03-2013 à 20:36:34    

Bonsoir tout le monde, :)
 
Dans le cadre de mon cours d'informatique, je suis sensé réaliser un programme codé en C++ qui recherche, par le biai d'une fonction et d'appels récursifs, la racine de la fonction cosinus entre 0 et 2 par dichotomie.  
Je crois que j'ai compris le principe et pourtant, lorsque je lance le programme que j'ai écrit, Windows m'indique que le programme a cessé de fonctionner.
 
Voici ci-bas le code source de ce programme. Pourriez-vous m'aider à comprendre pourquoi il ne fonctionne pas s'il-vous plait?  :sweat:  
 

Code :
  1. #include <iostream>
  2. #include <cmath>
  3. #include <windows.h>
  4. using namespace std;
  5. double racinedecos(double borneinf, double bornesup)
  6. {
  7.     double z = 0;
  8.     if (cos((borneinf+bornesup)/2) > 0)
  9.     {
  10.         z = ((borneinf+bornesup)/2);
  11.         return racinedecos(borneinf, z);
  12.     }
  13.     else if (cos((borneinf+bornesup)/2) < 0)
  14.     {
  15.         z = ((borneinf+bornesup)/2);
  16.         return racinedecos(z, bornesup);
  17.     }
  18.     else if (cos((borneinf+bornesup)/2) == 0)
  19.     {
  20.         z = ((borneinf+bornesup)/2);
  21.         return z;
  22.     }
  23.     return 0;
  24. }
  25. int main()
  26. {
  27.     double sup = 2;
  28.     double inf = 0;
  29.     double X = racinedecos(inf, sup);
  30.     cout << "La racine de la fonction cosinus qui est comprise entre 0 et 2 vaut " << X << endl;
  31.     system("pause" );
  32.     return 0;
  33. }


 
En vous remerciant d'avance de votre patience,
Swordfish :)


Message édité par 52v0rdf15h le 15-03-2013 à 20:37:26
Reply

Marsh Posté le 15-03-2013 à 20:36:34   

Reply

Marsh Posté le 15-03-2013 à 22:31:44    

Bonsoir !
 
A vue de nez, vous n'atteignez jamais exactement la valeur pi/2 et, donc, vous ne vous arrêtez jamais, donc vous empilez les fonctions jusqu'au dépassement de pile.
 
Dans ces cas là, on ne continue pas jusqu'à tomber sur 0, mais sur une valeur inférieure à un epsilon ou que l'écart entre la borne sup. et la borne inf. est inférieur à un epsilon, et on considère alors avoir trouvé la racine.
 
Bonne continuation !


Message édité par Farian le 15-03-2013 à 22:32:53
Reply

Marsh Posté le 16-03-2013 à 01:16:36    

Déja ça marche pas à cause de ceci:

Code :
  1. if (cos((borneinf+bornesup)/2) > 0)
  2.     {
  3.         z = ((borneinf+bornesup)/2);
  4.         return racinedecos(borneinf, z);
  5.     }
  6.     else if (cos((borneinf+bornesup)/2) < 0)
  7.     {
  8.         z = ((borneinf+bornesup)/2);
  9.         return racinedecos(z, bornesup);
  10.     }


qui devrait être

Code :
  1. if (cos((borneinf+bornesup)/2) > 0)
  2.     {
  3.         z = ((borneinf+bornesup)/2);
  4.         return racinedecos(z, bornesup);
  5.     }
  6.     else if (cos((borneinf+bornesup)/2) < 0)
  7.     {
  8.         z = ((borneinf+bornesup)/2);
  9.         return racinedecos(borneinf, z);
  10.     }


D'autre part, il faut un test d'arrêt un peu plus efficace, par exemple s’arrêter quand bornesup - borneinf ne diminue plus car on est en bout de précision.
 
ça donne ceci (réécrit pour essayer de faire de la tail récursion)

Code :
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <cmath>
  4. using namespace std;
  5. double racinedecos(double borneinf, double bornesup, double delta)
  6. {
  7.     double z = (borneinf + bornesup)/2;
  8.     double d = bornesup - borneinf;
  9.     if (cos(z) == 0 || d == delta) { return z; }
  10.    
  11.     double s, t;
  12.     if (cos(z) > 0) {
  13.         s = z;
  14.         t = bornesup;
  15.     }
  16.     else
  17.     {
  18.         s = borneinf;
  19.         t = z;
  20.     }
  21.     return racinedecos(s, t, d);
  22. }
  23. int main()
  24. {
  25.     double inf = 0, sup = 2;
  26.     double X = racinedecos(inf, sup, 0);
  27.     cout << "La racine de la fonction cosinus qui est comprise entre 0 et 2 vaut " << setprecision(15) << X << endl;
  28.     return 0;
  29. }


qui exécuté donne
La racine de la fonction cosinus qui est comprise entre 0 et 2 vaut 1.5707963267949  
(calculé en 55 appels récursifs)
A+,


Message édité par gilou le 16-03-2013 à 01:17:52

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 16-03-2013 à 04:00:22    

On peut aussi faire ça de manière non récursive:

Code :
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <limits>
  4. #include <cmath>
  5. using namespace std;
  6. inline int sign(double num) {
  7.     if (num > 0) return 1;
  8.     else if (num < 0) return -1;
  9.     else return 0;
  10. }
  11. double racinedecos(double borneinf, double bornesup)
  12. {
  13.     double low = borneinf, up = bornesup;
  14.     double zero;
  15.     double delta = up - low + 1; // pour rentrer dans le while
  16.     while (delta != (up - low)) {
  17.         delta = up - low;
  18.         zero   = (up + low)/2;
  19.         switch(sign(cos(zero))) {
  20.         case 1:
  21.             low = zero;
  22.             break;
  23.         case -1:
  24.             up = zero;
  25.             break;
  26.         case 0:
  27.             break
  28.         }
  29.     }
  30.     return zero;
  31. }
  32. int main()
  33. {
  34.     double inf = 0, sup = 2;
  35.     double X = racinedecos(inf, sup);
  36.     cout << "La racine de la fonction cosinus qui est comprise entre 0 et 2 vaut ";
  37.     cout << setprecision(1 + numeric_limits<double>::digits10)  << X << endl;
  38.     return 0;
  39. }

> La racine de la fonction cosinus qui est comprise entre 0 et 2 vaut 1.570796326794897
 
A+,


Message édité par gilou le 16-03-2013 à 04:04:00

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed