## Ejemplo de splines lineales y cuadráticos
import numpy as np
import matplotlib.pyplot as plt
= lambda x: np.sin(x) + np.sin(10*x)
f = np.linspace(0, 2*np.pi, 10)
x = np.linspace(0, 2*np.pi, 100)
x1 = f(x)
y = f(x1)
y1 'k', label='splines')
plt.plot(x, y, 'red', label='f(x)')
plt.plot(x1, y1, 'k.') plt.plot(x, y,
Splines
Los splines son otra herramienta para hacer interpolación de datos. La idea es que en lugar de usar polinomios de grado fijo, se usan polinomios de grado variable, que se van ajustando a los datos. En particular, los splines cúbicos son muy populares.
La idea es la siguiente: se tienen \(n\) puntos \((x_i, y_i)\), y se quiere encontrar una función \(S(x)\) lineal que pase por todos los puntos. Para ello, se divide el intervalo \([x_0, x_n]\) en \(n\) subintervalos \([x_i, x_{i+1}]\), y se define un polinomio \(S_i(x)\) en cada subintervalo, de tal manera que \(S(x)\) sea una función continua, y que \(S(x_i) = y_i\).
Cuales son las propiedades de los splines lineales
- Es una función continua
- No es diferenciable
- Es una función lineal a trozos
- Relativamente fácil de calcular
Ejercicio
Encuentre un algoritmo para encontrar los coeficientes de los splines lineales, y prográmelo.
Ejercicio
De los datos del la gráfica anterior, encuentre el valor de \(y\) para \(x=1.5\) usando splines lineales.
def gauss_seidel(A, b, x0, tol=1e-6, max_iter=1000):
"""
Solves the linear system Ax = b using the Gauss-Seidel method.
Returns the solution x and the number of iterations used.
"""
= len(b)
n = np.copy(x0)
x iter = 0
while iter < max_iter:
iter += 1
for i in range(n):
= 0
suma for j in range(n):
if j != i:
+= A[i][j] * x[j]
suma = (b[i] - suma) / A[i][i]
x[i] if np.linalg.norm(x - x0) < tol:
return x, iter
= np.copy(x)
x0
raise ValueError("Gauss-Seidel failed to converge after {} iterations".format(max_iter))
Splines cuadráticos
Si queremos que esta composición de funciones sea continua y diferenciable la debemos usar un polinomio de segundo orden para generar los splines. Vamos a ver un ejemplo
Sea los puntos
\(x_0\) | \(x_1\) | \(x_2\) | \(x_3\) |
---|---|---|---|
\(y_0\) | \(y_1\) | \(y_2\) | \(y_3\) |
necesitamos encontrar polinomios de segundo grado definidos de la siguiente forma
\[f(x)=\begin{cases}a_1x^2+b_1x+c_1 \text{ para }x\in[x_0,x_1],\\ a_2x^2+b_2x+c_2 \text{ para }x\in[x_1,x_2],\\ a_3x^2+b_3x+c_3 \text{ para }x\in[x_2,x_3]\end{cases}\]
Para encontrar estos coeficientes debemos plantear un sistema de ecuaciones consistente, para ello necesitaremos crear 9 ecuaciones. Para ello vamos a usar las hipótesis que la función debe ser continua y diferenciable en \([x_0,x_4]\), así el sistema que encontramos es de la siguiente forma
\[a_1x_0^2+b_1x_0+c_1 =y_0\] \[a_1x_1^2+b_1x_1+c_1=y_1\] \[2a_1x_1^2+b_1 =2a_2x_1^2+b_2\] \[a_2x_1^2+b_2x_1+x_2=y_1\] \[a_2x_2^2+b_2x_2+x_2=y_2\] \[2a_2x_3^2+b_2 =2a_3x_2^2+b_3\] \[a_3x_3^2+b_3x_3+c_3=y_3\] \[a_3x_4^2+b_3x_4+c_3=y_4\]
Note que para que este sistema sea consistente, necesitamos una ecuación más, esta ecuación puede ser obtenida de información previa del sistema o simplemente podríamos escoger que en un punto de los extremos la segunda derivada sea cero. Así,
\[2a_3=0\]
de esta forma completamos la consistencia del sistema.
Ejercicio
Escriba un sistema de ecuaciones adecuado para resolver el problema, cuando se construye el sistema se busca que la matriz tenga propiedades intrínsecas (si es posible) como que la matriz sea simétrica
Splines cúbicos
Los splines cúbicos se diferencia de los cuadrados en que ahora se usan polinomios de tercer orden para generar los splines y adicionalmente exigimos que la concavidad se conserve, para ello se espera que la segunda derivada en los puntos intermedios de cada polinomio sea igual. Ahora para que el sistema sea consistente se debe crear dos ecuaciones, para ello se puede usar el mismo criterio usado para los splines cuadráticos.
Ejercicio
Plantee el sistema para cuatro puntos.
Usando librerías
import numpy as np
from scipy.interpolate import CubicSpline
import matplotlib.pyplot as plt
= np.arange(10)
x = np.sin(x)
y = CubicSpline(x, y)
cs = np.arange(-0.5, 9.6, 0.1)
xs = plt.subplots(figsize=(6.5, 4))
fig, ax 'o', label='data')
ax.plot(x, y, ='true')
ax.plot(xs, np.sin(xs), label="S")
ax.plot(xs, cs(xs), label
-0.5, 9.5)
ax.set_xlim(='lower left', ncol=2)
ax.legend(loc plt.show()
Note que con la librería, no solo obtenemos la función que interpola usando splines cúbicos sino también su derivadas . Ejemplo obtenido de la librería.
import numpy as np
from scipy.interpolate import CubicSpline
import matplotlib.pyplot as plt
= np.arange(10)
x = np.sin(x)
y = CubicSpline(x, y)
cs = np.arange(-0.5, 9.6, 0.1)
xs = plt.subplots(figsize=(6.5, 4))
fig, ax 'o', label='data')
ax.plot(x, y, ='true')
ax.plot(xs, np.sin(xs), label="S")
ax.plot(xs, cs(xs), label1), label="S'")
ax.plot(xs, cs(xs, 2), label="S''")
ax.plot(xs, cs(xs, 3), label="S'''")
ax.plot(xs, cs(xs, -0.5, 9.5)
ax.set_xlim(='lower left', ncol=2)
ax.legend(loc plt.show()