49
Soluciones de una ecuación de tercer grado en Excel. Hace algún tiempo expliqué la manera de resolver, esto es, de encontrar la solución de una ecuación lineal de grado uno (ver ); en aquel entonces utilicé la herramienta Buscar objetivo. Recientemente, a través de un comentario en el blog, un usuario pedía ayuda para saber cómo solucionar una ecuación de tercer grado: ...lo q necesito es encontrar mas de una raíz, tengo un polinomio cubico y necesito las 3 raíces... He de decir que para encontrar las tres raíces/soluciones de un polinomio cúbico partiré de una hipótesis de trabajo, que el polinomio tiene tres raices; sabemos que una ecuación de tercer grado podría tener hasta tres puntos de corte con el eje X, es decir, hasta tres valores de X donde la ecuación devuelve un valor igual a cero. Inicio el trabajo con un ejemplo de ecuación de tercer grado con tres soluciones. y = 2x 3 - 4x 2 + 1 A pesar de mi hipótesis inicial, el método de trabajo es válido para cualquier polinomio cúbico. El primer paso es escribir nuestra ecuación de manera que Excel la entienda: =2*POTENCIA(A3;3)-4*POTENCIA(A3;2)+1 con esta fórmula, en un segundo paso, construiremos una gráfica (forma visual de encontrar las soluciones buscadas para nuestra ecuación): Ya en el gráfico podemos ver cuáles son las raíces de la ecuación, pero parece claro que dependerá mucho de los valores de la x que hayamos insertado para construir el gráfico. Se hace necesario, por tanto, tener buena vista, o probar un par de veces, para conseguir el gráfico adecuado a nuestros propósitos. Sin embargo, con el gráfico sólo podemos intuir la forma de la ecuación y más o menos por donde 'caen' las raíces. Para conocer las soluciones exactas nos basaremos en el gráfico recién construido.

Funciones y Ecuaciòn Cubica Excel

Embed Size (px)

Citation preview

Page 1: Funciones y Ecuaciòn Cubica Excel

Soluciones de una ecuación de tercer grado en Excel.Hace algún tiempo expliqué la manera de resolver, esto es, de encontrar la solución de una ecuación

lineal de grado uno (ver); en aquel entonces utilicé la herramienta Buscar objetivo.

Recientemente, a través de un comentario en el blog, un usuario pedía ayuda para saber cómo

solucionar una ecuación de tercer grado:

...lo q necesito es encontrar mas de una raíz, tengo un polinomio cubico y necesito las 3 raíces...

He de decir que para encontrar las tres raíces/soluciones de un polinomio cúbico partiré de una

hipótesis de trabajo, que el polinomio tiene tres raices; sabemos que una ecuación de tercer grado

podría tener hasta tres puntos de corte con el eje X, es decir, hasta tres valores de X donde la

ecuación devuelve un valor igual a cero. Inicio el trabajo con un ejemplo de ecuación de tercer grado

con tres soluciones.

y = 2x3 - 4x2 + 1

A pesar de mi hipótesis inicial, el método de trabajo es válido para cualquier polinomio cúbico.

El primer paso es escribir nuestra ecuación de manera que Excel la entienda:

=2*POTENCIA(A3;3)-4*POTENCIA(A3;2)+1

con esta fórmula, en un segundo paso, construiremos una gráfica (forma visual de encontrar las

soluciones buscadas para nuestra ecuación):

Ya en el gráfico podemos ver cuáles son las raíces de la ecuación, pero parece claro que dependerá

mucho de los valores de la x que hayamos insertado para construir el gráfico. Se hace necesario, por

tanto, tener buena vista, o probar un par de veces, para conseguir el gráfico adecuado a nuestros

propósitos.

Sin embargo, con el gráfico sólo podemos intuir la forma de la ecuación y más o menos por donde

'caen' las raíces. Para conocer las soluciones exactas nos basaremos en el gráfico recién construido.

Toca ahora construir un modelo sobre el que aplicar la herramienta SOLVER, que será quien nos de

nuestras raíces para la ecuación.

Page 2: Funciones y Ecuaciòn Cubica Excel

Recuperaremos la fórmula de la ecuación:

=2*POTENCIA(K2;3)-4*POTENCIA(K2;2)+1

Fijémonos que en la celda L5 aparece lo que será la celda objetivo en el modelo de Solver; y que

también he añadido lo que serán dos restricciones o condiciones en las celdas M3 y M4 que

asegurarán que Solver no repita las raíces.

Muy importante antes de ejecutar la herramienta Solver será aprovechar el trabajo realizado al

construir el gráfico; y es que habrá que 'ayudar' un poco a Solver a que nos devuelva las soluciones

correctas.

Viendo el gráfico es fácil determinar que la primera raiz (la menor de todas) es negativa y que la

segunda y tercera raíz son positivas, obviamente la tercera mayor que la segunda. Realmente con

esto sería suficiente, pero si lo estimamos necesario podemos ser más precisos y decir que la primera

raiz es un número cercano a -0,50, que la segunda es aproximádamente 0,60 y la tercera 1,90.

Voy a trabajar de una manera general, sin llegar a ayudar a Solver con tanta precisión (probablemente

muchas veces no pueda o quiera conocer esos valores). Escribo unos valores genéricos que se

adecúen a lo comentado:

Cuanto más próximos sean los valores dados más rápido encontrará Solver las soluciones.

Ya terminamos, ya que sólo queda ejecutar Solver y definir sus restricciones. Desde el menú Datos >

Análisis > Solver:

Page 4: Funciones y Ecuaciòn Cubica Excel

RESOLUCIÓN DE ECUACIONES UTILIZANDO MICROSOFT EXCEL

1. Introducción a Excel

Excel es un software diseñado para su uso como “hoja de cálculo”. Es decir,

permite agilizar la realización de cálculos de diversa índole, siendo una

herramienta muy extendida y potente.

En este sencillo ejemplo vamos a explicar brevemente como es posible resolver

una ecuación cúbica (que es la forma típica de las ecuaciones de estado que

vamos a usar en la asignatura) de una manera sencilla.

2. Ejemplo a resolver

La función de la que queremos obtener las raíces podría es: 4x3+3x2–6x–2 = 0

Esta ecuación tiene tres raíces reales, como puede observarse en la figura 1.

[pic]

Figura 1. Representación gráfica de y=4x3+3x2–6x–2

3. Resolución en Excel

En Excel, a cada una las celdas (que están formadas por la intersección una fila y

una columna) se le puede asignar un texto, un número o una operación/función

matemática. La asignación de texto o números es directa, mientras que las

operaciones van precedidas del signo =

[pic]

Figura 2. Introducción de datos en Excel

Page 5: Funciones y Ecuaciòn Cubica Excel

En la figura 2 se observa que se han asignado los coeficientes

de la ecuación cúbica a resolver a las celdas B6, C6, D6 y E6. Para calcular el

valor de la función (variable y), será necesario especificar un valor de la variable x.

Eso se ha hecho en la celda H8. El cálculo del valor de y se ha realizado en la

celda H6 escribiendo la secuencia que se ve la figura 2. Para escribir las celdas en

las ecuaciones puede usar el teclado o bien usar el ratón para seleccionar la celda

deseada.

Nuestro objetivo es hacer que Excel cambie el valor de la variable x (al cual le

hemos asignado un valor arbitrario) de modo que el valor de y sea cero. Para ello

se utiliza la función “buscar objetivo”.

      Esta función se encuentra en Datos→Análisis y si→Buscar objetivo, como

puede observarse en la figura 3.

[pic]

Figura 3. Ubicación de la función “buscar objetivo”

El funcionamiento de “buscar objetivo” es sencillo. Una vez seleccionado, los

parámetros a seleccionar son:

          1) Definir la celda: se selecciona la celda en la que se quiere fijar le valor (es

decir, nuestra variable y). Si se ha elegido las mismas celdas que en este tutorial,

sería H6

2) Con el valor: se fija el valor

(en nuestro caso 0)

          3) Para cambiar la celda: se selecciona la celda que queremos que cambie

de valor para llegar al objetivo (es decir, la variación del valor de x). Según la

Page 6: Funciones y Ecuaciòn Cubica Excel

figura 2 sería la celda H8

Una vez realizado esto, Excel iterará hasta buscar el objetivo.

4. Valor inicial de x

Como es bien conocido, la obtención de una raíz u otra de la ecuación cúbica

dependerá de la selección de un valor inicial para la variable x. Es decir,

dependerá del valor que ocupara la celda que contiene al valor de x (en este

ejemplo la celda H8) antes de usar la función “buscar objetivo”.

      Ejercicio: Calcule las tres raíces de la ecuación y=4x3+3x2–6x–2

Para la resolución de ecuaciones cúbicas de estado, los valores que interesan son

los valores menor y mayor de x (que representarían, por ejemplo, el volumen

parcial del líquido y del vapor, respectivamente). Las reglas explicadas en clase

para la selección de valores iniciales en la resolución iterativa “a mano” de

ecuaciones cúbicas también pueden ser aplicadas para la resolución en Excel,

garantizado que se calcula lo que realmente se está buscando

http://www.buenastareas.com/ensayos/Resoluci%C3%B3n-De-Ecuaciones-C%C3%BAbicas-Usando-Excel/3660547.html

Page 7: Funciones y Ecuaciòn Cubica Excel

Conciliar una partida con Solver.Vamos a ver cómo podemos encontrar, de un listado de valores, aquellos que suman una cantidad

definida por nosotros; esto es, vamos a conciliar una partida con un listado de valores. Para esto

emplearemos Solver.

Si bien, hay que advertir que esta aplicación será válida sólo en aquellos casos que la combinación de

valores que suman el valor a conciliar (el valor buscado) es única.

Veamos nuestro listado de valores:

Convertiremos nuestro listado en una Tabla (Ctrl+q), y luego con la Tabla

seleccionada,Insertaremos una columna de tabla a la derecha, que nombraremos

como 'binario'. 

También asignaremos nombre a los dos campos:

binario =Hoja1!$B$2:$B$17

Cantidades =Hoja1!$A$2:$A$17

Por último, como parte importante a la hora de configurar Solver, en la celda D2 insertaremos la

función:

=SUMAPRODUCTO(binario;Cantidades)

esta función se encargará de multiplicar fila a fila, elemento a elemento, los valores del rango 'binario'

y del rango 'Cantidades'.

Esta celda, será considerada en la configuración como la Celda objetivo.

Ejecutamos Solver, desde Datos > Análisis > Solver:

Page 8: Funciones y Ecuaciòn Cubica Excel

Vemos que hemos seleccionado como celda objetivo la celda $D$2, donde se encontraba la función

SUMAPRODUCTO. Además, como Celdas cambiantes hemos seleccionado el rango binario; la

consecuencia es que Solver completará este rango con los valores necesarios para que cumplan el

objetivo y sus condiciones.

El objetivo para nuestro ejemplo es encontrar aquella combinación de cantidades que sumen 415,09.

La única condición que damos es que cada uno de los valores del rango 'binario', tras la ejecución de

Solver únicamente podrán ser o ceros o unos (0 ó 1), es decir, un número binario. Esto lo conseguimos

agregando la siguiente condición:

Ya estamos en disposición de Resolver. Obteniendo la siguiente ventana de información:

El resultado es que ha encontrado la combinación de valores del campo 'Cantidades' que suma

415,09:

415,09 = 126,35 + 71,00 + 117,75 + 99,99

Page 9: Funciones y Ecuaciòn Cubica Excel

Vemos como Solver ha añadido ceros y unos en el rango 'binario' hasta encontrar la combinación por

la que SUMAPRODUCTO(binario; Cantidades) = 415,09

Page 10: Funciones y Ecuaciòn Cubica Excel

Conciliar en Excel por aproximación con Solver.Tiempo atrás, expliqué en un post la manera de conciliar ciertos importes, empleando para ello la

herramienta de Excel Solver (ver). Al hilo de este post un usuario preguntaba a través de un

comentario:

...¿podríamos hacer que las posibilidades de suma fueran por un aproximado de por ejemplo 5 unidades arriba y 5 abajo?...

La respuesta a esta cuestión sería afirmativa, claro está bajo ciertos supuestos, ya que en caso de

múltiples coincidencias solver siempre se decantaría por una de las posibles soluciones. sin embargo

construiremos un modelo en Excel que nos muestre en todo caso, de todas las aproximaciones

posibles a buscar, la que sea más próxima al valor buscado.

Importante aclarar, buscamos por aproximación al total de la suma.

Veamos nuestros datos de partida:

Realmente, nuestra base de trabajo es similar a la expuesta en la entrada Conciliar una partida con

Solver, si bien, necesitaremos ciertas modificaciones. En primer lugar, construiremos dos columnas C y

D anexas, ambas con la misma fórmula

=A2*B2

para luego acabar sumando estos valores en C8 y D8

=SUMA(C2:C7) y =SUMA(D2:D7); sumas que emplearemos después al Agregar nuestras

condiciones de Solver.

Importante también es definir correctamente la que será celda objetivo E8, con la fórmula:

=ABS(((G2*2)-(D8+C8))/2)

sabiendo que nuestro modelo es el siguiente, con la disposición de celdas que vemos en la imagen:

Además de la formulación de la celda $E$8 (futura celda objetivo), es clave determinar cuál es el

factor de aproximación, en mi ejemplo será de 2 por encima o por debajo del valor buscado o a

Page 11: Funciones y Ecuaciòn Cubica Excel

conciliar (27,92); estos valores serán empleados al construir las condiciones de Solver.

Ejecutemos la herramienta Solver, así que iremos a la Ficha Datos > Análisis > Solver, y

configuraremos los diferentes parámetros:

haz click en la imagen

Observemos como hemos seleccionado minimizar el valor de la celda objetivo $E$8, cambiando el

rango de celdas $B$2:$B$7, es decir, las celdas de nuestra Tabla origen, por las que multiplicaremos

cada importe. Y en cuanto a las tres restricciones, forzamos a que el rango $B$2:$B$7 sean 1 ó 0

(resultado binario), además de restringir que la suma del producto de cada registro por ese valor

binario a obtener sea mayor o igual que el mínimo (valor buscado menos la aproximación) y menor o

igual que el máximo (valor buscado más la aproximación).

Con estas restricciones, al minimizar el modelo desarrollado, conseguiremos llegar a las partidas

que mejor se aproximan al valor buscado, esto es a la 'conciliación por aproximación'.

Si Aceptamos la configuración, vemos la respuesta dada:

Page 12: Funciones y Ecuaciòn Cubica Excel

Que al comprobar manualmente con las diferentes combinaciones que se acercan al resultado

buscado, podemos ver que ciertamente el resultado propuesto es, de todos los posibles, el más

próximo.

kaz click en la imagen

Para nuestro ejemplo, las partidas cuya suma se aproximan más a 27,92 son 10,00 + 15,00 + 2,90.

Por supuesto, este método, sería válido también para la conciliación exacta.

Publicado por ExcelForo 

Page 13: Funciones y Ecuaciòn Cubica Excel

http://www.ayudaexcel.com/foro/macros-programacion-vba-10/ecuacion-excel-17856/

Hola, una forma manual de hacerlo a grandes rasgos sería:a) generas 3 celdas con nombre, es decir, X, N y Mb) generas la formula como en la imagenc) activas el cuadro de dialogo "Buscar objetivo" y lo estableces como en la imagen anexa.

Page 14: Funciones y Ecuaciòn Cubica Excel

Raíces de un polinomio. Método de Graeffe

http://www.sc.ehu.es/sbweb/fisica_/numerico/raices/graeffe.xhtml

En esta página, se describe un procedimiento matemático ingenioso para hallar las raíces de un polinomio con gran exactitud. El método de Graeffe se presta especialmente a ser programado en el ordenador, constituyendo de por sí un ejercicio relevante, en lo que concierne a los aspectos generales del lenguaje Java: sentencias condicionales e iterativas, arrays unidimensionales y bidimensionales, descomposición de un problema en tareas que se codifican en forma de funciones, y finalmente, la encapsulación de los datos y las funciones para formar una clase.

En muchos campos de las matemáticas es necesario hallar las raíces de un polinomio, por ejemplo, para calcular la integral de una función racional, para calcular las raíces del polinomio característico que son los valores propios de una matriz, etc. Solamente existen fórmulas si el polinomio tiene un grado igual o inferior a cuatro. Excepto para los polinomios de primer y segundo grado, las fórmulas son complicadas, por lo que se emplean procesos de aproximación numérica. Entre los numerosos métodos que existen, el más conocido es quizá el método de Newton. Sin embargo, describiremos un método, realmente ingenioso, que nos proporciona gran exactitud en las raíces de un polinomio.

Sea el polinomio

a 0 x n + a 1 x n−1 + a 2 x n−2 + a 3 x n−3 + ...  a n−1 x+ a n =0  (1)

Hacemos el polinomio más simple dividiendo todos los coeficientes por el primer término de modo que a0 es siempre 1. Supongamos que sus raíces reales y distintas son

-r1, -r2, -r3, ...-rn

Al elevar al cuadrado el polinomio y agrupar los términos se obtiene un polinomio de grado 2n

a 0 2 ( x n ) 2 −( a 1 2 −2 a 2 a 0 ) ( x n−1 ) 2 +( a 2 2 −2 a 1 a 3 +2 a 4 a 0 ) ( x n−2 ) 2 −( a 3 2 −2 a 2 a 4 +2 a 1 a5 −2 a 6 a 0 ) ( x n−3 ) 2 + ...=0 } (2)

Cuyas raíces serán

− r 1 2 ,− r 2 2 ,− r 3 2  ... − r n 2

Hemos construido así una nueva ecuación cuyas raíces son numéricamente iguales a los cuadrados de las raíces de la ecuación original. Repitiendo el

Page 15: Funciones y Ecuaciòn Cubica Excel

proceso, se pueden obtener ecuaciones cuyas raíces sean numéricamente iguales a las potencias cuarta, octava, decimosexta, etc. de las raíces de la ecuación original. El efecto de este proceso de elevar al cuadrado es el de producir ecuaciones cuyas raíces están cada vez más separadas. Por ejemplo, si dos raíces de la ecuación original están entre sí como 5 : 4 sus potencias 128 están en la razón 5128 : 4128, o sea, 2.54 1012: 1, lo que es muy deseable ya que las ecuaciones cuyas raíces están muy separadas se pueden resolver rápidamente con exactitud considerable. Supóngase ahora, que reiterando el proceso de elevación al cuadrado se llega a un polinomio

α 0 ( x n ) 2 m + α 1 ( x n−1 ) 2 m + α 2 ( x n−2 ) 2 m + α 3 ( x n−3 ) 2 m + ...=0  (3)

donde m es el número de veces que se repite el proceso de elevación al cuadrado. Así, si se repite siete veces el proceso de elevación al cuadrado, 2m =27 =128 sería el exponente al que estarían elevados las sucesivas potencias xn, xn-1, xn-2, ... del polinomio. Sus raíces serán las del polinomio original elevadas al exponente 2m.

− r 1 2 m ,− r 2 2 m ,− r 3 2 m , ... − r n 2 m

Por las relaciones conocidas entre raíces y coeficientes del polinomio, se tiene que

α 0 =1 α 1 =-(suma de las raíces)= r 1 2 m + r 2 2 m + ... + r n 2 m α 2 =(suma de las raíces tomando dos cada vez)= r1 2 m r 2 2 m + r 1 2 m r 3 2 m + ... + r 2 2 m r 3 2 m + ... + r n−1 2 m r n 2 m α 3=−(suma de las raíces tomando tres cada vez)= r 1 2 m r 2 2 m r 3 2 m + r 1 2 m r 2 2 m r 4 2 m + ... + r 2 2 m r 3 2 mr 4 2 m + ... + r n−2 2 m r n−1 2 m r n 2 m α n = ( −1 ) n (producto de todas las raíces)= r 1 2 m r 2 2 m r 3 2 m  ...  r n2 m

En la suposición de que

| r 1 |>| r 2 |>| r 3 |> ... | r n |

y de que 2m es grande por ejemplo 128 ó 256, se cumplirá que

| r 1 | 2 m >>> | r 2 | 2 m >>> | r 3 | 2 m >>> ...  | r n | 2 m

donde el símbolo >>> indica mucho mayor que. Las relaciones entre coeficientes y raíces quedarán simplificadas con gran aproximación a las expresiones.

α 0 =1 α 1 = r 1 2 m α 2 = r 1 2 m r 2 2 m α 3 = r 1 2 m r 2 2 m r 3 2 m α n = r 1 2 m r 2 2 m r 3 2 m  ...  r n 2 m

Page 16: Funciones y Ecuaciòn Cubica Excel

Así, el módulo de r1 se puede hallar extrayendo la raíz 2m-ésima de α1 . De la segunda ecuación se obtiene r2, y así sucesivamente. La fórmula para obtener el módulo de la raíz ri es

| r i |= α i α i−1 2 m

En la práctica, hallamos el logaritmo de ri, y luego, calculamos el antilogaritmo del resultado obtenido, de este modo se obtiene el valor absoluto de la raíz ri.

log | r i |= log  α i −log  α i−1 2 m (4)

Para determinar el signo, se halla el valor del polinomio original para los valores ri, y -ri, uno de los dos hará que dicho valor sea próximo a cero y por tanto, será la raíz buscada.

Cálculo de los coeficientes en las sucesivas iteracciones

Un polinomio cuyas raíces son reales y distintas es el caso más simple que se nos puede presentar. Sea por ejemplo el polinomio x3-4x2+x+6,cuyas raíces como se puede comprobar fácilmente por simple sustitución son 3, 2, y -1. En la tabla se observa los coeficientes αi resultantes del proceso de elevación del polinomio a las potencias 2, 4, 8, 16, 32, 64, 128, 256 y 512 respectivamente.

El primer coeficiente α0 es uno

El segundo α1 se obtiene a partir de los coeficientes de la fila anterior mediante la expresión a 1 2 −2 a 2 a 0

El tercer coeficiente α2 mediante la expresión a 2 2 −2 a 1 a 3

El cuarto coeficiente α3 mediante la expresión a 3 2

m (2m) α0 α1 α2 α3

0 (1) 1.0 -4.0 1.0 6.0

1 (2) 1.0 14.0 49.0 36.0

2 (4) 1.0 98.0 1393.0 1296.0

3 (8) 1.0 6818.0 1.6864 106 1.6796 106

4 (16) 1.0 4.3112 107 2.8212 1012 2.8211 1012

Page 17: Funciones y Ecuaciòn Cubica Excel

5 (32) 1.0 1.8553 1015 7.9587 1024 7.9587 1024

6 (64) 1.0 3.4337 1030 6.334 1049 6.334 1049

7 (128) 1.0 1.179 1061 4.012 1099 4.012 1099

8 (256) 1.0 1.3901 10122 1.6096 10199 1.6096 10199

9 (512) 1.0 1.9323 10244 2.5908 10398 2.5908 10398

Podemos observar en la tabla que cada coeficiente en la iteración 9, es aproximadamente el cuadrado del coeficiente en la iteración precedente, habiéndose eliminado el efecto de los dobles productos

A partir de este ejemplo, tenemos que codificar el procedimiento de Graeffe cualquiera que sea el grado n del polinomio y el número m de veces que se repite el proceso de elevación al cuadrado, lo que requiere los siguientes pasos:

1. Crear en memoria un array bidimensional de MAX_ITER filas y n+1 columnas (n es el grado del polinomio), para guardar los coeficientes del polinomio, tras la aplicación sucesiva del procedimiento de elevación al cuadrado, tal como se ve en la tabla.

2. Obtener los coeficientes de la siguiente fila a partir de la fila anterior, mediante las expresiones (2)

3. Obtener las raíces del polinomio, primero, su valor absoluto mediante la fórmula (4) y luego su signo, y guardarlas en un array unidimensional de dimensión n.

4. Mostrar las raíces del polinomio.

Reservamos memoria para un array bidimensional a, y guardamos en la primera fila los coeficientes del polinomio, de mayor a menor grado.

a= new double[MAX_ITER][n+1];//la primera fila de la tabla guarda los coeficientes del polinomio for(int j=0; j<n+1; j++){ a[0][j]=coef[j]; } for(int m=1; m<MAX_ITER; m++){ for(int j=0; j<n+1; j++){ a[m][j]=0.0; } }

Page 18: Funciones y Ecuaciòn Cubica Excel

Donde MAX_ITER es el número máximo de iteracciones, o de veces que se repite el proceso de elevación al cuadrado.

En una función miembro denominada tabla, codificaremos el procedimiento de elevación al cuadrado de un polinomio de grado n. Partiendo del polinomio original (1), obtenemos el polinomio resultante del procedimiento de elevar al cuadrado (3) según el esquema (2). En la expresión (2) observamos que el coeficiente de grado i del nuevo polinomio αi se obtiene efectuando las siguientes operaciones entre los coeficientes del polinomio original: se calcula el cuadrado de ai y se halla el doble producto de los elementos equidistantes ak y al, siendo los índices k=i-s y l=i+s, con s=1, 2, 3... hasta que se llegue al final del polinomio. Por ejemplo, los elementos equidistantes a a3 en un polinomio de 6º grado son (a2, a4), (a1, a5) y (a0, a6). Por tanto, el nuevo coeficiente αi del polinomio elevado al cuadrado se calculará mediante la fórmula

α 3 = a 3 2 −2 a 2 a 4 +2 a 1 a 5 −2 a 0 a 6

Sorprendentemente, el lenguaje Java, no produce error por "overflow", es decir, cuando se supera el límite máximo o mínimo para un tipo de dato básico: int, long, o double. Por ejemplo, podemos guardar números enteros en una variable tipo int siempre que esté en el intervalo -2147483648 a 2147483647. Las clases que envuelven a los tipos primitivos de datos,  Integer, Double, etc. nos proporcionan funciones miembro que nos notifican cuando se sobrepasen los límites especificados para un tipo de dato dado.

En el código de la función tabla, cuando se supera el valor máximo que puede guardar un dato de tipo double, se interrumpe el proceso de elevación al cuadrado, y se sale fuera del bucle. La función estática isInfinite de la claseDouble se encarga de verificarlo devolviendo true si hemos superado dicho límite permitido.

exterior: do{

for(int i=0; i<n+1; i++){ a[m][i]=a[m-1][i]*a[m-1][i]; if(Double.isInfinite(a[m][i])){ break exterior; } } //....

m++; }while(m<MAX_ITER);

Es necesario emplear un break con una etiqueta para salir al bucle exterior do...while, e interumpir el proceso de elevación al cuadrado. Si

Page 19: Funciones y Ecuaciòn Cubica Excel

solamente empleamos break salimos del bucle interior for y se continuaría en el bucledo...while el proceso de cálculo.

Nos queda ahora, la determinación el signo de cada uno de los dobles productos. Si el índice s es impar, entonces el signo es negativo y si es par, el signo es positivo. En vez de elevar -1 a la potencia s, empleamos el operador módulo %en conjunción con la macro if ... else, que se leerá: si s es impar (el resto de dividir s entre 2 es cero), entonces el valor de la variable entera signo es +1 en caso contrario es -1.

signo=(s%2==0)? +1: -1;

Los coeficientes del polinomio original se guarda en el array a[0][i], (i=0 ... n). Cuando se eleva al cuadrado los coeficientes del nuevo polinomio se guardan en el array a[1][i], (i=0 ... n), y así sucesivamente. Los coeficientes a[m][i], (i=0 ... n) corresponden al polinomio que se ha elevado a la potencia 2m. Dicha potencia se calcula mediante un buclefor.

pot2=1; for(int i=1; i<=m; i++){ pot2*=2; }

El código de la función tabla, que calcula los coeficientes polinomio resultante del proceso de elevar el polinomio original sucesivamente al cuadrado m veces, es el siguiente

private void tabla(){ int k,l, signo;//divide el polinomio por el primer coeficiente, las raíces no cambian for(int i=1; i<n+1; i++){ a[0][i]/=a[0][0]; }

a[0][0]=1.0; m=1;exterior: //etiqueta do{//cuadrados for(int i=0; i<n+1; i++){ a[m][i]=a[m-1][i]*a[m-1][i]; if(Double.isInfinite(a[m][i])){ break exterior; } }//dobles productos for(int i=1; i<n; i++){ for(int s=1; s<n/2+1; s++){ k=i-s; l=i+s; if((k<0)||(l>n)) break; //términos simétricos signo=(s%2==0)? +1: -1; a[m][i]+=signo*2*a[m-1][k]*a[m-1][l]; if(Double.isInfinite(a[m][i])){

Page 20: Funciones y Ecuaciòn Cubica Excel

break exterior; } } } m++; }while(m<MAX_ITER);

m--;//potencia de m de 2 pot2=1; for(int i=1; i<=m; i++){ pot2*=2; } }

Raíces reales y distintas

Un polinomio cuyas raíces son reales y distintas es el caso más simple que se nos puede presentar. Volvemos a estudiar el polinomio x3-4x2+x+6, cuyas raíces como se puede comprobar fácilmente por simple sustitución son 3, 2, y -1. En latabla que creamos en el apartado anterior, nos fijamos en la última fila.

m (2m) α0 α1 α2 α3

0 (1) 1.0 -4.0 1.0 6.0

9 (512) 1.0 1.9323 10244 2.5908 10398 2.5908 10398

Los módulos de las raíces reales, se calculan mediante la  fórmula (4) . Para hallar las raíces con gran exactitud tomaremos los coeficientes que figuran en la última fila, resultado de elevar el polinomio a la potencia 512.

log r0=(log(α1)-log(α0))/2m log r0=(log(1.9323 10244)-log(1))/512 r0 sale 3

log r1=(log(α2)-log(α1))/2m

log r1=(log(2.5908 10398)-log(1.9323 10244))/512 r1 sale 2

log r2=(log(α3)-log(α2))/2m

log r2=(log(2.5908 10398)-log(2.5908 10398))/512 r2 sale 1

Page 21: Funciones y Ecuaciòn Cubica Excel

Para codificar estos cálculos, emplearemos las funciones Math.log que halla el logaritmo de la raíz, y la función recíprocaMath.exp, para hallar la raíz. El valor absoluto de la raíz real se guarda en la variable local raiz.

private void raizRealSimple(int j){//valor absoluto de la raíz double logaritmo=(Math.log(a[m][j])-Math.log(a[m][j-1]))/pot2; double raiz=Math.exp(logaritmo);//determinación del signo raicesReales[numReales]=(Math.abs(valorPolinomio(raiz)) <Math.abs(valorPolinomio(-raiz)))? raiz : -raiz; numReales++; }

Para determinar el signo de la raíz real, hallaremos el valor del polinomio para dos valores raiz y -raiz, uno de los dos tiene que ser cero o muy próximo a cero. Una vez hallada la raíz real, su valor absoluto y su signo, se guarda en el arrayraicesReales.

Raíces reales dobles

En el apartado anterior, hemos supuesto que las raíces de un polinomio son reales y distintas, por lo que la aplicación del método de Graeffe es inmediata. Supongamos el polinomio x3-7x2+16x-12 que tiene una raíz doble 2, y una simple 3. Examinemos el comportamiento de sus coeficientes en el proceso de elevación al cuadrado en la tabla. Observaremos que el segundo coeficiente α1 se comporta como hemos descrito en el apartado anterior, cada coeficiente en una iteración es aproximadamente el cuadrado de la iteración precedente. Sin embargo, este comportamiento no se produce en el tercer coeficiente α2, ya que se obtiene la mitad del valor esperado. Por ejemplo, el valor de α2 en la séptima iteración es 8.024 1099 y su cuadrado es 6.4384 10199, sin embargo, se obtiene la mitad 3.2192 10199. Lo mismo ocurre en octava iteración el cuadrado de 3.2192 10199 es 1.0363 10399, sin embargo, obtenemos la mitad de este valor 5.1817 10398. Al tercer coeficiente, α2(índice 2), se denomina excepcional, y señala la presencia de raíces reales dobles.

m (2m) α0 α1 α2 α3

0 (1) 1.0 -7.0 16.0 -12.0

1 (2) 1.0 17.0 88.0 144.0

2 (4) 1.0 113.0 2048.0 20736.0

Page 22: Funciones y Ecuaciòn Cubica Excel

3 (8) 1.0 7073.0 3.4248 106 4.2998 108

4 (16) 1.0 4.3178 107 5.6465 1012 1.8488 1017

5 (32) 1.0 1.853 1015 1.5917 1025 3.4182 1034

6 (64) 1.0 3.4337 1030 1.2668 1050 1.1684 1069

7 (128) 1.0 1.179 1061 8.024 1099 1.3652 10138

8 (256) 1.0 1.3901 10122 3.2192 10199 1.8638 10276

9 (512) 1.0 1.9323 10244 5.1817 10398 3.4737 10552

Para obtener la raíz doble, se ha de aplicar la siguiente fórmula que damos sin justificar. La raíz repetida se puede hallar calculando la raíz 2·2m de la razón de los coeficientes que inmediatamente preceden y siguen al coeficiente excepcional. Si i es el coeficiente excepcional, el módulo de la raíz doble se calcula mediante la fórmula

| r i |= 2 m+1 α i+1 α i−1   (5)

La codificación de la función raizRealDoble es similar a la función raizRealSimple. Primero, halla el módulo de la raíz aplicando la fórmula (5), y posteriormente, determina su signo. La raíz buscada se guarda dos veces en el arrayraicesReales, y se incrementa dos unidades el contador de raíces reales numReales.

private void raizRealDoble(int j){//valor absoluto de la raíz

double logaritmo=(Math.log(a[m][j+1])-Math.log(a[m][j-1]))/(2*pot2);double raiz=Math.exp(logaritmo);

//determinación del signoboolean bPositiva=false, bNegativa=false;if (Math.abs(valorPolinomio(raiz))<CERO){

raicesReales[numReales]=raiz;numReales++;bPositiva=true;

}if (Math.abs(valorPolinomio(-raiz))<CERO){

raicesReales[numReales]=-raiz;numReales++;bNegativa=true;

}if(bPositiva && !bNegativa){

raicesReales[numReales]=raiz;

Page 23: Funciones y Ecuaciòn Cubica Excel

numReales++;}if(!bPositiva && bNegativa){

raicesReales[numReales]=-raiz;numReales++;}

}

Una raíz compleja y su conjugada

Los polinomios pueden tener también raíces complejas y sus respectivas conjugadas. El caso más simple es el del un polinomio x2+1 que tiene una raíz compleja y su correspondiente conjugada. Sea el polinomio x3-7x2+16x-12 que tiene las siguientes raíces exactas: 3, 2-3i, 2+3i.

Examinando en la tabla los valores y los signos de los coeficientes en las sucesivas iteraciones, vemos que el segundo coeficiente α1 cambia de signo en la tercera iteración, además el valor del coeficiente en una iteración no es aproximadamente igual al cuadrado de su valor en la siguiente iteración, sino la mitad de dicho valor, un comportamiento similar al de las raíces dobles. Al coeficiente α1 le denominaremos coeficiente excepcional.

m (2m) α0 α1 α2 α3

0 (1) 1.0 -7.0 25.0 -39.0

1 (2) 1.0 -1.0 79.0 1521.0

2 (4) 1.0 -157.0 9283.0 2.3134 106

3 (8) 1.0 6083.0 8.1259 108 5.352 1012

4 (16) 1.0 -1.5882 109 5.952 1017 2.8644 1025

5 (32) 1.0 1.3319 1018 4.4524 1035 8.2048 1050

6 (64) 1.0 8.8358 1035 1.9606 1071 6.7319 10101

7 (128) 1.0 3.886 1071 3.8437 10142 4.5318 10203

8 (256) 1.0 7.4134 10142 1.4774 10285 2.0537 10407

Page 24: Funciones y Ecuaciòn Cubica Excel

9 (512) 1.0 2.5411 10285 2.1827 10570 4.2177 10814

Para conocer si un polinomio tiene raíces complejas y sus correspondientes conjugadas basta examinar el cambio de signo de los coeficientes en sucesivas iteraciones, a partir, por ejemplo, de la segunda. Para ello, declaramos y definimos una función miembro denominada cambiaSigno que explora cada columna buscando cambios de signo en el coeficiente de orden j, tras sucesivas iteraciones. Si no detecta ningún cambio de signo devuelve false y si encuentra un cambio de signo, quiere decir, que ha encontrado una raíz compleja y su correspondiente conjugada, añadiéndose una unidad al contador numComplejas. Posteriormente, calcula el módulo de dicha raíz, y por último, devuelve true.

private boolean cambiaSigno(int j){ for(int k=2; k<=m; k++){ if(a[k][j]>0) continue; //..... return true; } return false; }

El módulo de las raíces complejas se determina mediante la misma fórmula que las raíces dobles., calculando la raíz 2·2mde la razón de los coeficientes que inmediatamente preceden y siguen al coeficiente excepcional.

Para calcular una raíz compleja hemos de determinar su parte real, ya que la parte imaginaria se obtiene a partir de su módulo y de su parte real.

Denotemos las raíces complejas como u+vi y u-vi, si conocemos la parte real u, la parte imaginaria v se determina mediante la fórmula v= r 2 − u 2 , donde r es el módulo obtenido a partir de la fórmula (5). Queda, por tanto, determinar la parte real u, mediante la fórmula que daremos sin justificar.

u=− 1 2 ( coeficiente de  x n-1 +suma de todas las raíces reales )

El código de la función denominada unaRaizCompleja, calcula primero la suma de todas las raíces reales. Luego, se determina u, y a partir de u se calcula v. La raíz compleja y su correspondiente conjugada se guardan el arrayraicesComplejas.

private void unaRaizCompleja(){ double suma=0.0; for(int i=0; i<numReales; i++){ suma+=raicesReales[i]; } double u, v; u=-(a[0][1]+suma)/2;

Page 25: Funciones y Ecuaciòn Cubica Excel

v=Math.sqrt(moduloComplejas[0]*moduloComplejas[0]-u*u); raicesComplejas[0]=new Complejo(u, v); raicesComplejas[1]=new Complejo(u, -v); }

En esta porción de código, hemos empleado un nuevo tipo de dato, denominado Complejo. Se trata de una clase cuyos miembros dato son la parte real y la parte imaginaria del número complejo y como funciones miembro, tiene los constructores, las funciones que suman, restan, multiplican o dividen dos numeros complejos.

Dos raíces complejas y sus conjugadas

Supongamos ahora el polinomio x5-4x4+11x3+4x2-10x-52 que tiene una raíz real 2 y dos raíces complejas y sus correspondientes conjugadas, 2+3i, 2-3i, -1+i, -1-i. Examinando la tabla vemos que los coeficientes segundo α1 y quinto α4 cambian de signo y además, se comportan de modo similar al de las raíces dobles, signo inequívoco de una raíz compleja. Por tanto, el polinomio tendrá dos raíces complejas y sus respectivas conjugadas, en total cuatro raíces que es el máximo número que permite este procedimiento.

m (2m) α0 α1 α2 α3 α4 α5

0 (1) 1.0 -4.0 11.0 4.0 -10-0 -52.0

1 (2) 1.0 -6.0 133.0 652.0 516.0 2704.0

2 (4) 1.0 -230.0 2.6545 104 2.554 105 -3.2598 106 7.3116 106

3 (8) 1.0 -190.0 8.156 108 2.3493 1011 6.8913 1012 5.346 1013

4 (16) 1.0 -1.6312 109 6.6531 1017 4.3949 1022 2.2371 1025 2.8579 1027

5 (32) 1.0 1.3301 1018 4.4278 1035 1.9018 1045 2.4926 1050 8.1678 1054

6 (64) 1.0 8.8357 1035 1.9605 1071 3.6165 1090 3.1066 10100 6.6714 10109

7 (128) 1.0 3.886 1061 3.8437 10142 1.3079 10181 4.8255 10200 4.4507 10219

8 (256) 1.0 7.4134 10142 1.4774 10275 1.7107 10362 1.1643 10401 1.9809 10439

Page 26: Funciones y Ecuaciòn Cubica Excel

9 (512) 1.0 2.5411 10285 2.1827 10570 2.9265 10724 6.7774 10801 3.9238 10878

Denotaremos las dos raíces complejas y sus respectivas conjugadas como u1±v1i y u2±v2i. Conocidos u1 y u2 se calculav1 y v2 mediante las fórmulas

v 1 = r 1 2 − u 1 2    v 2 = r 2 2 − u 2 2

Para determinar u1 y u2 se emplean las siguientes fórmulas

u 1 + u 2 =− 1 2 ( coeficiente de  x n-1 +suma de todas las raíces reales ) u 1 r 2 2 + u 2 r 1 2 = (−1) n−1 a n−1 2(producto de las n-4 raíces reales ) − r 1 2 r 2 2 2 ( suma de las inversas de las n-4 raíces reales )

Se trata de un sistema de dos ecuaciones con dos incógnitas de las que se despeja u1 y u2

La función denominada dosRaicesComplejas, calcula la suma de todas las raíces reales, el producto y la suma de las inversas de dichas raíces. Después calcula los segundos miembros de cada una de las dos ecuaciones y los guarda en las variables locales y y z

La solución del sistema de dos ecuaciones con dos incógnitas es

u 1 = y r 1 2 −z r 1 2 − r 2 2    u 2 = −y r 2 2 +z r 1 2 − r 2 2

lo que nos permite calcular u1 y u2y posteriormente, v1 y v2

Finalmente, guardamos los valores obtenidos en el array raicesComplejas

private void dosRaicesComplejas(){ double suma=0.0; double producto=1.0; double inversa=0.0; for(int i=0; i<numReales; i++){ suma+=raicesReales[i]; producto*=raicesReales[i]; inversa+=1/raicesReales[i]; }

double r1=moduloComplejas[0]; double r2=moduloComplejas[1]; double y=-(a[0][1]+suma)/2; int signo=((n-1)%2==0)? +1: -1; double z=signo*a[0][n-1]/(2*producto)-r1*r1*r2*r2*inversa/2;

double u1=(y*r1*r1-z)/(r1*r1-r2*r2); double u2=(-y*r2*r2+z)/(r1*r1-r2*r2); double v1=Math.sqrt(r1*r1-u1*u1); double v2=Math.sqrt(r2*r2-u2*u2);

raicesComplejas[0]=new Complejo(u1, v1); raicesComplejas[1]=new Complejo(u1, -v1);

Page 27: Funciones y Ecuaciòn Cubica Excel

raicesComplejas[2]=new Complejo(u2, v2); raicesComplejas[3]=new Complejo(u2, -v2); }

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á

Page 28: Funciones y Ecuaciòn Cubica Excel

habitualmente cero, salvo en el caso de raíces dobles. Cuando la variable cociente de la funcióncambiaSigno es cero (el logaritmo de la unidad es cero) o un valor muy próximo a cero (menor que la constante CEROfijada 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;

Page 29: Funciones y Ecuaciòn Cubica Excel

}//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]+" ---> "+

Page 30: Funciones y Ecuaciòn Cubica Excel

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 Complejoque 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; }

Page 31: Funciones y Ecuaciòn Cubica Excel

Ejemplos

Para hallar las raíces de un polinomio, primero creamos un array de los coeficientes, de mayor a menor grado. Para el polinomio x3-4x2+x+6 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:

x3-0x2-3x+1=0

x4+x3-10x2-34x-26=0

x4+0x3+4x2-3x+3=0

x3-6x2+11x-7=0

x3+2x2+2x+2=0

x4-x3-10x2-x+1=0

4x4+16x3+25x2+21x+9=0

16x5-16x4-12x3+12x2+0x-1=0

x5+0x4-5x3+0x2+4x-10=0

x5-8x4+17x3-10x2+0x-1=0

x7+x6-4x5-4x4-2x3-5x2-x-1=0

Nota: Aplicaremos el método de Graeffe a un polinomio cuyo término independiente es distinto de cero. Ya que una ecuación como x3-4x2+x=0, tiene una raíz x=0 y por tanto, solamente precisamos calcular las raíces de la ecuaciónx2-4x+1=0.

Las raíces complejas de la ecuación 16x5-16x4-12x3+12x2+0x-1=0 no salen bien.

Page 32: Funciones y Ecuaciòn Cubica Excel

Referencias

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

B. P. Demidovich, I.A. Maron. Cálculo numérico funadamental. Método Lobachevski-Graeffe. Edt. Paraninfo (1977) págs 202-223

Ángel Franco.El método de Graeffe. Un procedimiento para hallar las raíces de un polinomio. Revista Profesional de Programadores nº 39, Abril de 1998, págs. 38-46.

Código fuente

public class Graeffe { public int n; public double[] raicesReales; public Complejo[] raicesComplejas=new Complejo[4]; public int numReales; public int numComplejas; private double[][] a; private int pot2=1; private int m; private final int MAX_ITER=10; private static final double CERO=0.0001; private double[] moduloComplejas=new double[2];

public Graeffe(double[] coef) { n=coef.length-1; raicesReales=new double[n]; a= new double[MAX_ITER][n+1];//la primera fila de la tabla guarda los coeficientes del polinomio for(int j=0; j<n+1; j++){ a[0][j]=coef[j]; } for(int m=1; m<MAX_ITER; m++){ for(int j=0; j<n+1; j++){ a[m][j]=0.0; } } numReales=0; numComplejas=0; }

private void tabla(){ int k,l, signo;//divide el polinomio por el primer coeficiente, las raíces no cambian for(int i=1; i<n+1; i++){ a[0][i]/=a[0][0]; } a[0][0]=1.0; m=1;

Page 33: Funciones y Ecuaciòn Cubica Excel

exterior: do{//cuadrados for(int i=0; i<n+1; i++){ a[m][i]=a[m-1][i]*a[m-1][i]; if(Double.isInfinite(a[m][i])){ break exterior; } }//dobles productos for(int i=1; i<n; i++){ for(int s=1; s<n/2+1; s++){ k=i-s; l=i+s; if((k<0)||(l>n)) break; //términos simétricos signo=(s%2==0)? +1: -1; a[m][i]+=signo*2*a[m-1][k]*a[m-1][l]; if(Double.isInfinite(a[m][i])){ break exterior; } } } m++; }while(m<MAX_ITER);

m--;//potencia de m de 2 pot2=1; for(int i=1; i<=m; i++){ pot2*=2; } }//valor de un polinomio para una variable real public double valorPolinomio(double x){ double y=0.0;//sucesivas potencias de x, se puede utilizar también 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; } 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; }

private void raizRealSimple(int j){

Page 34: Funciones y Ecuaciòn Cubica Excel

//valor absoluto de la raíz // System.out.println("Raiz simple"); double logaritmo=(Math.log(a[m][j])-Math.log(a[m][j-1]))/pot2; double raiz=Math.exp(logaritmo);//determinación del signo, y1 o y2 tienen que ser casi cero

raicesReales[numReales]=(Math.abs(valorPolinomio(raiz))< Math.abs(valorPolinomio(-raiz)))? raiz : -raiz; numReales++; }

private void raizRealDoble(int j){//valor absoluto de la raíz double logaritmo=(Math.log(a[m][j+1])-Math.log(a[m][j-1]))/(2*pot2); double raiz=Math.exp(logaritmo); boolean bPositiva=false, bNegativa=false; if (Math.abs(valorPolinomio(raiz))<CERO){ raicesReales[numReales]=raiz; numReales++; bPositiva=true; } if (Math.abs(valorPolinomio(-raiz))<CERO){ raicesReales[numReales]=-raiz; numReales++; bNegativa=true; } if(bPositiva && !bNegativa){ raicesReales[numReales]=raiz; numReales++; } if(!bPositiva && bNegativa){ raicesReales[numReales]=-raiz; numReales++; } }

private void unaRaizCompleja(){ double suma=0.0; for(int i=0; i<numReales; i++){ suma+=raicesReales[i]; } double u, v; u=-(a[0][1]+suma)/2; v=Math.sqrt(moduloComplejas[0]*moduloComplejas[0]-u*u); raicesComplejas[0]=new Complejo(u, v); raicesComplejas[1]=new Complejo(u, -v); } private void dosRaicesComplejas(){ double suma=0.0; double producto=1.0; double inversa=0.0; for(int i=0; i<numReales; i++){ suma+=raicesReales[i]; producto*=raicesReales[i]; inversa+=1/raicesReales[i]; }

Page 35: Funciones y Ecuaciòn Cubica Excel

double r1=moduloComplejas[0]; double r2=moduloComplejas[1]; double y=-(a[0][1]+suma)/2; int signo=((n-1)%2==0)? +1: -1; double z=signo*a[0][n-1]/(2*producto)-r1*r1*r2*r2*inversa/2; double u1=(y*r1*r1-z)/(r1*r1-r2*r2); double u2=(-y*r2*r2+z)/(r1*r1-r2*r2); double v1=Math.sqrt(r1*r1-u1*u1); double v2=Math.sqrt(r2*r2-u2*u2); raicesComplejas[0]=new Complejo(u1, v1); raicesComplejas[1]=new Complejo(u1, -v1); raicesComplejas[2]=new Complejo(u2, v2); raicesComplejas[3]=new Complejo(u2, -v2); }

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; }

public void hallarRaices(){ 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; }//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(); } }

Page 36: Funciones y Ecuaciòn Cubica Excel

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(""); }}public class RaizPolinomioApp { public static void main(String[] args) {//Ecuación//a[n]x^n+a[n-1]·x^(n-1)+.....+a[3]·x^3+a[2]·x^2+a[1]·x+a[0]=0

double[] coef={1, -4, 1, 6}; Graeffe g=new Graeffe(coef); g.mostrarRaices();//de mayor a menor grado double[] coef1={1, -7, 16, -12}; g=new Graeffe(coef1); g.mostrarRaices(); double[] coef2={1, -7, 25, -39}; g=new Graeffe(coef2); g.mostrarRaices(); double[] coef3={1, 0, -5, 0, 4, -10}; g=new Graeffe(coef3); g.mostrarRaices();

double[] coef4={1, -6, 11, -7}; g=new Graeffe(coef4); g.mostrarRaices(); double[] coef5={1, 2, 2, 2}; g=new Graeffe(coef5); g.mostrarRaices();

double[] coef6={1, -1, -10, -1, 1}; g=new Graeffe(coef6); g.mostrarRaices();

double[] coef7={4, 16, 25, 21, 9}; g=new Graeffe(coef7); g.mostrarRaices(); double[] coef8={16, -16, -12, 12, 0, 1};

Page 37: Funciones y Ecuaciòn Cubica Excel

g=new Graeffe(coef8); g.mostrarRaices(); double[] coef9={1, -8, 17, -10, 0, 1}; g=new Graeffe(coef9); g.mostrarRaices(); }}public class Complejo{ private double real; private double imag;

public Complejo() { real=0.0; imag=0.0; } public Complejo(double real, double imag){ this.real=real; this.imag=imag; } public static Complejo conjugado(Complejo c){ return new Complejo(c.real, -c.imag); } public static Complejo opuesto(Complejo c){ return new Complejo(-c.real, -c.imag); } public double modulo(){ return Math.sqrt(real*real+imag*imag); }//devuelve el ángulo en grados public double argumento(){ double angulo=Math.atan2(imag, real); if(angulo<0) angulo=2*Math.PI+angulo; return angulo*180/Math.PI; }//suma de dos números complejos public static Complejo suma(Complejo c1, Complejo c2){ double x=c1.real+c2.real; double y=c1.imag+c2.imag; return new Complejo(x, y); }//producto de dos números complejos public static Complejo producto(Complejo c1, Complejo c2){ double x=c1.real*c2.real-c1.imag*c2.imag; double y=c1.real*c2.imag+c1.imag*c2.real; return new Complejo(x, y); }//producto de un complejo por un número real public static Complejo producto(Complejo c, double d){ double x=c.real*d; double y=c.imag*d; return new Complejo(x, y); }//producto de un número real por un complejo public static Complejo producto(double d, Complejo c){ double x=c.real*d; double y=c.imag*d;

Page 38: Funciones y Ecuaciòn Cubica Excel

return new Complejo(x, y); }//cociente de dos números complejos//excepción cuando el complejo denominador es cero public static Complejo cociente(Complejo c1, Complejo c2) throws ExcepcionDivideCero{ double aux, x, y; if(c2.modulo()==0.0){ throw new ExcepcionDivideCero("Divide entre cero"); }else{ aux=c2.real*c2.real+c2.imag*c2.imag; x=(c1.real*c2.real+c1.imag*c2.imag)/aux; y=(c1.imag*c2.real-c1.real*c2.imag)/aux; } return new Complejo(x, y); }//cociente entre un número complejo y un número real public static Complejo cociente(Complejo c, double d) throws ExcepcionDivideCero{ double x, y; if(d==0.0){ throw new ExcepcionDivideCero("Divide entre cero"); }else{ x=c.real/d; y=c.imag/d; } return new Complejo(x, y); }//el número e elevado a un número complejo public static Complejo exponencial(Complejo c){ double x=Math.cos(c.imag)*Math.exp(c.real); double y=Math.sin(c.imag)*Math.exp(c.real); return new Complejo(x, y); }//raíz cuadrada de un número positivo o negativo public static Complejo csqrt(double d){ if(d>=0) return new Complejo(Math.sqrt(d), 0); return new Complejo(0, Math.sqrt(-d)); }//función auxiliar para la potencia de un número complejo private static double potencia(double base, int exponente){ double resultado=1.0; for(int i=0; i<exponente; i++){ resultado*=base; } return resultado; }//función auxiliar para la potencia de un número complejo private static double combinatorio(int m, int n){ long num=1; long den=1; for(int i=m; i>m-n; i--){ num*=i; } for(int i=2; i<=n; i++){ den*=i;

Page 39: Funciones y Ecuaciòn Cubica Excel

} return (double)num/den; }//potencia de un número complejo public static Complejo potencia(Complejo c, int exponente){ double x=0.0, y=0.0; int signo; for(int i=0; i<=exponente; i++){ signo=(i%2==0)?+1:-1;//parte real x+=combinatorio(exponente, 2*i)*potencia(c.real, exponente-2*i) *potencia(c.imag, 2*i)*signo; if(exponente==2*i) break;//parte imaginaria y+=combinatorio(exponente, 2*i+1)*potencia(c.real, exponente-(2*i+1)) *potencia(c.imag, 2*i+1)*signo; } return new Complejo(x, y); }//representa un número complejo como un string public String toString(){ if(imag>0) return new String((double)Math.round(100*real)/100 +" + "+(double)Math.round(100*imag)/100+"*i"); return new String((double)Math.round(100*real)/100+" - " +(double)Math.round(-100*imag)/100+"*i"); }}

class ExcepcionDivideCero extends Exception {

public ExcepcionDivideCero() { super(); } public ExcepcionDivideCero(String s) { super(s); }}