Python para Interpolação

Neste capítulo, o Python será usado para armazenar pontos, construir tabelas de diferenças, calcular bases de interpolação e montar polinômios. Como listas, laços e funções já foram apresentados na parte inicial de Python, aqui o foco será escolher boas estruturas para os dados e traduzir as fórmulas de Lagrange, Newton e Gregory-Newton para código.

Representando pontos

Um conjunto de pontos pode ser escrito como uma lista de pares \((x,y)\). Essa forma mantém cada abscissa junto do valor correspondente da função:

pontos = [(-1, -3), (1.5, -1.75), (2.5, 12.75), (4, 87)]

Cada item da lista é uma tupla. O primeiro valor representa \(x\), e o segundo representa \(y\).

x0, y0 = pontos[0]
print(x0)
print(y0)

Quando o método exige trabalhar separadamente com as listas de abscissas e ordenadas, podemos separar os dados com zip:

xs, ys = zip(*pontos)

print(xs)
print(ys)

Percorrendo os pontos

Na interpolação, o índice do ponto costuma aparecer diretamente nas fórmulas. Por isso, é comum percorrer os pontos junto com sua posição:

for i, ponto in enumerate(pontos):
    print(i, ponto)
Comando Uso na interpolação
pontos[i] Acessa o ponto da posição \(i\)
pontos[i][0] Acessa o valor de \(x_i\)
pontos[i][1] Acessa o valor de \(y_i\)
len(pontos) Retorna a quantidade de pontos

Produtos e somatórios

Nos métodos de Lagrange e Newton, aparecem produtos e somatórios. O importante não é apenas multiplicar valores, mas excluir corretamente o termo que não entra no produto. No polinômio de Lagrange, por exemplo, a base \(L_i(x)\) ignora o caso \(j=i\):

def base_lagrange(i, valor_x, xs):
    produto = 1

    for j, xj in enumerate(xs):
        if j != i:
            produto = produto * (valor_x - xj) / (xs[i] - xj)

    return produto

Com a base calculada, o valor interpolado pode ser escrito como um somatório:

valor_x = 2
aproximacao = sum(ys[i] * base_lagrange(i, valor_x, xs) for i in range(len(xs)))

print(aproximacao)

Cálculo simbólico

Para montar polinômios na forma algébrica, usaremos sympy. Primeiro declaramos a variável simbólica e depois escrevemos a expressão. Ao final, podemos expandir ou simplificar o polinômio:

import sympy as sp

x = sp.symbols("x")
valor = (x - 2) * (x + 4)

print(valor)
print(sp.expand(valor))

Quando for necessário avaliar o polinômio simbólico em um ponto, use subs:

p = sp.expand(valor)
print(p.subs(x, 3))

Diferenças divididas e diferenças finitas

Algumas tabelas do capítulo serão construídas linha por linha. A tabela de diferenças finitas, por exemplo, pode ser montada criando uma nova linha a partir dos valores da linha anterior:

linha = [2, 5, 11]
nova_linha = []

for i in range(len(linha) - 1):
    nova_linha.append(linha[i + 1] - linha[i])

print(nova_linha)

Para guardar todas as ordens de diferença, adicionamos cada nova linha em uma tabela:

tabela = [ys]

while len(tabela[-1]) > 1:
    linha = tabela[-1]
    nova_linha = [linha[i + 1] - linha[i] for i in range(len(linha) - 1)]
    tabela.append(nova_linha)

print(tabela)

Atividade

Crie uma lista com os pontos \((0,2)\), \((1,5)\) e \((2,10)\). Depois, separe xs e ys, monte a primeira linha de diferenças finitas e calcule a base de Lagrange \(L_0(1.5)\).