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.