Racines de polynomes

Description

Extraction de racines de polynomes par dichotomie !

Donne seulement une racine sur un intervalle precis ou l'on peut appliquer le theoreme de la valeur intermediaire !

Source / Exemple :


#include <stdio.h>
#include <conio.h>
#include <stdarg.h>

#define MY_PRECISION 50

#define SIZE_TAB(x) sizeof(x)/sizeof((x)[0])
// --------------------------------------------------------
// calcul un polynome
double EvalPoly(double *tabCoeff,int degre,double x)
{
// toutes les puissances de x :
//  0   1        degre
// x   x   ...  x
double power;
// pointeur sur un coefficient
double *pCurCoeff;
double somme;

power       = 1.;         // (x^0 = 1)
pCurCoeff   = tabCoeff;   // pointeur sur le premier coefficient
somme       = 0.;         // au debut la somme vaut 0
// la boucle qui balaye tous les coefficients
do
  {
  somme += (*pCurCoeff) * power;

  // on passe au coefficient suivant
  power       *= x;
  pCurCoeff   ++;
  }while(degre--);

return somme;
}

// --------------------------------------------------------
// Donne une approximation d'une racine d'un polynome
// entre a et b.
// Retourne 0 s'il n'y a pas de racine
// et retourne 1 sinon.
int EvalRoot( 
              double *tabCoeff, // tous les coefficients
              int degre,        // le degre
              double a,         // valeur a gauche
              double b,         // valeur a droite
              int n,            // la precision (nombre d'iteration)
              double *pRoot     // pointeur sur le resultat (la racine)
              )
{
// image par le polynome de a et b
double  Pa,Pb;
// milieu et image du milieu de a et b
double  m,Pm;
// indice
int     i;

Pa = EvalPoly(tabCoeff,degre,a);
Pb = EvalPoly(tabCoeff,degre,b);

// S'il n'y a pas de racine
// (si Pa et Pb on le meme signe).
// Ceci est plus rapide que :
//( Pa < 0 && Pb < 0) || ( Pa > 0 && Pb > 0)
if(Pa * Pb > 0)
  {
  return 0;
  }

for(i=0;i<n;i++)
  {
  // m est le milieu
  m = (a+b)/2;
  // Pm est l'image de m
  Pm = EvalPoly(tabCoeff,degre,m);
  // si on est tombe sur une racine (tres rare)
  if(Pm == 0)
    {
    break;
    }
  // si Pm est positif, 
  else if(Pm * Pb > 0)
    {
    b   = m;
    Pb  = Pm;
    }
  // si Pm est negatif, 
  else
    {
    a   = m;
    Pa  = Pm;
    }
  }

  • pRoot = m;
return 1; } // -------------------------------------------------------- void myFunc( double *tabCoeff, // tous les coefficients int degre, // le degre int n, // la precision (nombre d'iteration) int nbIntervalle, // nombre d'intervalles ... ) { int i; va_list arg; int nbChar; va_start(arg,nbIntervalle); for(i=0;i<nbIntervalle;i++) { double root; double Xmin,Xmax; int j; Xmin = va_arg(arg,double); Xmax = va_arg(arg,double); nbChar = printf("[%+9.6lf,%+9.6lf]",Xmin,Xmax); // on centre jusqu'au 30 eme caractere for(j=nbChar;j<=30;j++) printf("."); printf(" "); if(EvalRoot(tabCoeff,degre,Xmin,Xmax,n,&root)) printf("%+9.6lf\n",root); else printf("--- pas de racine ---\n"); } va_end(arg); } // -------------------------------------------------------- int main(int argc,char **argv) { // x^2 + 1 // pas de solution double poly1[] = {1,0,1}; // x^2 + x - 1 // nombre en Or ... double poly2[] = {-1,1,1}; // x^3 + 2x^2 - 13 x + 10 // <=> (x-1)*(x+5)*(x-2) double poly3[] = {10,-13,2,1}; // x^2 - 1/2 // Rac(2)/2 ... double poly4[] = {-0.5,0,1}; // === poly1 === printf("x^2 + 1\n"); myFunc( poly1, SIZE_TAB(poly1) - 1, MY_PRECISION, 4, // 4 intervalles -99. , -1., // intervalle [-99;-1] -1. , 0., // intervalle [-1;0] 0. , +1., // intervalle [0;-1] +1. , +99. // intervalle [-1;99] ); // === poly2 === printf("\nx^2 + x - 1\n"); myFunc( poly2, SIZE_TAB(poly2) - 1, MY_PRECISION, 4, // 4 intervalles -99. , -2., -2. , 0., 0. , +2., +2. , +99. ); // === poly3 === printf("\n(x-1)*(x+5)*(x-2)\n"); myFunc( poly3, SIZE_TAB(poly3) - 1, MY_PRECISION, 4, // 4 intervalles -99. , -1.5, -1.5 , 0., 0. , +1.5, +1.5 , +99. ); // === poly4 === printf("\nx^2 - 1/2\n"); myFunc( poly4, SIZE_TAB(poly4) - 1, MY_PRECISION, 4, // 4 intervalles -99. , -2., -2. , 0., 0. , +2., +2. , +99. ); getch(); return 0; }

Codes Sources

A voir également

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.