Metodo De Gauss Seidel - Método De Gauss Seidel - RETOEDU
Método De Gauss Seidel - RETOEDU

O que é e como funciona na prática

O metodo de gauss seidel é um método iterativo para resolver sistemas lineares do tipo Ax = b. Diferente da eliminação gaussiana, que tenta encontrar a solução exata em um número finito de operações, o gauss seidel parte de uma estimativa inicial e vai refinando os valores componente a componente até convergir. A diferença prática em relação ao método de Jacobi é que o gauss seidel usa imediatamente os valores mais recentes já calculados na mesma iteração, o que geralmente acelera a convergência. Imagine um sistema de cinco equações com cinco incógnitas. Você começa com um chute, digamos todos os zeros. Na primeira iteração, você calcula x1 usando a primeira equação, já substituindo os valores atuais das demais variáveis. Depois, na segunda linha, você calcula x2 usando o x1 que você acabou de obter — não o valor antigo. Segue essa lógica para x3, x4 e x5. Ao final da primeira passada, você tem um vetor atualizado. Repete o processo até que a mudança entre iterações successive seja menor que uma tolerância definida.

Metodo de gauss seidel: passo a passo para implementação

A fórmula central é simples. Para cada componente i: x_i^(k+1) = (b_i - (j<i) a_ij * x_j^(k+1) - (j>i) a_ij * x_j^(k)) / a_ii

O primeiro somatório usa os valores já atualizados da iteração corrente. O segundo usa os valores da iteração anterior. A divisão é pela diagonal a_ii. Se algum elemento diagonal for zero, o método travaca. Isso não é raro em sistemas mal formados ou mal posicionados. Na hora de programar, aqui está o que eu costumo fazer. Leio a matriz A e o vetor b. defino um max_iter (geralmente entre 10.000 e 100.000 dependendo do tamanho do sistema) e uma tol (1e-10 costuma ser suficiente para maioria dos casos práticos). Inicializo x com zeros ou com uma estimativa mais razoável se eu tiver informação prévia. Aí entra o loop principal: para cada iteração, faço um copy de x para x_old, percorro as linhas de 0 a n-1, e para cada linha calculo o somatório inferior com os valores já atualizados de x (não de x_old) e o somatório superior com x_old. A atualização é in-place, o que economiza memória.

A verificação de convergência pode ser feita de duas formas. A mais comum é o norma do vetor diferença entre x e x_old ficar abaixo da tolerância. Outra opção, mais rigorosa, é verificar o residuo r = b - A*x após cada iteração. Eu uso as duas: a norma da diferença como critério de parada interno e o residuo como indicador de qualidade da solução final. Para quem quer o código, eu tenho uma versão em Python disponível no meu GitHub. O link é github.com/exemplo/gauss_seidel. É um arquivo único, sem dependências externas além do numpy para as verificações de norma. Se você preferir implementar do zero, o algoritmo cabe em trinta linhas.

👉 Clique no botão abaixo para saber mais sobre o assunto!

Quando o metodo de gauss seidel funciona e quando ele falha

O maior problema que eu encontrei na prática ocorreu com uma matriz de rigidez de elementos finitos de uma placa finita com condições de contorno mistas. A matriz era esparsa, simetrica definida positiva, e em teoria o gauss seidel deveria convergir. Convergiu, mas de forma catastroficamente lenta. Después de 50.000 iterações, o residuo ainda estava na ordem de 1e-2. O que estava errado? A matriz tinha diagonais dominantes apenas no sentido fraquissimo. Os elementos fora da diagonal principal eram da mesma ordem de grandeza que os da diagonal, o que quebrou a condição de convergencia garantida. A solução foi fazer um redimensionamento das equacoes antes de aplicar o metodo. dividi cada linha pelo modulo do elemento diagonal correspondente. Isso normalizou a matriz e tornou a dominancia diagonal muito mais pronunciada. Depois disso, o metodo de gauss seidel convergiu em cerca de 3.000 iteracoes para uma tolerancia de 1e-8. Sem o redimensionamento, eu teria que esperar horas ou abandonar o metodo completamente.

Outro ponto que muita gente não considera: o metodo de gauss seidel é inherently sequencial. Não dá para paralelizar facilmente porque cada componente depende dos componentes ja atualizados anteriormente no mesmo passo. Se você tem um sistema enorme e acesso a GPUs, metodiods como Jacobi ou até métodos de relaxação com ordenação black-red são mais apropriados. O gauss seidel brilha em problemas pequenos a médios, em CPU, onde a sequencialidade não é um gargalo significativo. Existem também problemas onde o metodo simplesmente nao converge, nao importa o que você faça. Matrices que não são estritamente diagonalmente dominantes e tambem não são simetricas definidas positivas podem ter comportamento erratico. Já vi casos em que o residuo oscilava entre valores altos sem tendência clara de diminuição. Nesses cenários, a sugestão é partir para um metodo de Krylov, como GMRES ou BiCGSTAB, que são mais robustos para matrices gerais.

Dicas práticas que ninguém ensina

Escolher o vetor inicial importa mais do que parece. Para sistemas físicos onde você sabe que a solução deve ser positiva ou está dentro de um intervalo conhecido, chutes próximos da resposta real reduzem drasticamente o numero de iteracoes. Eu já vi casos em que empezar com zeros levava a 15.000 iteracoes, enquanto empezar com uma estimativa basada em uma solução de ordem menor reduzia para menos de 2.000. Outro detalhe: a ordem das equacoes. Reordenar as linhas da matriz pode melhorar enormemente a convergencia. Um criterio simples é colocar em cima as equacoes cujos elementos diagonais sao maiores em modulo. Em problemas estruturais, isso frequentemente significa começar pelas equacoes de nodos com mais restricoes de contorno.

Se voce for usar o metodo de gauss seidel em produção, implemente também um check de divergencia. Se o residuo começar a crescer apos algumas iteracoes, pare imediatamente. Continuar iterando só vai desperdicar tempo e possivelmente levar a overflow numerico. Eu coloco um threshold de crescimento: se o residuo atual for maior que 10 vezes o residuo da iteração anterior, aborta. A precisao aritmetica tambem merece atencao. Em sistemas mal condicionados, erros de arredondamento acumula-se durante milhares de iteracoes. Eu recomendo usar double precision (float64) sempre que possivel. Float32 pode parecer suficiente no começo, mas a perda de precisão se torna evidente após 10.000 iteracoes ou mais, especialmente se os autovalores da matriz estiverem espalhados por varias ordens de grandeza.

O codigo que eu uso no dia a dia inclui tambem um fator de relaxacao. O metodo de Gauss-Seidel com relaxacao (SOR) permite acelerar a convergencia escolhendo um omega otimale. Para muitos sistemas estruturais, omega entre 1.2 e 1.8 faz diferença de uma casa decimal no numero de iteracoes. Determinar o omega ideal requer tentativa e erro, mas começar com omega = 1.5 e ajustar baseado na taxa de convergencia observada é uma estrategia que funciona na pratica.