6.16. Curvas e integração¶
As páginas de matemática cobriram operações que recebem um array e produzem um array (ou escalar) – aritmética, reduções, difusão. Esta página cobre uma classe diferente de operações: as que tratam o array como uma função amostrada e fazem perguntas sobre a própria função. Interpolação entre amostras, ajuste de uma curva, integração por baixo delas, convolução com outro buffer.
Todas estas aceitam entradas ndarray e devolvem um escalar float ou um ndarray float.
6.16.1. Interpolação¶
interp() realiza interpolação linear unidimensional. xp é um array 1-D monotonicamente crescente de valores independentes; fp são os valores dependentes correspondentes; x é o ponto onde o interpolante deve ser avaliado:
xp = np.array([0.0, 1.0, 2.0, 3.0])
fp = np.array([10.0, 20.0, 25.0, 30.0])
x = np.array([0.5, 1.5, 2.5])
np.interp(x, xp, fp)
# array([15.0, 22.5, 27.5])
Fora do intervalo [xp[0], xp[-1]], o resultado é recortado para fp[0] e fp[-1] respetivamente; as palavras-chave left= e right= substituem esses extremos.
Usado na câmara para remapear uma tabela de calibração para posições de amostra arbitrárias – uma tabela temperatura-tensão de um termístor, uma curva de resposta de pixel não linear, uma tabela de pesquisa gamma por canal. Uma chamada à biblioteca, uma passagem pelas entradas, sem ciclo Python.
6.16.2. Ajuste e avaliação de polinómios¶
polyfit() ajusta um polinómio de grau deg aos pontos de dados (x, y) por mínimos quadrados e devolve os coeficientes (grau mais alto primeiro):
x = np.array([0.0, 1.0, 2.0, 3.0, 4.0])
y = np.array([0.0, 1.1, 3.9, 9.1, 15.8])
coeffs = np.polyfit(x, y, 2)
# array([1.0, 0.0, 0.0]) (approximately)
Quando x é omitido, é usado range(len(y)) – útil para ajustar um polinómio rápido a um buffer regularmente amostrado sem eixo x associado:
np.polyfit(y, 2)
polyval() avalia o polinómio cujos coeficientes são p em x. A entrada x pode ser um escalar (devolve um float) ou um ndarray (devolve um ndarray):
p = np.polyfit(x, y, 2)
fitted = np.polyval(p, x)
O emparelhamento natural é chamar polyfit uma vez na calibração, guardar os coeficientes, e chamar polyval para avaliar a curva resultante em cada fotograma. O passo de avaliação do polinómio é um punhado de operações float por amostra, o que é económico mesmo nas câmaras mais pequenas.
6.16.3. Convolução¶
convolve() devolve a convolução linear discreta de comprimento total de dois arrays 1-D. Apenas o modo full está implementado; o comprimento da saída é len(a) + len(v) - 1. Corte o resultado para obter o mesmo efeito dos modos same e valid que o numpy de secretária oferece:
a = np.array([1.0, 2.0, 3.0])
v = np.array([0.5, 0.5])
np.convolve(a, v)
# array([0.5, 1.5, 2.5, 1.5])
Útil para filtros FIR curtos e núcleos de suavização (caixa, triângulo, gaussiano) onde configurar uma cadeia SOS seria excessivo. O tempo de execução é proporcional ao produto dos comprimentos dos dois arrays – adequado para núcleos curtos, mas rapidamente mais caro do que uma convolução por FFT para núcleos longos.
6.16.4. Integração trapezoidal¶
trapz() integra uma função amostrada pela regra trapezoidal composta:
x = np.linspace(0, np.pi, num=128)
y = np.sin(x)
np.trapz(y, x) # ~ 2.0
Passe dx= quando o espaçamento das amostras é uniforme e só o passo é relevante; passe x= quando as amostras não estão igualmente espaçadas. A chamada certa para integrar dados de sensor já capturados, quando a forma analítica não está disponível.
Para dados de amostra que foram limitados em banda (um buffer de áudio após um filtro anti-aliasing, por exemplo), a regra trapezoidal converge com o quadrado do número de amostras, o que significa que duplicar o comprimento do buffer reduz o erro por um fator de quatro.
Quando o integrando não é um buffer de amostras mas uma função Python que a aplicação pode avaliar em pontos arbitrários, uma família diferente de resolvedores é a escolha certa.