Matemática Computacional com Python

Explorando cálculo, álgebra linear e visualizações matemáticas

matemática
python
numpy
scipy
Autor

João Pedro F. Duarte

Data de Publicação

01/04/2024

Introdução

A matemática é a linguagem fundamental da engenharia e ciência da computação. Neste post, vamos explorar como usar Python para resolver problemas matemáticos e criar visualizações elegantes.

1. Funções e Cálculo

Derivadas Numéricas

import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize

# Definir função
def f(x):
    return x**3 - 6*x**2 + 9*x + 1

# Calcular derivada numérica usando diferenças finitas
def df(x):
    h = 1e-6
    return (f(x + h) - f(x - h)) / (2 * h)

# Gerar pontos
x = np.linspace(-1, 5, 200)
y = f(x)
dy = [df(xi) for xi in x]

# Plotar
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))

# Função original
ax1.plot(x, y, 'b-', linewidth=2, label='f(x) = x³ - 6x² + 9x + 1')
ax1.axhline(y=0, color='k', linestyle='--', alpha=0.3)
ax1.axvline(x=0, color='k', linestyle='--', alpha=0.3)
ax1.grid(True, alpha=0.3)
ax1.set_xlabel('x')
ax1.set_ylabel('f(x)')
ax1.set_title('Função Original', fontweight='bold')
ax1.legend()

# Derivada
ax2.plot(x, dy, 'r-', linewidth=2, label="f'(x) = 3x² - 12x + 9")
ax2.axhline(y=0, color='k', linestyle='--', alpha=0.3)
ax2.axvline(x=0, color='k', linestyle='--', alpha=0.3)
ax2.grid(True, alpha=0.3)
ax2.set_xlabel('x')
ax2.set_ylabel("f'(x)")
ax2.set_title('Derivada', fontweight='bold')
ax2.legend()

plt.tight_layout()
plt.show()

Encontrando Pontos Críticos

# Encontrar raízes da derivada (pontos críticos)
raizes = optimize.fsolve(df, [1, 3])

print("Pontos críticos (onde f'(x) = 0):")
for raiz in raizes:
    print(f"  x = {raiz:.4f}, f(x) = {f(raiz):.4f}")
    
# Determinar se são máximos ou mínimos (segunda derivada)
def d2f(x):
    h = 1e-6
    return (df(x + h) - df(x - h)) / (2 * h)

print("\nClassificação:")
for raiz in raizes:
    segunda_derivada = d2f(raiz)
    tipo = "mínimo" if segunda_derivada > 0 else "máximo"
    print(f"  x = {raiz:.4f} é um {tipo} local (f''(x) = {segunda_derivada:.4f})")
Pontos críticos (onde f'(x) = 0):
  x = 1.0000, f(x) = 5.0000
  x = 3.0000, f(x) = 1.0000

Classificação:
  x = 1.0000 é um máximo local (f''(x) = -6.0001)
  x = 3.0000 é um mínimo local (f''(x) = 5.9996)

2. Integrais

Integração Numérica

from scipy import integrate

# Função a integrar
def g(x):
    return np.sin(x) * np.exp(-x/10)

# Calcular integral definida de 0 a 10
resultado, erro = integrate.quad(g, 0, 10)

print(f"∫₀¹⁰ sin(x)·e^(-x/10) dx = {resultado:.6f}")
print(f"Erro estimado: {erro:.2e}")

# Visualizar
x = np.linspace(0, 10, 200)
y = g(x)

plt.figure(figsize=(10, 6))
plt.plot(x, y, 'b-', linewidth=2, label='f(x) = sin(x)·e^(-x/10)')
plt.fill_between(x, 0, y, alpha=0.3, label=f'Área = {resultado:.4f}')
plt.axhline(y=0, color='k', linestyle='-', linewidth=0.5)
plt.grid(True, alpha=0.3)
plt.xlabel('x')
plt.ylabel('f(x)')
plt.title('Integração Numérica', fontweight='bold')
plt.legend()
plt.tight_layout()
plt.show()
∫₀¹⁰ sin(x)·e^(-x/10) dx = 1.315535
Erro estimado: 3.43e-12

3. Álgebra Linear

Operações com Matrizes

# Criar matrizes
A = np.array([[2, 1, -1],
              [1, 3, 2],
              [-1, 2, 4]])

b = np.array([8, 13, 10])

print("Matriz A:")
print(A)
print(f"\nVetor b: {b}")

# Resolver sistema linear Ax = b
x = np.linalg.solve(A, b)
print(f"\nSolução do sistema Ax = b:")
print(f"x = {x}")

# Verificar
print(f"\nVerificação (Ax): {A @ x}")
print(f"Esperado (b): {b}")
print(f"Diferença: {np.linalg.norm(A @ x - b):.2e}")
Matriz A:
[[ 2  1 -1]
 [ 1  3  2]
 [-1  2  4]]

Vetor b: [ 8 13 10]

Solução do sistema Ax = b:
x = [ 7.2 -1.4  5. ]

Verificação (Ax): [ 8. 13. 10.]
Esperado (b): [ 8 13 10]
Diferença: 0.00e+00

Autovalores e Autovetores

# Calcular autovalores e autovetores
autovalores, autovetores = np.linalg.eig(A)

print("\nAutovalores:")
for i, val in enumerate(autovalores):
    print(f"  λ{i+1} = {val:.4f}")

print("\nAutovetores:")
for i in range(len(autovalores)):
    print(f"  v{i+1} = {autovetores[:, i]}")

Autovalores:
  λ1 = 0.2855
  λ2 = 3.1433
  λ3 = 5.5712

Autovetores:
  v1 = [-0.6345873   0.59615502 -0.49183142]
  v2 = [ 0.77083835  0.53412697 -0.34715503]
  v3 = [-0.05574221  0.5994227   0.79848935]

Visualização de Transformações Lineares

import plotly.graph_objects as go

# Matriz de transformação (rotação + escala)
T = np.array([[0.8, -0.6],
              [0.6, 0.8]])

# Vetores originais (grade)
n = 10
x_orig = np.linspace(-2, 2, n)
y_orig = np.linspace(-2, 2, n)

# Criar vetores
vetores_orig = []
vetores_trans = []

for x in x_orig:
    for y in y_orig:
        v = np.array([x, y])
        v_trans = T @ v
        vetores_orig.append(v)
        vetores_trans.append(v_trans)

vetores_orig = np.array(vetores_orig)
vetores_trans = np.array(vetores_trans)

# Criar visualização
fig = go.Figure()

# Vetores originais
fig.add_trace(go.Scatter(
    x=vetores_orig[:, 0],
    y=vetores_orig[:, 1],
    mode='markers',
    name='Original',
    marker=dict(size=8, color='blue', opacity=0.6)
))

# Vetores transformados
fig.add_trace(go.Scatter(
    x=vetores_trans[:, 0],
    y=vetores_trans[:, 1],
    mode='markers',
    name='Transformado',
    marker=dict(size=8, color='red', opacity=0.6)
))

fig.update_layout(
    title='Transformação Linear: Rotação + Escala',
    xaxis_title='x',
    yaxis_title='y',
    showlegend=True,
    height=600,
    width=700,
    xaxis=dict(scaleanchor="y", scaleratio=1),
    yaxis=dict(scaleanchor="x", scaleratio=1)
)

fig.show()

4. Equações Diferenciais

Resolução Numérica de EDOs

from scipy.integrate import odeint

# Equação diferencial: dy/dt = -2y + sin(t)
def modelo(y, t):
    return -2*y + np.sin(t)

# Condição inicial
y0 = 0

# Pontos de tempo
t = np.linspace(0, 10, 200)

# Resolver
y = odeint(modelo, y0, t)

# Plotar
plt.figure(figsize=(10, 6))
plt.plot(t, y, 'b-', linewidth=2, label="y(t)")
plt.plot(t, np.sin(t), 'r--', alpha=0.5, label="sin(t)")
plt.xlabel('t')
plt.ylabel('y')
plt.title("Solução de dy/dt = -2y + sin(t), y(0) = 0", fontweight='bold')
plt.grid(True, alpha=0.3)
plt.legend()
plt.tight_layout()
plt.show()

5. Séries e Aproximações

Série de Taylor

A série de Taylor para \(e^x\) é:

\[e^x = \sum_{n=0}^{\infty} \frac{x^n}{n!} = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \cdots\]

import math

def taylor_exp(x, n_termos):
    """Aproximação de e^x usando série de Taylor"""
    resultado = 0
    for n in range(n_termos):
        resultado += x**n / math.factorial(n)
    return resultado

# Testar aproximações
x_test = 2
print(f"Aproximações de e^{x_test}:")
print(f"Valor real: {np.exp(x_test):.10f}")

for n in [1, 2, 5, 10, 20]:
    aprox = taylor_exp(x_test, n)
    erro = abs(aprox - np.exp(x_test))
    print(f"  {n:2d} termos: {aprox:.10f} (erro: {erro:.2e})")
Aproximações de e^2:
Valor real: 7.3890560989
   1 termos: 1.0000000000 (erro: 6.39e+00)
   2 termos: 3.0000000000 (erro: 4.39e+00)
   5 termos: 7.0000000000 (erro: 3.89e-01)
  10 termos: 7.3887125220 (erro: 3.44e-04)
  20 termos: 7.3890560989 (erro: 4.77e-13)

Visualização da Convergência

x = np.linspace(-2, 2, 200)

plt.figure(figsize=(12, 6))

# Função real
plt.plot(x, np.exp(x), 'k-', linewidth=3, label='e^x (real)', zorder=10)

# Aproximações de Taylor
cores = ['red', 'orange', 'green', 'blue', 'purple']
for i, n in enumerate([1, 2, 3, 5, 10]):
    y_aprox = [taylor_exp(xi, n) for xi in x]
    plt.plot(x, y_aprox, '--', color=cores[i % len(cores)], 
             linewidth=2, alpha=0.7, label=f'{n} termos')

plt.xlabel('x')
plt.ylabel('y')
plt.title('Aproximação de e^x pela Série de Taylor', fontweight='bold')
plt.ylim(-1, 8)
plt.grid(True, alpha=0.3)
plt.legend()
plt.tight_layout()
plt.show()

6. Equações Matemáticas com LaTeX

Podemos escrever equações elegantes usando LaTeX:

Identidade de Euler: \[e^{i\pi} + 1 = 0\]

Transformada de Fourier: \[\hat{f}(\omega) = \int_{-\infty}^{\infty} f(t) e^{-i\omega t} dt\]

Equação de Schrödinger: \[i\hbar\frac{\partial}{\partial t}\Psi(\mathbf{r},t) = \hat{H}\Psi(\mathbf{r},t)\]

Teorema de Pitágoras: \[a^2 + b^2 = c^2\]

Conclusão

Python oferece ferramentas poderosas para matemática computacional:

  • NumPy: Operações com arrays e álgebra linear
  • SciPy: Otimização, integração, EDOs
  • Matplotlib/Plotly: Visualizações
  • SymPy: Matemática simbólica (não coberto aqui)

Essas ferramentas são essenciais para engenharia, física, ciência de dados e muito mais!

Recursos Adicionais


Próximo post: Análise de Fourier e Processamento de Sinais