Corrija o código fornecido adicionando um critério de parada correto baseado no erro entre as iterações sucessivas.
Por exemplo:
Teste
Resultado
A = np.array([[5, 1], [2, 4]], dtype=float)
b = np.array([3, 6], dtype=float)
x0 = np.zeros(2)
print(gauss_seidel(A, b, x0))
[0.33333333 1.33333333]
Resposta: (penalty regime: 10, 20, … %)
Reset answer
def gauss_seidel(A, b, x0, max_iter=100):
n = len(b)
x = x0.copy()
for _ in range(max_iter):
for i in range(n):
x[i] = (b[i] - sum(A[i][j] * x[j] for j in range(n) if j != i)) / A[i][i]
return x
Passo 1
O enunciado nos dá uma implementação de Gauss–Seidel sem critério de parada (além de um número máximo de iterações). Queremos adicionar um critério baseado no erro entre duas iterações sucessivas do vetor solução, isto é, parar quando
Se err<tol, consideramos que o método já convergiu satisfatoriamente e interrompemos o laço.
Passo 3
Para implementar: . Antes de atualizar cada componente, copiamos o vetor antigo: \(x_old =\) x.copy(). . Depois de atualizar todas as componentes de x, calculamos err \(=\) np.linalg.norm(x - \(x_old\), np.inf). . Se err < tol, fazemos break para sair do laço principal.
Resposta
import numpy as np
defgauss_seidel(A, b, x_0, tol=1e-8, max_iter=100):
"""
Resolve \(Ax=b\) pelo método de Gauss--Seidel.
Critério de parada: \(\|x_{new} - x_{old}\|_{\infty} < \text{tol}\)
"""
n = len(b)
x = x_0.copy()
for k inrange(max_iter):
x_old = x.copy()
for i inrange(n):
# soma de A[i,j]*x[j] para j \neq i
s = sum(A[i, j] * x[j] for j inrange(n) if j != i)
x[i] = (b[i] - s) / A[i, i]
# erro infinito diferença entre iterações
err = np.linalg.norm(x - x_old, np.inf)
if err < tol:
# Método convergiuprint(f"Convergiu em {k+1} iterações com erro {err:.2e}")
breakreturn x
# Exemplo de usoif __name__ == "__main__":
A = np.array([[5, 1], [2, 4]], dtype=float)
b = np.array([3, 6], dtype=float)
x_0 = np.zeros(2)
sol = gauss_seidel(A, b, x_0)
print("Solução aproximada:", sol)