Mostrar las raíces de un polinomio

prev.gif (997 bytes)chapter.gif (1105 bytes)home.gif (1232 bytes)next.gif (998 bytes)

Raíces de una ecuación

La función discriminadora

Mostrar las raíces calculadas

Comprobación de las raíces

Ejemplos

Bibliografía

Código fuente


La función discriminadora

La función pública hallaRaices se encarga de llamar a la función tabla para calcular los coeficientes polinomio resultante del proceso de elevar el polinomio original sucesivamente al cuadrado. Los coeficientes se guardan en el array bidimensional a[m][i] (i=0... n) donde m representa la iteración, e i el coeficiente: 0 es el índice del coeficiente de mayor grado y n es el índice del término independiente.

    private boolean cambiaSigno(int j){
        double logaritmo;
        for(int k=2; k<=m; k++){
            if(a[k][j]>0)   continue;
            numComplejas++;
//máximo dos raíces complejas, 4 contando sus respectivas conjugadas
            if(numComplejas<3){
                logaritmo=(Math.log(a[m][j+1])-Math.log(a[m][j-1]))/(2*pot2);
                moduloComplejas[numComplejas-1]=Math.exp(logaritmo);
                return true;
            }
        }
        return false;
    }

Ya que a[m][0] es siempre la unidad analizaremos cada uno de los n coeficientes restantes a[m][i] (i=1 ... n). En primer lugar, miraremos si hay cambios de signo en cada uno de los coeficientes i, llamando a la función cambiaSigno, y pasándole el índice i. Si la función devuelve true, quiere decir que se ha detectado una raíz compleja y su correspondiente conjugada.

        tabla();
//el pimer coeficiente a[m][0] es siempre 1
        for(int i=1; i<n+1; i++){      //i es la raíz
            if(cambiaSigno(i)){
//raíz compleja y su correspondiente conjugada
                i++;
                continue;
            }

Posteriormente, analiza si hay una raíz doble, comprobando la relación entre los valores del coeficiente i en las dos últimas iteraciones. Recuérdese que a[m][i] es habitualmente el cuadrado de a[m-1][i], salvo para los coeficientes excepcionales. Cuando hay presentes raíces dobles a[m][i] es el cuadrado de a[m-1][i] dividido entre dos. La variable local cociente valdrá habitualmente cero, salvo en el caso de raíces dobles. Cuando la variable cociente de la función cambiaSigno es cero (el logaritmo de la unidad es cero), o un valor muy próximo a cero (menor que la constante CERO fijada de antemano), se llama a la función raizRealSimple para hallar la raíz correspondiente al coeficiente i del polinomio. En caso contrario, tendremos una raíz doble, y se llamará a la función raizRealDoble para calcularla.

//raíces simple y dobles
            double logaritmo=Math.log(a[m][i])-2*Math.log(a[m-1][i]);
            if(Math.abs(logaritmo)<CERO){
                raizRealSimple(i);
            }else{
                raizRealDoble(i);
                i++;
                continue;
            }
        }

La primera verificación se realiza sobre las raíces complejas ya que cumplen una condición más estricta que las raíces dobles, es decir, se comportan como las raíces dobles pero además presentan cambios de signo en las primeras iteraciones, mientras el término cuadrado no domina sobre los dobles productos.

Una vez concluido el análisis de cada uno de los coeficientes del polinomio en las sucesivas iteraciones que lo elevan al cuadrado, y se han calculado las raíces reales simples y dobles se procede al cálculo de las raíces complejas. Si solamente hay una raíz compleja y su conjugada, se llama a la función unaRaizCompleja.

        if(numComplejas==1){
            unaRaizCompleja();
        }

Si hay dos raíces complejas y sus conjugadas, se llama a la función dosRaicesComplejas.

        if(numComplejas==2){
            dosRaicesComplejas();
        }

El código completo de la función miembro hallarRaices que calcula todas las raíces de un polinomio se muestra a continuación

   public void hallarRaices(){
        tabla();
//el pimer coeficiente a[m][0] es siempre 1
        for(int i=1; i<n+1; i++){     
            if(cambiaSigno(i)){
//raíz compleja y su correspondiente conjugada
                i++;
                continue;
            }
//raíces simple y dobles
            double logaritmo=Math.log(a[m][i])-2*Math.log(a[m-1][i]);
            if(Math.abs(logaritmo)<CERO){
                raizRealSimple(i);
            }else{
                raizRealDoble(i);
                i++;
                continue;
            }
        }
        if(numComplejas==1){
            unaRaizCompleja();
        }
        if(numComplejas==2){
            dosRaicesComplejas();
        }
     }


Mostrar las raíces calculadas

Primero, se muestran las raíces reales con dos cifras decimales

	(double)Math.round(raicesReales[i]*100)/100

A continuación, se muestran las raíces complejas

	System.out.println(raicesComplejas[2*i]);

La función println no solamente imprime objetos de la clase String, sino que también imprime datos numéricos de los tipos básicos y como vemos convierte automáticamente un número complejo en su representación textual, pero para ello hemos de redefinir en dicha clase la función toString miembro de la clase base Object de la cual derivan todas las clases en Java. La llamada implícita a dicha función muestra la parte real seguida de la imaginaria ambas con dos cifras decimales y seguida de la unidad imaginaria i. El código completo de la función mostrarRaices es el siguiente.

   public void mostrarRaices(){
        hallarRaices();
//raíces reales
        System.out.println("Raíces reales");
        for(int i=0; i<numReales; i++){
            System.out.println((double)Math.round(raicesReales[i]*100)/100+" ---> "+
			valorPolinomio(raicesReales[i]));
        }
        System.out.println("");
//raíces complejas
        System.out.println("Raíces complejas");
        for(int i=0; i<numComplejas; i++){
            System.out.println(raicesComplejas[2*i]+" ---> "+
			valorPolinomio(raicesComplejas[2*i]));
            System.out.println(raicesComplejas[2*i+1]+" ---> "+
			valorPolinomio(raicesComplejas[2*i]));
        }
        System.out.println("");
    }


Comprobación de las raíces

La función valorPolinomio halla el valor de un polinomio para un valor real de su variable x. Dicha función calcula primero las sucesivas potencias de x, las guarda en el array pot_x, y luego, las multiplica por sus respectivos coeficientes y suma los resultados.

    public double valorPolinomio(double x){
        double y=0.0;
//sucesivas potencias de x, se puede utilizar tambien la funcion Math.pow
        double[] pot_x=new double[n+1];
        pot_x[0]=1.0;
        for(int i=1; i<n+1; i++){
            pot_x[i]=pot_x[i-1]*x;
        }
//valores de los sucesivos términos
        for(int i=0; i<n+1; i++){
            y+=a[0][i]*pot_x[n-i];
        }
        return y;
    }

Es algo más complicado hallar el valor del polinomio cuando la variable es compleja x. Tendremos que hallar las sucesivas potencias de la variable compleja, multiplicar por los coeficientes y sumar los resultados. La clase Complejo que describe dicha entidad matemática ha definir las siguientes operaciones: la suma de dos números complejos, el producto de un número real por un número complejo, y la potencia de un número complejo.

La función valorPolinomio devolverá un número complejo, cuando se le pasa en su único argumento otro número complejo. Su definición en términos de las funciones mencionados es la siguiente.

  public Complejo valorPolinomio(Complejo x){
        Complejo y=new Complejo();
        for(int i=0; i<n+1; i++){
            y=Complejo.suma(y, Complejo.producto(a[0][i], Complejo.potencia(x, (n-i))));
        }
        return y;
    }

 

Ejemplos

Para hallar las raíces de un polinomio primero creamos un array de los coeficientes, de mayor a menor grado. Para el polinomio se escribirá

        double[] coef={1, -4, 1, 6};

A continuación, se crea un objeto g de la clase Graeffe y le pasamos el array de los coeficientes coef a su constructor. Desde dicho objeto se llama a la función miembro mostrarRaices, para hallar y mostrar las raíces del polinomio.

        Graeffe g=new Graeffe(coef);
        g.mostrarRaices();

Para que practique el lector, se le propone hallar las raíces de los siguientes ecuaciones polinómicas:

 

Bibliografía

Wylie. Matemáticas superiores para la ingeniería. Ediciones del Castillo. Apéndice.

Ángel Franco. El lenguaje C++ y las Matemáticas (II). La sobrecarga de operadores.   RPP nº 27, Marzo de 1997.

 

Código fuente

disco.gif (1035 bytes) Complejo.java, Graeffe.java, RaizPolinomioApp.java