Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Newton Neville

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 9

Notebook

May 1, 2014

1 POLINOMIO INTERPOLADOR DE NEWTON


Tomamos como puntos de interpolación los puntos (no necesariamente equiespaciados):

(x1 , y1 ), (x2 , y2 ), . . . , (xn , yn )

El polinomio interpolador de Newton lo expresaremos mediante la base:

{1, (x − x1 ), (x − x1 )(x − x2 ), (x − x1 )(x − x2 )(x − x3 ), . . . , (x − x1 )(x − x2 ) · · · (x − xn )}

El polinomio interpolador expresado respecto esta base es:

pn (x) = cn+1 + cn (x − x1 ) + cn−1 (x − x1 )(x − x2 ) + · · · + c1 (x − x1 )(x − x2 ) · · · (x − xn )

Para averiguar los coeficientes lo hacemos mediante las Diferencias Divididas:

cn+1 = f [x1 ]

f [x2 ] − f [x1 ]
cn = = f [x1 , x2 ]
x2 − x1
cn−k+1 = f [x1 , x2 , . . . xk+1 ]
Hay que tener en cuenta que, en general, las diferencias de orden k vienen definidas por:

f [xi+1 , xi+2 , . . . , xi+k ] − f [xi , xi+1 , . . . , xi+k−1 ]


f [xi , xi+1 , . . . , xi+k ] =
xi+k − xi

Si calculamos todas las diferencias divididas las podemos almacenar en una matriz triangular inferior. De
dicha matriz los elementos de la diagonal principal son los coeficientes de nuestro polinomio interpolador de
Newton.

2 ALGORITMO INTERPOLADOR DE NEVILLE


Dentro de la interpolación polinómica tenemos el algoritmo de Neville, el cual se basa en el polinomio inter-
polador de Newton y en el algoritmo de Aitken. Partimos de un conjunto de n+1 puntos no necesariamente
equiespaciados (xi , yi ); 0 ≤ i ≤ n. Denotemos por pi, j el polinomio de grado j − i, el cual pasa por los
puntos (xk , yk ); k = i, i + 1, . . . , j. El pi j satisface la siguiente relación de recurrencia:

(xj − x)pi, j−1 (x) + (x − xi )pi+1, j (x)


pi, i (x) = yi 0 ≤ i ≤ npi, j (x) = 0≤i<j≤n
xj − xi

Dicha recurrencia nos da el valor que buscamos, p0, n (x)

1
2.0.1 EJEMPLO:
Consideremos la siguiente tabla de valores:

In [6]: import pandas


pandas.core.format.set_option(’display.notebook_repr_html’,True)
df = (pandas.read_csv(’data.csv’)).T
df

Out[6]: 0 1 2 3 4 5
x 0.15000 2.30000 3.1500 4.85000 6.25000 7.95000
y 4.79867 4.49013 4.2243 3.47313 2.66674 1.51909

Vamos a aplicar en dichos datos el polinomio interpolador de Newton y el algoritmode Neville. Tendremos
πx 
en cuenta que los datos de la tabla son aproximaciones de la función f (x) = 4.8 cos Para ello hemos
20
creado un módulo python en el que hemos definido mediante funciones los dos métodos vistos aquı́. Dibujamos
a parte la función de la que tenemos sus aproximaciones en la tabla.

In [22]: %matplotlib inline


import matplotlib.pyplot as plt
import numpy as np

f = lambda x: 4.8 * np.cos((np.pi * x) / 20)

fig, ax = plt.subplots(1)
fig.set_size_inches(10, 10)
x = np.linspace(0., 8., 100)
plt.plot(x, f(x), ’b-’)
ax.axis([0, 8, 0, 5])
ax.set_title(’$f(x)$’, color=’blue’, fontsize=18)
vector_legend = [’$f(x)$’]
mylegend = ax.legend(vector_legend, loc=4, ncol=3, fancybox=True,
prop={’size’:8}, title=’$FUNCION REAL$’)
plt.setp(mylegend.get_title(),fontsize=’18’, color=’red’)
plt.setp(mylegend.get_texts(),fontsize=’14’, color=’black’)
frame = mylegend.get_frame()
frame.set_facecolor(’0.95’)
ax.set_xlabel(’$Abscisa\; x$’, color=’blue’, fontsize=16)
ax.set_ylabel(’$Ordenada\; y$’, color=’blue’, fontsize=16)
xtcks = np.arange(0, 8)
xtckslatex = []
for i in xtcks:
xtckslatex.append(’$’ + str(i) + ’$’ )
ytcks = np.arange(0, 5)
ytckslatex = []
for i in ytcks:
ytckslatex.append(’$’ + str(i) + ’$’ )
ax.set_xticks(xtcks, xtckslatex)
ax.set_yticks(ytcks, ytckslatex)
ax.grid(’on’)
plt.show()
plt.close()

2
In [7]: %load diferencias.py

Éste es el código del módulo que utilizaremos para resolver el ejemplo. Consta de 4 funciones que están
debidamente documentadas siguiendo los estándares para la creación de la documentación en Python.

In []: __author__ = ’tobal’

#/usr/bin/env python3
# -*- coding: utf-8 -*-

from sympy import symbols


import numpy as np
from numpy import zeros, diag

3
x = symbols(’x’)

def diferencias(x, y, n):


’’’
(array, array, int) -> array
Dados los n datos de una tabla (x,y) calcula sus diferencias
divididas. Nos devuelve un array con los elementos de la
diagonal principal, que son los coeficientes del polinomio
de Taylor.
’’’
T = y
for k in range(1, n + 1):
T[k: n] = (T[k: n] - T[k - 1]) / (x[k: n] - x[k - 1])
return T

def polnewton(diff, x, x0):


’’’
(array, array, float) -> list
Dados los coeficientes del Polinomio de Taylor con diff y el vector
de abscisas x nos calcula las aproximaciones del Polinomio de Taylor
centradas en el punto x0.
En una lista nos devuelve con pol el valor aproximado, y con P un array
con todas las aproximaciones obtenidas en cada paso y ası́ poderlas dibujar.
’’’
n = len(x) - 1
P = np.zeros(len(x), dtype=float)
pol = diff[n]
for k in range(1, n + 1):
pol = diff[n - k] + (x0 - x[n - k])*pol
P[k] = pol
return [pol, P]

def polnewtonsym(diff, xx):


’’’
(array, array) -> polynomial
Calcula la expresión simbólica (algebraica) del Polinomio de Taylor.
’’’
n = len(xx) - 1
pol = diff[n]
for k in range(1, n + 1):
pol = diff[n - k] + (x - xx[n - k])*pol
return pol

def polneville(x, y, x0):


’’’
(array, array, float) -> list
Calcula la aproximación interpolante en un punto x0 mediante el algoritmo
de Neville. En una lista nos devuelve la aproximación final y las
aproximaciones en cada paso en un array para poder dibujarlas.
’’’

4
Q = np.zeros((len(x), len(x)), dtype=float)
for k in range(0, len(x)):
Q[k][0] = y[k]

for i in range(1, len(x)):


for j in range(1, i + 1):
Q[i][j] = ((x0-x[i-j])*Q[i][j-1]-(x0-x[i])*Q[i-1][j-1])/(x[i]-x[i-j])

return [Q[-1][-1], np.diag(Q, 0)]

In [36]: %matplotlib inline

In [37]: %load newtonvsneville.py

In [23]: __author__ = ’tobal’

#/usr/bin/env python3
# -*- coding: utf-8 -*-

import numpy as np
from numpy import array, cos, pi
from sympy import symbols, init_printing, lambdify, horner, expand, pprint
from diferencias import diferencias, polnewton, polnewtonsym, polneville
import matplotlib.pyplot as plt
from matplotlib import rcParams

rcParams[’text.latex.unicode’] = True
rcParams[’text.usetex’] = True
rcParams[’text.latex.preamble’] = ’\\usepackage{amsthm}’,
’\\usepackage{amsmath}’, ’\\usepackage{amssymb}’,
’\\usepackage{amsfonts}’, ’\\usepackage[T1]{fontenc}’, ’\\usepackage[utf8]{inputenc}’

x = symbols(’x’)

init_printing(use_unicode=True)

datosx = np.array([0.15, 2.3, 3.15, 4.85, 6.25, 7.95], dtype=float)


datosy = np.array([4.79867, 4.49013, 4.2243, 3.47313, 2.66674, 1.51909], dtype=float)
datosy2 = datosy.copy()
diff = diferencias(datosx, datosy, len(datosx))
pprint(’ALGORITMOS INTERPOLADORES DE NEWTON Y DE NEVILLE.’)
pprint(’=================================================’)
print()
pprint(’Introduce el valor en el que desees interpolar: ’)
interpolar = eval(input())
valor = polnewton(diff, datosx, interpolar)[0]
pprint(’Para {0} obtenemos {1} con Newton. ’.format(interpolar, valor))

valorN = polneville(datosx, datosy2, interpolar)[0]


pprint(’Para {0} obtenemos {1} con Neville. ’.format(interpolar, valorN))
polnewtonsym = polnewtonsym(diff, datosx)
pprint(’El polinomio interpolador de Newton es:’)
pprint(expand(polnewtonsym))
polnewtonsym = horner(polnewtonsym)

5
P = lambdify(x, polnewtonsym, ’numpy’)

f, (ax1, ax2) = plt.subplots(1, 2)


f.set_size_inches(15, 15)
f.subplots_adjust(hspace=0)
f.suptitle(r’$ALGORITMOS\; DE\; NEWTON\; Y\; NEVILLE.$’, fontsize=20)
title1 = r’$Polinomio \; Interpolador \; Newton \; Grado \; n={}$’.format(len(datosx) - 1)
ax1.set_title(title1, fontsize=18)
title2 = r’$Newton\; Vs.\; Neville.\; n\; =\; {}$’.format(len(datosx))
ax2.set_title(title2, fontsize=18)
t = np.linspace(datosx[0], datosx[-1], 1000)

ax1.xaxis.label.set_fontsize(20)
ax1.yaxis.label.set_fontsize(20)
ax1.set_xlabel(r’$Datos\; x$’, color=’blue’)
ax1.set_ylabel(r’$Datos\; y$’, color=’blue’)

ax2.xaxis.label.set_fontsize(20)
ax2.yaxis.label.set_fontsize(20)
ax2.set_xlabel(r’$Datos\; x$’, color=’blue’)
ax2.set_ylabel(r’$Datos\; y$’, color=’blue’)

ax1.axis([0.0, 8.0, -2.0, 5.0])


ax2.axis([0.0, 8.0, -2.0, 5.0])

ax1.grid(’on’)
ax2.grid(’on’)

ax1.scatter(datosx, datosy2, c=’r’, s=70, edgecolors=’r’)


ax1.scatter(interpolar, valor, c=’g’, s=70, edgecolors=’g’)
ax1.plot(t, P(t), ’b-’, lw=1.5)

text1 = r’$Pol.\; Newton$’


text2 = r’$Puntos\; Tabla$’
text3 = r’$P({0},\; {1})$’.format(interpolar, valor)

legend = ax1.legend([text1, text2, text3], scatterpoints=1, markerscale = 1.5, shadow=True)


frame = legend.get_frame()
frame.set_facecolor(’0.90’)

ax2.scatter(datosx, polnewton(diff, datosx, interpolar)[1], c=’r’, s=70, edgecolors=’r’)


ax2.plot(datosx, polnewton(diff, datosx, interpolar)[1], ’r-’, lw=1.5)
ax2.scatter(datosx, polneville(datosx, datosy2, interpolar)[1], c=’b’, s=70, edgecolors=’g’)
ax2.plot(datosx, polneville(datosx, datosy2, interpolar)[1], ’b-’, lw=1.5)

xtcks = np.arange(0, 9)
xtckslatex = []
for i in xtcks:
xtckslatex.append(’$’ + str(i) + ’$’ )
ytcks = np.arange(-2, 6)
ytckslatex = []
for i in ytcks:
ytckslatex.append(’$’ + str(i) + ’$’ )

6
ax1.set_xticklabels(xtckslatex, fontsize=18)
ax1.set_yticklabels(ytckslatex, fontsize=18)

ax2.set_xticklabels(xtckslatex, fontsize=18)
ax2.set_yticklabels(ytckslatex, fontsize=18)

text21 = r’$Puntos\; Aprox.\; Newton$’


text22 = r’$Poligonal\; Aprox.\; Nevwton$’
text23 = r’$Puntos\; Aprox.\; Neville$’
text24 = r’$Poligonal\; Aprox.\; Neville$’

legend2 = ax2.legend([text22, text24, text21, text23], scatterpoints=1,


markerscale = 1.5, shadow=True, loc=4)
frame2 = legend2.get_frame()
frame2.set_facecolor(’0.90’)

plt.show()
plt.close()

ALGORITMOS INTERPOLADORES DE NEWTON Y DE NEVILLE.


=================================================

Introduce el valor en el que desees interpolar:


3.5
Para 3.5 obtenemos 4.092666147572255 con Newton.
Para 3.5 obtenemos 4.092666147572256 con Neville.
El polinomio interpolador de Newton es:
5 4 3
- 2.30081527502247e-6·x + 0.000142856446368703·x - 9.39713572923442e-5·x -

2
0.0590145616002341·x - 0.00018014557743914·x + 4.80002509447959

7
Conclusión En el código anterior lo hemos ejecutado para calcular el valor aproximado interpolador 3.5
para ambos  métodos. Vemos que por ambos métodos obtenemos una muy buena aproximación de la función
π · x
f (x)4.8 · cos en f (3) . Como polinomio interpolador de Newton hemos obtenido la expresión: P (x) =
20
−2.30081527502247·10−6 ·x5 +0.000142856446368703·x4 −9.39713572923442·10−5 ·x3 −0.0590145616002341·
x2 −0.00018014557743914·x+4.80002509447959 En la primera gráfica de la imagen de arriba si la comparamos
con la gráfica de la función f (x) vemos que es prácticamente la misma, con lo que el Método de Newton nos
da resultados satisfactorios. En la segunda gráfica comparamos Neville y Newton con el valor aproximado
que obtenemos para 3.5. Apreciamos que ambos convergen a la misma solución (decimal arriba, decimal
abajo), pero Neville converge mucho más suave y monótonamente que Newton. Con lo que todo nos hace
indicar que para interpolar más valores de nuestro ejemplo nos decantarı́amos por Neville. Cosa que no
deberı́a extrañarnos, ya que en condiciones normales, Neville es una mejora de Newton.

8
2.1 REFERENCIAS:
[1] http://en.wikipedia.org/wiki/Newton polynomial [2] http://en.wikipedia.org/wiki/Neville%27s algorithm
[3] http://en.wikipedia.org/wiki/Category:Interpolation

In []:

También podría gustarte