Skip to content
This repository was archived by the owner on May 21, 2020. It is now read-only.

Commit a486b38

Browse files
committed
Creada clase 6a
1 parent eb4ff1f commit a486b38

File tree

2 files changed

+362
-0
lines changed

2 files changed

+362
-0
lines changed
Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
{
2+
"metadata": {
3+
"name": ""
4+
},
5+
"nbformat": 3,
6+
"nbformat_minor": 0,
7+
"worksheets": [
8+
{
9+
"cells": [
10+
{
11+
"cell_type": "markdown",
12+
"metadata": {},
13+
"source": [
14+
"# Curso AeroPython ETSIAE\n",
15+
"\n",
16+
"## Juan Luis Cano ([@Pybonacci](https://twitter.com/Pybonacci)) y \u00c1lex S\u00e1ez ([@Alex__S12](https://twitter.com/Alex__S12))"
17+
]
18+
},
19+
{
20+
"cell_type": "markdown",
21+
"metadata": {},
22+
"source": [
23+
"<a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/deed.es\"><img alt=\"Licencia Creative Commons\" style=\"border-width:0\" src=\"http://i.creativecommons.org/l/by/4.0/88x31.png\" /></a><br /><span xmlns:dct=\"http://purl.org/dc/terms/\" property=\"dct:title\">Curso AeroPython</span> por <span xmlns:cc=\"http://creativecommons.org/ns#\" property=\"cc:attributionName\">Juan Luis Cano Rodriguez y Alejandro S\u00e1ez Mollejo</span> se distribuye bajo una <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/deed.es\">Licencia Creative Commons Atribuci\u00f3n 4.0 Internacional</a>."
24+
]
25+
},
26+
{
27+
"cell_type": "heading",
28+
"level": 1,
29+
"metadata": {},
30+
"source": [
31+
"CLASE 6a: Interpolaci\u00f3n y ajuste"
32+
]
33+
},
34+
{
35+
"cell_type": "markdown",
36+
"metadata": {},
37+
"source": [
38+
"La \u00faltimas tareas importantes que vamos a ver c\u00f3mo hacer con SciPy van a ser **interpolar** y **ajustar** una serie de puntos. Son tareas diferentes que aprovecharemos en circunstancias distintas, pero ambas muy \u00fatiles. Esta clase est\u00e1 basada en el art\u00edculo http://pybonacci.wordpress.com/2013/08/15/ajuste-e-interpolacion-unidimensionales-basicos-en-python-con-scipy/"
39+
]
40+
},
41+
{
42+
"cell_type": "markdown",
43+
"metadata": {},
44+
"source": [
45+
"Vamos a trabajar de nuevo con NumPy y matplotlib, as\u00ed que hacemos los imports necesarios:"
46+
]
47+
},
48+
{
49+
"cell_type": "code",
50+
"collapsed": false,
51+
"input": [],
52+
"language": "python",
53+
"metadata": {},
54+
"outputs": []
55+
},
56+
{
57+
"cell_type": "markdown",
58+
"metadata": {},
59+
"source": [
60+
"Supongamos que tenemos una serie de puntos que representan los datos de un cierto experimento. Como ejemplo, vamos a cargar los datos de la polar de un avi\u00f3n que est\u00e1n en el archivo `polar.dat`."
61+
]
62+
},
63+
{
64+
"cell_type": "code",
65+
"collapsed": false,
66+
"input": [
67+
"#!cat polar.dat Linux / Mac OS X\n",
68+
"!type polar.dat"
69+
],
70+
"language": "python",
71+
"metadata": {},
72+
"outputs": [
73+
{
74+
"output_type": "stream",
75+
"stream": "stdout",
76+
"text": [
77+
"/usr/bin/sh: line 0: type: polar.dat: not found\r\n"
78+
]
79+
}
80+
],
81+
"prompt_number": 2
82+
},
83+
{
84+
"cell_type": "markdown",
85+
"metadata": {},
86+
"source": [
87+
"La primera l\u00ednea son los datos de $C_L$ y la segunda los datos de $C_D$. Recordamos que hab\u00eda que usar la funci\u00f3n `np.loadtxt`, y en este caso no hay que especificar ning\u00fan argumento extra m\u00e1s porque ya por defecto detecta que los comentarios empiezan por `#`."
88+
]
89+
},
90+
{
91+
"cell_type": "code",
92+
"collapsed": false,
93+
"input": [],
94+
"language": "python",
95+
"metadata": {},
96+
"outputs": []
97+
},
98+
{
99+
"cell_type": "markdown",
100+
"metadata": {},
101+
"source": [
102+
"Vamos a representar esos datos con cruces azules (pista: usar `mew=2`, \"marker edge width 2\", para que las cruces se vean mejor):"
103+
]
104+
},
105+
{
106+
"cell_type": "code",
107+
"collapsed": false,
108+
"input": [],
109+
"language": "python",
110+
"metadata": {},
111+
"outputs": []
112+
},
113+
{
114+
"cell_type": "markdown",
115+
"metadata": {},
116+
"source": [
117+
"Vemos la forma cl\u00e1sica de la polar de un avi\u00f3n. Hallando *el \u00edndice* del m\u00e1ximo valor de $C_L$ podemos descartar los datos fuera de la regi\u00f3n de entrada en p\u00e9rdida, y para eso necesitamos la funci\u00f3n `np.argmax`:"
118+
]
119+
},
120+
{
121+
"cell_type": "code",
122+
"collapsed": false,
123+
"input": [],
124+
"language": "python",
125+
"metadata": {},
126+
"outputs": []
127+
},
128+
{
129+
"cell_type": "code",
130+
"collapsed": false,
131+
"input": [],
132+
"language": "python",
133+
"metadata": {},
134+
"outputs": []
135+
},
136+
{
137+
"cell_type": "markdown",
138+
"metadata": {},
139+
"source": [
140+
"Hay dos cosas que nos pueden interesar:\n",
141+
"\n",
142+
"* Como *solo tenemos puntos intermedios*, no tenemos posibilidad de evaluar, por ejemplo, $C_L$ para un $C_D$ que no est\u00e9 en los datos. Si **interpolamos** la curva ya podemos hacerlo.\n",
143+
"* Sabemos que, fuera de la regi\u00f3n de entrada en p\u00e9rdida, la polar tiene *forma parab\u00f3lica*. Si **ajustamos** la curva podemos hallar el $C_{D0}$ y el $k$."
144+
]
145+
},
146+
{
147+
"cell_type": "heading",
148+
"level": 2,
149+
"metadata": {},
150+
"source": [
151+
"Interpolaci\u00f3n"
152+
]
153+
},
154+
{
155+
"cell_type": "markdown",
156+
"metadata": {},
157+
"source": [
158+
"Para interpolar utilizaremos el paquete `interpolate` de SciPy:"
159+
]
160+
},
161+
{
162+
"cell_type": "code",
163+
"collapsed": false,
164+
"input": [],
165+
"language": "python",
166+
"metadata": {},
167+
"outputs": []
168+
},
169+
{
170+
"cell_type": "markdown",
171+
"metadata": {},
172+
"source": [
173+
"Vamos a generar unos puntos de ejemplo para explicar c\u00f3mo funciona. Para eso, vamos a usar simplemente la funci\u00f3n $\\sin{x}$ en un dominio con pocos puntos:"
174+
]
175+
},
176+
{
177+
"cell_type": "code",
178+
"collapsed": false,
179+
"input": [],
180+
"language": "python",
181+
"metadata": {},
182+
"outputs": []
183+
},
184+
{
185+
"cell_type": "markdown",
186+
"metadata": {},
187+
"source": [
188+
"Para crear una **funci\u00f3n interpolante** utilizaremos el objeto `InterpolatedUnivariateSpline` del paquete `interpolate`. A este objeto solo hay que pasarle los puntos de interpolaci\u00f3n y el grado, y generar\u00e1 un *spline*."
189+
]
190+
},
191+
{
192+
"cell_type": "code",
193+
"collapsed": false,
194+
"input": [],
195+
"language": "python",
196+
"metadata": {},
197+
"outputs": []
198+
},
199+
{
200+
"cell_type": "markdown",
201+
"metadata": {},
202+
"source": [
203+
"\u00bfC\u00f3mo obtengo los puntos desde aqu\u00ed? El resultado que hemos obtenido es una *funci\u00f3n* y admite como argumento la $x$."
204+
]
205+
},
206+
{
207+
"cell_type": "code",
208+
"collapsed": false,
209+
"input": [],
210+
"language": "python",
211+
"metadata": {},
212+
"outputs": []
213+
},
214+
{
215+
"cell_type": "markdown",
216+
"metadata": {},
217+
"source": [
218+
"Vamos a representar esta funci\u00f3n junto con los puntos de interpolaci\u00f3n. F\u00edjate en que, ahora que tenemos una funci\u00f3n interpolante, podemos representarla en un dominio:"
219+
]
220+
},
221+
{
222+
"cell_type": "code",
223+
"collapsed": false,
224+
"input": [],
225+
"language": "python",
226+
"metadata": {},
227+
"outputs": []
228+
},
229+
{
230+
"cell_type": "markdown",
231+
"metadata": {},
232+
"source": [
233+
"Retrocede ahora y comprueba lo que pasa si cambias el grado del *spline*."
234+
]
235+
},
236+
{
237+
"cell_type": "markdown",
238+
"metadata": {},
239+
"source": [
240+
"**Ejercicio**: Crear una funci\u00f3n interpolante $C_D = f(C_L)$ usando splines de grado 2 y representarla.\n",
241+
"\n",
242+
"1. Utiliza solo los datos que resultan de haber eliminado la regi\u00f3n de entrada en p\u00e9rdida.\n",
243+
"2. Ten en cuenta que la $x$ y la $y$ para este caso est\u00e1n cambiadas de sitio.\n",
244+
"3. Crea un dominio de $C_L$ entre `C_L.min()` y `C_L.max()`.\n",
245+
"4. Halla los valores interpolados de $C_D$ en ese dominio.\n",
246+
"5. Representa la funci\u00f3n y los puntos."
247+
]
248+
},
249+
{
250+
"cell_type": "code",
251+
"collapsed": false,
252+
"input": [],
253+
"language": "python",
254+
"metadata": {},
255+
"outputs": []
256+
},
257+
{
258+
"cell_type": "heading",
259+
"level": 2,
260+
"metadata": {},
261+
"source": [
262+
"Ajuste"
263+
]
264+
},
265+
{
266+
"cell_type": "markdown",
267+
"metadata": {},
268+
"source": [
269+
"El ajuste funciona de manera totalmente distinta: obtendremos una curva que no pasar\u00e1 por ninguno de los puntos originales, pero que a cambio tendr\u00e1 una expresi\u00f3n anal\u00edtica simple. Para realizar ajustes polin\u00f3micos vamos a utilizar el paquete `np.polynomial.polynomial` (s\u00ed, est\u00e1 dos veces)."
270+
]
271+
},
272+
{
273+
"cell_type": "code",
274+
"collapsed": false,
275+
"input": [],
276+
"language": "python",
277+
"metadata": {},
278+
"outputs": []
279+
},
280+
{
281+
"cell_type": "markdown",
282+
"metadata": {},
283+
"source": [
284+
"Vamos otra vez a generar unos datos para ver c\u00f3mo funcionar\u00eda, del tipo:\n",
285+
"\n",
286+
"$$y(x) = x^2 - x + 1 + \\text{Ruido}$$"
287+
]
288+
},
289+
{
290+
"cell_type": "code",
291+
"collapsed": false,
292+
"input": [],
293+
"language": "python",
294+
"metadata": {},
295+
"outputs": []
296+
},
297+
{
298+
"cell_type": "markdown",
299+
"metadata": {},
300+
"source": [
301+
"Vamos a utilizar la funci\u00f3n `polynomial.polyfit`, que recibe los puntos de interpolaci\u00f3n y el grado del polinomio. El resultado ser\u00e1n los coeficientes del mismo, **en orden de potencias crecientes**."
302+
]
303+
},
304+
{
305+
"cell_type": "code",
306+
"collapsed": false,
307+
"input": [],
308+
"language": "python",
309+
"metadata": {},
310+
"outputs": []
311+
},
312+
{
313+
"cell_type": "markdown",
314+
"metadata": {},
315+
"source": [
316+
"\u00a1Muy similares a lo que esper\u00e1bamos! Para evaluar un polinomio con estos coeficientes, o bien construimos la funci\u00f3n nosotros mismos o usamos la funci\u00f3n `polynomial.polyval`:"
317+
]
318+
},
319+
{
320+
"cell_type": "code",
321+
"collapsed": false,
322+
"input": [],
323+
"language": "python",
324+
"metadata": {},
325+
"outputs": []
326+
},
327+
{
328+
"cell_type": "markdown",
329+
"metadata": {},
330+
"source": [
331+
"**Ejercicio**: Si modelizamos la polar como:\n",
332+
"\n",
333+
"$$C_D = C_{D0} + k C_L^2$$\n",
334+
"\n",
335+
"hallar los coeficientes $C_{D0}$ y $k$.\n",
336+
"\n",
337+
"<p></p>\n",
338+
"\n",
339+
"<div class=\"alert alert-warning\">**\u00a1Importante!** Estamos tentados de hacer un ajuste parab\u00f3lico pero ese no es el camino, porque nos dar\u00e1 un t\u00e9rmino lineal que ya sabemos que es cero. Es mejor hacer un cambio de variable y hacer un ajuste lineal:</div>\n",
340+
"\n",
341+
"$$y \\leftarrow C_D \\\\ x \\leftarrow C_L^2 \\\\ y = C_{D0} + k x$$"
342+
]
343+
},
344+
{
345+
"cell_type": "code",
346+
"collapsed": false,
347+
"input": [],
348+
"language": "python",
349+
"metadata": {},
350+
"outputs": []
351+
}
352+
],
353+
"metadata": {}
354+
}
355+
]
356+
}

Notebooks/polar.dat

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Polar data for a certain airplane
2+
# 1st line: C_L
3+
# 2rd line: C_D
4+
5+
-0.9100 -0.7200 -0.4800 -0.2700 -0.0600 0.1600 0.3100 0.4700 0.6000 0.8200 1.0200 1.2000 1.2400 1.1500 1.0000 0.8000
6+
0.0538 0.0438 0.0316 0.0245 0.0228 0.0232 0.0262 0.0301 0.0348 0.0461 0.0608 0.0771 0.0814 0.0900 0.0950 0.1000

0 commit comments

Comments
 (0)