Recherche de zéro d'une fonction par dichotomie

Soyez le premier à donner votre avis sur cette source.

Vue 24 405 fois - Téléchargée 827 fois

Description

Le titre est assez explicite, c'est juste 60 petites lignes pour trouver le zéro d'une fonction par dichotomie.

Il s'agit d'un processus itératif où l'intervalle de recherche du zéro est divisé par deux à chaque étape,
ce qui le rend assez efficace.

J'ai essayé d'expliquer le fonctionnement avec des commentaires, ça me parait assez compréhensible...

Source / Exemple :


#include <stdio.h>
#include <stdlib.h>
#include <math.h> //pour cos, sin ou autre...

int dichotomie ( double (*)(double), double, double, double*, double); //fonction

int main (int argc, char *argv[])
{ 
  double zero , //zero recherché
         a, b, //intervalle [a,b]
         precision ; //précision voulue
  
  printf("Exemple : \n");
  
  if ( dichotomie (sin, -1.0, 1.0, &zero, 1.0e-2) != -1 ) {// exemple avec sin dans [-1;1]
  printf("Zero de la fonction sin dans l'intervalle [-1;1] a 1e-2 pres : \n%le\n", zero);
  }
  else printf("Erreur.\n");
  
  if ( dichotomie (sin, -1.0, 2.0, &zero, 1.0e-2) != -1 ) {// exemple avec sin dans [-1;2]
  printf("Zero de la fonction sin dans l'intervalle [-1;2] a 1e-2 pres : \n%le\n", zero);
  }
  else printf("Erreur.\n");
  
  system("PAUSE");	
  return 0;
}

int  dichotomie ( double (*f)(double), double a, double b, double* zero, double precision)
//f : fonction dont on veut trouver le zero
//a et b : intervalle
//zero : zero
//precision : precision voulue
{double m, //milieu de l'intervalle courant
        fm,  //valeur de f(m)
        fa, fb ; //valeur de f(a) et de f(b)

fa = (*f)(a);
fb = (*f)(b);
if (fa*fb>=0 || a>=b ) {printf("Intervalle incorrect.\n"); return -1;} //Intervalle incorrect

while ( b-a > precision )
{
m = (b+a) / 2 ;
fm = (*f)(m) ;
if (fm==0) break; //zero trouvé

if (fa*fm < 0) {
b = m;
fb = fm;
}
else  {
a = m;
fa = fm;
}

}

  • zero = m;
return 0; }

Codes Sources

Ajouter un commentaire

Commentaires

Cyberboy2054
Messages postés
173
Date d'inscription
jeudi 20 décembre 2001
Statut
Membre
Dernière intervention
22 août 2008
-
Plus qu'à coder le parser d'expression qui va avec pour plus avoir a coder les fonctions en dur, et ce serait excellent :)
Un petit probleme par contre, mais qui vient de l'algo lui même: et si la fonction a plusieurs zéros dans l'intervalle donné :p ?
Sinon, je comprends pas comment le compilo accepte de compiler le code avec une declaration de fonction à l'intérieur d'une autre fonction (cf dichotomie dans main)
Voilou
ncoder
Messages postés
244
Date d'inscription
vendredi 6 mai 2005
Statut
Membre
Dernière intervention
6 avril 2008
1 -
Je peux déclarer une fonction à l'intérieur d'une autre mais alors je peux utiliser la fonction déclarée que par la fonction dans laquelle elle a été déclarée...

Euh, c'est compréhensible ce que j'ai mis ? :/
ncoder
Messages postés
244
Date d'inscription
vendredi 6 mai 2005
Statut
Membre
Dernière intervention
6 avril 2008
1 -
Si ya 2 zéros dans l'intervalle donné ça renvoie "Intervalle incorrect" ...
Cyberboy2054
Messages postés
173
Date d'inscription
jeudi 20 décembre 2001
Statut
Membre
Dernière intervention
22 août 2008
-
Oui c'est parfaitement compréhensible, je ne savais pas que c'est possible. Par contre je maintiens que ce serait encore mieux avec un parser d'expression mathématiques ;)
jad_raad
Messages postés
15
Date d'inscription
lundi 14 mars 2005
Statut
Membre
Dernière intervention
6 juin 2005
-
j'ai lu tous vos commentaires ici mais est ce qu'il y a quelqu'un peut me donner un exmeple du source sur le parser
message pour l'auteur du source en fait ta methode pour la dichotomie et avec la definition des variables est tres compliqué et tu peux la faire autrement j'ai deja codé ce programme avant et je pense que cette methode va t'interesser


//dichotomie
#include<math.h>
#include<stdio.h>

double f(double x)//la fonction f
{
return (exp(2*x)-exp(x)-1);
}

int main()
{
int n;//n = nombre d'iteration
double a,b,c,e;//les points a et b sont l'intervalles à choisir
//e est la precision
printf("Saisir respectivement a,b,e:\n");
printf("a=");
scanf("%lf",&a);
printf("b=");
scanf("%lf",&b);
printf("e=");
scanf("%lf",&e);

n=0;
while(fabs(b-a)>e)
{
n++;

c=(a+b)/2;
if(f(a)*f(c)<0)
b=c;
else a=c;

}//end while
printf("\nle resultat est:%lf\niteration:%d\n",c,n);
system("pause");
}

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.