UNIVERSIDAD POLITÉCNICA DE MADRID ESCUELA TÉCNICA SUPERIOR DE INGENIEROS DE MINAS DEPARTAMENTO DE MATEMÁTICA APLICADA Y MÉTODOS INFORMÁTICOS TITULACIÓN: INGENIERÍA DE MINAS ASIGNATURA: PROGRAMACIÓN Y MÉTODOS NUMÉRICOS PRÁCTICA Nº 3: COMPLEMENTOS DE ÁLGEBRA MATRICIAL. ESTRUCTURAS DE BIFURCACIÓN Y BUCLES CONDICIONALES CURSO 2006-07 PRÁCTICA ELABORADA POR: Prof. Carlos Conde Lázaro Prof. Arturo Hidalgo López Prof. Alfredo López Benito Depto. de Matemática Aplicada y Métodos Informáticos Escuela Técnica Superior de Ingenieros de Minas Universidad Politécnica de Madrid Mayo 2007 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid OBJETIVOS DE LA PRÁCTICA 1º. Conocer y utilizar las instrucciones de MAPLE que permiten determinar si una matriz es definida positiva, así como el calcular normas vectoriales o matriciales y el condicionamiento de la matriz de un sistema lineal de ecuaciones. 2º. Conocer, diseñar y programar estructuras algorítmicas condicionales realizando procesos de bifurcación 2º. Conocer, diseñar y programar estructuras algorítmicas repetitivas realizando bucles condicionales. 3º. Programar en MAPLE algunos métodos iterativos estudiados en cursos anteriores FORMA DE DESARROLLAR ESTA PRÁCTICA. El desarrollo de la práctica consistirá en la realización de ejemplos resueltos (epígrafe de EJEMPLOS) y tras ello se propone al alumno el desarrollo de algunos ejercicios (epígrafe de EJERCICIOS PROPUESTOS) que deberá desarrollar individualmente. DURACIÓN ESTIMADA DE ESTA PRÁCTICA El tiempo estimado para la realización de esta práctica es de 2 horas. BIBLIOGRAFÍA Algunos de los ejercicios de esta práctica están basados en los recogidos en los libros: C. Conde Lázaro y G. Winter Althaus (1990) Métodos y Algoritmos Básicos del Álgebra Numérica. Ed. Reverté, S.A. P. L. Lascaux & R. Theodor (1998) Analyse Numérique Matricielle Apliquée à l'Art de l'Ingénieur. Vol 2: Méthodes Itératives. Ed. Dunod. 1 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid EJEMPLOS Primer ejemplo: Preliminares (Normas, condicionamientos y verificación de que una matriz es definida positiva). > restart: Los métodos básicos de resolución de sistemas lineales de ecuaciones mediante técnicas de optimización sólo son aplicables a sistemas con matriz del sistema definida positiva. Además en ellos juegan un papel importante los conceptos de normas (vectoriales y matriciales) y condicionamiento del sistema. En este ejemplo introduciremos los comandos y procesos que pueden seguirse en MAPLE para verificar si una matriz es definida positiva o para evaluar normas vectoriales o matriciales o para realizar el cálculo del condicionamiento de un sistema. Comencemos definiendo una matriz (simétrica) de orden 5: > n:= 5: > A:=matrix(n,n,[]): Al ser simétrica podemos dar valores sólo a los elementos que están en la diagonal o por debajo de ella: > A[1,1]:=1.: A[2,1]:=-2.: A[2,2]:= 7: A[3,1]:= 0: A[3,2]:= 1: A[3,3]:= 5.: A[4,1]:=-1: A[4,2]:= 0: A[4,3]:=-1: A[4,4]:= 6: A[5,1]:= 0: A[5,2]:=-1: A[5,3]:= 2.: A[5,4]:= 1: A[5,5]:=9: evalm(A); ⎡ 1. A1, 2 A1, 3 A1, 4 A1, 5⎤ ⎥ ⎢ ⎢-2. 7 A2, 3 A2, 4 A2, 5⎥⎥ ⎢ ⎥ ⎢ ⎥ ⎢ ⎥ ⎢0 1 5. A A 3, 4 3, 5⎥ ⎢ ⎥ ⎢ ⎢ -1 0 -1 6 A4, 5⎥⎥ ⎢ ⎥ ⎢ ⎥ ⎢0 -1 2. 1 9 ⎦ ⎣ y asignar valores a los elementos que están por encima de la diagonal por simetría: 2 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid > for i from 1 by 1 to n-1 do: for j from i+1 by 1 to n do: A[i,j]:= A[j,i]: od: od: Con ello la matriz A es: > print(A); ⎡ 1. ⎢ ⎢-2. ⎢ ⎢ ⎢0 ⎢ ⎢ -1 ⎢ ⎢ ⎢0 ⎣ -2. 7 1 0 -1 0 1 5. -1 2. -1 0 -1 6 1 0⎤ ⎥ -1⎥⎥ ⎥ 2. ⎥⎥ 1 ⎥⎥ ⎥ 9 ⎥⎦ Una forma de comprobar que la matriz es definida positiva consiste en verificar que sus valores propios son todos ellos estrictamente positivos. Para ello puede utilizarse el comando eigenvalues( ) que fue introducido en la primera práctica. Recuerda que este comando está en la librería linalg y que para usarlo debemos cargar previamente dicha librería: > with(linalg): > VP:=eigenvalues(A); VP := 0.2279726322 , 3.124017014 , 6.718150983 , 7.889042837 , 10.04081653 En este caso, al ser todos los valores propios positivos puede afirmarse que la matriz es definida positiva. Otra forma más breve de verificar si una matriz es definida positiva consiste en utilizar el comando definite( ) de la librería linalg de MAPLE. En concreto, para saber si la matriz del ejemplo anterior es definida positiva, podría realizarse la operación: > definite(A,positive_def); true MAPLE nos informa de que es cierto ("true") el que, en este caso la matriz A es definida positiva. 3 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales NOTA 1ª: El comando definite C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid nos permite otras opciones (sustituyendo positive_def por la opción correspondiente) como son: positive_semidef --> Matriz simétrica con todos sus valores propios no negativos negative_def --> Matriz con todos sus valores propios estrictamente negativos negative_semidef --> Matriz con todos sus valores propios no positivos. NOTA 2ª: Recuerda también que siendo [A] una matriz real simétrica dada , de n filas y columnas, se verifica: si [A] es definida positiva x T Ax > 0 ∀x ∈ \ n − 0 si [A] es semi-definida positiva x T Ax ≥ 0 si [A] es definida negativa x T Ax < 0 ∀x ∈ \ n − 0 ∀x ∈ \ n − 0 si [A] es semi-definida negativa x T Ax ≤ 0 ∀x ∈ \ n − 0 En el estudio de métodos iterativos de resolución de sistemas lineales se calculan a menudo las normas de un vector o de una matriz. En la bibliografía señalada al comienzo de la práctica puede consultarse la definición genérica de NORMA VECTORIAL y de NORMA MATRICIAL así como la definición concreta de las más usuales: la norma-1, la norma-2 y la norma-infinito. Examinemos cómo se calculan estas normas con MAPLE. Para ello, definamos otra matriz A (distinta de la antes definida para que no sea simétrica y así darle mayor generalidad a la exposición) e introduzcamos un vector, también de 5 elementos, con el que practicar. > A:=matrix(n,n,[[1.25,-2.,4.35,9.97,11.],[-2.51, sqrt(2.), exp(0.35), 7.9,1.1],[5.,-3.,-4.,sqrt(7.),-1.],[3.,-exp(2.), sqrt(35),8.,4.],[5.,1.,3.5,9,-0.7]]); v:=vector(n,[1,-5.,3.,-4,2]); -2. 4.35 9.97 11. ⎤ ⎡ 1.25 ⎢ ⎥ ⎢-2.51 1.414213562 1.419067549 7.9 1.1 ⎥⎥ ⎢ ⎢ ⎥ -3. -4. 2.645751311 -1. ⎥⎥ A := ⎢⎢ 5. ⎢ ⎥ ⎢ 3. 35 8. 4. ⎥⎥ -7.389056099 ⎢ ⎢ 5. 1. 3.5 9 -0.7⎥⎦ ⎣ v := [ 1, -5., 3., -4, 2 ] La norma-1 del vector puede obtenerse sumando los valores absolutos de sus componentes: 4 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid > norma1v:=0.: for i from 1 to n by 1 do norma1v:=norma1v+abs(v[i]): od: print(norma1v); 15. Ota forma de realizar esta suma consiste en utilizar el comando add( ) como sigue: > norma1v:=add(abs(v[i]),i=1..5); norma1v := 15. No obstante, la forma más cómoda de calcular la norma-1 de un vector consiste en utilizar el comando norm( ) de la librería linalg como sigue: > norma1v:=norm(v,1); norma1v := 15. La norma-1 de la matriz A puede obtenerse hallando el superior de los valores que se obtienen al sumar los valores absolutos de las columnas de la matriz. Puede diseñarse un procedimiento para ello pero la forma más cómoda de hacer esta operación con MAPLE vuelve a ser el utilizar el comando norm( ) de la librería linalg : > norma1A:=norm(A,1); norma1A := 37.51575131 Para otras normas vectoriales basta con modificar en el comando norm( ) el segundo parámetro utilizando el índice de la norma que se desea utilizar. Para el caso de normas matriciales se opera de la misma manera, si bien en este caso el segundo parámetro sólo puede ser 1, 2, infinity o frobenius. Por ejemplo, para calcular la norma-2 del vector v (raíz cuadrada de la suma de los cuadrados de sus componentes) y de la matriz A (raíz cuadrada del radio espectral de la matriz que se obtiene al multiplicar A por su adjunta) se escribiría: > norma2v:=norm(v,2); norma2A:=norm(A,2); norma2v := 7.416198487 norma2A := 22.01158691 5 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid y para calcular la norma-infinito del vector v (valor absoluto del elemento de mayor valor absoluto) y de la matriz A (valor superior de lo que suman los valores absolutos de las filas de la matriz) se escribe: > normainfv:=norm(v,infinity);normainfA:=norm(A,infinity); normainfv := 5. normainfA := 28.57 En el caso de las matrices también puede calcularse la norma de Frobenius (la raíz cuadrada de la suma de los cuadrados de los elementos de la matriz). Para los vectores la norma de Frobenius coincide con la norma-2. > normfrv:=norm(v,frobenius);normafrA:=norm(A,frobenius); normfrv := 7.416198487 normafrA := 25.98380077 También debe calcularse en muchas ocasiones el CONDICIONAMIENTO de (la matriz de) un sistema lineal. En la bibliografía señalada puede encontrar que se denomina condicionamiento de un sistema, en el sentido de la norma con la que se esté trabajando, al producto de la norma de la matriz del sistema por la norma de su inversa. Los condicionamientos siempre son números reales positivos superiores o iguales a 1. Cuanto más próximos a 1 estén mejor funcionarán los métodos de resolución sobre ellos. Sabiendo calcular normas matriciales e inversas de matrices, es fácil evaluar los condicionamientos. Por ejemplo, para calcular el condicionamiento de la matriz A en el sentido de la norma - 2 podemos realizar el proceso siguiente: > A1:=inverse(A): > norma2A1:=norm(A1,2); norma2A1 := 0.2655724831 > cond2A:=norma2A*norma2A1; cond2A := 5.845671793 Nuevamente debe señalarse que MAPLE ya tiene un comando en el que se realiza todo este proceso de una vez. Es el comando cond( ) de la librería linalg y que se utilizaría de la forma: > cond2A:=cond(A,2); cond2A := 5.845671793 6 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid Para calcular condicionamientos en el sentido de otras normas basta con sustituir el segundo parámetro por el correspondiente a la norma que se desee utilizar: > cond1A:=cond(A,1); cond1A := 37.51575131 2513.709895 + 371.3062126 35 20788.23056 + 1990.086320 35 −1005.684069 + 343.4636455 35 20788.23056 + 1990.086320 35 87614.74765 + 20788.23056 + 1990.086320 35 + 37.51575131 226.8750000 20788.23056 225.8852978 + 37.51575131 20788.23056 + 37.51575131 35 + 2149.705867 + 1990.086320 35 35 + 556.3653099 + 1990.086320 35 > evalf(%,25); 15.50404303923924581145170 > condinfinityA:=cond(A,infinity); 349713.9606 condinfinityA := 20788.23056 + 1990.086320 35 > evalf(%,17); 10.740026809163490 > fin; fin Segundo ejemplo: Bucles estructuras de bifurcación. condicionales y > restart: MAPLE permite comparar los valores de constantes y variables mediante los denominados operadores de relación que son: > Mayor que <= Menor o igual que >= Mayor o igual que = Igual que 7 < Menor que <> Distinto que Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid El resultado de comparar dos variables o constantes mediante un operador de relación es "TRUE" o "FALSE", es decir es un resultado lógico. Si deseas que MAPLE te informe de ese resultado debes utilizar el comando is( ). Por ejemplo: > is(5>7); false > a:=sqrt(17.35*12):b:=11: > is(a>=b); true Los resultados de comparaciones pueden combinarse a su vez mediante operadores lógicos. En MAPLE los operadores lógicos son and y or. El primero, and, produce como resultado "TRUE" cuando los operandos lógicos que se combinan con and son ambos "TRUE". En el caso de que alguno sea "FALSE" el resultado es "FALSE". El operador lógico or sólo produce resultado "FALSE" cuando ambos operandos lógicos son "FALSE". En caso contrario el resultado es "TRUE". Por ejemplo: > a:=5:b:=-2:c:=4:d:=-2: > is((a>b) and (d<=c)); true > is ((a*b > c*d) or (a<=d)); false > is ((a*b > c*d) or (a>=d)); true Una de las aplicaciones que tienen las expresiones de relación y las expresiones lógicas es la construcción de bucles condicionales. Estos se realizan con el comando de MAPLE while( )siendo lo que está encerrado entre paréntesis una expresión de relación o lógica. Más concretamente la estructura más elemental de un bucle condicional es la siguiente: while( expresión de relación o lógica) do Instrucciones a realizar od; (u od:) Las instrucciones a las que se refiere el bucle serán realizadas mientras la expresión de relación o lógica sea "TRUE" y dejarán de ralizarse cuando su valor sea "FALSE". Obviamente, entre las instrucciones a realizar debe haber alguna que modifique el resultado de la expresión de relación o lógica pues en caso contrario el bucle se realizaría eternamente o ninguna vez. 8 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid Ilustrémoslo con un ejemplo: > iter:=0: maxit:=100: eps:=1.1*10^(-4): tol:=2.*eps: > while((iter<100) and (tol>eps)) do iter:=iter+1: a:=(iter*iter+2): tol:=1./a: print(iter,tol); od: 1, 0.3333333333 2, 0.1666666667 3, 0.09090909091 4, 0.05555555556 5, 0.03703703704 6, 0.02631578947 7, 0.01960784314 8, 0.01515151515 9, 0.01204819277 10, 0.009803921569 11, 0.008130081301 …………. ………….. …………… 93, 0.0001155935730 94, 0.0001131477710 95, 0.0001107787748 96, 0.0001084834020 La forma general de los bucles condicionales es la siguiente: for vcontr from vinic to vfin by paso while (condición) do Instrucciones od; 9 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales donde: vcontr vinic vfin C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid es la variable de control del bucle es el valor inicial que toma esa variable es el valor final que se permite tomar a la variable de control condición es la condición que exigimos que se verifique para que se continúe realizando el bucle paso es el incremento que se le da a la variable de control El bucle anterior también podría haberse realizado: > eps:=1.1*10^(-4.):tol:=2.*eps: for iter from 1 to 100 by 1 while (tol>eps) do a:=(iter*iter+2): tol:=1./a: print(iter,tol); od: 1, 0.3333333333 2, 0.1666666667 3, 0.09090909091 4, 0.05555555556 5, 0.03703703704 6, 0.02631578947 7, 0.01960784314 8, 0.01515151515 9, 0.01204819277 10, 0.009803921569 11, 0.008130081301 …………. ………….. …………… 93, 0.0001155935730 94, 0.0001131477710 95, 0.0001107787748 96, 0.0001084834020 10 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid En esta y sucesivas prácticas podrás encontrar ejemplos de bucles condicionales. Otra utilidad de las expresiones de relación y lógicas (de las condiciones) consiste en la realización de estructuras de bifurcación en las que, en función de que se verifiquen unas u otras condiciones se realizan unas u otras instrucciones. La forma más simple de una estructura condicional en MAPLE es: if (Condición) then Proceso fi; En ella el "Proceso" se realizará tan sólo si la "Condición" es "TRUE". Ilustrémoslo con un ejemplo: > a:=7:; b:=10: c:='a_es_mayor_que_b': > if (a<=b) then c:='a_es_menor_o_igual_que_b': #Se realiza el proceso fi: > print(c): a_es_menor_o_igual_que_b > a:=9:; b:=3: c:='a_es_mayor_que_b': > if (a<=b) then c:='a_es_menor_o_igual_que_b': # NO se realiza el proceso fi: > print(c): a_es_mayor_que_b La estructura de bicfurcación puede completarse como sigue: if Condición then Proceso 1 else Proceso 2 fi; En esta estructura si se verifica "Condición" se realiza el "Proceso 1", pero si no se verifica "Condición", en lugar de no hacer nada como antes, se realiza el "Proceso 2". Ilustrémoslo con un ejemplo: 11 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid > a:=9:; b:=3: > if (a<=b) then mensaje:='a_es_menor_o_igual_que_b': else mensaje:='a_es_mayor_que_b': fi: > print(mensaje): a_es_mayor_que_b Más completa es la estructura de bifurcación (o condicional) siguiente: if Condición 1 then Proceso 1 elif Condición 2 then Proceso 2 else Proceso 3 fi; En ella si se verifica la "Condición 1", se realiza el "Proceso 1"; si no es cierta la "Condición 1" pero sí se verifica la "Condición 2" se realiza el "Proceso 2"; si no se verifican ni la "Condición 1" ni la "Condición 2" se realiza el "Proceso 3". Nótese que las tres partes de la estructura son excluyentes, de tal manera que sólo se realizará uno de los Procesos. Ilustremos esta estructura con un ejemplo. En él vamos a ir acumulando las sumas de los 25 primeros números naturales. Mientras la suma sea inferior a 25 escribiremos el valor del último número sumado,el valor de la suma y el mensaje "Inferior a 25". Mientras el valor de la suma sea mayor o igual que 25 pero inferior a 175 escribiremos el valor del último número sumado, el valor de la suma y el mensaje "Entre 25 y 175". Por último, cuando el valor de la suma sea superior o igual a 175 escriberemos el valor del último número sumado, el valor de la suma y el mensaje "Esto se dispara" > suma:=0: for i from 1 to 25 by 1 do suma:= suma+i: if (suma < 25) then 12 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid print(i, suma, "Inferior a 25"); elif (suma < 175) then print(i, suma, "Entre 25 y 175"); else print(i, suma, "Esto se dispara"); fi: od: 1, 1, "Inferior a 25" 2, 3, "Inferior a 25" 3, 6, "Inferior a 25" 4, 10, "Inferior a 25" 5, 15, "Inferior a 25" 6, 21, "Inferior a 25" 7, 28, "Entre 25 y 175" 8, 36, "Entre 25 y 175" 9, 45, "Entre 25 y 175" 10, 55, "Entre 25 y 175" 11, 66, "Entre 25 y 175" 12, 78, "Entre 25 y 175" 13, 91, "Entre 25 y 175" 14, 105, "Entre 25 y 175" 15, 120, "Entre 25 y 175" 16, 136, "Entre 25 y 175" 17, 153, "Entre 25 y 175" 18, 171, "Entre 25 y 175" 19, 190, "Esto se dispara" 20, 210, "Esto se dispara" 21, 231, "Esto se dispara" 22, 253, "Esto se dispara" 23, 276, "Esto se dispara" 24, 300, "Esto se dispara" 25, 325, "Esto se dispara" 13 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid Es posible incluir tantas sentencias del tipo elif .... then como sea necesario, si bien sólo puede haber una del tipo if .... then (que, además, es obligatoria) y una del tipo else (que no es obligatoria). Lo que sí es obligatorio es acabar con fi . De esta forma una estructura de bifurcación genérica puede escribirse en la forma: if Condición 1 then Proceso 1 elif Condición 2 then Proceso 2 elif Condición 3 then Proceso 3 elif Condición 4 then Proceso 4 ............................................... ............................................... elif Condición n then Proceso n else Proceso n+1 fi; > fin; fin Tercer ejemplo: Método de Gauss-Seidel > restart; El método de Gauss-Seidel para sistemas [A].{x} = {b}, puede obtenerse minimizando la funcional: J({ x}) = 1 { x}T [ A] {x} − { x}T {b} 2 Utilizando en cada iteración direcciones de descenso paralelas a los ejes (es decir vectores con todas sus componentes menos una iguales a 0 y con la que no es nula con valor 1; la componente no nula va ocupando sucesivamente posiciones consecutivas en el vector de dirección de descenso y, una vez recorridas todas las posiciones vuelve a comenzarse por la primera). Eso conduce a que, partiendo de un vector inicial las componentes de los sucesivos vectores se evalúan mediante la expresión: 14 {x } , (0) Programación y Métodos Numéricos. Práctica3: Estructuras condicionales xk(i + 1) = (b − k −1 ∑ ak,j·xj(i + 1) − j=1 C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid n ∑ j= k +1 ak,j·xj(i) ) / ak,k (k = 1,2,..., n) donde n es el número de ecuaciones del sistema y los sumatorios con índice superior inferior al índice inferior, o con índice inferior mayor que el superior, no se realizan. Programemos el MÉTODO DE GAUSS-SEIDEL aplicándolo al sistema de matriz simétrica utilizada en el primero de los ejemplos de esta práctica: Datos: Número de ecuaciones: > n:=5: Matriz del sistema: > A:= matrix(n,n,[]): > A[1,1]:= 1.: A[2,1]:=-2.: A[2,2]:= 7.: A[3,1]:= 0: A[3,2]:= 1: A[3,3]:= 5.: A[4,1]:=-1.: A[4,2]:= 0: A[4,3]:=-1.: A[4,4]:= 6.: A[5,1]:= 0.: A[5,2]:=-1.: A[5,3]:= 2.: A[5,4]:= 1.: A[5,5]:=9.: for i from 1 by 1 to n-1 do: for j from i+1 by 1 to n do: A[i,j]:= A[j,i]: od: od: > evalm(A); ⎡ 1. -2. 0 -1. 0. ⎤ ⎥ ⎢ ⎢-2. 7. 1 0 -1.⎥⎥ ⎢ ⎥ ⎢ ⎢0 1 5. -1. 2. ⎥⎥ ⎢ ⎢-1. 0 -1. 6. 1. ⎥ ⎥ ⎢ ⎥ ⎢ ⎢ 0. -1. 2. 1. 9. ⎥ ⎦ ⎣ Y con el vector de segundos terminos siguiente: > b:=vector(n,[]): b[1] := 3: b[2] := 2: b[3] := 1: b[4] := 4: b[5] := 0: > evalm(b); [ 3, 2, 1, 4, 0 ] Usaremos como vector inicial (vector semilla): 15 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid > x:=vector(n,[1.,1.,1.,1.,1.]); x := [ 1., 1., 1., 1., 1. ] Y emplearemos una tolerancia de error admisible: > eps:=1.*10^(-4); eps := 0.0001000000000 Permitiremos realizar un máximo número de iteraciones: > maxit:=100: Proceso de cálculo En el proceso de cálculo es necesario repetir un conjunto de operaciones hasta que, o bien se hayan realizado todas las iteraciones permitidas o bien se obtengan dos soluciones suficientemente parecidas. En resumen hay que realizar un bucle condicionado a que se satisfagan ambas condiciones. > iter:=0: tol:=2.*eps: while ((iter<maxit) and (tol>eps)) do iter:= iter + 1: tol:= 0.: for i from 1 to n by 1 do suma:= b[i]: for j from 1 to n by 1 do if (j <> i) then suma:= suma - A[i,j]*x[j]: fi: od: aux:=suma/A[i,i]: tol:=tol + (x[i]-aux)^2: toldib[iter]:=tol: x[i]:=aux: od: tol:= sqrt(tol): od: Presentación de Resultados > if (tol > eps) then print("Error... No pudo verificarse el test de convergencia"); else print("Solución: ..."); 16 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid evalm(x); fi; "Solución: ..." [ 16.40347409 , 5.042151429 , -0.2427377540 , 3.319226692 , 0.2453778050 ] Representación de la evolucion del indicador de error: > with(plots): > dibtol:=[seq([ k, toldib[k] ],k=1..iter)]: > pointplot(dibtol, color=red, symbol=CIRCLE, font=[TIMES, BOLD,12]); NOTA: En la práctica de esta asignatura dedicada a los métodos de tipo gradiente se programará este método de forma matricial. > fin; fin 17 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid EJERCICIO Ejercicio: La fórmula de Cardano-Tartaglia- del Ferro - Bombelli. > restart; En 1545 Gerolamo CARDANO publicó su obra Artis magnae sive de regulis algebricis (Del Gran Arte o de las reglas algebraicas). En dicha obra demuestra que las soluciones de la ecuación cúbica: a.x3 + b.x2 + c.x = d están relacionadas con las soluciones de la ecuación cúbica reducida: y3 + p.y = q donde: 1 ⎛ b2 ⎞ p = .⎜ c − ⎟ a ⎝ 3.a ⎠ 1 ⎛ c.b 2.b3 ⎞ − q = ⋅⎜d + ⎟ a ⎝ 3.a 27.a 2 ⎠ y La relación encontrada por Cardano entre las soluciones de ambas ecuaciones es: x = y− b 3.a Junto a esta relación Cardano publicó la fórmula para resolver ecuaciones cúbicas reducidas. Dicha fórmula le había sido revelada años antes por Niccolo Fontana (más conocido como Niccolo TARTAGLIA debido a la tartamudez que le provocaron de pequeño las heridas causadas por soldados franceses). Con ello, aparte de originarse una agria disputa entre Tartaglia y Cardano , se dio un enorme impulso al problema de calcular las raíces de los polinomios de tercer grado que venía ocupando a numerosos matemáticos desde muchos siglos antes. La fórmula en cuestión es conocida habitualmente con el nombre de fórmula de Cardano, aunque al haberle sido revelada por Tartaglia se cita en algunos textos como fórmula de Tartaglia. Aun tiene un tercer nombre ya que ni Cardano ni Tartaglia fueron los primeros en dar con ella pues fue el profesor boloñés Scipione DEL FERRO el primer matemático del que se tiene constancia que la utilizara, motivo por cual también es citada en ocasiones como fórmula de del Ferro. La fórmula de del Ferro - Tartaglia - Cardano (que denotaremos como fórmula FTC) para resolver la ecuación y3 + p.y = q es: 18 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid 2 y= 3 3 2 q −q ⎛q⎞ ⎛p⎞ ⎛q⎞ ⎛p⎞ + ⎜ ⎟ +⎜ ⎟ − 3 + ⎜ ⎟ +⎜ ⎟ 2 2 ⎝2⎠ ⎝3⎠ ⎝2⎠ ⎝3⎠ Conocida mediante el procedimiento anterior una raíz real 3 x* = y − b 3.a de la ecuación cúbica (a.x3 + b.x2 + c = d), las otras dos raíces son la solución de la ecuación donde: de segundo grado: α.x 2 + β.x + γ = 0 α = a , β = b + α.x*, γ = c + β.x* El problema, sin embargo, aún no estaba cerrado. En efecto, en muchos casos la raíz cuadrada que aparece dentro de las raíces cúbicas de la fórmula FTC se referían a valores negativos. Considerando que en esa época aun no se habían introducido los números complejos la fórmula servía de poco en estos casos. Es por ello que Rafael BOMBELLI en el Libro I de su obra Algebra (aparecida en 1572) introduce unos nuevos entes a los que llama números imaginarios que le sirven para resolver definitivamente el caso irreducible de la ecuación de tercer grado. En síntesis, con la terminología actual, el procedimiento descrito por Bombelli se puede esquematizar como sigue: Dada la ecuación cúbica a.x3 + b.x2 + c.x = d 1º) Se forman los números: 1 ⎛ b2 ⎞ p = .⎜ c − ⎟ a ⎝ 3.a ⎠ 1 ⎛ c.b 2.b3 ⎞ q = ⋅⎜d + − ⎟ a ⎝ 3.a 27.a 2 ⎠ y 2º) Con ellos, a su vez, se calcula el número: 2 ⎛q⎞ ⎛p⎞ r =⎜ ⎟ +⎜ ⎟ ⎝2⎠ ⎝3⎠ 3 y: 2-a) Si (r > 0) se calcula una raíz real de la ecuación cúbica reducida mediante la fórmula FTC: 19 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid ⎛q⎞ ⎛ −q ⎞ y= 3⎜ ⎟+ r − 3⎜ ⎟+ r ⎝2⎠ ⎝ 2 ⎠ 2º - b) Si (r < 0) se calcula una raíz real de la ecuación cúbica reducida mediante el procedimiento siguiente: En primer lugar se evalúan s = Con ellos se calcula ρ = q 2 y t = −r s2 + t 2 y un parámetro θ evaluado como sigue: Si ( s > 0) : θ = 2º- b - I) 2º - b – II) Si (s < 0): θ = 1 ⎛t⎞ .arctg ⎜ ⎟ 3 ⎝ s⎠ 1 ⎡ ⎤ ⎛t⎞ . ⎢ arctg ⎜ ⎟ + π ⎥ 3 ⎣ ⎝s⎠ ⎦ 2º - b – III) Si (s = 0): π 6 −π 2º-b-III-2) Si ( t < 0): θ = 6 3 Finalmente, en este caso: y = 2. ρ .cos(θ) 2º-b-III-1) Si (t > 0): θ = 2º - c) Si (r = 0) se calcula una raíz real de la ecuación cúbica reducida mediante la expresión: y = 2. 3 q 2 3º) Una vez calculada la raíz real de la ecuación cúbica reducida, y, se calcula una raíz real de la ecuación dada mediante: x1 = y − y se evalúan los coeficientes: α = a , b 3.a β = b + α.x1 , γ = c + β.x1 . Con ellos se determina el valor: v = β2 – 4.α.γ 20 Programación y Métodos Numéricos. Práctica3: Estructuras condicionales C. Conde, A. Hidalgo y A. López ETSI Minas de la Univ. Politécnica de Madrid 4º ) 4º- A) Si (v > 0) la ecuación cúbica tiene tres raíces reales distintas que son, además de x1, las siguientes: x2 = −β + v 2.α y x3 = −β − v 2.α 4º - B) Si (v < 0) la ecuación cúbica tiene la raíz real, x1, y otras dos complejas conjugadas cuya parte real e imaginaria están dadas por: Partereal = −β , 2.α Parteimaginaria = −v 2.α 4º - C) Si (v = 0) la ecuación tiene la raíz real simple, x1, y una raíz real doble dada por: x2 = −β 2.α Se pide que escribas un programa en MAPLE que resuelva ecuaciones cúbicas mediante el procedimiento descrito por BOMBELLI, escribiendo las tres raíces de la ecuación cuando estas sean reales simples, la raíz real simple y la parte real y compleja de las otras dos raíces complejas conjugadas cuando este sea el tipo de raíces o bien la raíz real simple y la raíz real doble cuando sólo haya dos raíces distintas de la ecuación cúbica. En todos los casos deberá escribirse el tipo de raíces (tres simples y reales, una simple y dos complejas conjugadas o una real simple y otra real doble) que tiene la ecuación. Comprueba el programa aplicándolo a las ecuaciones: Ec. 1ª: 3.x3 + 5.x2 – 3.x = y: 3 1 2 Ec. 2ª: x - 10.x – 4.x = - 40 Ec. 3ª: x3 + 6.x2 + 20.x = 100 Ec. 4ª: - 3.x3 + 5.x2 – 3.x = > restart: > > 21 1