| Contacto | Chat | Foro |__
  
 
Principal Hoja de Vida Universidad Artículos Programas Descargas
 

Cálculo de raíces de un polinomio hasta de 5to grado


PROG00014 - C/C++
Esta rutina es capaz de determinar las raíces tanto reales como imaginarias de un polinomio hasta de quinto grado.

Teoría de operación

Este programa halla todas las raíces de un polinomio de grado 5 y menor. La ecuación es de la forma:

x^5 + an-1 xn-1 + ... + a1x + a0 = 0, n= 2, 3, 4 ó 5

Si el primer coeficiente no es igual a 1, es necesario convertirlo en 1, dividiendo toda la ecuación por dicho coeficiente.

Ecuaciones

Los programas para las ecuaciones de tercer y quinto grado utilizan una rutina iterativa para hallar una raíz real de la ecuación. Esta rutina exige que el término constante a0 no sea cero. Una vez se ha hallado luna raíz, se efectúa una división para reducir la ecuación inicial a una de segundo o cuarto grado.

Para resolver una ecuación de cuarto grado de la forma

x^4 + a3x^3 + a2x^2 + a1^x+ao

es necesario resolver previamente la siguiente ecuación de tercer grado:

y^3 + b2y^2 + b1y + b0 = 0

donde

b2 = -a2

b1 = a3a1 – 4a0

b0 = a0(4a2-a3^2)-a1^2

Sea y la mayor raíz real de la ecuación precedente, entonces la ecuación de cuarto grado se reduce a las dos ecuaciones de segundo grado siguientes:

x2 + (A + C)x + (B + D) = 0

x2 + (A - C)x + (B - D) = 0

donde

A= a3/2

B= y/2

C= (A^2 -a2x)^1/2

D= (B^2 - a0)^1/2

Las raíces de la ecuación de cuarto grado se calcula con la resolución de las dos ecuaciones de segundo grado.

Las ecuaciones de grado 2 se resuelven utilizando la fórmula del discriminante. Esta fórmula está implementada de tal forma que determina si la expresión dentro de la raíz es positiva o negativa. Si es positiva, la calcula normalmente originando raíces reales. Si es negativa, se cálcula la raíz del valor absoluto del dato obtenido y se expresa el resultado como raíz imaginaria.

#define TOLERANCE 1E-10
#define REAL 0
#define COMPLEX 1

void reduce (int n,double a[],double x)
{
   int i;

   a[0]= -a[0]/x;
   for (i=1;i<(n-1);i++)
      a[i]= (a[i-1]-a[i])/x;
   a[n-1]= a[n];
   a[n]= 0;
}

double solve (int n,double a[])
{
   int i;
   double p0= a[0],p,y,dy;

   for (;;p0=p)
   {
      for (i=n,y=0;i>=0;i--)
         y+= pow(p0,i)*a[i];
      for (i=n,dy=0;i>0;i--)
         dy+= i*pow(p0,i-1)*a[i];
      p= p0-y/dy;
      if (fabs(p-p0)<TOLERANCE)
         break;
   }
   return(p);
}

int solve2 (double a[],double *x,double *y)
{
   double d= a[1]*a[1]-4*a[0];

   *x= -a[1]/2;

   if (d<0)
   {
      *y= sqrt(fabs(d))/2;
      return(COMPLEX);
   }
   *y= *x-sqrt(d)/2;
   *x+= sqrt(d)/2;
   return(REAL);
}

void main (int argc,char **argv)
{
   double a[6],x,y,z;
   int n,i;

   printf("POLY Ver 1.00 (C)1994 - Ramon Medina\n\n");

   if ((argc<2)||(argc<(2+(n=atoi(argv[1]))))||(n<2)||(n>5))
   {
      printf("ERROR: Argumentos insuficientes o erroneos\n");
      printf("USO: POLY N An An-1 ... Ao (2 <= N <= 5)\n");
      exit(-1);
   }

   for (i=n;i>=0;i--)
      a[i]= _atold(argv[n-i+2])/_atold(argv[2]);
   i= 1;

   switch(n)
   {
      case 5:
         printf("X%d= %lf\n",i++,x=solve(5,a));
         reduce(5,a,x);

      case 4: {
         double b[4],A,B,C,D;

         b[3]=1; b[2]=-a[2];
         b[1]=a[3]*a[1]-4*a[0];
         b[0]=a[0]*(4*a[2]-a[3]*a[3])-a[1]*a[1];
         x= solve(3,b);
         reduce(3,b,x);
         if (solve2(b,&y,&z)==REAL)
         {
            if (y>x) x= y;
               if (z>x) x= z;
         }
         A= a[3]/2;
         B= x/2;
         C= sqrt(A*A-a[2]+x);
         D= sqrt(B*B-a[0]);

         b[2]= 1;
         b[1]= A+C;
         b[0]= B+D;
         if (solve2(b,&x,&y)==REAL)
            printf("X%d= %lf\nX%d= %lf\n",i++,x,i++,y);
         else
            printf("X%d= %lf + %lfj\nX%d= %lf -
              %lfj\n",i++,x,y,i++,x,y);

         b[1]= A-C;
         b[0]= B-D;
         if (solve2(b,&x,&y)==REAL)
            printf("X%d= %lf\nX%d= %lf\n",i++,x,i++,y);
         else
            printf("X%d= %lf + %lfj\nX%d= %lf -
              %lfj\n",i++,x,y,i++,x,y);
      } break;

      case 3:
         printf("X%d= %lf\n",i++,x=solve(5,a));
         reduce(3,a,x);

      case 2:
         if (solve2(a,&x,&y)==REAL)
            printf("X%d= %lf\nX%d= %lf\n",i++,x,i++,y);
         else
            printf("X%d= %lf + %lfj\nX%d= %lf -
              %lfj\n",i++,x,y,i++,x,y);
         break;
   }
}

Advertencia
Aunque no he escatimado esfuerzos en cuanto a proveer aplicaciones e información confiable y veraz, sin embargo no puedo garantizar que esté totalmente libre de errores; por esa razón, no asumo responsabilidad alguna por las consecuencias que se deriven de su empleo.




7-Zip

Descarga Adobre Reader

Descargar programa
  Copyright 2005 | Ramón Medina | Todos los derechos reservados | Última Actualización: Agosto del 2008 | webmaster@ramonmedina.name