Documentos de Académico
Documentos de Profesional
Documentos de Cultura
0001 SciPy Interpolacion Ajuste PDF
0001 SciPy Interpolacion Ajuste PDF
INTERPOLACIÓN Y AJUSTE
Vamos a ver cómo interpolar y ajustar una serie de puntos con SciPy. Son tareas diferentes que
aprovecharemos en circunstancias distintas, pero ambas muy útiles. Esta clase está basada en el artículo
http://pybonacci.org/2013/08/15/ajuste-e-interpolacion-unidimensionales-basicos-en-python-con-scipy/
(http://pybonacci.org/2013/08/15/ajuste-e-interpolacion-unidimensionales-basicos-en-python-con-scipy/)
In [1]:
import numpy as np
In [2]:
%matplotlib inline
import matplotlib.pyplot as plt
Vamos a representar esos datos con cruces azules (pista: usar mew=2 , "marker edge width 2", para que las
cruces se vean mejor):
http://localhost:8888/notebooks/Desktop/Python/Notebooks/0001-SciPy-interpolacion-ajuste.ipynb 1/11
9/4/2018 0001-SciPy-interpolacion-ajuste
In [4]:
Out[4]:
<matplotlib.legend.Legend at 0x18ebf00f278>
Vemos la forma clásica de la polar de un avión. Hallando el índice del máximo valor de CL
podemos descartar
los datos fuera de la región de entrada en pérdida, y para eso necesitamos la función np.argmax :
In [5]:
Out[5]:
12
In [6]:
# C_L max
C_L[idx_stall]
Out[6]:
1.24
http://localhost:8888/notebooks/Desktop/Python/Notebooks/0001-SciPy-interpolacion-ajuste.ipynb 2/11
9/4/2018 0001-SciPy-interpolacion-ajuste
In [7]:
Out[7]:
<matplotlib.legend.Legend at 0x18ebf00f978>
Como solo tenemos puntos intermedios, no tenemos posibilidad de evaluar, por ejemplo, CL para unCD
que no esté en los datos. Si interpolamos la curva ya podemos hacerlo.
Sabemos que, fuera de la región de entrada en pérdida, la polar tiene forma parabólica. Si ajustamos la
curva podemos hallar el CD0 k
y el .
In [8]:
http://localhost:8888/notebooks/Desktop/Python/Notebooks/0001-SciPy-interpolacion-ajuste.ipynb 3/11
9/4/2018 0001-SciPy-interpolacion-ajuste
In [9]:
x_i = [0.0, 0.9, 1.8, 2.7, 3.6, 4.4, 5.3, 6.2, 7.1, 8.0]
y_i = [0.0, 0.8, 1.0, 0.5, -0.4, -1.0, -0.8, -0.1, 0.7, 1.0]
plt.plot(x_i, y_i, 'x', mew=2)
Out[9]:
[<matplotlib.lines.Line2D at 0x18ebf827e10>]
In [10]:
9 8 7 6 5 4
-8.812e-05 x + 0.003069 x - 0.04453 x + 0.3494 x - 1.614 x + 4.502 x
3 2
- 7.378 x + 6.033 x - 0.9713 x
In [11]:
x = np.linspace(x_i[0], x_i[-1])
plt.plot(x, lag_pol(x))
plt.plot(x_i, y_i, 'x', mew=2)
Out[11]:
[<matplotlib.lines.Line2D at 0x18ebf0af438>]
http://localhost:8888/notebooks/Desktop/Python/Notebooks/0001-SciPy-interpolacion-ajuste.ipynb 4/11
9/4/2018 0001-SciPy-interpolacion-ajuste
Fenómeno de Runge
In [12]:
# preserve
def runge(x):
return 1 / (1 + x ** 2)
In [13]:
# Número de nodos
N = 11 # Nodos de interpolación
y = lag_pol(x)
# pintamos
plt.plot(x, y, label='interpolation')
plt.plot(xp, fp, 'o', label='samples')
plt.plot(x, runge(x), label='real')
plt.legend(loc='upper center')
Out[13]:
<matplotlib.legend.Legend at 0x18ec08c7630>
In [14]:
http://localhost:8888/notebooks/Desktop/Python/Notebooks/0001-SciPy-interpolacion-ajuste.ipynb 5/11
9/4/2018 0001-SciPy-interpolacion-ajuste
Vamos a generar unos puntos de ejemplo para explicar cómo funciona. Para eso, vamos a usar simplemente la
función sinx
en un dominio con pocos puntos:
In [15]:
# preserve
x_i = [0.0, 0.9, 1.8, 2.7, 3.6, 4.4, 5.3, 6.2, 7.1, 8.0]
# y_i es aproximación a un decimal de sin(x_i)
y_i = [0.0, 0.8, 1.0, 0.5, -0.4, -1.0, -0.8, -0.1, 0.7, 1.0]
plt.plot(x_i, y_i, 'x', mew=2)
Out[15]:
[<matplotlib.lines.Line2D at 0x18ec092aa58>]
Out[16]:
<scipy.interpolate.fitpack2.InterpolatedUnivariateSpline at 0x18ebf85c080>
¿Cómo obtengo los puntos desde aquí? El resultado que hemos obtenido es una función y admite como
x
argumento la . Evaluemos f_interp( π2 )
In [17]:
f_interp(np.pi / 2)
Out[17]:
array(0.94906585)
Vamos a representar esta función junto con los puntos de interpolación. Fíjate en que, ahora que tenemos una
función interpolante, podemos representarla en un dominio:
http://localhost:8888/notebooks/Desktop/Python/Notebooks/0001-SciPy-interpolacion-ajuste.ipynb 6/11
9/4/2018 0001-SciPy-interpolacion-ajuste
In [18]:
# Representación
x = np.linspace(0, 8)
y_interp = f_interp(x)
Out[18]:
[<matplotlib.lines.Line2D at 0x18ec095a3c8>]
Retrocede ahora y comprueba lo que pasa si cambias el grado del spline, por ejemplo k=3.
1. Crea un polinomio interpolante usando los valores que encajan en el modelo parabólico.
2. Crea un dominio de CL
entre C_L.min() y C_L.max() .
3. Halla los valores interpolados de CD
en ese dominio.
4. Representa la función y los puntos.
http://localhost:8888/notebooks/Desktop/Python/Notebooks/0001-SciPy-interpolacion-ajuste.ipynb 7/11
9/4/2018 0001-SciPy-interpolacion-ajuste
In [19]:
plt.plot(C_D_interp, C_L_domain)
plt.plot(C_D, C_L, 'x', mew=2)
plt.xlabel('$C_D$')
plt.ylabel('$C_L$')
plt.show()
Ajuste
El ajuste funciona de manera totalmente distinta: obtendremos una curva que no tiene por qué pasar por
ninguno de los puntos originales, pero que a cambio tendrá una expresión analítica simple.
In [20]:
Vamos otra vez a generar unos datos para ver cómo funcionaría, del tipo:
y(x) = x2 − x + 1 + Ruido
http://localhost:8888/notebooks/Desktop/Python/Notebooks/0001-SciPy-interpolacion-ajuste.ipynb 8/11
9/4/2018 0001-SciPy-interpolacion-ajuste
In [21]:
# preserve
x_i = np.linspace(-2, 3, num=10)
y_i = x_i ** 2 - x_i + 1 + 0.5 * np.random.randn(10)
plt.plot(x_i, y_i, 'x', mew=2)
Out[21]:
[<matplotlib.lines.Line2D at 0x18ec0a61d68>]
Vamos a utilizar la función polynomial.polyfit , que recibe los puntos de interpolación y el grado del
polinomio. El resultado serán los coeficientes del mismo, en orden de potencias decrecientes.
In [22]:
In [23]:
print(a, b, c)
http://localhost:8888/notebooks/Desktop/Python/Notebooks/0001-SciPy-interpolacion-ajuste.ipynb 9/11
9/4/2018 0001-SciPy-interpolacion-ajuste
In [24]:
x = np.linspace(-2, 3)
y_fit = poldeg2(x, a, b, c)
#grafica la curva
plt.plot(x, y_fit, color='g')
Out[24]:
[<matplotlib.lines.Line2D at 0x18ec0a61470>]
Ejercicio
CD = CD0 + kCL2
hallar los coeficientes CD0 y k.
In [25]:
In [26]:
#Dominio C_L
print(C_L)
[-0.91 -0.72 -0.48 -0.27 -0.06 0.16 0.31 0.47 0.6 0.82 1.02 1.2
1.24 1.15 1. 0.8 ]
In [27]:
http://localhost:8888/notebooks/Desktop/Python/Notebooks/0001-SciPy-interpolacion-ajuste.ipynb 10/11
9/4/2018 0001-SciPy-interpolacion-ajuste
In [28]:
A, B = popt
In [29]:
In [30]:
plt.plot(y, x)
plt.plot(C_D, C_L, 'x', mew=2, c='r')
plt.xlabel('$C_D$')
plt.ylabel('$C_L$')
Out[30]:
Text(0,0.5,'$C_L$')
Hemos aprendido:
http://localhost:8888/notebooks/Desktop/Python/Notebooks/0001-SciPy-interpolacion-ajuste.ipynb 11/11