Lista 03 · Derivando dados medidos¶
Acompanha o capítulo 3. Aqui não há fórmula: só tabelas de medições — de uma indústria, de uma pista de aeroporto, de um foguete, de uma epidemia. O \(h\) é a distância entre as medições, e as bordas pedem cuidado.
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 — indústria química. Um reator é desligado e a temperatura do líquido é registrada a cada 5 minutos:
| \(t\) (min) | 0 | 5 | 10 | 15 | 20 |
|---|---|---|---|---|---|
| \(T\) (°C) | 95,0 | 82,4 | 71,6 | 62,3 | 54,3 |
a) Estime a taxa de resfriamento \(dT/dt\) em \(t = 0\), \(t = 10\) e \(t = 20\) min, usando em cada ponto a única fórmula possível (qual?).
b) Qual a unidade da resposta? O que o sinal significa?
c) A taxa fica maior ou menor com o tempo? Isso faz sentido físico?
Exercício 02¶
Escreva derivada_dados(t, y), que devolve um array com a derivada de \(y\) em
cada ponto da tabela: progressiva no primeiro ponto, regressiva no último,
central nos demais. O espaçamento de t pode ser irregular.
import numpy as np
def derivada_dados(t, y):
"""Derivada de y em relação a t, ponto a ponto (array)."""
n = len(t)
d = np.zeros(n)
# TODO: d[0] progressiva; laço de 1 a n-2 com a central (divida por
# t[i+1] - t[i-1], não por 2*h); d[n-1] regressiva
return d
# --- testes (não altere) ---
import numpy as np
d = derivada_dados([0, 1, 3, 4], [0, 1, 9, 16])
assert len(d) == 4, "um valor por ponto da tabela"
assert abs(d[0] - 1) < 1e-9, "borda esquerda: progressiva"
assert abs(d[1] - 3) < 1e-9 and abs(d[2] - 5) < 1e-9, "meio: central com espaçamento irregular"
assert abs(d[3] - 7) < 1e-9, "borda direita: regressiva"
d = derivada_dados(np.array([0.0, 0.5, 1.0]), np.array([2.0, 3.0, 4.0]))
for i in range(3):
assert abs(d[i] - 2) < 1e-9, "a derivada de uma reta é a inclinação em todo ponto"
print("Exercício 02: todos os testes passaram!")
Exercício 03¶
Aviação. Na decolagem, a posição de um avião na pista foi registrada a cada 2 segundos:
| \(t\) (s) | 0 | 2 | 4 | 6 | 8 | 10 |
|---|---|---|---|---|---|---|
| \(x\) (m) | 0 | 12 | 48 | 108 | 192 | 300 |
Escreva velocidade_final_kmh(t, x), que estima a velocidade no último
instante da tabela, em km/h (multiplique m/s por 3,6).
Depois de passar nos testes: os dados seguem \(x = 3t^2\) exatamente. Qual a velocidade verdadeira em \(t = 10\) s? Por que a estimativa ficou abaixo?
def velocidade_final_kmh(t, x):
"""Velocidade no último ponto da tabela, em km/h."""
# TODO: no último ponto só existe o vizinho da esquerda
pass
# --- testes (não altere) ---
t = [0, 2, 4, 6, 8, 10]
x = [0, 12, 48, 108, 192, 300]
assert abs(velocidade_final_kmh(t, x) - 194.4) < 1e-6, "regressiva no último ponto, vezes 3,6"
assert abs(velocidade_final_kmh([0, 1, 2, 3], [0, 5, 10, 15]) - 18) < 1e-6, "5 m/s = 18 km/h"
print("Exercício 03: todos os testes passaram!")
Exercício 04¶
Aeroespacial. A telemetria de um foguete registrou a velocidade a cada 10 segundos, até o fim da queima do motor:
| \(t\) (s) | 0 | 10 | 20 | 30 | 40 | 50 |
|---|---|---|---|---|---|---|
| \(v\) (m/s) | 0 | 45 | 110 | 190 | 260 | 300 |
Escreva aceleracao_maxima(t, v), que devolve a maior aceleração (m/s²)
da tabela. A função derivada_dados já está escrita: use-a e depois
np.max.
Em que instante a aceleração foi máxima? Por que ela cai no fim da queima?
import numpy as np
def derivada_dados(t, y):
"""Derivada de uma tabela: progressiva no início, central no meio,
regressiva no fim. JÁ ESCRITA."""
n = len(t)
d = np.zeros(n)
d[0] = (y[1] - y[0]) / (t[1] - t[0])
for i in range(1, n - 1):
d[i] = (y[i + 1] - y[i - 1]) / (t[i + 1] - t[i - 1])
d[n - 1] = (y[n - 1] - y[n - 2]) / (t[n - 1] - t[n - 2])
return d
def aceleracao_maxima(t, v):
"""Maior aceleração (m/s²) da tabela de velocidades."""
# TODO: a aceleração é a derivada da velocidade
pass
# --- testes (não altere) ---
t = [0, 10, 20, 30, 40, 50]
v = [0, 45, 110, 190, 260, 300]
assert abs(aceleracao_maxima(t, v) - 7.5) < 1e-9, "a maior aceleração é em t = 30 s"
assert abs(aceleracao_maxima([0, 1, 2], [0, 9.8, 19.6]) - 9.8) < 1e-9, "queda livre"
print("Exercício 04: todos os testes passaram!")
Exercício 05¶
Saúde pública. O boletim de uma secretaria de saúde publica os casos
acumulados de dengue, um número por dia. Escreva casos_novos(acumulados),
que devolve uma lista com os casos novos de cada dia a partir do segundo:
acumulado do dia menos acumulado do dia anterior.
Que diferença finita é essa, e qual o \(h\)?
def casos_novos(acumulados):
"""Casos novos por dia, a partir do segundo dia."""
novos = []
# TODO: laço de 1 até o fim, append da diferença com o dia anterior
return novos
# --- testes (não altere) ---
assert casos_novos([10, 15, 25, 40, 50]) == [5, 10, 15, 10]
assert casos_novos([0, 0, 3]) == [0, 3]
assert casos_novos([7, 7]) == [0], "nenhum caso novo"
print("Exercício 05: todos os testes passaram!")
Exercício 06¶
O pico da epidemia. Escreva dia_do_pico(acumulados), que devolve o
número do dia com mais casos novos. O dia 0 é o primeiro da lista (ele não
tem "casos novos"); os casos novos do dia \(i\) são
acumulados[i] - acumulados[i - 1].
casos_novos já está escrita. Cuidado com o deslocamento de índice: a
posição 0 da lista de casos novos é o dia 1.
def casos_novos(acumulados):
"""Casos novos por dia, a partir do segundo dia. JÁ ESCRITA."""
novos = []
for i in range(1, len(acumulados)):
novos.append(acumulados[i] - acumulados[i - 1])
return novos
def dia_do_pico(acumulados):
"""Número do dia com mais casos novos."""
# TODO: padrão extremo sobre casos_novos(acumulados); some 1 à posição
pass
# --- testes (não altere) ---
assert dia_do_pico([10, 15, 25, 40, 50]) == 3
assert dia_do_pico([0, 100, 150, 160]) == 1, "o pico pode ser no primeiro dia"
assert dia_do_pico([5, 6, 8, 20]) == 3, "ou no último"
print("Exercício 06: todos os testes passaram!")
Exercício 07¶
Contra o ruído: vizinhos afastados. Escreva derivada_afastada(t, y, k),
que devolve uma lista com a derivada central usando os vizinhos a
distância k,
para cada \(i\) de k até len(t) - k - 1 (os pontos que têm os dois vizinhos).
t = [0, 1, 2, 3, 4, 5, 6]
y = [0, 1, 4, 9, 16, 25, 36]
derivada_afastada(t, y, 2) # -> [4.0, 6.0, 8.0]
Depois de passar nos testes, aplique a função aos dados da estufa do capítulo 3 com \(k = 1, 6\) e \(24\). O que acontece com o pico da taxa?
def derivada_afastada(t, y, k):
"""Derivada central com vizinhos a distância k (lista)."""
taxas = []
# TODO: laço com i de k até len(t) - k - 1 (cuidado com o range)
return taxas
# --- testes (não altere) ---
t = [0, 1, 2, 3, 4, 5, 6]
y = [0, 1, 4, 9, 16, 25, 36]
r = derivada_afastada(t, y, 2)
assert len(r) == 3, f"com k = 2 só os pontos 2, 3 e 4 têm os dois vizinhos (veio {len(r)})"
esperado = [4, 6, 8]
for i in range(3):
assert abs(r[i] - esperado[i]) < 1e-9, f"posição {i}: veio {r[i]}, devia ser {esperado[i]}"
r = derivada_afastada(t, y, 1)
esperado = [2, 4, 6, 8, 10]
assert len(r) == 5, "k = 1 é a central comum: 5 pontos têm os dois vizinhos"
for i in range(5):
assert abs(r[i] - esperado[i]) < 1e-9, "k = 1 é a central comum"
assert derivada_afastada(t, y, 3) == [6.0], "com k = 3 só sobra o ponto do meio"
print("Exercício 07: todos os testes passaram!")