Lista 07 · Eliminação de Gauss¶
Acompanha o capítulo 7.
Sistemas lineares em circuitos, química e economia: primeiro o escalonamento à
mão, depois os laços, depois o pivotamento. Confira sempre com A @ x.
Como esta lista funciona
Abra o caderno no Colab, escreva a sua solução no lugar do # TODO e rode a
célula de teste logo abaixo. Ela mesma diz o que passou e o que falhou — você
não precisa esperar correção de ninguém.
O código de cada exercício também está aqui embaixo, caso você prefira colar num editor local. Os testes comparam números com tolerância.
Exercícios marcados com ✏️ são à mão, no papel, com 4 casas decimais — como na parte em papel das avaliações.
Exercício 01¶
✏️ À mão. Resolva por eliminação de Gauss (sem trocar linhas):
a) Escreva a matriz \(A\) e o vetor \(b\).
b) Faça a eliminação: diga os fatores usados em cada passo e escreva a matriz triangular e o novo \(b\).
c) Faça a substituição de trás para frente.
d) Confira substituindo a resposta nas três equações.
Exercício 02¶
Escreva eliminacao(A, b), que faz a fase de eliminação de Gauss (sem trocar
linhas) e devolve a tupla (U, c): a matriz triangular superior e o lado direito
transformado. Não modifique A nem b: trabalhe em cópias (.copy()).
import numpy as np
def eliminacao(A, b):
"""Triangulariza A x = b (sem pivotamento). Devolve (U, c), sem mexer em A e b."""
U = A.copy()
c = b.copy()
n = len(c)
# TODO: para cada coluna k, para cada linha i abaixo: fator e subtração
return (U, c)
# --- testes (não altere) ---
import numpy as np
A = np.array([[2.0, 1.0, -1.0], [-3.0, -1.0, 2.0], [-2.0, 1.0, 2.0]])
b = np.array([8.0, -11.0, -3.0])
U, c = eliminacao(A, b)
esperado_U = [[2, 1, -1], [0, 0.5, 0.5], [0, 0, -1]]
for i in range(3):
for j in range(3):
assert abs(U[i, j] - esperado_U[i][j]) < 1e-12, f"U[{i}, {j}] = {U[i, j]}"
for i in range(3):
assert abs(c[i] - [8, 1, 1][i]) < 1e-12, f"c[{i}] = {c[i]}"
assert A[1, 0] == -3.0 and b[1] == -11.0, "A e b originais não podem mudar: use .copy()"
print("Exercício 02: todos os testes passaram!")
Exercício 03¶
Escreva substituicao(U, c), que resolve um sistema triangular superior de trás
para frente:
import numpy as np
def substituicao(U, c):
"""Resolve U x = c, com U triangular superior, de trás para frente."""
n = len(c)
x = np.zeros(n)
# TODO: for i in range(n - 1, -1, -1): comece com c[i], subtraia U[i, j] * x[j]
# para j depois de i e divida por U[i, i]
return x
# --- testes (não altere) ---
import numpy as np
U = np.array([[2.0, 1.0, -1.0], [0.0, 0.5, 0.5], [0.0, 0.0, -1.0]])
c = np.array([8.0, 1.0, 1.0])
x = substituicao(U, c)
for i in range(3):
assert abs(x[i] - [2, 3, -1][i]) < 1e-12, f"x = {x}"
x = substituicao(np.array([[4.0]]), np.array([10.0]))
assert abs(x[0] - 2.5) < 1e-12, "sistema de uma equação só"
print("Exercício 03: todos os testes passaram!")
Exercício 04¶
Pivotamento parcial. Escreva gauss_pivotamento(A, b), que resolve \(A\,x = b\)
por eliminação de Gauss, mas, antes de zerar cada coluna \(k\), troca a linha \(k\)
pela linha (de \(k\) para baixo) com o maior valor absoluto na coluna \(k\) — nos
dois, A e b.
Para trocar duas linhas de uma matriz, guarde uma cópia de uma delas:
Teste no sistema do capítulo, com o pivô \(10^{-17}\): sem pivotamento, \(x\) sai 0; com pivotamento, sai 1.
import numpy as np
def gauss_pivotamento(A, b):
"""Resolve A x = b por Gauss com pivotamento parcial."""
A = A.copy()
b = b.copy()
n = len(b)
# TODO: para cada coluna k: ache a linha p (de k para baixo) com o maior
# abs(A[p, k]); troque as linhas k e p em A e em b; depois elimine.
# No fim, a substituição de trás para frente.
pass
# --- testes (não altere) ---
import numpy as np
A = np.array([[1e-17, 1.0], [1.0, 1.0]])
b = np.array([1.0, 2.0])
x = gauss_pivotamento(A, b)
assert x is not None, "faltou o return?"
assert abs(x[0] - 1) < 1e-12 and abs(x[1] - 1) < 1e-12, f"com pivotamento, x = (1, 1) (veio {x})"
A = np.array([[0.0, 2.0, 1.0], [1.0, 1.0, 1.0], [2.0, 1.0, 3.0]])
b = np.array([5.0, 6.0, 13.0])
x = gauss_pivotamento(A, b)
assert np.max(A @ x - b) < 1e-12 and np.min(A @ x - b) > -1e-12, "pivô zero na primeira linha"
print("Exercício 04: todos os testes passaram!")
Exercício 05¶
Conferir sempre. Escreva residuo_maximo(A, x, b), que calcula o resíduo
\(r = b - A\,x\) (com @) e devolve o maior valor absoluto entre os elementos de
\(r\). Um resíduo perto de \(10^{-15}\) quer dizer que \(x\) resolve o sistema; um
resíduo grande quer dizer que não.
def residuo_maximo(A, x, b):
"""O maior |b_i - (A x)_i|: quanto a resposta erra ao ser substituída."""
# TODO: r = b - A @ x; depois o padrão extremo com abs
pass
# --- testes (não altere) ---
import numpy as np
A = np.array([[2.0, 1.0], [1.0, 3.0]])
b = np.array([3.0, 5.0])
assert residuo_maximo(A, np.array([0.8, 1.4]), b) < 1e-12, "(0.8, 1.4) é a solução"
assert abs(residuo_maximo(A, np.array([1.0, 1.0]), b) - 1.0) < 1e-12, "(1, 1) erra por 1 na segunda equação"
print("Exercício 05: todos os testes passaram!")
Exercício 06¶
Química — balanceamento. Na queima de um hidrocarboneto \(\text{C}_n\text{H}_m\),
Cada elemento dá uma equação, porque os átomos se conservam:
- carbono: \(b = n\);
- hidrogênio: \(2c = m\);
- oxigênio: \(2a = 2b + c\).
Escreva combustao(nC, nH), que monta esse sistema com as incógnitas na ordem
\((a, b, c)\) e o resolve com np.linalg.solve.
import numpy as np
def combustao(nC, nH):
"""Coeficientes (a, b, c) de CnHm + a O2 -> b CO2 + c H2O."""
# TODO: uma linha da matriz por elemento (C, H, O), com as incógnitas a, b, c;
# passe tudo que tem incógnita para a esquerda
pass
# --- testes (não altere) ---
r = combustao(3, 8)
assert r is not None, "faltou o return?"
for i in range(3):
assert abs(r[i] - [5, 3, 4][i]) < 1e-12, f"propano: veio {r}"
r = combustao(8, 18)
for i in range(3):
assert abs(r[i] - [12.5, 8, 9][i]) < 1e-12, f"octano: veio {r}"
print("Exercício 06: todos os testes passaram!")
Exercício 07¶
Economia — o modelo de Leontief. Numa economia de dois setores (agricultura e indústria), para produzir R$ 1 de agricultura gastam-se R$ 0,20 de agricultura e R$ 0,40 de indústria; para produzir R$ 1 de indústria, R$ 0,30 de agricultura e R$ 0,10 de indústria. A matriz \(A\) guarda esses consumos (coluna = quem produz). Para atender uma demanda final \(d\) (o que vai para a população), a produção total \(x\) tem de cobrir o consumo interno e a demanda:
em que \(I - A\) tem \(1 - A_{ii}\) na diagonal e \(-A_{ij}\) fora dela.
Escreva producao_total(A, demanda), que monta a matriz \(I - A\) com dois laços —
comece com M = np.zeros((n, n)), uma matriz \(n \times n\) de zeros — e resolve o
sistema.
A = np.array([[0.2, 0.3], [0.4, 0.1]])
producao_total(A, np.array([100.0, 50.0])) # -> ≈ [175. 133.33]
import numpy as np
def producao_total(A, demanda):
"""Produção x de cada setor para atender a demanda final: (I - A) x = demanda."""
n = len(demanda)
M = np.zeros((n, n))
# TODO: dois laços (i e j): na diagonal, 1 - A[i, j]; fora dela, -A[i, j].
# Depois resolva M x = demanda.
pass
# --- testes (não altere) ---
import numpy as np
A = np.array([[0.2, 0.3], [0.4, 0.1]])
x = producao_total(A, np.array([100.0, 50.0]))
assert x is not None, "faltou o return?"
esperado = [175.0, 133.33333333333334]
for i in range(2):
assert abs(x[i] - esperado[i]) < 1e-9, f"veio {x}"
assert A[0, 0] == 0.2, "não mexa na matriz A"
print("Exercício 07: todos os testes passaram!")