Está en la página 1de 10

Programación Para Ciencia y Tecnología (PPCT)

Práctica 3: Aproximación de Funciones

Curso 2022/23

1. Objetivos
El objetivo de esta práctica es implementar y aplicar métodos para aproximar funciones
reales de variable real, tanto mediante la técnica de mínimos cuadrados como mediante la
técnica de splines de interpolación.

2. Problema objeto de estudio


Utilizaremos las técnicas de aproximación de funciones para resolver el siguiente problema.
Queremos estudiar el redimiento de una turbina eólica de generación de electricidad. Para
ello, se han realizado mediciones, en distintos momentos, de la velocidad del viento y de la
potencia generada a esa velocidad. Los datos se presentan en la siguiente tabla:
Medición 1 Medición 2 Medición 3 Medición 4 Medición 5 Medición 6
Viento (m/s) 5.3 7.7 8.7 11.2 12.5 14.1
Potencia (kW) 0.910 2.556 3.807 9.450 12.986 17.059

A partir de esos datos, queremos poder predecir la potencia generada para cualquier
velocidad de viento dentro del intervalo [5.3, 14.1]. Para ello, podemos recurrir a mínimos
cuadrados o bien a interpolación.
Si los datos tienen cierto error y queremos una aproximación polinómica que exprese la
relación entre las variables sin que necesariamente pase por los puntos de partida, elegiremos
mínimos cuadrados.
Si por el contrario queremos que la función de aproximación pase exactamente por los
puntos, usaremos interpolación.

1
3. Aproximación mediante mínimos cuadrados
3.1. Dibujo de los puntos de partida
Si las coordenadas de los puntos de partida se encuentran en las variables x e y (como
simples listas de valores), para dibujarlos en una gráfica basta con ejecutar la siguiente orden
(previamente hemos de importar pyplot, por ejemplo mediante import matplotlib.pyplot
as plt):
>>> plt.plot(x,y,'*')

Ejercicio 1.
Dibuja los puntos de partida correspondientes a la tabla de datos de nuestro problema.
Dado que queremos predecir la potencia en función de la velocidad de viento, dicha
velocidad será la variable independiente (x).
Comprueba que la gráfica obtenida coincide con la de la Figura 1.

Figura 1: Gráfica de los puntos de partida.

3.2. Trabajando con polinomios con numpy


La librería numpy dispone de la clase Polynomial para trabajar con polinomios. Podemos
importarla con la orden:
from numpy.polynomial import Polynomial

2
Las siguientes líneas de código construyen el polinomio P (x) = 1 + 2x + 3x2 , lo muestran
usando print y lo evalúan en x = 2.5:
>>> p=Polynomial([1,2,3])
>>> print(p)
1.0 + 2.0 x**1 + 3.0 x**2
>>> p(2.5)
24.75

La secuencia de coeficientes ([1,2,3] en el ejemplo) puede ser una lista o un array de numpy.
También se puede evaluar de una sola vez un polinomio en un conjunto de puntos (va-
lores de x). Por ejemplo, el siguiente código evalúa el polinomio anterior en los puntos
[0.2, 0.5, 0.6, 0.9]:
>>> x=np.array([0.2, 0.5, 0.6, 0.9])
>>> p(x)
array([1.52, 2.75, 3.28, 5.23])

El conjunto de puntos se debe proporcionar en forma de array.

3.3. Cálculo del polinomio de aproximación de mínimos cuadrados


A partir de las coordenadas de un conjunto de puntos de partida, el Algoritmo 1 cal-
cula los coeficientes del polinomio de aproximación Pm (x) por mínimos cuadrados. Para su
implementación en Python conviene tener en cuenta lo siguiente:
La descomposición QR de la matriz E se hace de la siguiente forma:
Q,R=linalg.qr(E,mode='economic')
El argumento mode='economic' indica que no se desea calcular la matriz ortogonal
completa, sino solo las (m + 1) primeras columnas.

El sistema de ecuaciones lineales puede resolverse mediante la función linalg.solve


o mediante la función sustitucion_inversa de la práctica 1.

Ejercicio 2.
Implementa una función de Python, con el nombre polinomio_aproximacion, co-
rrespondiente al Algoritmo 1.
A continuación, calcula el polinomio de aproximación de grado 2 que mejor se ajusta
a los puntos de la tabla de datos de nuestro problema. Comprueba que el polinomio que
obtienes es

P (x) = 2.699838 − 1.234931x + 0.161672x2 .

3
Algoritmo 1: polinomio_aproximacion
Entrada: x, y: vectores de n elementos con las coordenadas de los puntos de partida
m: grado del polinomio de aproximación
Resultado: p: polinomio de aproximación
1 construir la matriz E, de dimensiones n × (m + 1), mediante la fórmula:
m−1
 
m
1 x1 x21 · · · x1 x1
m−1
1 x2 x22 · · · x2 xm
 
2 
x3 x23 · · · xm−1 xm
 
1
E=

3 3 
. .. .. . . .. .. 
 .. . . . . . 
 
1 xn x2n · · · xm−1n xm
n
2 calcular la descomposición QR de E (E = QR)
3 construir el vector de términos independientes b = QT y
4 resolver el sistema lineal triangular superior Ra = b
5 p = polinomio cuyos coeficientes son los del vector a

Ejercicio 3.
El polinomio de aproximación permite obtener nuevas aproximaciones de la variable
dependiente.
¿Cuál sería la potencia generada para una velocidad de viento de 10 m/s?
Solución: 6.51775 kW.

3.4. Cálculo del error cuadrático medio


Ejercicio 4.
Implementar una función, con el nombre error_cuadratico_medio, que evalúe la
expresión
n
(Pm (xi ) − yi )2
X

i=1
,
n
encargada de calcular el error cuadrático medio cometido. Los datos de entrada y el
resultado de la función deben ser los siguientes:
Entrada: x, y: vectores de n elementos con las coordenadas de los puntos de partida
p: polinomio de aproximación
Resultado: error cuadrático medio

A continuación, utiliza dicha función para calcular el error cuadrático medio corres-
pondiente al polinomio de aproximación obtenido en el ejercicio 2. El resultado debería
ser 0.114029.

4
3.5. Dibujo del polinomio de aproximación
Una vez obtenido el polinomio de aproximación y el error cuadrático medio, procederemos
a dibujarlo gráficamente, añadiéndolo a los puntos de partida (ejercicio 1). Para ello, basta
con las siguientes órdenes:
>>> vx=np.linspace(min(x),max(x),200)
>>> vy=p(vx)
>>> plt.plot(vx,vy)

Figura 2: Gráfica de polinomio de aproximación y los puntos de partida.

Ejercicio 5.
Dibuja una gráfica donde aparezcan los puntos de partida del ejercicio 1 junto con
el polinomio de aproximación obtenido en el ejercicio 2. Comprueba que obtienes una
gráfica como la de la figura 2.

5
4. Aproximación mediante splines
Pasamos ahora a considerar la aproximación mediante splines, la cual sería adecuada
en caso de que supongamos que los puntos de partida no contienen error, de manera que
queremos que la función de aproximación pase por los puntos de partida.

4.1. Cálculo de los parámetros de un spline cúbico con frontera


libre
El algoritmo 2 se encarga de obtener los parámetros de un spline cúbico de frontera libre.
Algoritmo 2: spline_libre
Entrada: x, y: vectores de n componentes con las coordenadas de los puntos base
Resultado: h: vector con la distancia entre dos elementos consecutivos del vector x
m: vector con el valor de la segunda derivada en los puntos base
1 construir el vector h, dado por
hi = xi+1 − xi , i ∈ rango(n − 1)
2 construir la matriz A de coeficientes, dada por
 
1 0 0 0 ··· 0
h1 2(h1 + h2 ) h2 0 ··· 0 
 
 
0
 h2 2(h2 + h3 ) h3 ··· 0 
 
 
A=  .
 . .. ... ... ... .. 
 . . . 

 
 
 
0

0 ··· hn−2 2(hn−2 + hn−1 )
hn−1 

0 0 ··· 0 0 1
3 construir el vector b, parte derecha del sistema de ecuaciones, dado por
 
0
y3 − y2 y2 − y1
   
 6 − 
h h
 
 2 1 
y4 − y3 y3 − y2
   

6 − 
h3 h2
 
b=
 
.. 
.
 
 
 !
 y n − y n−1 yn−1 − y n−2 

6 −
hn−1 hn−2
 
 
0
4 obtener m, solución del sistema de ecuaciones lineales Am = b

Ejercicio 6.
Implementa en Python una función con el nombre spline_libre, correspondiente al
Algoritmo 2.
A continuación, utiliza la función para calcular el spline cúbico con frontera libre

6
correspondiente a los puntos de la tabla de datos de nuestro problema. Comprueba que
obtienes los siguientes resultados:
h i
h = 2.4 1. 2.5 1.3 1.6
h i
m = 0 0.38813 0.75169 0.1549 −0.21511 0

Si los resultados no coinciden, comprueba si la matriz A y el vector b han sido gene-


rados correctamente. Deberían ser:
   
1 0 0 0 0 0 0
2.4 6.8 1 0 0 0  3.391 
  

 0 1 7 2.5 0 0  6.0372 
   
A=
 0
, b= 
 0 2.5 7.6 1.3 0 

 2.7768 
 
 0 0 0 1.3 5.8 1.6 −1.04625
   

0 0 0 0 0 1 0

4.2. Cálculo de los parámetros de un spline cúbico con frontera


sujeta
El algoritmo 3 se encarga de obtener los parámetros de un spline cúbico de frontera sujeta.
Observa que el algoritmo es casi igual que el de frontera libre; solo cambian algunos elementos
en la primera y la última fila A y b (elementos en negrita).
En la implementación en Python del algoritmo 3, hay que tener en cuenta, en especial al
dar valor a los elementos de la primera y última fila de A y b (elementos en negrita), que los
índices de los vectores h e y empiezan en cero en vez de en uno.

Ejercicio 7.
Implementa en Python una función con el nombre spline_sujeto, correspondiente
al Algoritmo 3.
A continuación, utiliza la función para calcular el spline cúbico con frontera sujeta
correspondiente a los puntos de la tabla de datos de nuestro problema, y con derivadas
en los extremos f ′ (x1 ) = 1.5 y f ′ (xn ) = 4.1. Comprueba que obtienes los siguientes
resultados:
h i
h = 2.4 1. 2.5 1.3 1.6
h i
m = −1.4857 0.935989 0.591959 0.382999 −1.24145 3.53518

Si los resultados no coinciden, comprueba si la matriz A y el vector b han sido generados


correctamente. Deberían ser los siguientes (aparecen en negrita los únicos elementos que

7
Algoritmo 3: spline_sujeto
Entrada: x, y: vectores de n componentes con las coordenadas de los puntos base
dx1 : derivada de la función en el punto x1
dxn: derivada de la función en el punto xn
Resultado: h: vector con la distancia entre dos elementos consecutivos del vector x
m: vector con el valor de la segunda derivada en los puntos base
1 construir el vector h dado por
hi = xi+1 − xi , i ∈ rango(n − 1)
2 construir la matriz A de coeficientes dada por
 
2h1 h1 0 0 ··· 0
 h1 2(h1 + h2 ) h2 0 ··· 0 
 
 
 0
 h2 2(h2 + h3 ) h3 ··· 0  
 
 
A=  .. .. ... ... ... .. 
. . . 
 

 
 
 

 0 0 ··· hn−2 2(hn−2 + hn−1 ) hn−1 

0 0 ··· 0 hn−1 2hn−1
3 construir el vector b, parte derecha ! 
del sistema de ecuaciones, dado por
y2 − y1

 6 − f ′ (x1 )
 h1

 
y3 − y2 y2 − y1
  
6 −
 
 
 h2 h1

y − y y − y
   
4 3 3 2

 
 6 
b=
 h3 h2

..
 


 . 
!

yn − yn−1 yn−1 − yn−2 
6 −
 


 hn−1 hn−2 !  


yn − yn−1

6 f (xn ) −
 
hn−1
4 obtener m, solución del sistema de ecuaciones lineales A m = b

8
son diferentes del caso de frontera libre):
   
4.8 2.4 0 0 0 0 -4.885

 2.4 6.8 1 0 0 0 
  3.391 
 
 0 1 7 2.5 0 0  6.0372 
   

A=
 , b=
 
 0 0 2.5 7.6 1.3 0   2.7768 


 0 0 0 1.3 5.8 1.6  −1.04625
   

0 0 0 0 1.6 3.2 9.32625

4.3. Función que evalúa un spline en un punto


La función evalua_spline, proporcionada como material de la práctica, evalúa S(x),
valor del spline en un punto x. Para ello averigua, en primer lugar, el intervalo al que corres-
ponde el punto a evaluar, es decir, obtiene k tal que x ∈ [xk , xk+1 ]. A continuación, evalúa
Sk (x), donde Sk es el polinomio correspondiente al intervalo k.
La evaluación de Sk (x) se hace mediante otra función auxiliar, llamada sk, que utiliza la
fórmula vista en las clases de teoría:
! !
(xk+1 − x)3 (x − xk )3 yk+1 hk yk hk
Sk (x) = mk + mk+1 + − mk+1 (x−xk )+ − mk (xk+1 −x)
6hk 6hk hk 6 hk 6

Ejercicio 8.
Los splines permiten obtener nuevas aproximaciones de la variable dependiente.
¿Cuál sería, según el spline de frontera libre, la potencia generada para una velocidad
de viento de 10 m/s? ¿y según el spline de frontera sujeta?
Solución:
6.39089 kW según el spline de frontera libre.
6.36221 kW según el spline de frontera sujeta.

4.4. Dibujo del spline


La función dibuja_spline, proporcionada también como material de la práctica, dibuja
por pantalla un spline previamente calculado. Esta función utiliza la función evalua_spline
para evaluar el spline en cada punto.

Ejercicio 9.
Dibuja, por medio de la función dibuja_spline, los splines obtenidos en los ejercicios
6 y 7, junto con los puntos base. Comprueba que las gráficas obtenidas coinciden con las
de la figura 3.

9
Figura 3: Gráfica del spline libre (izquierda) y sujeto (derecha), con los puntos de partida.

10

También podría gustarte