Interpolación polinomial de Lagrange#
La tarea de encontrar un polinomio de grado uno que pase por los puntos \((x_{0}, y_{0})\) y \((x_{1}, y_{1})\) es equivalente a aproximar una función \(f\), para la cual \(f(x_{0}) = y_{0}\) y \(f(x_{1}) = y_{1}\), mediante un polinomio de primer grado que interpole —o coincida con— los valores de \(f\) en los puntos dados. El uso de este polinomio para realizar una aproximación dentro del intervalo definido por dichos puntos se denomina interpolación polinómica.
Dadas las funciones
El polinomio de interpolación de Lagrange lineal que pasa por \((x_{0} , y_{0} )\) y \((x_{1} , y_{1})\) es
Ejemplo 1. Determine el polinomio de interpolación lineal de Lagrange que pasa por los puntos \((2, 4)\) y \((5, 1)\).
En esta caso se tiene
tal que
import numpy as np
import matplotlib.pyplot as plt
# Suprimir advertencias menores de integración durante los bucles de optimización
import warnings
warnings.filterwarnings("ignore")
# Configurar el estilo de graficación para una mejor visualización
plt.style.use('ggplot')
x = np.linspace(0, 5, 100)
P = lambda x: - x + 6 # Función original
# Graficar
plt.figure(figsize=(12, 8))
plt.plot(x, P(x), 'b', linewidth=2, label='P(x) = -x + 6')
plt.plot(2, 4, 'ko', markersize=10, label='P(2) = 4')
plt.plot(5, 1, 'ko', markersize=10, label='P(5) = 1')
plt.xlabel('x')
plt.ylabel('P(x)')
plt.grid(True, alpha=0.3)
plt.axis('tight')
plt.legend()
plt.show()
Para generalizar el concepto de interpolación lineal, consideremos la construcción de un polinomio de grado a lo sumo \(n\) que pase por los \(n + 1\) puntos
Para cada \(k = 0, 1, \dots, n\), una función \(L_{n,k} (x)\) con la propiedad de que \(L_{n,k} (x_{i} ) = 0\) cuando \(i \neq k\) y \(L_{n,k} (x_{k} ) = 1\). Para satisfacer \(L_{n,k} (x_{i} ) = 0\) para cada \(i \neq k\), se requiere que el numerador de \(L_{n,k} (x)\) contenga el término
Para satisfacer \(L_{n,k}(xk) = 1\), el denominador de \(L_{n,k}(x)\) debe ser este mismo término, pero evaluado en \(x = x_{k}\). Por tanto
Teorema 11
Si \(x_{0}, x_{1}, \dots, x_{n}\) son \(n + 1\) números distintos y \(f\) es una función cuyos valores se dan en estos números, entonces existe un polinomio único \(P(x)\) de grado como máximo \(n\) con
Este polinomio está dado por
donde, para cada \(k=0,1,\dots,n,\)
Teorema 12
Suponga que \(x_{0} , x_{1}, \dots , x_{n}\) son números distintos en el intervalo \([a, b]\) y \(f \in C^{n+1} [a, b]\). Entonces, para cada \(x \in [a, b]\), existe un número \(\xi(x)\) (generalmente desconocido) entre \(x_{0} , x_{1} ,\dots , x_{n}\) , y por lo tanto en \((a, b)\), con
donde \(P(x)\) es la interpolación polinomial dada en la Ec. (1).
import numpy as np
import matplotlib.pyplot as plt
# Definimos la funcion base del polinomio de Lagrange
def Lagrange_base(x_nodos, k, x):
L_nk = 1.0
n = len(x_nodos)
for i in range(n):
if i != k:
L_nk *= (x - x_nodos[i]) / (x_nodos[k] - x_nodos[i])
return L_nk
# Definimos el polinomio de Lagrange
def Lagrange_poli(x_nodos, y_nodos, x):
Px = 0.0
for k in range(len(x_nodos)):
Px += y_nodos[k] * Lagrange_base(x_nodos, k, x)
return Px
if __name__ == '__main__':
x_nodos = np.linspace(0, 2, 5)
y_nodos = -np.exp(x_nodos)
x_pts_finos = np.linspace(0, 2, 100)
y_exacta = -np.exp(x_pts_finos)
y_aprox = [Lagrange_poli(x_nodos, y_nodos, xi) for xi in x_pts_finos]
plt.figure(figsize=(15, 10))
plt.subplot(121)
plt.plot(x_pts_finos, y_exacta, label='Exacta')
plt.plot(x_pts_finos, y_aprox, '--', label='Lagrange')
plt.plot(x_nodos, y_nodos, 'ok', label='Nodos interp.')
plt.legend(loc='upper right')
# plt.subplot(122)
plt.show()