Pular para conteúdo

Lista 12 · Trapézio e Simpson

Acompanha o capítulo 12. A integral como área, cortada em faixas: retas (trapézio) ou parábolas (Simpson). Confira sempre se o número de faixas de Simpson é par.

Abrir no Colab

Baixar o caderno

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. Queremos \(\displaystyle\int_1^3 \frac{1}{x+1}\,dx\), cujo valor exato é \(\ln 2 = 0{,}693147\).

a) Calcule pela regra do trapézio com \(n = 2\) faixas.

b) Calcule pela regra de Simpson 1/3 com \(n = 2\) faixas.

c) Calcule o erro relativo percentual de cada uma. Quantas vezes o erro de Simpson é menor?

Exercício 02

Escreva trapezio(f, a, b, n), a regra do trapézio composta com n faixas:

\[ I \approx \frac{h}{2}\Big(y_0 + 2\,(y_1 + \cdots + y_{n-1}) + y_n\Big), \qquad h = \frac{b - a}{n}. \]
import numpy as np


def trapezio(f, a, b, n):
    """Integral de f de a a b pela regra do trapézio com n faixas."""
    # TODO: h, os n + 1 pontos com np.linspace, os valores y = f(x) e a fórmula
    pass


# --- testes (não altere) ---
import numpy as np



def inversa_ex02(x):
    return 1 / (x + 1)


assert abs(trapezio(inversa_ex02, 1, 3, 2) - 0.7083333333333333) < 1e-12
assert abs(trapezio(np.exp, 0, 1, 1000) - (np.exp(1) - 1)) < 1e-6
print("Exercício 02: todos os testes passaram!")

Exercício 03

Escreva simpson(f, a, b, n), a regra de Simpson 1/3 composta. Se n for ímpar, devolva None em vez de uma resposta errada.

\[ I \approx \frac{h}{3}\Big(y_0 + 4\,(y_1 + y_3 + \cdots) + 2\,(y_2 + y_4 + \cdots) + y_n\Big). \]
import numpy as np


def simpson(f, a, b, n):
    """Integral pela regra de Simpson 1/3 com n faixas; None se n for ímpar."""
    # TODO: se n for ímpar (n % 2 != 0), return None; senão, a fórmula com as
    # fatias y[1:-1:2] (peso 4) e y[2:-1:2] (peso 2)
    pass


# --- testes (não altere) ---
import numpy as np



def inversa_ex03(x):
    return 1 / (x + 1)


assert abs(simpson(inversa_ex03, 1, 3, 2) - 0.6944444444444443) < 1e-12
assert abs(simpson(np.exp, 0, 1, 64) - (np.exp(1) - 1)) < 1e-9
assert simpson(np.exp, 0, 1, 5) is None, "n ímpar: None"
print("Exercício 03: todos os testes passaram!")

Exercício 04

Dados com espaçamento irregular. Numa tabela de medições, os intervalos nem sempre são iguais. Escreva trapezio_dados(x, y), que soma a área de cada trapézio, \(\dfrac{(x_{i+1} - x_i)(y_i + y_{i+1})}{2}\), faixa por faixa.

trapezio_dados([0, 1, 3], [2, 4, 0])    # -> 3 + 4 = 7
def trapezio_dados(x, y):
    """Integral de uma tabela com espaçamento qualquer: soma dos trapézios."""
    total = 0.0
    # TODO: um trapézio por faixa, cada um com a sua largura
    return total


# --- testes (não altere) ---
assert abs(trapezio_dados([0, 1, 3], [2, 4, 0]) - 7) < 1e-12
assert abs(trapezio_dados([0, 0.5, 2, 4], [1, 1, 1, 1]) - 4) < 1e-12, "função constante 1: a área é a largura"
print("Exercício 04: todos os testes passaram!")

Exercício 05

Hidrologia — o volume de uma represa. Um levantamento batimétrico mediu a área do espelho d'água de uma represa em várias profundidades, a cada 2 m:

profundidade (m) 0 2 4 6 8 10 12
área (m²) 4200 3900 3500 3000 2300 1500 600

O volume é a integral da área ao longo da profundidade. Escreva volume_reservatorio(areas, h), que calcula o volume por Simpson (as áreas são um array, e há 6 faixas: um número par).

import numpy as np


def volume_reservatorio(areas, h):
    """Volume (m³) por Simpson, com as áreas (m²) de seções a cada h metros."""
    # TODO: a fórmula de Simpson com os valores da tabela (sem função nenhuma)
    pass


# --- testes (não altere) ---
import numpy as np


areas = np.array([4200.0, 3900.0, 3500.0, 3000.0, 2300.0, 1500.0, 600.0])
assert abs(volume_reservatorio(areas, 2.0) - 33333.33333333333) < 1e-6
assert abs(volume_reservatorio(np.array([10.0, 10.0, 10.0]), 1.0) - 20) < 1e-12, "área constante: área vezes altura"
print("Exercício 05: todos os testes passaram!")

Exercício 06

Telecomunicações — a energia de um pulso. Um pulso de 1 kHz, que se apaga em poucos milissegundos, é aplicado a uma carga de \(R\) ohms. A potência em cada instante é \(v(t)^2/R\), e a energia é a integral da potência. A função tensao(t) (já escrita) dá o pulso.

Escreva energia_pulso(R, n), que integra \(v^2/R\) de 0 a 10 ms por Simpson com n faixas.

energia_pulso(50, 1000)    # -> ≈ 2.484e-04 J

Com que \(n\) o resultado para de mudar na quarta casa significativa?

import numpy as np


def tensao(t):
    """Pulso de 1 kHz amortecido (V). JÁ ESCRITA."""
    return 5 * np.exp(-t / 0.002) * np.sin(2 * np.pi * 1000 * t)


def energia_pulso(R, n):
    """Energia (J) dissipada no resistor R: integral de tensao(t)**2 / R de 0 a 10 ms,
    por Simpson com n faixas."""
    # TODO: os n + 1 instantes, a potência em cada um e a fórmula de Simpson
    pass


# --- testes (não altere) ---
assert abs(energia_pulso(50, 1000) - 0.000248415546831682) < 1e-12
assert abs(energia_pulso(100, 1000) - energia_pulso(50, 1000) / 2) < 1e-12, "o dobro da resistência, metade da energia"
print("Exercício 06: todos os testes passaram!")

Exercício 07

Quantas faixas bastam? Escreva n_para_precisao(f, a, b, exato, tol), que testa Simpson (já escrita) com \(n = 2, 4, 8, 16, \ldots\) (dobrando) e devolve o primeiro \(n\) com erro absoluto menor que tol.

Para \(e^x\) em \([0, 1]\) com tol = 1e-8, qual o \(n\)? E para o trapézio (seria preciso trocar a função), quanto seria?

import numpy as np


def simpson(f, a, b, n):
    """JÁ ESCRITA."""
    h = (b - a) / n
    y = f(np.linspace(a, b, n + 1))
    return h / 3 * (y[0] + 4 * np.sum(y[1:-1:2]) + 2 * np.sum(y[2:-1:2]) + y[-1])


def n_para_precisao(f, a, b, exato, tol):
    """Menor n da sequência 2, 4, 8, 16, ... com erro de Simpson menor que tol."""
    n = 2
    # TODO: while o erro não ficar menor que tol: dobre n
    return n


# --- testes (não altere) ---
import numpy as np


assert n_para_precisao(np.exp, 0, 1, np.exp(1) - 1, 1e-8) == 32
assert n_para_precisao(np.exp, 0, 1, np.exp(1) - 1, 1e-3) == 2
print("Exercício 07: todos os testes passaram!")