Escolar Documentos
Profissional Documentos
Cultura Documentos
Sum ario
1 Introdu c ao 2 Teoria 2.1 Arrays, vetores e matrizes . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.1 Aloca c ao din amica de arrays . . . . . . . . . . . . . . . . . . . . . . 2.2 Fun co es e subrotinas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Implementa c ao Refer encias 1 1 2 3 3 4 11
Introdu c ao
Uma matriz e um arranjo retangular de n umeros. Por exemplo, 8 7 2 3 5 10 A= 4 11 3 1 15 7 As opera co es b asicas que podem ser aplicadas a matrizes s ao: adi c ao, multiplica c ao, transposi c ao e invers ao. Nossa preocupa ca o maior neste documento e a implementa ca o destas opera c oes na linguagem de programa c ao Fortran 90. Para uma discuss ao te orica sobre matrizes, sugerimos o livro [3].
Teoria
Antes de implementarmos as opera c oes matriciais, vamos fornecer um breve resumo de alguns conceitos da linguagem Fortran 90 que iremos utilizar mais adiante neste documento.
2.1
Para implementar matrizes na linguagem Fortran 90 iremos utilizar uma array1 . Uma array e uma estrutura de dados que consiste de uma cole c ao de valores (vari aveis ou constantes) de um mesmo tipo que s ao referidos por um mesmo nome. Um valor individual dentro da array e chamado um elemento da array e e identicado pelo nome da array juntamente com um ndice indicando a localiza c ao do elemento dentro da array. Por exemplo, a seguinte cole c ao de 5 n umeros inteiros {5, 7, 9, 1, 8} poder a ser representada em Fortran 90 por
i n t e g e r , dimension ( 5 ) : : numeros = ( / 5 , 7 , 9 , 1 , 8 / )
O trecho de c odigo acima declara uma array chamada numeros contendo 5 n umeros inteiros. No c odigo, a array numeros e inicializada j a na sua pr opria declara c ao pelo construtor de arrays (/ . . . /). Outra forma de declarar e inicializar esta array seria
i n t e g e r , dimension ( 5 ) numeros ( 1 ) numeros ( 2 ) numeros ( 3 ) numeros ( 4 ) numeros ( 5 ) = = = = = 5 7 9 1 8 : : numeros
O n umero entre os par enteses e o ndice que localiza a posi ca o dentro da array; o ndice 1 localiza a primeira posi c ao na array, o 2 a segunda e assim em diante. Portanto, o c odigo acima atribui o valor 5 a ` posi ca o 1 da array, o valor 7 a ` posi c ao 2, etc. O sinal de igual = e a forma de atribuir valores a vari aveis em Fortran 90. As arrays em Fortran 90 podem ter mais de um ndice, podendo ser organizadas em m ultiplas dimens oes. Essas arrays s ao convenientes para representar dados organizados, por exemplo, em forma matricial (linhas e colunas). Utilizaremos arrays bidimensionais (dois ndices) para representar matrizes. Chamaremos de matrizes as arrays bidimensionais e de vetores as arrays unidimensionais. Por exemplo, se quis essemos representar a matriz identidade de ordem 3 1 0 0 Id3 = 0 1 0 0 0 1 poder amos utilizar o seguinte c odigo em Fortran 90
integer : : i , j i n t e g e r , dimension ( 3 , 3 )
: : identidade
Por falta de uma melhor tradu c ao da palavra, iremos utilizar o termo em ingl es neste documento.
Neste trecho de c odigo utilizamos as vari aveis i e j para representar os valores das linhas e colunas, respectivamente. O la co externo percorre as linhas da matriz, equanto que o la co interno percorre as colunas. Para cada elemento da matriz e atribu do o valor 0, caso a posi c ao deste elemento esteja fora da diagonal (i = j), ou o valor 1, caso o elemento esteja na diagonal (i = j). 2.1.1 Aloca c ao din amica de arrays
Em todos os trechos de c odigo acima, as declara co es das arrays s ao do tipo denominado aloca c ao est atica da mem oria, isso porque o tamanho de cada array e escolhido no momento da declara ca o e n ao poder a mudar. Desta maneira, o tamanho da array dever a ser grande o suciente para que todos os valores possam ser armazenados sem problemas. A aloca ca o est atica de mem oria pode apresentar s erias limita c oes. Por exemplo, suponha que voc e declare uma array de 1000 posi co es. Essa array ir a ocupar parte da mem oria do computador para armazenar 1000 n umeros, mesmo que voc e s o utilize 2 posi co es dela, ou seja, voc e estaria desperdi cando 998 posi co es de mem oria. Uma solu ca o para este problema e a chamada aloca c ao din amica da mem oria, exemplicada no seguinte c odigo
i n t e g e r , a l l o c a t a b l e , dimension ( : , : ) : : identidade
O c odigo acima declara a matriz identidade com aloca ca o din amica da mem oria. Observe que os sinais de dois pontos, :, entre os par enteses, s ao obrigat orios, assim como a palavra allocatable. Observe tamb em que a v rgula ap os o primeiro sinal de dois pontos foi necess aria, pois estamos declarando uma array bidimensional (uma matriz). Com este tipo de declara c ao, nenhuma mem oria e reservada. Para utilizarmos a matriz identidade, temos que alocar (reservar) mem oria antes. Veja o seguinte c odigo
i n t e g e r , a l l o c a t a b l e , dimension ( : , : ) a l l o c a t e ( identidade ( 3 , 3 ) ) : : identidade
Para alocarmos mem oria, utilizamos a fun ca o allocate com o nome da matriz e o tamanho que quisermos2 . Feito isto, podemos atribuir valores aos elementos da matriz normalmente. Ap os utilizarmos a matriz, poderemos liberar a mem oria para ela reservada, utilizando a fun c ao deallocate, como a seguir
d e a l l o c a t e ( identidade )
2.2
Utilizamos certos procedimentos em Fortran 90, tais como fun c oes e subrotinas, para organizar melhor nossos programas. Essa organiza c ao facilita a corre c ao de erros, estrutura ca o do programa em tarefas e subtarefas, etc. Iremos apenas mostrar como utilizar fun co es e subrotinas em Fortran 90. Para mais informa c oes sobre este assunto, sugerimos o livro [1]. Basicamente, subrotinas s ao procedimentos que s ao executados por uma instru c ao chamada CALL. Subrotinas podem retornar m ultiplos resultados atrav es da sua lista de argumentos de chamada. Fun co es s ao procedimentos que s ao executados pelos pr oprios
2
nomes em express oes e s o podem retornar um u nico resultado a ser usado na express ao. Os exemplos a seguir d ao a forma geral de uma subrotina e de uma fun ca o, respectivamente
s u b r o u t i n e m in ha _s u br ot in a ( lista de argumentos ) ... (declara c oes de vari aveis) ... (c odigo a ser executado) ... return end s u b r o u t i n e
f u n c t i o n minha_funcao ( lista de argumentos ) ... (declara c oes de vari aveis) ... (c odigo a ser executado) ... minha_funcao = express ao return end f u n c t i o n
Tanto para subrotinas quanto para fun c oes, e poss vel estabelecer uma lista de argumentos que ser ao utilizados pela subrotina ou fun ca o. Vale destacar que na fun ca o, e necess ario que haja uma atribui c ao de valor ao nome da fun ca o, indicando o valor que ser a retornado pela mesma.
Implementa c ao
O c odigo a seguir e a implementa ca o em Fortran 90 das opera co es b asicas sobre matrizes e o c alculo do determinante de uma matriz pela sua decomposi ca o em matrizes triangulares inferior e superior, conhecida como decomposi ca o LU. O algoritmo utilizado e conhecido como algoritmo de Doolittle. Utilizamos um algoritmo simples para o c alculo da inversa de uma matriz. Esse algoritmo e baseado no processo de elimina ca o gaussiana e tem um car ater mais did atico, pois seu desempenho e baixo. Tentamos, exageradamente, comentar o c odigo para facilitar a compreens ao do material. Utilizamos v arias t ecnicas e constru co es sint aticas para mostrar v arias formas de implementa c ao. O c odigo e extenso devido ao seu car ater did atico, mas voc e poder a modic a-lo ` a vontade, buscando melhores formas de expor os algoritmos ou, at e mesmo, utilizar algoritmos mais ecientes e precisos! aconselh E avel que voc e digite (ao inv es de copiar-e-colar) todo o c odigo e tente execut a-lo, pois assim, estar a treinando suas habilidades para detectar e corrigir erros, caso ocorram. Vale ressaltar que este e um c odigo com car ater did atico e n ao deve ser utilizado em outros ambientes que n ao os de sala de aula. Algumas instru c oes em Fortran 90 possuem op c oes at e agora n ao utilizadas, como por exemplo, a op c ao advance=no na instru ca o write. N ao detalharemos o signicado dessas op c oes, mas todas elas s ao facilmente encontradas em [1].
! A vari avel seed ser a compartilhada com a subrotina que cria os elementos das matrizes A e B ! aleatoriamente. Isto e necess ario para que os valores das matrizes n ao sejam iguais. ! ! M odulos devem sempre vir denidos antes do seu uso no programa. module global i m p l i c i t none i n t e g e r : : seed end module
! In cio do programa program matrizes u s e global ! ! Prop osito: ! Criar procedimentos para somar, multiplicar, transpor, inverter e decompor matrizes e ! calcular o determinante de uma matriz. ! ! Data: 1.5.2010 ! Programador: Juvenal Muniz ! ! Revis oes ! 1.5.2010 : C odigo original i m p l i c i t none ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! Declara c oes das vari aveis e das subrotinas utilizadas Descri c ao das vari aveis e/ou matrizes n Dimens ao da matriz i Contador condicao Indica se houve erro ao abrir o arquivo opcao Armazena a opcao selecionada pelo usu ario determinante Valor do determinante da matriz a, b, c Matrizes a, b e c arquivo Constante utilizada para acessar o arquivo resposta Armazenar a a resposta a ` pergunta (S ou N) nome arquivo Nome do arquivo contendo os elementos das matrizes Descri c ao das subrotinas matriz aleatoria Gera uma matriz quadrada aleat oria de ordem n matriz adicao Efetua a adi c ao de duas matrizes matriz mul Efetua a multiplica ca o de duas matrizes matriz transposta Obt em a transposta de uma matriz matriz inversa Obt em a inversa de uma matriz matriz lu Decomp oe a matriz em matrizes triangulares inferior e superior matriz imprime Exibe os elementos da matriz
i n t e g e r : : n , i , j , condicao , opcao r e a l : : determinante r e a l , a l l o c a t a b l e , dimension ( : , : ) : : a , b , c i n t e g e r , p a r a m e t e r : : arquivo = 17 c h a r a c t e r ( 1 ) : : resposta c h a r a c t e r ( 2 0 ) : : nome_arquivo ! Valor inicial para a fun c ao RAN() seed = 32764561 ! Leitura da dimens ao das matrizes quadradas w r i t e ( , ' (A) ' , advance= ' no ' ) ' Qual e a dimensao das m a t r i z e s ? ' read ( , ' ( I ) ' ) n ! Verica se a dimens ao e maior ou igual a 2. Caso contr ario, interrompe o programa. i f ( n >= 2 ) then allocate (a(n , n) , b(n , n) , c(n , n) ) else w r i t e ( , ) ' As m a t r i z e s devem p o s s u i r dimensao maior ou i g u a l a 2 ! ' stop end i f ! Pede conrma ca o para gerar as matrizes aleatoriamente w r i t e ( , ' (A) ' , advance= ' no ' ) ' D e s e j a que a s m a t r i z e s a e b sejam g e r a d a s ? ( S ou N) ' r e a d ( , ' (A1) ' ) resposta ! Verica a resposta dada pelo usu ario i f ( ( resposta == ' S ' ) . or . ( resposta == ' s ' ) ) then ! Usu ario prefere que as matrizes sejam geradas aleatoriamente c a l l m a t r i z _ a l e a t o ri a ( a , n )
c a l l m a t r i z _ a l e a t o ri a ( b , n ) else ! Usu ario prefere fornecer as matrizes em um arquivo w r i t e ( , ' ( / , x ,A) ' ) 'ATENCAO! Termine o a r q u i v o com uma l i n h a em b ra nco . ' w r i t e ( , ' ( x ,A) ' , advance= ' no ' ) ' Nome do a r q u i v o c o n t e n d o a s m a t r i z e s (max . 20 caracteres ) : ' r e a d ( , ' ( A20 ) ' ) nome_arquivo ! Abrindo o nome arquivo para leitura. ! status=old for ca que nome arquivo j a exista ! iostat=condicao armazena informa c oes sobre erros ao abrir o arquivo open ( u n i t=arquivo , f i l e =nome_arquivo , s t a t u s= ' o l d ' , a c t i o n= ' r e a d ' , i o s t a t=condicao ) ! O nome arquivo abriu sem problemas? i f ( condicao == 0 ) then ! Arquivo aberto ! Agora vamos ler os valores das matrizes a e b r e a d ( arquivo , ) ( ( a ( i , j ) , j = 1 , n ) , i r e a d ( arquivo , ) ( ( b ( i , j ) , j = 1 , n ) , i w r i t e ( , ' ( / , x ,A) ' ) ' M a t r i z e s l i d a s com else ! Erro ao abrir o arquivo. Terminar o programa. w r i t e ( , ' ( / , x ,A) ' ) ' Erro ao a b r i r o c l o s e ( arquivo ) stop end i f
! Fechar o arquivo, pois j a temos os valores armazenados nas vari aveis c l o s e ( arquivo ) end i f ! Menu para sele c ao das opera c oes matriciais implementadas ! Este la co se repetir a at e que o usu ario escolha a op c ao 0. do w r i t e ( , ' ( 3 / , x ,A) ' ) ' ( 1 ) Somar a s m a t r i z e s A e B ' write ( , ) ' (2) M u l t i p l i c a r as matrizes A e B ' w r i t e ( , ) ' ( 3 ) Obter a t r a n s p o s t a de A ' w r i t e ( , ) ' ( 4 ) Obter a i n v e r s a de A ' w r i t e ( , ) ' ( 5 ) C a l c u l a r o d e t e r m i n a n t e de A ' write ( , ) ' (6) Exibir as matrizes A e B ' write ( ,) ' (0) Sair ' w r i t e ( , ' ( / ,A) ' , advance= ' no ' ) ' D i g i t e a opcao d e s e j a d a (0 6) : r e a d ( , ) opcao i f ( opcao == 1 ) then ! C=A+B c a l l matriz_soma ( a , b , c , n ) w r i t e ( , ' ( / , x ,A) ' ) ' A soma da m a t r i z A com B e i g u a l a ' c a l l matr iz_impri me ( c , n ) e l s e i f ( opcao == 2 ) then ! C=A*B c a l l matriz_mul ( a , b , c , n ) w r i t e ( , ' ( / , x ,A) ' ) 'O p r o d u t o da m a t r i z A com B e i g u a l a ' c a l l matr iz_impri me ( c , n ) e l s e i f ( opcao == 3 ) then ! Matriz transposta de A w r i t e ( , ' ( / , x ,A) ' ) ' A m a t r i z t r a n s p o s t a de A e i g u a l a ' w r i t e ( , ' ( / , x ,A) ' ) 'MATRIX A ' c a l l matr iz_impri me ( a , n ) c a l l matriz_transposta ( a , n ) w r i t e ( , ' ( / , x ,A) ' ) 'MATRIX A ( t r a n s p o s t a ) ' c a l l matr iz_impri me ( a , n ) e l s e i f ( opcao == 4 ) then ! Matriz inversa de A w r i t e ( , ' ( / , x ,A) ' ) ' A m a t r i z i n v e r s a de A e i g u a l a ' w r i t e ( , ' ( / , x ,A) ' ) 'MATRIX A ' c a l l matr iz_impri me ( a , n ) c a l l matr iz_inver sa ( a , b , n ) w r i t e ( , ' ( / , x ,A) ' ) 'MATRIX B ( i n v e r s a ) ' c a l l matr iz_impri me ( b , n ) c a l l matriz_inversa_verifica ( a , b , n )
'
e l s e i f ( opcao == 5 ) then ! Decomposi ca o de A em LU c a l l matriz_lu ( a , n ) ! C alculo do determinante para uma matriz LU determinante = 1 . 0 do i = 1 , n determinante = determinante a ( i , i ) end do w r i t e ( , ' ( / , x ,A) ' ) 'MATRIX A ' c a l l matr iz_impri me ( a , n ) w r i t e ( , ' ( / , x , A, F) ' ) 'O d e t e r m i n a n t e da m a t r i z A v a l e : e l s e i f ( opcao == 6 ) then ! Exibe os elementos das matrizes A e B w r i t e ( , ' ( / , x ,A) ' ) 'MATRIX A ' c a l l matr iz_impri me ( a , n ) w r i t e ( , ' ( / , x ,A) ' ) 'MATRIX B ' c a l l matr iz_impri me ( b , n ) e l s e i f ( opcao == 0 ) then ! Interrompe o programa w r i t e ( , ' ( / , x , A, / ) ' ) ' Programa t e r m i n a d o . Ate mais ! ' exit end i f end do ! Libera a mem oria ocupada pelas matrizes A, B, C deallocate (a , b , c) end program
' , determinante
! Esta subrotina exibe os valores dos elementos de uma matriz ! ! Par ametros: ! a Matriz cujos elementos ser ao exibidos ! n Dimens ao da matriz (apenas matrizes quadradas) s u b r o u t i n e matr iz_impri me ( a , n ) i m p l i c i t none integer : : n , i , j real : : a(n , n) do i = 1 , n do j = 1 , n w r i t e ( , ' ( f , 2 x ) ' , advance= ' no ' ) a ( i , j ) end do print end do end s u b r o u t i n e
! Esta subrotina gera uma matriz com valores aleat orios para seus elementos ! ! Par ametros: ! a Matriz que armazenar a os elementos gerados ! n Dimens ao da matriz (apenas matrizes quadradas) s u b r o u t i n e m a t r i z _ a l e a t o r ia ( a , n ) u s e global i m p l i c i t none integer : : n , i , j real : : a(n , n) do i = 1 , n do j = 1 , n ! Calcula valores aleat orios de -5 a ` +5 ! A fun c ao ran() retorna valores entre 0.0 e 1.0 a ( i , j ) = ( 1 . 0 ) ( i+j ) 5 . 0 ran ( seed ) end do end do end s u b r o u t i n e
! Esta subrotina faz a adi ca o de duas matrizes quadradas (a + b) ! ! Par ametros: ! a e b Matrizes de entrada
! c Matriz que armazenar a a soma de a com b ! n Dimens ao da matriz (apenas matrizes quadradas) s u b r o u t i n e matriz_soma ( a , b , c , n ) i m p l i c i t none integer : : n , i , j real : : a(n , n) , b(n , n) , c(n , n) do i = 1 , n do j = 1 , n c(i , j) = a(i , j) + b(i , j) end do end do end s u b r o u t i n e
! Esta subrotina faz a multiplica c ao de duas matrizes quadradas (a * b) ! ! Par ametros: ! a e b Matrizes de entrada ! c Matriz que armazenar a o produto de a por b ! n Dimens ao da matriz (apenas matrizes quadradas) s u b r o u t i n e matriz_mul ( a , b , c , n ) i m p l i c i t none integer : : n , i , j , k real : : a(n , n) , b(n , n) , c(n , n) c = 0.0 do i = 1 , n do j = 1 , n do k = 1 , n c(i , j) = c(i , j) + a(i , k) b(k , j) end do end do end do end s u b r o u t i n e
! Esta subrotina cria a transposta de uma matriz ! ! Par ametros: ! a Matriz de entrada ! n Dimens ao da matriz (apenas matrizes quadradas) ! ! AVISO: A matriz a ser a modicada no processo s u b r o u t i n e matriz_transposta ( a , n ) i m p l i c i t none integer : : n , i , j r e a l : : a ( n , n ) , temp do i = 1 , n do j = 1 , n i f ( i < j ) then temp = a ( i , j ) a(i , j) = a(j , i) a ( j , i ) = temp end i f end do end do end s u b r o u t i n e
! Esta subrotina calcula a inversa de uma matriz por elimina c ao gaussiana ! ! Par ametros: ! matriz Matriz de entrada ! inversa Matriz que armazenar a a inversa ! n Dimens ao da matriz (apenas matrizes quadradas) ! ! AVISO: A matriz a ser a modicada no processo ! Refer encia : ! http://math.uww.edu/mcfarlat/inverse.htm ! http://www.tutor.ms.unimelb.edu.au/matrix/matrix inverse.html s u b r o u t i n e matr iz_inver sa ( matriz , inversa , n ) i m p l i c i t none integer : : n
r e a l , d i m e n s i o n ( n , n ) : : matriz r e a l , d i m e n s i o n ( n , n ) : : inversa l o g i c a l : : invertivel = . true . integer : : i , j , k , l real : : m r e a l , d i m e n s i o n ( n , 2 n ) : : m a t r i z _ a u m e n t ad a ! Matriz aumentada com uma matriz identidade do i = 1 , n do j = 1 , 2 n i f ( j <= n ) then m a t r i z _ a u m e n ta d a ( i , j ) = matriz ( i , j ) e l s e i f ( ( i+n ) == j ) then m a t r i z _ a u m e n ta d a ( i , j ) = 1 else m a t r i z _ a u m e n ta d a ( i , j ) = 0 endif end do end do ! Reduzir a matriz aumentada a uma matriz triangular superior pela elimina c ao gaussiana do k = 1 , n 1 ! Verica se algum elemento da diagonal e zero i f ( abs ( m a t r i z _ a u m e n t ad a ( k , k ) ) <= 1 . 0 E 6) then invertivel = . false . do i = k + 1 , n ! Verica se os elementos s ao maiores que zero i f ( abs ( m a t r i z _ a u m e n t a da ( i , k ) ) > 1 . 0 E 6) then do j = 1 , 2 n m a t r i z _ a u m e n t ad a ( k , j ) = m a t r i z _ a u m e n t a d a ( k , j ) + m a t r i z _ a u m e n t ad a ( i , j ) end do invertivel = . true . exit endif ! Se algum elemento da diagonal for zero, n ao podemos calcular a inversa i f ( invertivel == . false . ) then w r i t e ( , ' ( / , x , A, / ) ' ) ' A m a t r i z nao e i n v e r s t i v e l ! ' inversa = 0 stop endif end do endif ! Elimina c ao gaussiana do j = k + 1 , n m = m a t r i z _ a u m e n t ad a ( j , k ) / m a t r i z _ a u m e n t a da ( k , k ) do i = k , 2 n m a t r i z _ a u m e n ta d a ( j , i ) = m a t r i z _ a u m e n t a da ( j , i ) m m a t r i z _ a u m e n t ad a ( k , i ) end do end do end do ! Teste para invertibilidade do i = 1 , n ! Elementos da diagonal n ao podem ser zero i f ( abs ( m a t r i z _ a u m e n t ad a ( i , i ) ) <= 1 . 0 E 6) then w r i t e ( , ' ( / , x , A, / ) ' ) ' A m a t r i z nao e i n v e r s t i v e l ! ' inversa = 0 stop endif end do ! Elementos da diagonal iguais a 1 do i = 1 , n m = m a t r i z _ a u m e n t ad a ( i , i ) do j = i , 2 n m a t r i z _ a u m e n ta d a ( i , j ) = m a t r i z _ a u m e n t a da ( i , j ) / m end do end do ! Reduzir o lado esquerdo da matriz aumentada a matriz identidade do k = n 1 , 1 , 1 do i = 1 , k
m = m a t r i z _ a u m e n t ad a ( i , k +1) do j = k , 2 n m a t r i z _ a u m e n ta d a ( i , j ) = m a t r i z _ a u m e n t a da ( i , j ) m a t r i z _ a u m e n t a d a ( k +1 , j ) m end do end do end do ! Armazene o resultado do i =1 , n do j = 1 , n inversa ( i , j ) = m a t r i z _ a u m e n t a d a ( i , j + n ) end do end do end s u b r o u t i n e
! Esta subrotina verica se a matriz inversa e v alida (a * b = identidade) ! ! Par ametros: ! a Matriz original ! b Matriz inversa de a ! n Dimens ao da matriz (apenas matrizes quadradas) s u b r o u t i n e matriz_inversa_verifica ( a , b , n ) i m p l i c i t none integer : : n , i , j r e a l , d i m e n s i o n ( n , n ) : : a , b , identidade l o g i c a l : : ok ok = . true . c a l l matriz_mul ( a , b , identidade , n ) do i = 1 , n do j = 1 , n ! Elementos fora da diagonal principal n ao podem ser diferentes de zero i f ( ( i /= j ) . and . ( abs ( identidade ( i , j ) ) >= 1 . 0 E 6) ) then ok = . false . ! Elementos na diagonal principal n ao podem ser diferentes de um e l s e i f ( ( i == j ) . and . ( abs ( identidade ( i , i ) 1 . 0 ) >= 1 . 0 E 6) ) then ok = . false . end i f end do end do i f ( ok == . false . ) then w r i t e ( , ' ( / , x , A, / ) ' ) ' A v e r f i c a c a o da m a t r i z i n v e r s a f a l h o u ' else w r i t e ( , ' ( / , x , A, / ) ' ) ' A v e r f i c a c a o da m a t r i z i n v e r s a f o i c o n c l u i d a com s u c e s s o ! ' end i f end s u b r o u t i n e
! Esta subrotina decomp oe uma matriz em matrizes triangulares inferior e superior (LU) ! pelo algoritmo de Doolittle (diagonal principal da matriz L igual a 1). Para uma ! descri c ao te orica sobre o algoritmo de Doolittle, veja [2]. ! ! Par ametros: ! a Matriz que armazenar a as matrizes LU ! n Dimens ao da matriz (apenas matrizes quadradas) ! ! AVISO: A matriz a ser a modicada no processo s u b r o u t i n e matriz_lu ( a , n ) i m p l i c i t none integer : : n , i , j , k r e a l : : a ( n , n ) , s , ss ! Os elementos da diagonal n ao podem ser zero i f ( abs ( a ( 1 , 1 ) ) <= 1 . 0 E 6) then w r i t e ( , ' ( / , x , A, / ) ' ) ' I m p o s s i v e l f a t o r a r a m a t r i z ' stop end i f do i = 2 , n a(i ,1) = a(i ,1) / a (1 ,1)
10
end do do i = 2 , n 1 s = 0.0 do k = 1 , i 1 s = s a(i , k) a(k , i) end do a(i , i) = ( a(i , i) + s ) ! Os elementos da diagonal n ao podem ser zero i f ( abs ( a ( i , i ) ) <= 1 . 0 E 6) then w r i t e ( , ' ( / , x , A, / ) ' ) ' i m p o s s i v e l f a t o r a r a m a t r i z ' stop end i f do j = i + 1 , n ss = 0 . 0 s = 0.0 do k = 1 , i 1 ss = ss a ( i , k ) a ( k , j ) s = s a(j , k) a(k , i) end do a ( i , j ) = a ( i , j ) + ss a(j , i) = (a(j , i) + s) / a(i , i) end do end do s = 0.0 do k = 1 , n 1 s = s a(n , k) a(k , n) end do a(n , n) = a(n , n) + s end s u b r o u t i n e
Refer encias
[1] Stephen J. Chapman, Fortran 95/2003 for scientists and engineers, McGrall-Hill Companies, New York, NY, 2007. [2] R.L. Burden e J.D. Faires, Numerical analysis, Brooks Cole, California, CA, 2000. [3] J.L. Boldrini et al., Algebra linear, Editora Harbra, Ltda., S ao Paulo, SP, 1980.
11