Testes: test_sistemaslineares

_Sem docstring de módulo._

Conteúdo dos testes:

  1import numpy as np
  2import pytest
  3from codigos import sistemaslineares as sl
  4
  5
  6def test_eliminacao_sem_pivotamento_basic():
  7    """Verifica solução de um sistema 2x2 pelo método de Gauss sem pivotamento.
  8
  9    - Matriz A e vetor b simples; compara a solução retornada com
 10      `numpy.linalg.solve` para garantir correção numérica.
 11    """
 12    A = np.array([[2.0, 1.0], [4.0, -6.0]])
 13    b = np.array([3.0, -2.0])
 14    x, Atri, bmod, flag = sl.eliminacao_gauss_sem_pivotamento(A, b)
 15    assert x is not None
 16    assert np.allclose(x, np.linalg.solve(A, b), atol=1e-12)
 17
 18
 19def test_eliminacao_sem_pivotamento_pivo_zero():
 20    """Garante que o método sem pivotamento detecta pivô zero e retorna falha.
 21
 22    - Matriz com zero na diagonal principal (pivô) deve provocar retorno
 23      com solução ``None`` e erro sinalizado.
 24    """
 25    A = np.array([[0.0, 1.0], [0.0, 2.0]])
 26    b = np.array([1.0, 2.0])
 27    x, *_ = sl.eliminacao_gauss_sem_pivotamento(A, b)
 28    assert x is None
 29
 30
 31def test_eliminacao_com_pivotamento_basic():
 32    """Verifica que a eliminação com pivotamento resolve sistemas que
 33    necessitam troca de linhas para evitar pivôs nulos.
 34    """
 35    A = np.array([[0.0, 2.0], [1.0, 3.0]])
 36    b = np.array([1.0, 4.0])
 37    x, A_mod, b_mod, flag = sl.eliminacao_gauss_com_pivotamento(A, b)
 38    assert x is not None
 39    assert flag is False
 40    assert np.allclose(x, np.linalg.solve(A, b), atol=1e-12)
 41
 42
 43def test_lu_sem_pivot_reconstructs_A():
 44    """Verifica que a decomposição LU sem pivotamento reconstrói A (L@U == A)."""
 45    A = np.array([[4.0, 3.0], [6.0, 3.0]])
 46    L, U = sl.lu_sem_pivot(A, np.zeros(2))
 47    assert np.allclose(L @ U, A, atol=1e-12)
 48
 49
 50def test_lu_com_pivot_reconstructs_PA():
 51    """Verifica que para LU com pivotamento vale P @ A == L @ U."""
 52    A = np.array([[0.0, 2.0], [1.0, 3.0]])
 53    P, L, U = sl.lu_com_pivot(A, np.zeros(2))
 54    assert np.allclose(P @ A, L @ U, atol=1e-12)
 55
 56
 57def test_calcular_residuo_zero_for_exact_solution():
 58    """Garante que o resíduo r = b - A x é zero quando x é solução exata."""
 59    A = np.array([[2.0, 0.0], [0.0, 5.0]])
 60    x = np.array([1.0, -1.0])
 61    b = A @ x
 62    r = sl.calcular_residuo(A, x, b)
 63    assert np.allclose(r, np.zeros_like(r), atol=1e-12)
 64
 65
 66def test_eliminacao_sem_pivotamento_flag_error():
 67    """Verifica que a função sinaliza erro (flag True) quando detecta pivô zero."""
 68    A = np.array([[0.0, 1.0], [0.0, 2.0]])
 69    b = np.array([1.0, 2.0])
 70    x, Atri, bmod, flag = sl.eliminacao_gauss_sem_pivotamento(A, b)
 71    assert x is None
 72    assert flag is True
 73
 74
 75def test_eliminacao_com_pivotamento_impossible():
 76    """Caso degenerado: matriz nula deve ser marcada como impossível pelo método."""
 77    A = np.array([[0.0, 0.0], [0.0, 0.0]])
 78    b = np.array([1.0, 2.0])
 79    x, A_mod, b_mod, flag = sl.eliminacao_gauss_com_pivotamento(A, b)
 80    assert x is None
 81    assert flag is True
 82
 83
 84def test_forward_solve_basic():
 85    """Testa substituição progressiva (forward solve) para uma L triangular inferior."""
 86    L = np.array([[1.0, 0.0], [0.5, 1.0]])
 87    b = np.array([2.0, 3.0])
 88    y = sl.forward_solve(L, b)
 89    expected = np.array([2.0, 2.0])  # 2, 3 - 0.5*2
 90    assert np.allclose(y, expected)
 91
 92
 93def test_backward_solve_basic():
 94    """Testa substituição regressiva (backward solve) para uma U triangular superior."""
 95    U = np.array([[2.0, 1.0], [0.0, 3.0]])
 96    y = np.array([5.0, 3.0])
 97    x = sl.backward_solve(U, y)
 98    expected = np.array([2.0, 1.0])  # From U x = y: x1=3/3=1, x0=(5-1*1)/2=2
 99    assert np.allclose(x, expected)
100
101
102def test_lu_sem_pivot_zero_pivot_raises():
103    """Verifica que LU sem pivotamento lança ZeroDivisionError quando pivô é zero."""
104    A = np.array([[0.0, 1.0], [1.0, 2.0]])
105    with pytest.raises(ZeroDivisionError):
106        sl.lu_sem_pivot(A, None)
107
108
109def test_gauss_com_pivotamento_example_1():
110    """Exemplo realista (3x3) testando eliminação com pivotamento.
111
112    - Checa consistência A @ x == b e flag == False para sucesso
113    """
114    A = np.array([[8.0, 2.0, -2.0], [10.0, 2.0, 4.0], [12.0, 2.0, 2.0]])
115    b = np.array([-2.0, 4.0, 6.0])
116    x, A_mod, b_mod, flag = sl.eliminacao_gauss_com_pivotamento(A, b)
117    assert x is not None
118    assert flag is False
119    assert np.allclose(A @ x, b, atol=1e-12)
120
121
122def test_gauss_sem_pivotamento_example_2():
123    """Exemplo 3x3 testando eliminação sem pivotamento retorna solução correta."""
124    A = np.array([[8.0, 4.0, -1.0], [-2.0, 5.0, 1.0], [2.0, -1.0, 6.0]])
125    b = np.array([11.0, 4.0, 7.0])
126    x, Atri, bmod, flag = sl.eliminacao_gauss_sem_pivotamento(A, b)
127    assert x is not None
128    assert np.allclose(A @ x, b, atol=1e-12)
129    assert flag is False  # success
130
131
132def test_lu_sem_pivot_example_3():
133    """Outro exemplo 3x3 verificando LU sem pivotamento e solução resultante."""
134    A = np.array([[2.0, -6.0, -1.0], [-3.0, -1.0, 7.0], [-8.0, 1.0, -2.0]])
135    b = np.array([-38.0, -34.0, -20.0])
136    L, U = sl.lu_sem_pivot(A, b)
137    assert np.allclose(L @ U, A, atol=1e-12)
138    # Solve and check
139    y = sl.forward_solve(L, b)
140    x = sl.backward_solve(U, y)
141    assert np.allclose(A @ x, b, atol=1e-12)
142
143
144def test_gauss_sem_pivotamento_example_4():
145    """Exemplo 3x3 com resultados conhecidos para validação do método sem pivotamento."""
146    A = np.array([[10.0, 2.0, -1.0], [-3.0, -6.0, 2.0], [1.0, 1.0, 5.0]])
147    b = np.array([27.0, -61.5, -21.5])
148    x, Atri, bmod, flag = sl.eliminacao_gauss_sem_pivotamento(A, b)
149    assert x is not None
150    assert np.allclose(A @ x, b, atol=1e-12)
151
152
153def test_gauss_com_pivotamento_5x5():
154    """Caso 5x5 retirado do conjunto de exemplos interativos, valida convergência."""
155    A = np.array([
156        [0.0, 1.0, 3.0, 2.0, 4.0],
157        [8.0, -2.0, 9.0, -1.0, 2.0],
158        [5.0, 1.0, 1.0, 7.0, 2.0],
159        [-2.0, 4.0, 5.0, 1.0, 0.0],
160        [7.0, -3.0, 2.0, -4.0, 1.0]
161    ])
162    b = np.array([3.0, -5.0, 6.0, -1.0, 8.0])
163    x, A_mod, b_mod, flag = sl.eliminacao_gauss_com_pivotamento(A, b)
164    assert x is not None
165    assert flag is False
166    assert np.allclose(A @ x, b, atol=1e-12)
167
168
169def test_input_validation_non_square_A():
170    """Validação: matriz não quadrada deve levantar ValueError."""
171    A = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])  # 2x3
172    b = np.array([1.0, 2.0])
173    with pytest.raises(ValueError, match="A deve ser uma matriz quadrada 2D"):
174        sl.eliminacao_gauss_sem_pivotamento(A, b)
175
176
177def test_input_validation_b_wrong_shape():
178    """Validação: vetor b com tamanho incompatível deve levantar ValueError."""
179    A = np.array([[1.0, 2.0], [3.0, 4.0]])
180    b = np.array([1.0, 2.0, 3.0])  # wrong length
181    with pytest.raises(ValueError, match="b deve ser um vetor 1D com comprimento igual ao número de linhas de A"):
182        sl.eliminacao_gauss_sem_pivotamento(A, b)
183
184
185def test_input_validation_b_not_1d():
186    """Validação: vetor b com dimensões incorretas (2D) deve levantar ValueError."""
187    A = np.array([[1.0, 2.0], [3.0, 4.0]])
188    b = np.array([[1.0], [2.0]])  # 2x1 instead of 1d
189    with pytest.raises(ValueError, match="b deve ser um vetor 1D"):
190        sl.eliminacao_gauss_sem_pivotamento(A, b)
191
192
193def test_montar_sistema_valores_eof(monkeypatch):
194    """Se ocorrer EOF durante a leitura interativa, a função retorna None.
195
196    - Simula `input` que levanta EOFError e verifica comportamento seguro.
197    """
198    def raise_eof(prompt=''):
199        raise EOFError
200    monkeypatch.setattr('builtins.input', raise_eof)
201    assert sl.montar_sistema_valores() is None

Resumo das funções de teste:

  • test_eliminacao_sem_pivotamento_basic: Verifica solução de um sistema 2x2 pelo método de Gauss sem pivotamento.

  • test_eliminacao_sem_pivotamento_pivo_zero: Garante que o método sem pivotamento detecta pivô zero e retorna falha.

  • test_eliminacao_com_pivotamento_basic: Verifica que a eliminação com pivotamento resolve sistemas que

  • test_lu_sem_pivot_reconstructs_A: Verifica que a decomposição LU sem pivotamento reconstrói A (L@U == A).

  • test_lu_com_pivot_reconstructs_PA: Verifica que para LU com pivotamento vale P @ A == L @ U.

  • test_calcular_residuo_zero_for_exact_solution: Garante que o resíduo r = b - A x é zero quando x é solução exata.

  • test_eliminacao_sem_pivotamento_flag_error: Verifica que a função sinaliza erro (flag True) quando detecta pivô zero.

  • test_eliminacao_com_pivotamento_impossible: Caso degenerado: matriz nula deve ser marcada como impossível pelo método.

  • test_forward_solve_basic: Testa substituição progressiva (forward solve) para uma L triangular inferior.

  • test_backward_solve_basic: Testa substituição regressiva (backward solve) para uma U triangular superior.

  • test_lu_sem_pivot_zero_pivot_raises: Verifica que LU sem pivotamento lança ZeroDivisionError quando pivô é zero.

  • test_gauss_com_pivotamento_example_1: Exemplo realista (3x3) testando eliminação com pivotamento.

  • test_gauss_sem_pivotamento_example_2: Exemplo 3x3 testando eliminação sem pivotamento retorna solução correta.

  • test_lu_sem_pivot_example_3: Outro exemplo 3x3 verificando LU sem pivotamento e solução resultante.

  • test_gauss_sem_pivotamento_example_4: Exemplo 3x3 com resultados conhecidos para validação do método sem pivotamento.

  • test_gauss_com_pivotamento_5x5: Caso 5x5 retirado do conjunto de exemplos interativos, valida convergência.

  • test_input_validation_non_square_A: Validação: matriz não quadrada deve levantar ValueError.

  • test_input_validation_b_wrong_shape: Validação: vetor b com tamanho incompatível deve levantar ValueError.

  • test_input_validation_b_not_1d: Validação: vetor b com dimensões incorretas (2D) deve levantar ValueError.

  • test_montar_sistema_valores_eof: Se ocorrer EOF durante a leitura interativa, a função retorna None.