Introducción El análisis numérico es una rama de las matemáticas cuyos límites no son del todo precisos. De una forma rigurosa, se puede definir como la disciplina ocupada de describir, analizar y crear algoritmos numéricos que nos permitan resolver problemas matemáticos, en los que estén involucradas cantidades numéricas, con una precisión determinada. En el contexto del cálculo numérico, un algoritmo es un procedimiento que nos puede llevar a una solución aproximada de un problema mediante un número finito de pasos que pueden ejecutarse de manera lógica. En general, estos métodos se aplican cuando se necesita un valor numérico como solución a un problema matemático, y los procedimientos "exactos" o "analíticos" (manipulaciones algebraicas, teoría de ecuaciones diferenciales, métodos de integración, etc.) son incapaces de dar una respuesta. 1 Objetivo El objetivo de este trabajo practico es el de resolver un problema que se puede presentar en la realidad, mediante la utilización de herramientas de cálculo numérico vistas en clase. Para ello se utilizarán los métodos de resolución de sistemas de ecuaciones lineales aprendidos en clase con los que podremos hallar una aproximación a la solución del problema mediante el uso de la computadora. También se analizará el condicionamiento del problema para saber si la utilización de estos métodos para la resolución del problema es o no acertada. 2 DESARROLLO Resolución del Problema Práctico El objetivo de este trabajo fue el de resolver un problema práctico con métodos numéricos. El problema en cuestión era el de un horno industrial que se utiliza para calentar unas planchas de acero que se van transportando por él una tras otra, y obtener vector de temperaturas de las placas régimen estacionario. Para resolver el problema se realizaron varias aproximaciones físicas que permitieron llevar el problema de 3 a 2 dimensiones y por otro lado se consideró que el calor era sólo transmitido por radiación y no por convección o por conducción lo que disminuye considerablemente la cantidad de factores a tener en cuenta y complejidad del problema. El problema en si fue planteado como un sistema de 56 ecuaciones, con la misma cantidad de incógnitas. Estas incógnitas se correspondían con los flujos calor de los planchones, que se iban moviendo a través del horno, y de las paredes del horno. El sistema de ecuaciones resultante fue: T*q = S * eb (1) Donde T es una matriz construida en base a los factores de vista (obtenidos del archivo de factores de vista), las áreas de las placas y las emisividades. S está construida en base a los factores de vista y las áreas. El vector q está formado por las incógnitas y eb es un vector que se arma con las temperaturas. Los pasos para resolver el problema fueron: 1. formar el vector eb inicial con todas las placas a temperatura ambiente, para poder obtener una solución q inicial. 2. con el vector de soluciones se obtiene la evolución de temperatura de todas las placas 3. el proceso 2. se repite 10 veces, una por cada minuto que la placa permanece en la posición i con {i : 0≤i≤50 } 4. se desplazan las placas una posición hacia adelante. Para ello muevo los valores del vector t (vector con la temperatura de las placas) de la posición i a la posición i+1. La temperatura de la posición 50 se pierde y en la primera colocación del vector se establece una placa con temperatura ambiente (293 K). 5. se vuelve a calcular q pero esta vez con eb compuesto con las nuevas temperaturas. Este proceso se repite hasta que hayan pasado las 50 placas de las que consta el problema. Luego una vez que se termina el ciclo con el vector t de temperaturas se puede obtener una dispersión del valor que tiene cada placa al pasar por una determinada posición del horno. En este trabajo práctico el sistema fue resuelto por medio de un método iterativo (SOR) y uno directo (Gauss con pivoteo parcial). 3 Condición de la Matriz En el análisis numérico, el número de condición de una matriz se utiliza como indicador para saber si un problema esta bien condicionado numéricamente o no. Un problema con un número de condición baja se dice que está bien acondicionado, mientras que un problema con un número de condición alta se dice que está mal condicionado. La forma teórica para hallar este valor se realiza por medio de la ecuación: K(A) = ||A-1|| ||A|| Este método en general es muy difícil de hallar por medio de esa formula debido a las dificultades que supone invertir una matriz (sobre todo cuando tratamos con una de gran dimensión). Por ello en general se recurre a un método experimental con el que se obtiene un valor aproximado de K(A). Esta aproximación es: K(A) ≈ ||δX|| / ||X|| * b-t Con b que representa la base en la que se realizan los cálculos y t la cantidad de dígitos que se utilizan en las cuentas. En este trabajo utilizamos ambos métodos para obtener el condicionamiento de la matriz T para observar que tan buena es la aproximación por el método experimental. Método Empírico Anteriormente se mencionó la existencia de un método experimental para calcular el condicionamiento de una matriz. En esta sección se detallara la forma en la que se obtiene dicha estimación. Para comenzar se cuenta con un sistema Ax=b (1). Debido a los errores cometidos por el redondeo realizado por la maquina existe un residuo denominado r. Este se calcula como r= Ax – Ax* = A(x-x*) (2), donde x es la solución exacta del sistema Ax=b y x* es la solución obtenida que contiene errores de redondeo. Evidentemente como no se conoce x se debe recurrir a una alternativa de esta fórmula, (1) se puede remplazar en (2) y obtengo r = b- Ax* (3). Para la cuenta (3) utilizo doble precisión. Luego paso r a una variable de simple precisión. Posteriormente se debe resolver el sistema A dx = r (4). Para ello utilizo la factorización de la matriz A en la forma LU=PA (5). Reemplazo (5) en (4) y obtengo el sistema LU dx= P r (6). Finalmente con el dx obtenido reemplazo en la fórmula: K(A) ≈ ||δX|| / ||X|| * 10-t 4 Métodos Iterativos Los métodos iterativos comienzan con una primera aproximación, que es sucesivamente mejorada por los elementos de una secuencia de números que convergen a la solución exacta. Evidentemente el proceso se trunca cuando los números obtenidos alcanzan la precisión deseada, dando lugar entonces a la existencia de un error de truncamiento. (En esos métodos, la solución del problema numérico es sólo una aproximación de la solución del problema matemático.) El método SOR (que será analizado en esta sección) está categorizado dentro de los métodos iterativos. Este método es una modificación del método de Gauss Seidel, introduciendo un factor que permite mejorar sustancialmente la velocidad de convergencia del método. Estos métodos a diferencia de los métodos directos no pueden utilizarse para resolver cualquier sistema de ecuaciones lineales. Éste impedimento se debe a que la convergencia de la solución no está garantizada para cualquier matriz. La convergencia de estos métodos sólo esta asegurada para aquellas matrices cuyo radio espectral (módulo de su máximo valor asociado) es menor a 1. Además, en general el método converge para matrices ralas, como la que trataremos en este trabajo práctico. Propagacion de errores en los métodos iterativos Ya que consideramos que no hay error de entrada, nos ocuparemos de hablar solo de los errores de truncamiento y de redondeo. Error de truncamiento El error de truncamiento surge de la necesidad de cortar un proceso que debía haber sido infinito. Al cortar este proceso, el resultado obtenido no es el resultado exacto, sino una aproximación, pero podemos saber que tan lejos esta de la solución exacta. Sea X la solución de X EX C , y X (k ) el valor obtenido por el método en la iteración k. X ( k ) X E( X ( k 1) X ) E( X ( k ) X ( k 1) ) E( X k X ) Entonces X k X E X ( k ) X ( k 1) E X k X . Suponemos que E 1 (para convergencia del método). Luego: Xk X E 1 E X k X k 1 . Si E 0,5 (caso de la matriz T utilizada en este tp) entonces X k X X k 1 X k Error de redondeo 5 Partiendo de la ecuación general de los métodos iterativos X ( k 1) TX ( k ) C , podemos considerar nulos los errores de X (k ) , suponiendo que partimos de X ( k ) X ( k ) . Entonces el error es solo el del ultimo paso. Operando se puede llegar a que el error es : X k 1 Xk (q.1.01 p2 3p 1) 2 Con p = cantidad de elementos no nulos de la fila con máxima cantidad de elementos no nulos. Y con q = máximo valor absoluto de la matriz T Considerando que q suele ser menor o igual que 1, se tiene que el error de redondeo es despreciable en la matrices con grandes espacios llenos de ceros (matrices ralas). Como la matriz T de este trabajo práctico es una matriz rala, tomaremos despreciable el error producido por el redondeo en el método de SOR. Método SOR (Sobrerelajaciones sucesivas) Este método se obtiene como una variación del método de Gauss-Seidel por el agregado de un factor de un factor w que se utiliza para mejorar la velocidad de convergencia. Este factor varía entre 0 y 2. A continuación se hará una descripción del algoritmo para un sistema Ax = b: 1. se realiza una descomposición A = D-U-L con U (L) triangular superior (inferior) formada por los elementos arriba (debajo) de la diagonal de A multiplicados por -1 y formada por los elementos de la diagonal de A. 2. luego se obtiene la matriz Tsor Csor = w(D-wL)-1 * b.1 = (D - wL)-1*[(1-w)*D+ wU] y la matriz 3. se plantea el sistema xk+1= Tsor * xk + Csor. 2 4. se repite el paso 3. hasta lograr que ||xk+1 – xk|| < er . Donde er es la cota de error de truncamiento que busco para mi solución. Propagacion de errores en método SOR. X ( k 1) TX k C En este trabajo práctico consideramos que no hay errores de entrada, entonces el error total será el error producido por el truncamiento mas el error producido por el redondeo. Como la matriz utilizada en el trabajo práctico para el calculo de los calores es una matriz rala, el error de redondeo para este tipo de matrices suele ser del orden de: p2 3p , con p la cantidad de elementos no nulos de la fila que tiene un máximo de 2 elementos no nulos, con lo cual este error suele ser despreciable en matrices ralas. 1 Para encontrar el factor w que sea óptimo para el problema se deberán probar distintos valores de w hasta que se encuentre uno que logre la convergencia con un determinado error en menos iteraciones. Esto se debe aclarar el w no se conoce a priori. 2 Para el vector x0 se puede elegir una semilla con valor arbitrario, teniendo en cuenta que cuanto más se acerque a la respuesta menos iteraciones se deberán realizar. 6 Entonces, el error total para la resolución del problema por el método SOR es igual a el error de truncamiento, el cual se puede calcular como: Et T 1 T X ( k 1) X k Método Directo Gauss y descomposición LU Se llama métodos directos a aquellos que calculan la solución exacta en un numero de pasos finito y conocido de antemano. Al resolver el problema directamente de forma matematica, es nulo el error de truncamiento, por lo que el error total es la suma de los errores de entrada y de redondeo. Triangulación Sea el sistema Ax b , con a cuadrada. Para resolver el sistema, el método de gauss utiliza un algoritmo de triangulación de la matriz, que consiste en eliminar los elementos que se encuentran debajo de la diagonal, para poder despejar las variables por separado. Un sistema triangular superior tiene la forma : Sean ai , j los coeficientes de la matriz A bi los coeficientes del termino independiente b x i los coeficientes de la incógnita x a1,1 x1 a1,2 x2 ... a1,n xn b1 a2,2 x2 a2,3 x3 .... a2,n xn b2 ..... an,n xn bn Y entonces con este sistema las variables se pueden despejar de la siguiente forma : xn bn / an,n xn1 (bn1 an1,n xn ) / an1,n1 ...... x1 (b1 a1,2 x2 .... a1,n xn ) / a1,1 Eliminación de Gauss Es el algoritmo que utiliza el método de gauss para lograr convertir a la matriz A en una matriz triangular superior. Consiste en eliminar las variables en forma secuencial, haciendo operaciones entre las filas de la matriz. Sea la matriz A una matriz cuadrada no singular tal que a1,1 0 , entonces se pueden eliminar x1 de las n-1 ecuaciones a partir de la fila 2 de la siguente forma: A la i-ésima ecuación se le resta la primera, multiplicada por mi ,1 ai ,1 / a1,1 7 Entonces, si ai ,i 0 entonces se puede proceder de forma análoga para las siguientes n-1 ecuaciones. Pivoteo parcial Siempre que se aplica la eliminación de gauss, puede suceder que para algún i<n, ai ,i = 0 luego de operar con las filas. Esto impide continuar con la eliminación, ya que presenta una división por 0. Además, si los factores m resultan muy grandes, se produce un considerable aumento del error de redondeo, que en ciertas ocaciones puede ser mayor que el resultado obtenido, haciendo que este resultado no sirva para ningún tipo de calculo. Para solucionar estos problemas que surgen en la eliminación de gauss, se utiliza una estrategia denominada “pivoteo”. El “pivoteo parcial”, que es el utilizado en este trabajo práctico, consiste en intercambiar la i-ésima fila con la fila que tenga el coeficiente a j ,i de mayor valor absoluto. De esta forma, se puede asegurar que ai ,i será distinto de 0 (por ser matriz no singular) y además se esta obteniendo el menor error posible, considerando solo intercambios de filas. Asi: a ( k ) s ,k max{ a ( k ) i ,k } con k i n Se puede armar una matriz de permutaciones Pi , j simplemente intercambiando la fila i por la fila j. Descomposicion LU Dada una matriz A nxn supongamos conocer una matriz L y otra U con las siguientes propiedades: A = L U, L triangular inferior y U triangular superior. En este caso para resolver A X = B procedemos de siguiente forma: Resolvemos primero mediante una sustitución directa L Y = B y luego mediante una sustitución inversa U X = Y. Ademas, esto se puede hacer siempre ya que hay un teorema que asegura que Dada una matriz A de nxn no singular, existen una matriz P de permutaciones, una matriz L triangular inferior con unos en la diagonal, y una matriz U triangular superior, tales que: PA = LU u i , j son los resultantes de la eliminación de gauss. li , j son los factores mi , j Asi la matriz resultante, que tiene todos los valores de L y U es: u1,1 u1, 2 l 2,1 l 2, 2 .... .... l n ,1 l n , 2 .... u1,n .... u 2,n .... .... .... u n ,n 8 u1,1 u1, 2 0 u 2, 2 U = .... .... 0 0 0 1 l 1 2 ,1 L = .... .... l n ,1 l n , 2 .... u1,n .... u 2,n .... .... .... u n ,n 0 .... 0 .... .... .... l n ,n .... Finalmente, el sistema puede resolver en forma matricial resolviendo 2 sistemas sencillos: Pf Pi , j Pi 1, j 1.... P1, 2 LUx Ly Pf b Ux y Errores en Método de Eliminacion Gaussiana Los errores en cualquier método numérico pueden ser de varios tipos. En el caso de este trabajo práctico consideramos que los errores de entrada son nulos. Como se había mencionado antes, los errores de truncamiento en este método son nulos, ya que no se esta truncando una serie de operaciones que debería ser infinita, sino que se esta resolviendo matemáticamente una cantidad finita de pasos. Entonces el error total se puede considerar como el error proveniente solo del redondeo. Este error es provocado por la incapacidad de la maquina de contener infinitas cifras en la mantisa. El error de redondeo se puede calcular de la siguiente manera: Dado el sistema: AX b llamamos X al vector que hallamos con los errores de redondeo. Como la cantidad de operaciones necesario para hacer A X es mucho menor que la cantidad necesaria para la Eliminación de Gauss, podemos considerar despreciable el error de redondeo en esta operación con respecto al de X y considerar que el termino residual r AX A X b A X tiene error despreciable. Entonces: X X At r X X At b Como b A X entonces el error de redondeo es XX X K ( A) r b con K ( A) A A 1 Este error es análogo para la Eliminación de gauss o para la descomposición LU, aunque se puede calcular de otras maneras. El algoritmo entonces es: 1. Triangular la matriz utilizando eliminación de gauss, y pivoteando filas en cada paso. Colocar los factores “Mij” en las posiciones debajo de la diagonal. 2. Generar las matrices L y U con los datos obtenidos. 9 3. Resolver Ly = b, despejando L de forma directa. 4. Resolver Ux = y, despejando U de forma inversa. 5. Calcular el error resultante con la formula antes mencionada. Resultados obtenidos Condicionamiento de la matriz El K(A) de la matriz utilizando el método teórico es 52,8839 El K(A) de la matriz utilizando el método experimental es 3,5783 Ambos valores son aceptables para un buen cálculo del resultado. Con método SOR Vector t: 1.0e+003 * 0.2930 0.3465 0.4028 0.4611 0.5206 0.5800 0.6384 0.6947 0.7479 0.7973 0.8426 0.8836 0.9204 0.9532 0.9820 1.0070 1.0283 1.0460 1.0608 1.0737 1.0853 1.0967 1.1089 1.1227 1.1388 1.1573 1.1773 1.1972 1.2154 1.2309 1.2436 10 1.2538 1.2623 1.2700 1.2774 1.2854 1.2944 1.3046 1.3157 1.3269 1.3373 1.3462 1.3536 1.3597 1.3650 1.3699 1.3750 1.3805 1.3871 1.3948 Grafica de Temperatura Obtenida por método SOR Error total T 0,42506 11 Fijamos como condición de corte que X ( k 1) X k 1 10 14 Entonces tomamos como error Et 0,42506 1 1014 0,68 1014 1 0,42506 w Óptimo Para calcular el w óptimo para el problema planteamos el sistema de ecuaciones inicial y luego elegimos dos referencias para el w (en nuestro caso 0 y 2). Luego promediamos las referencias y obtenemos el punto medio entre ambas. Con este punto medio tomamos dos intervalos, y realizamos el promedio entre el punto medio cada uno de nuestros extremos originales. Luego realizamos SOR del sistema de ecuaciones con los dos promedios que habíamos obtenido en el paso anterior y vemos cual converge más rápido. El que converge mas rápido pasa a ser nuestro punto de referencia y esto se repite 100 veces hasta encontrar un valor de w muy aproximado. El w obtenido fue 1.0547 Con método ELIMINACION DE GAUSS Vector t 1.0e+003 * 0.2930 0.3465 0.4028 0.4611 0.5206 0.5800 0.6384 0.6947 0.7479 0.7973 0.8426 0.8836 0.9204 0.9532 0.9820 1.0070 1.0283 1.0460 1.0608 1.0737 1.0853 1.0967 1.1089 1.1227 1.1388 1.1573 1.1773 1.1972 1.2154 1.2309 1.2436 12 1.2538 1.2623 1.2700 1.2774 1.2854 1.2944 1.3046 1.3157 1.3269 1.3373 1.3462 1.3536 1.3597 1.3650 1.3699 1.3750 1.3805 1.3871 1.3948 Gráfica de Temperatura Obtenida por método GAUSS Error Total Error Total = Error Entrada + Error Redondeo + Error Truncamiento El error de entrada y el de truncamiento son 0. Error Total = Error Redondeo = 1,0321 1014 13 Comparacion de resultados Si bien ambos resultados tienen errores muy pequeños, y constituyen aproximaciones aceptables para casi cualquier aplicación, observamos que con el método SOR, se puede lograr un mejor resultado que con el método de eliminación de Gauss, aunque esto solo se logra realizando muchas iteraciones. Con la condición de corte que definimos para este trabajo práctico: Egauss 1,0321 1014 1,664. El error de gauss es 1,664 veces mayor que el de SOR. Esor 0,68 1014 Código Fuente function ProgramaPrincipal clc; disp('Trabajo Practico N° 1'); o=0; while (o~=4)%%MENU PRINCIPAL ok=false; o=0; o2=0; while (~ok) disp('Seleccione la operación que desea realizar'); disp('(1). Calcular Condición de la matriz T '); disp('(2). Resolver utilizando método de Gauss'); disp('(3). Resolver utilizando método SOR'); disp('(4). Salir'); o=input('\nOpción: '); ok= validar(1,4,o); if(~ok) disp('Opcion inválida'); end end clc;%limpiar la pantalla switch (o) case 1,%%MENU DE CONDICIÓN DE MATRIZ disp('Calcular Condicion de la matriz T'); 14 disp('(1). Resolver por método Teórico'); disp('(2). Resolver por método Práctico'); disp('(3). Salir a menu principal') ok=false; [T,S,t]= CalcularSistema(); while (~ok) o2=input('\nOpción: '); ok=validar(1,3,o2); if (~ok) disp('Opción inválida'); end end if(o2==1) r=CondicionMatriz(@Kteorico,T); elseif (o2==2) eb=Calcular_eb(t); r=CalcularK(T,S*eb); end if (o2~=3) disp('K(T)='); disp(r); end if (o2~=3) input(''); end clc; case 2,%%MENU DE METODO DE GAUSS disp('Resolver utilizando método de Gauss'); disp('(1). Obtener gráfico de temperaturas'); disp('(2). Ver vectores de temperaturas y flujos de calor'); disp('(3). Error de redondeo'); disp('(4). Salir a menú principal'); ok=false; fh= @resolverLinealGauss; [t,q]=CalcularTemp(fh); while (~ok) o2=input('\nOpcion: '); ok=validar(1,4,o2); if (~ok) disp('Opción inválida'); end end switch o2 case 1,%Grafica el vector T plot(t, 'DisplayName', 't', 'YDataSource', 't'); figure(gcf); xlabel('N° de Placa'); ylabel('Temperatura (K)'); title('Grafico de Temperaturas Gauss'); set(findobj(gca,'Type','line','Color',[0 0 1]),'Color','red') case 2,%muestra por pantalla los vectores q y t disp('Vector t'); disp(t); 15 disp('Vector q'); disp(q); case 3,%Error de redondeo [T,S,t]= CalcularSistema; eb=Calcular_eb(t); r = calcularErrorDirecto(T,(S*eb)); disp('Error de redondeo: '); disp(r); otherwise %%SALIDA DEL MENU DE GAUSS end if(o2~=4) input(''); end clc; case 3,%%MENU DE METODO SOR disp('Resolver utilizando método SOR'); disp('(1). Obtener gráfico de temperaturas'); disp('(2). Ver vectores de temperaturas y flujos de calor'); disp('(3). Mostrar w óptimo'); disp('(4). Salir a menú principal'); ok=false; fh= @SOR; [t,q]=CalcularTemp(fh); while (~ok) o2=input('\nOpcion: '); ok=validar(1,4,o2); if (~ok) disp('Opción inválida'); end end switch o2 case 1,%Grafica el vector T plot(t, 'DisplayName', 't', 'YDataSource', 't'); figure(gcf); xlabel('N° de Placa'); ylabel('Temperatura (K)'); title('Grafico de Temperaturas con SOR'); case 2,%muestra por pantalla los vectores q y t disp('Vector t'); disp(t); disp('Vector q'); disp(q); case 3, %Calcular el w optimo y mostrarlo por pantalla [T,S,t]= CalcularSistema; eb=Calcular_eb(t); w = CalcularWOptimo(T,S*eb); disp(w); otherwise %%SALIDA DEL MENU DE SOR end if(o2~=4) 16 input(''); end clc; otherwise end%switch end%while (o~5) end %Programa Principal function v= validar(ini,fin,o) if (o>=ini && o<=fin) v=true; else v=false; end end ///////////////////////////////////////////////////////////////////////////////////////7 function [eb]= Calcular_eb(t) eb=ones(56,1); sigma=5.67*10^-8;%constante Stefan-boltzman for n=1:56 eb(n,1)=(t(n)^4); end eb=eb*sigma; end ///////////////////////////////////////////////////////////////////////////////////// function [A]= CalcularAreas() A=zeros(56); for i=1:50 % placas A(i,i)= 0.4; end A(51,51)=2;%pared salida A(56,56)=2; for i=52:55 %techo del horno A(i,i)=5; end end ///////////////////////////////////////////////////////////////////////////////////// %ESTA FUNCION DEVUELVE EL VECTOR DE TEMPERATURAS DEL SISTEMA %PARAMETRO: fh referencia a una funcion function [t2,q]= CalcularTemp(fh) [T,S,t]=CalcularSistema; eb=Calcular_eb(t); 17 b=S*eb; q=fh(T,b); for i=1:50 for j=1:10 %cantidad de dTiempo que tarda una placa en avanzar una pos t=actualizar_t(t,q); end aux=t; for k=1:49%avanzo todas las placas una posicion t(k+1)=aux(k); end t(1)=293;%temp ambiente (cte del problema) %Calculo q con los nuevos valores de t eb=Calcular_eb(t); b=S*eb; q=fh(T,b); end t2=zeros(50,1); for i=1:50 t2(i)=t(i); end end function [eb]= Calcular_eb(t) eb=ones(56,1); sigma=5.67*10^-8;%constante Stefan-boltzman for n=1:56 eb(n,1)=(t(n)^4); end eb=eb*sigma; end function [t]=actualizar_t(t,q) A=CalcularAreas; grosor=0.10;%Cte; p=7840;%cte ro del acero cp=500;%cp del acero for i=1:50 %actualizo el vector temperatura para cada placa t(i)=t(i)-(q(i)*A(i,i))/(A(i,i)*grosor*p*cp)*60; end end ////////////////////////////////////////////////////////////////////////////////////////////////////// function w = CalcularWOptimo(A,b) cs = 2; ci = 0; for i=1:50 w = (ci+cs)/2; wauxi=(ci+w)/2; 18 wauxd=(cs+w)/2; [x,itauxi] = SOR2(A,b,wauxi); [x,itauxd] = SOR2(A,b,wauxd); if(itauxi<itauxd) cs = w; else ci = w; end end ///////////////////////////////////////////////////////////////////////////////////////////////7 function [x,i]= SOR2 (A,b,w) er=0.00000000000001;%constante de error para truncamiento MAXITE=50;%maxima cantidad de iteraciones que puede realizar el %metodo [U,L,D]= Factorizar(A); %TODO: esto debe ser modificado por %una funcion que calcule el mejor w try aux = inv(D-w*L);%preguntar por la excepcion que lanza cuando es %matriz singular T= aux *((1-w)*D+w*U); C= w*aux*b; catch end i=0; fin=false; x=zeros(length(b),1); while (~fin && i<MAXITE ) i=1+i; xaux=x; x=T * xaux+C; if (er > norm(x-xaux) ) fin=true; end end end %Pre la matriz debe ser cuadrada y la diagonal debe tener sus %elementos no nulos %Pos devuelve una factorizacion LUD de la matriz A, para el metodo SOR function [U,L,D]= Factorizar(A) [m,n]=size(A); U= CalcU(A,n); L= CalcL(A,n); D= CalcD(A,n); end function [M] = CalcU(A,n) M=zeros(n); for i=1:n for j=(i+1):n M(i,j)=-1*A(i,j); end end 19 end function [M] = CalcL(A,n) M=zeros(n); for i=1:n for j=(i+1):n M(j,i)=-1*A(j,i); end end end function [M] = CalcD(A,n) M=zeros(n); for i=1:n M(i,i)=A(i,i); end end /////////////////////////////////////////////////////////////////////////////////////7 function [x]= SOR (A,b) er=0.00000000000001;%constante de error para truncamiento MAXITE=35;%maxima cantidad de iteraciones que puede realizar el %metodo [U,L,D]= Factorizar(A); w=1.0469; % w optimo calculado try aux = inv(D-w*L);%preguntar por la excepcion que lanza cuando es %matriz singular T= aux *((1-w)*D+w*U); z = norm(T,inf); C= w*aux*b; catch return; end i=0; fin=false; x=zeros(length(b),1); while (~fin && i<MAXITE ) i=1+i; xaux=x; x=T * xaux+C; if (er > norm(x-xaux) )%encontrar una forma de que no %entre en un ciclo infinito fin=true; end end end %Pre la matriz debe ser cuadrada y la diagonal debe tener sus %elementos no nulos %Pos devuelve una factorizacion LUD de la matriz A, para el metodo SOR function [U,L,D]= Factorizar(A) [m,n]=size(A); U= CalcU(A,n); 20 L= CalcL(A,n); D= CalcD(A,n); end function [M] = CalcU(A,n) M=zeros(n); for i=1:n for j=(i+1):n M(i,j)=-1*A(i,j); end end end function [M] = CalcL(A,n) M=zeros(n); for i=1:n for j=(i+1):n M(j,i)=-1*A(j,i); end end end function [M] = CalcD(A,n) M=zeros(n); for i=1:n M(i,i)=A(i,i); end end ////////////////////////////////////////////////////////////////////////////////////////////////////////////// function K = CalcularK(A,b) x = resolverLinealGauss(A,b);%obtengo solucion aprox y = A*x; r = b - y;% calculo el residuo dx = resolverLinealGauss(A,r); K = (10^16)*norm(dx,inf)/norm(x,inf); end /////////////////////////////////////////////////////////////////////////////////////////////////////// function EsDiagonalDominante(A); for i=1:n totalD = total+A(i,i); end for i=1:n for j=1:n totalM = totalM + A(1,j); end end if(totalM - totalD > totalD) x = 0; else x = 1; end ///////////////////////////////////////////////////////////////////////////////////////////////77 %Este método devulve la condición de la matriz %Param: fh una referencia a una funcion que se encarga de %calcular la condicion de la matriz. M es la matriz que se 21 %quiere analizar function K = CondicionMatriz(fh,M) K=fh(M); end ////////////////////////////////////////////////////////////////////////////////////777 function K= Kteorico(M) K= norm(inv(M),inf)* norm(M,inf); end //////////////////////////////////////////////////////////////////////////////// function K = CalcularK(A,b) x = resolverLinealGauss(A,b);%obtengo solucion aprox y = A*x; r = b - y;% calculo el residuo dx = resolverLinealGauss(A,r); K = (10^16)*norm(dx,inf)/norm(x,inf); end ///////////////////////////////////////////////////////////////////////////// %Este método devulve la condición de la matriz %Param: fh una referencia a una funcion que se encarga de %calcular la condicion de la matriz. M es la matriz que se %quiere analizar function K = CondicionMatriz(fh,M) K=fh(M); end ////////////////////////////////////////////////////////////////////////////// function K= Kteorico(M) K= norm(inv(M),inf)* norm(M,inf); end ////////////////////////////////////////////////////////////////////////// function x = resolverLinealGauss(A,b) b=b'; [A,P] = EliminarPivoteoParcial(A); y = despejarY(A,P,b'); x = despejarX(A,y); end ///////////////////////////////////////////////////////////////////777 function [A,P] = PivotearParcial(fil,A) pos = MaxMatrizFil(fil,A); A = SwapFil(fil,pos(1),A); s = length(A); P = SwapFil(fil,pos(1),eye(s)); 22 /////////////////////////////////////////////////////////////////// function [C,Pf] = EliminarPivoteoParcial(A) C=A; Pf = eye(length(A)); for i=1:length(A)-1 [B,P] = PivotearParcial(i,C); Pf = P * Pf; C = Eliminar(i+1,B); end //////////////////////////////////////////////////////////////////// function r = calcularErrorDirecto(A,b) K = norm(A,inf)*(norm(inv(A),inf)); x = resolverLinealGauss(A,b); resto = b - A*x; r = K*norm(resto)/norm(b); end //////////////////////////////////////////////////////////////////// function B = Eliminar(fil,A) B=A; for i = fil:length(A) m = A(i,fil-1) ./ A(fil-1,fil-1); for j = fil-1:length(A) B(i,j) = A(i,j) - (A(fil-1,j) .* m); end B(i,fil-1) = m; end ////////////////////////////////////////////////////////////////// function x = despejarX(A,y) tam = size(A); U = zeros(tam(1)); for i=1:tam(1) for j=i:tam(2) U(i,j) = A(i,j); end end x = zeros(tam(1),1); for i=1:tam(2) x(i) = y(i); end x(tam(1)) = x(tam(1)) ./ U(tam(1),tam(2)); for i=tam(1)-1:-1:1 for j=i+1:tam(1) x(i) = x(i) - U(i,j)*x(j); end x(i) = x(i)./ U(i,i); end end 23 ///////////////////////////////////////////////////////////////// function y = despejarY(A,P,b) bf = P*b; tam = size(A); L = zeros(tam(1)); for i=2:tam(1) for j=1:i-1 L(i,j) = A(i,j); end end y = zeros(tam(2),1); L = L + eye(tam(1)); y(1) = bf(1); for i=2:tam(1) for j=1:i-1 y(i) = y(i) - L(i,j)*y(j); end y(i) = y(i) + bf(i); end end /////////////////////////////////////////////////////////////////////7 function B=SwapCol(col1,col2,A) B=A; for i=1:length(A) B(i,col1) = A(i,col2); B(i,col2) = A(i,col1); end /////////////////////////////////////////////////////////////////// function A = SwapFil(fil1,fil2,A) for i=1:length(A) aux = A(fil1,i); A(fil1,i) = A(fil2,i); A(fil2,i) = aux; end ////////////////////////////////////////////////////////////////////////////7 function MaxMatrizFila = MaxMatrizFil(fil,A) b = size(A); max = A(fil,fil); maxPos = [fil,fil]; for i=fil:b(1) if(abs(A(i,fil)) > abs(max)) max = A(i,fil); maxPos = [i,fil]; end end MaxMatrizFila=maxPos; 24 Bibliografía Análisis Numérico. Autor: Hernán González. Análisis Numérico. Autor: W. Allen Smith. Wikipedia. 25