INSTITUTO DE GEOCIêNCIAS - SEGUNDO SEMESTRE DE 1998
Quarto Exercício-Programa
Data de entrega: até 27 de novembro de 1998
Prof. Ronaldo Fumio Hashimoto
O objetivo deste EP é implementar a resolução de um sistema de equações lineares aplicando o Método de conhecido como Método de Decomposição LU.
Definição: Um sistema de equações lineares (de n equações e n
incógnitas) é um sistema do tipo:
|
onde os ai,j e os yi (i,j = 0,1,2,¼, n-1) são dados, e os xi (i = 0,1,2,¼,n-1) são as incógnitas do sistema. Por exemplo,
|
é um sistema de 3 equações e 3 incógnitas.
Sejam
|
Então, podemos escrever o sistema (1) como A·x = y.
Um sistema dado pode não ter solução, ou ter uma ou mais soluções (inclusive
infinitas). No exemplo (*****), x0 = -2, x1 = 1 e x2 = 2 é
a única solução
do sistema. As vantagens de uma representação por matrizes são, além de ser
uma notação mais compacta, permite trabalhar em um computador.
Temos dois casos especiais que são de resolução imediata:
1. A matriz A é uma matriz triangular
superior, isto é, ai,j = 0 se i > j. Assim, os valores abaixo da diagonal
de A são todos nulos. Por exemplo, seja o sistema:
|
A resolução é então trivial: da última equação achamos x2 = 1. Com x2 e a segunda equação, achamos x1 = 0. E com x1 e x2 achamos, da primeira equação, o valor de x0 = -5. Este método chama-se de ``back-substitution''.
2. A matriz A é uma matriz triangular
inferior, isto é, ai,j = 0 se i < j. Assim, os valores acima da diagonal
de A são todos nulos. Por exemplo, considere dado o seguinte sistema:
|
Novamente, a resolução fica trivial: de primeira equação, x0 = 2. Com x0 e a segunda equação, obtemos x1 = -1, e finalmente, da última equação, e com os valores de x0 e x1, temos que x2 = 4. Este método chama-se de ``forward-substitution''.
Dada uma matriz A, vamos tentar achar (se for possível) uma matriz L triangular inferior e uma matriz U triangular superior tais que A = LU. Nesse caso,
como A = LU, temos:
e podemos fazer:
Fazendo Ux = z, temos:
Dessa forma, resolver o sistema Ax = y equivale a resolver dois sistemas
lineares (triangulares) simples: primeiramente o sistema (triangular
inferior) Lz = y por ``forward-substitution'' e depois o sistema
(triangular superior) Ux = z por ``back-substitution''.
Dada uma matriz A = (ai,j), queremos obter a partir dela uma matriz L com zeros acima da diagonal. Para isso, vamos começar ``zerar'' gradualmente os elementos a0,1, a0,2, ¼ , a0,n-1. Seja l tal que a0,1-la0,0 = 0. Então l = a0,1/a0,0 (assumir a0,0 não nulo). Calculamos, então, os novos valores para a segunda coluna da seguinte forma: a primeira coluna menos l vezes a segunda coluna. Ou seja,
|
Isto é,
|
Claramente, obtemos a¢0,1 = 0 (pela escolha do l). Repetimos o procedimento para a terceira coluna, isto é, para ``zerar'' a0,2, recalculamos a terceira coluna a partir da primeira. Seja l¢ = a0,1/a0,0. Então
|
Ou seja,
|
Claramente, obtemos a¢0,2 = 0 (pela escolha do l¢).
Repetindo esse processo, vamos ``zerar'' todos elementos a0,1,
a0,2, ¼ , a0,n-1, obtendo:
|
Devemos prosseguir para ``zerar'' a segunda linha. Para ``zerar'' a¢1,2, recalculamos a terceira coluna a partir da segunda (utilizando a coluna já modificada no passo anterior!). Seja b = a¢1,2/a¢1,1 (assumir a¢1,1 não nulo). Então:
|
Ou seja,
|
Assim, obteremos a¢¢1,2 = 0.
Da mesma forma, para obtermos a¢¢1,3 = 0, recalculamos a quarta
coluna a partir da segunda. Seja b¢ = a¢1,3/a¢1,1. Então:
|
Ou seja,
|
Seguindo este procedimento, vamos ``zerar'' todos os elementos a¢1,2, a¢1,3, ¼ , a¢1,n-1, obtendo:
|
Prosseguimos assim para a terceira linha, zerando a¢¢2,3, a¢¢2,4, ¼ , a¢¢2,n-1, sempre usando a terceira coluna. Depois, a quarta linha usando a quarta coluna. Seguindo esse processo para as demais linhas, até obter uma matriz L diagonal inferior.
|
A matriz U é obtida simplesmente armazenando os coeficientes usados em cada passo do procedimento (anterior) para obter a matriz L, da seguinte forma:
|
Definimos ui,i = 1 e ui,j = 0, para i=1, 2, ¼, n-1 e
j < i. Assim obteremos a matriz:
|
Pode-se verificar que A = LU, e que a decomposição é única.
Observação: Se em algum momento a¢¼¢i,i = 0, o método
deve parar.
|
Primeiro passo, zerar a0,1 e a0,2, isto é, 4 e 2. Para isso, primeiro calculamos
l = a0,1/a0,0 = 4/2 = 2, e recalculamos a segunda coluna:
a¢0,1 = 0,
a¢1,1 = a1,1-la1,0 = 7-2·4 = -1,
a¢2,1 = a2,1-la2,0 = -7-2·(-2) = -3.
Para zerar a0,2, calculamos l¢ = a0,2/a0,0 = 2/2 = 1, e assim,
recalculamos a terceira coluna (a partir da primeira):
a¢0,2 = 0,
a¢1,2 = a1,2-la1,0 = 7-1·4 = 3,
a¢2,2 = a2,2-la2,0 = 5-1·(-2) = 7.
Os multiplicadores são
l = 2 e l¢ = 1, assim u0,1 = 2 e
u0,2 = 1 (como U tem 1 na diagonal, u0,0 = 1). A matriz depois deste
passo será:
|
Segundo passo, zerar o resto da segunda linha, isto é, a¢1,2 = 3. Para isso, calculamos l = a¢1,2/a¢1,1 = 3/(-1) = -3 (agora usamos a segunda coluna!). Assim, recalculamos a terceira coluna:
a¢¢1,2 = 0,
a¢¢2,2 = a¢2,2-la¢2,1 = 7-(-3)·(-3) = -2.
O multiplicador foi
l = -3, e assim u1,2 = -3. Uma vez que U é
triangular superior e tem em sua diagonal, então devemos ter u1,0 = 0 e
u1,1 = 1.
Agora acabou o processo, u2,0 = u2,1 = 0 e u2,2 = 1, e obtemos:
|
Dessa forma, basta resolvermos:
|
E finalmente, resolvendo:
|
Observe que, como os computadores tem uma precisão limitada, necessariamente vamos ter erros de arredondamento nos cálculos, e então uma solução para o sistema Ax = y não vai ser exata. Seja x a solução encontrada pelo seu programa. O erro pode ser medido achando-se a diferença entre o vetor Ax e y. A diferença é calculada da seguinte forma:
||v || = max {|vi| : 0 £ i £ n-1}.
Fazer um programa em Linguagem C tal que, lida uma matriz real quadrada A de ordem n e um real vetor y de n elementos, resolva (se for possível) o sistema linear Ax = y, seguindo os seguintes passos:
1. Achar uma decomposição A = LU;
2. Resolver (por forward-substitution) Lz = y;
3. Resolver (por back-substitution) Ux = z;
4. Achar o erro Erro = ||Ax - y|| da solução encontrada x, onde
||v|| = max{|vi| : 0 £ i £ n-1}.
5. Imprimir A, L e U, z, x e o erro E.
Para isso, você deve definir as seguintes funções:
Copia a matriz quadrada A de ordem n na matriz B quadrada, também de
ordem n.
Esta função obtêm L e U. Inicialmente devemos ter L = A. Não use
nenhuma matriz auxiliar nesta função! Na matriz LU deve ficar a matriz
L na parte inferior de LU e a matriz U (sem a diagonal de 1)
na parte superior de LU. Para o exemplo (*****),
teríamos a matriz LU como:
|
Observação: Se na execução de calc_lu achamos algum li,i = 0, então a função deve retornar um valor especial para permitir ao programa principal detectar tal situação, imprimindo na tela uma mensagem de erro.
Calcula o produto da matriz An×n pelo vetor xn×1, guardando o resultado em yn×1, ou seja,
|
Resolve Lz = y por forward-substitution, onde L é a parte inferior de LU.
Resolve Ux = z por back-substitution, onde U é a parte superior (sem considerar a diagonal) de LU, sendo que cada elemento de sua diagonal de U deve valer 1.
Devolve o valor de ||x ||. Você pode usar a função fabs (double a) da biblioteca de C para calcular o valor absoluto de a.
Imprime o vetor x com n elementos.
Imprime a matriz quadrada A de ordem n.
Imprima a saída do seu programa para a seguinte entrada:
A: uma matriz 10×10 (obs.: .7030 representa 0.7030);
y: um vetor de 10 elementos.
|