Creando fractales con el método de Newton Pablo Santamaría v. (Junio 9) El método de Newton, ideado por Isacc Newton alrededor de 67, constituye una de las técnicas numéricas más poderosas para aproximar raíces de una ecuación f(x) =. El método comienza con una aproximación inicial x para la raíz y genera una sucesión de aproximaciones x, x,... según la fórmula x n+ = x n f(x n) f, n =,,... (x n ) sucesión que converge rápidamente a la raíz si la aproximación inicial se encuentra suficientemente próxima a la misma. Nótese que el método no está restringido a los números reales, sino que, de hecho, puede ser aplicado por igual a funciones sobre el campo complejo. Consideremos en particular la ecuación z 4 =. En el campo real la misma sólo tiene una raíz, a saber,. Pero en el campo complejo, la ecuación tiene cuatro raíces: ζ =, ζ =, ζ 3 = i, ζ 4 = i. Supongamos que, entonces, aplicamos el método de Newton a esta ecuación. En 876, Arthur Cayley propuso el siguiente problema: dado un valor inicial z cualquiera del plano complejo, a cual de las cuatro raíces convergerá el método de Newton? La respuesta a este problema conduce sorprendentemente a una figura de naturaleza fractal. Para ver ésto procederemos como sigue: En el cuadrado [, ] [, ] consideramos un gran número de valores iniciales z escogidos al azar. Aplicamos el método de Newton a la ecuación z 4 = para cada valor z escogido. Coloreamos el punto z en el plano complejo ya sea de rojo, verde, azul o magenta según a que raíz ζ, ζ, ζ 3 o ζ 4, respectivamente, ha convergido el método. Un programa en Fortran 77 para realizar tal procedimiento es dado a continuación. En apuntes anteriores ya hemos implementado el método de Newton en sendas subrutinas de Fortran 77 y Fortran 95. Llevar tal subrutina al campo complejo no reviste mayor dificultad que reemplazar las correspondientes variables reales por variables complejas. Esto conduce a la siguiente subrutina. SUBROUTINE NEWTON(F,DF,XX,NMAX,TOL,RAIZ,ICLAVE) * METODO DE NEWTON-RAPHSON para encontrar una * solución de f(x)= dada la función derivable * f y una aproximación inicial x. * Bloque de identificación de argumentos Ver los apuntes Subrutinas para la resolución de ecuaciones de una variable o Subrutinas en Fortran 95 para la resolución de ecuaciones de una variable
* F = Función que define la ecuación (arg entrada) * DF = Función derivada de F (arg entrada) * XX = Aproximación inicial (arg entrada) * NMAX = Número máximo de iteraciones (arg entrada) * TOL = Tolerancia del error relativo (arg entrada) * RAIZ = Estimación de la solución (arg salida) * ICLAVE = Clave de éxito (arg salida) * = éxito * = iteraciones excedidas * Bloque de declaración de tipo INTEGER NMAX, ICLAVE DOUBLE COMPLEX F, DF, XX, RAIZ DOUBLE PRECISION TOL INTEGER I DOUBLE COMPLEX X * Bloque de procesamiento ICLAVE = X = XX DO I=,NMAX RAIZ = X - F(X)/DF(X) IF (ABS((RAIZ-X)/RAIZ).LT.TOL) RETURN X = RAIZ ICLAVE = RETURN El método de Newton requiere de la función que define a la ecuación y su derivada, las cuales son implementadas en apropiadas FUNCTION complejas. DOUBLE COMPLEX FUNCTION F(Z) DOUBLE COMPLEX Z F = Z**4 -(.D,.D) RETURN DOUBLE COMPLEX FUNCTION DF(Z) DOUBLE COMPLEX Z DF = (4.D,.D)*Z**3 RETURN Finalmente consideremos el programa principal. En el cuadrado de semilado A =, conteniendo el origen, generamos NPOINTS = 5 números complejos Z = (X,Y) como condiciones iniciales para el método de Newton. Para ello utilizamos un generador de números aleatorios, provisto por las subrutinas intrínsecas RANDOM_SEED, que inicializa el generador, y RANDOM_NUMBER, la cual devuelve un número al azar entre y. Puesto que nosotros queremos números aleatorios en el rango [-A:A] efectuamos una simple transformación lineal para llevarlos a tal rango. Con el fin de distinguir a cual de las cuatro raíces converge el método creamos cuatro archivos, uno para cada
raíz. Entonces dependiendo la solución obtenida con el método de Newton, la condición inicial es guardada en el archivo que corresponde a la raíz a la cual ha convergido. PROGRAM FRACTAL_NEWTON ---------------- INTEGER NROOTS! Número de raíces INTEGER NPOINTS! Número de aproximaciones iniciales INTEGER NMAX! Número máximo de iteraciones en Newton REAL A! Semilado del cuadrado [-A:A][-A:A] DOUBLE PRECISION TOL! Cota para el error relativo en Newton PARAMETER (NROOTS = 4, NPOINTS = 5, NMAX =, A =., TOL =.D-8) DOUBLE COMPLEX ROOTS(NROOTS)! Raíces de la ecuación DATA ROOTS/(.D,.D),! (-.D,.D),! - (.D,.D),! i (.D,-.D)/! -i INTEGER CLAVE INTEGER UNIDAD INTEGER I,J DOUBLE COMPLEX F,DF EXTERNAL F,DF! Clave de error de la subrutina Newton! Número de unidad para archivos de salida! Funcion y derivada de la ecuación DOUBLE COMPLEX Z,RAIZ! Aproximación inicial y solución DOUBLE PRECISION X,Y! Parte real e imaginaria de la aprox. inicial REAL R! Número al azar entre y CHARACTER(7) ARCHIVO CHARACTER() NUMSTRING LOGICAL SEGUIR ---------------- * Crear archivos de salida para cada una de las raíces ---------------- DO J=,NROOTS UNIDAD = +J WRITE(NUMSTRING, (I.) ) J ARCHIVO = raiz- // NUMSTRING OPEN(UNIDAD,FILE=ARCHIVO) ---------------- * Proceder ---------------- CALL RANDOM_SEED()! Inicializar semilla DO I =,NPOINTS ------------- * Construir una aproximación inicial compleja dentro del * del cuadrado [-A:A][-A:A] ------------- CALL RANDOM_NUMBER(R) X = DBLE(-A+.*A*R) 3
CALL RANDOM_NUMBER(R) Y = DBLE(-A+.*A*R) Z = COMPLEX(X,Y) ------------- * Resolver la ecuación con el método de Newton con tal aproximación ------------- CLAVE = CALL NEWTON(F,DF,Z,NMAX,TOL,RAIZ,CLAVE) ------------- * Imprimir la condición inicial en el archivo correspondiente * según la raíz obtenida ------------- IF (CLAVE.EQ.) THEN J = SEGUIR =.TRUE. DO WHILE(SEGUIR.AND.J.LE.NROOTS) IF (ABS(RAIZ-ROOTS(J)).LE.TOL) THEN UNIDAD = + J WRITE (UNIDAD,*) X, Y SEGUIR =.FALSE. IF J = J + IF ------------- * Cerrar archivos de salida y terminar ------------- DO J=,NROOTS UNIDAD = +J CLOSE(UNIDAD) STOP Con los cuatro archivos, raiz-, raiz-, raiz-3 y raiz-4, generados por la ejecución del programa, utilizamos las siguientes sentencias en el programa gnuplot para obtener el mapa de aproximaciones. gnuplot> set size square gnuplot> set xrange [-:] gnuplot> set yrange [-:] gnuplot> plot "raiz-" w d, "raiz-" w d, "raiz-3" w d, "raiz-4" w d El resultado obtenido se ilustra en la figura. Las amplias regiones de un solo color corresponden a puntos que convergen rápidamente a la respectiva raíz. Pero entre tales áreas de convergencia obtenemos estructuras fractales donde la convergencia no está bien comportada. Estructuras fractales similares resultan para otras ecuaciones. Por ejemplo, la figura ilustra la distribución de las aproximaciones iniciales para la ecuación z 3 =, cuyas raíces son, / ± i 3/. Es fácil generalizar el programa para analizar la convergencia de las aproximaciones iniciales z para una ecuación algebraica cualquiera dados los n ceros ζ i, i =,..., n de la misma: n f(z) = (z ζ i ) =. En este caso, aplicando la regla de derivación de un producto tenemos que: n n f n n (z) = (z ζ j ) = (z ζ j ) = f(z) (z ζ i ) i= j i i= i= j= i= (z ζ i ) 4
.5.5 -.5 - -.5 - - -.5 - -.5.5.5 Figura. Distribución en el plano complejo de las aproximaciones iniciales z para la ecuación z 4 = según la convergencia por el método de Newton a la raíz ζ = (en rojo), ζ = (en verde), ζ3 = i (en azul) o ζ4 = i (en magenta). con lo cual, un paso del método de Newton puede ser calculado en forma simple como: xn+ X n f (xn ) = xn. = xn f (xn ) (xn ζi ) i= De este modo no se requiere especificar la función f ni su derivada, sino que simplemente se necesita especificar los ceros. A continuación presentamos el programa que hace uso de este resultado, donde la subrutina que implementa el método de Newton ha sido modificada para éste propósito. Como caso particular consideramos la ecuación: (z 3)(z )(z )(z + )(z + )(z + 3) =, () la cual tiene 6 raíces. La estructura fractal obtenida, ilustrada en la figura 3, es mucho más pequeña comparada con la estructura general, sin embargo, en los bordes de las zonas de convergencia bien comportada, ésta se presenta nuevamente. * PROGRAM FRACTAL_NEWTON ------------------------------------------------------------------ INTEGER NROOTS INTEGER NPOINTS INTEGER NMAX! Número de raíces! Número de aproximaciones iniciales! Número máximo de iteraciones en Newton 5
.5.5 -.5 - -.5 - - -.5 - -.5.5.5 Figura. Distribución en el plano complejo de las aproximaciones iniciales z para la ecuación z 3 = según la convergencia por el método de Newton a la raíz ζ = (en rojo), ζ = / + i 3/ (en verde) ó ζ3 = / i 3/ (en azul). REAL A DOUBLE PRECISION TOL PARAMETER (NROOTS = NPOINTS = NMAX = A = TOL =! Semilado del cuadrado [-A:A][-A:A]! Cota para el error relativo en Newton 6, 5,, 3.,.D-8) DOUBLE COMPLEX ROOTS(NROOTS)! Raíces de la ecuación DATA ROOTS/( 3.D,.D), (.D,.D), (.D,.D), (-.D,.D), (-.D,.D), (-3.D,.D)/ INTEGER CLAVE INTEGER UNIDAD INTEGER I,J DOUBLE COMPLEX Z,RAIZ DOUBLE PRECISION X,Y REAL R! Clave de error de la subrutina Newton! Número de unidad para archivos de salida! Aproximación inicial y solución! Parte real e imaginaria de la aprox. inicial! Número al azar entre y 6
CHARACTER(7) ARCHIVO CHARACTER() NUMSTRING LOGICAL SEGUIR ---------------- * Crear archivos de salida para cada una de las raíces ---------------- DO J=,NROOTS UNIDAD = +J WRITE(NUMSTRING, (I.) ) J ARCHIVO = raiz- // NUMSTRING OPEN(UNIDAD,FILE=ARCHIVO) ---------------- * Proceder ---------------- CALL RANDOM_SEED()! Inicializar semilla DO I =,NPOINTS ------------- * Construir una aproximación inicial compleja dentro del * del cuadrado [-A:A][-A:A] ------------- CALL RANDOM_NUMBER(R) X = DBLE(-A+.*A*R) CALL RANDOM_NUMBER(R) Y = DBLE(-A+.*A*R) Z = COMPLEX(X,Y) ------------- * Resolver la ecuación con el método de Newton con tal aproximación ------------- CLAVE = CALL NEWTON(ROOTS,NROOTS,Z,NMAX,TOL,RAIZ,CLAVE) ------------- * Imprimir la condición inicial en el archivo correspondiente * según la raíz obtenida ------------- IF (CLAVE.EQ.) THEN J = SEGUIR =.TRUE. DO WHILE(SEGUIR.AND.J.LE.NROOTS) IF (ABS(RAIZ-ROOTS(J)).LE.TOL) THEN UNIDAD = + J WRITE (UNIDAD,*) X, Y SEGUIR =.FALSE. IF J = J + IF ------------- * Cerrar archivos de salida y terminar ------------- DO J=,NROOTS UNIDAD = +J CLOSE(UNIDAD) STOP 7
SUBROUTINE NEWTON(ROOTS,NROOTS,XX,NMAX,TOL,RAIZ,ICLAVE) * METODO DE NEWTON-RAPHSON para encontrar la * solución de f(x)=(x -x)...(x-xn) = dadas los * N ceros de la ecuación a la cual conduce la * aproximación inicial. * Bloque de identificación de argumentos * NROOTS = Número de raices (arg entrada) * ROOTS(NROOTS) = Vector de raíces (arg entrada) * XX = Aproximación inicial (arg entrada) * NMAX = Número máximo de iteraciones (arg entrada) * TOL = Tolerancia del error relativo (arg entrada) * RAIZ = Estimación de la solución (arg salida) * ICLAVE = Clave de éxito (arg salida) * = éxito * = iteraciones excedidas * Bloque de declaración de tipo INTEGER NROOTS,NMAX,ICLAVE DOUBLE COMPLEX ROOTS(NROOTS) DOUBLE COMPLEX XX,RAIZ DOUBLE PRECISION TOL INTEGER I,J DOUBLE COMPLEX X,SUMA * Bloque de procesamiento ICLAVE = X = XX DO I=,NMAX SUMA = (.D,.D) DO J =,NROOTS SUMA = SUMA + (.D,.D)/(X - ROOTS(J)) RAIZ = X - (.D,.D)/SUMA IF (ABS((RAIZ-X)/RAIZ).LT.TOL) RETURN X = RAIZ ICLAVE = RETURN 8
3 - - -3-3 - - 3 Figura 3. Distribución en el plano complejo de las aproximaciones iniciales z para la ecuación (z 3)(z )(z )(z + )(z + )(z + 3) = según la convergencia por el método de Newton a la raíz correspondiente ( 3 en rojo, en verde, en azul, en magenta, cian, 3 amarillo.) 9