LU com pivoteamento
Como computar a decomposição LU com pivoteamento parcial
Vamos lá?
Na aula passada vimos em um exemplo como a ordem das equações pode influenciar bastante o resultado numérico da resolução de um sistema linear, quando trabalhamos em aritmética com precisão finita. Nesta aula vamos incorporar à decomposição LU a estratégia de pivoteamento parcial, para mitigar potenciais problemas numéricos.
- 1
- 2
- 3
No que consiste o pivoteamento parcial?
Como é construída a matriz de permutação?
Para reduzir erros numéricos quando resolvemos um sistema linear em aritmética de precisa finita, devemos evitar trabalhar com pivôs pequenos durante o processo de escalonamento. Isso vale tanto para a eliminação de Gauss, quanto para a decomposição LU. Um exemplo de como a magnitude relativa do pivô tem influência na solução numérica do sistema linear foi visto na aula passada.
A forma tradicional de se fazer isso é através da estratégia de pivoteamento parcial. Relembre que o algoritmo para decomposição LU sem pivoteamento é:
- $U \leftarrow A,$ $L \leftarrow I$
- Para $j=1,2,\ldots,n-1$
- Se $u_{jj} = 0,$ então $A$ não tem decomposição LU. FIM.
- Para $i=j+1,\ldots,n$
- $l_{ij} \leftarrow u_{ij} / u_{jj}$
- $u_{ij} \leftarrow 0$
- Para $k=j+1,\ldots, n$
- $u_{ik} \leftarrow u_{ik} - l_{ij} u_{jk}$
Neste algoritmo, quando iniciamos o passo $j,$ ou seja, quando formos eliminar os elementos abaixo da diagonal da coluna $j,$ o pivô é $u_{jj}$ (nesse ponto, $U$ é a matriz temporária, obtida no processo de escalonamento das colunas anteriores). A estratégia de pivoteamento parcial consiste em trocar a linha do pivô $j,$ por alguma das linhas abaixo dela, digamos a linha $k,$ determinada de forma que \begin{equation}\label{pivocond} |u_{kj}| =\max_{j\le i \le n} |u_{ij}|. \end{equation} Feita a troca das linhas (caso tenha sido preciso), o algoritmo segue como antes. Para registrar essa troca de linhas, precisamos de uma nova matriz, denominada matriz de permutação $P.$ Essa matriz nada mais é que a matriz identidade, sobre a qual se realizam as mesmas operações de troca de linhas que tenham sido realizadas em $U.$
O algoritmo para a decomposição LU com pivoteamento parcial fica assim
- $U \leftarrow A,$ $L \leftarrow I$, $P\leftarrow I$
- Para $j=1,2,\ldots,n-1$
- Determine a linha $k$ do pivô, tal que $\eqref{pivocond}$ se cumpra.
- Se $k\neq j,$ então
- $U(j,:) \leftrightarrow U(k,:)$ (troca das linhas $j$ e $k$ de $U$)
- $P(j,:) \leftrightarrow P(k,:)$ (troca das linhas $j$ e $k$ de $P$)
- $L(j,1:j-1) \leftrightarrow L(k,1:j-1)$ (troca dos multiplicadores computados anteriormente)
- Se $u_{jj} = 0,$ não há o que escalonar na coluna $j.$ Volte para o passo 2.
- Para $i=j+1,\ldots,n$
- $l_{ij} \leftarrow u_{ij} / u_{jj}$
- $u_{ij} \leftarrow 0$
- Para $k=j+1,\ldots, n$
- $u_{ik} \leftarrow u_{ik} - l_{ij}\, u_{jk}$
Vamos detalhar alguns passos do algoritmo acima. No passo 2.1 determinamos a linha $k,$ abaixo da linha $j$, que contem o maior elemento em módulo abaixo da diagonal. Se $k\neq j,$ então será necessário fazer o pivoteamento. Isto é feito nos passos de 2.2.1 a 2.2.3. Por simplicidade, estamos usando aqui a notação própria do Octave, a saber $A(j,:)$ representa a linha $j$ da matriz $A$ e $A(j,p:q)$ representa a linha $j$ de $A,$ apenas entre as colunas $p$ e $q.$ Os passos 2.2.1 e 2.2.2 são apenas as trocas de linhas de $U$ e $P$ como já havíamos comentado. Mas o passo 2.2.3 merece atenção. Nesse passo, estamos trocando as linhas de $j$ e $k$ da matriz $L,$ mas apenas da primeira coluna a até a coluna $j-1,$ pois apenas essas foram computadas nesse momento da execução do algoritmo. Essa troca é necessária pois cada elemento da matriz $L$ armazena um multiplicador que estava relacionado a duas linhas no processo de escalonamento (a linha pivô e a linha onde a operação de eliminação foi aplicada). Caso as linhas troquem de ordem por conta do pivoteamento, os multiplicadores também precisam ser trocados, pois do contrário essas associação entre multiplicadores e linhas ficariam incorretas.
No passo 2.3, após o pivoteamento, verificamos se o pivô é nulo. Se este for o caso, isto significa que todos os elementos abaixo da diagonal também são nulos (por quê?). Logo, não há nada mais a ser eliminado e podemos passar para o processo de eliminação dos elementos na próxima coluna.
Perceba que agora não há mais a possibilidade do algoritmo interromper sua execução antes do fim e, como consequência, toda matriz tem decomposição LU com pivoteamento parcial. Isso é diferente do que acontecia com decomposição LU sem pivoteamento, que pode existir ou não.
Ao final da execução do algoritmo acima, temos três matrizes $P,$ $L$ e $U$, que satisfazem $$ PA=LU. $$ Para resolver um sistema linear $Ax=b,$ premultiplicamos ambos os lados dessa equação por $P,$ assim o produto $PA$ pode ser substituído por $LU.$ Chamando $Ux=y$ temos $$ \left\{ \begin{array}{l} L y = Pb, \\ Ux = y. \end{array} \right. $$ Ou seja, o sistema original é reescrito como dois sistemas lineares, um triangular inferior e outro triangular superior.
Antes de concluir, um último comentário sobre a implementação computacional deste algoritmo. Caso a matriz original $A$ não seja mais necessária após sua decomposição nos fatores $L,$ $U$ e $P,$ podemos utilizar o espaço de memória que abrigava $A$ para armazenar os fatores $L$ e $U.$ Como essas duas matrizes são triangulares, uma inferior e outra superior, a porção triangular inferior de $A$ abrigará $L,$ enquanto que a porção triangular superior abrigará $U.$ Claro que falta espaço para armazenar os elementos da diagonal de $L$ e $U.$ Porém, a diagonal de $L$ é constante e igual a $1,$ não precisando ser armazenada. Com essa estratégia, não é necessário espaço adicional para os fatores $L$ e $U$ e o algoritmo acima fica até um pouco mais compacto (ainda mais usando operações vetoriais do Octave!).
- $P\leftarrow I$
- Para $j=1,2,\ldots,n-1$
- Determine a linha $k$ do pivô, tal que $\eqref{pivocond}$ se cumpra.
- Se $k\neq j,$ então
- $A(j,:) \leftrightarrow A(k,:)$ (troca das linhas $j$ e $k$ de $L$ e $U$ ao mesmo tempo)
- $P(j,:) \leftrightarrow P(k,:)$ (troca das linhas $j$ e $k$ de $P$)
- Se $A(j,j) = 0,$ não há o que escalonar na coluna $j.$ Volte para o passo 2.
- $A(j+1:n,j) \leftarrow A(j+1:n,j) / A(j,j)$ (multiplicadores)
- Para $i=j+1,\ldots,n$
- $A(i,j+1:n) \leftarrow A(i,j+1:n) - A(i,j) A(j,j+1:n)$
Na próxima aula, veremos um exemplo prático, computado passo a passo, onde a decomposição LU com pivoteamento parcial é computada e e empregada na resolução do sistema linear.
Referência
Lloyd N. Trefethen e David Bau, III. Numerical Linear Algebra. SIAM, 1997.
1. Se $ L = \left[ \begin{array}{cccc} 1 & 0 & 0 & 0 \\ 1/5 & 1 & 0 & 0 \\ -2/5\hphantom{-} & 3/4 & 1 & 0 \\ 4/5 & 2/4 & -1/2\hphantom{-} & 1 \end{array}\right],$ $U= \left[ \begin{array}{rrrr} 5 & -2 & 2 & 1 \\ 0 & 2 & 1 & -5 \\ 0 & 0 & 1 & 6 \\ 0 & 0 & 0 & -3 \end{array}\right]$ e $P =\begin{bmatrix} 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} $ são os fatores da decomposição LU com pivoteamento de uma matriz $A,$ resolva o sistema linear $Ax=b$, para $b=(-5, 5, -7, -4.5)^T.$
A solução do primeiro sistema, $Ly=Pb$, é $y=(5,-8,3,-3)^T$. E a solução de $Ux=y$ é $x=(2,0,-3,1)^T.$
2. Aplique o algoritmo da decomposição LU com pivoteamento parcial à matriz $$ A = \left[ \begin{array}{rrrr} -3.0 & 3.0 & 1.50 & -9.0 \\ 6.0 & 2.0 & -1.00 & 0.0 \\ 1.5 & -1.5 & 0.25 & 4.5 \\ 1.0 & -1.0 & 0.50 & 6.0 \end{array} \right]. $$ Usando os fatores da decomposição, resolva o sistema linear $Ax=b$, para $b = (9, 8, -6.5, -8)^T.$ Quando encontrar a solução, verifique se ela está correta, substituindo-a no sistema linear.
Os fatores da decomposição LU de $A$ são: $$L=\left[\begin{array}{rrrr} 1\; \\ -1/2 & 1\; \\ 1/4 & -1/2 & 1 \\ 1/6 & -1/3 & 1 & 1 \end{array}\right], \quad U = \left[\begin{array}{rrrr} 6& 2& -1& 0\\ & 4& 1& -9\\ & & 1& 0\\ & & & 3 \end{array}\right], \quad \mbox{e} $$ $$P= \left[\begin{array}{cccc} 0 &1 & 0 & 0\\ 1 &0 & 0 & 0\\ 0 &0 & 1 & 0\\ 0 &0 & 0 & 1 \end{array}\right].$$ A solução do sistema é $x=(1/2,3/2,-2,-1)^T.$
3. Reescreva o passo 2.4.3 do segundo algoritmo apresentado usando a notação compacta do Octave. Você deve escrever esse passo sem usar um loop.
$U(i,j+1:n) \leftarrow U(i,j+1:n) - L(i,j) U(j,j+1:n)$