Search code examples
pythoninterpolationnumeric

Interpolation polynomial with chebyshev nodes python


I'm trying to interpolate a function f(x) in my four chebyshev nodes, but I get the error "list index out of range" in my lagrange function:

line 47, in lagrange poly = poly + ydata[i]*l[i]

IndexError: list index out of range

I'm not very good at python, and cant seem to fix the problem. I have tried checking the length of ydata but my code is so long so if I comment something out, it just gives more errors:)) Also tried changing my n and input in the range. Any tips and trick would be greatly appreciated.

import numpy as np
from numpy import pi
import matplotlib.pyplot as plt

newparams = {'figure.figsize': (6.0, 6.0), 'axes.grid': True,
             'lines.markersize': 8, 'lines.linewidth': 2,
             'font.size': 14}
plt.rcParams.update(newparams)

#LEGGER INN NØDVENDIGE FUNKSJONER

#definerer funksjonen f
def f(x):                         
    return 2**(x**2-6*x+9) 


#chebyshev noder
def chebyshev_nodes(a, b, n):
    # n Chebyshev noder i intervallet [a, b]
    i = np.array(range(n))
    x = np.cos((2*i+1)*pi/(2*(n))) # noder over intervallet [-1,1]
    return 0.5*(b-a)*x+0.5*(b+a) # noder over intervallet [a,b]

#kardinalfunksjonene
def cardinal(xdata, x):
    n=len(xdata)
    l = []
    for i in range(n):
        li = np.ones(len(x))
        for j in range(n):
            if i is not j:
                li = li*(x-xdata[j])/(xdata[i]-xdata[j])
        l.append(li)
        return l

#lagrange
def lagrange(ydata, l):
    poly = 0
    for i in range(len(ydata)):
        poly = poly + ydata[i]*l[i]
    return poly
    
            
a, b = 2, 5                      #endepunkter til intervallet                      
x = np.linspace(a,b,101)         #x-veridene for plotting
 
#antall noder/interpolasjonspunktene                                       
n = 4;  
xdata = chebyshev_nodes(a, b, n+1)       #Chebyshev-nodene
ydata = f(xdata);

#evaluering av interpolasjonspolynomet i x-verdiene
l =cardinal(xdata, x)
p =lagrange(ydata, l)

# Plot f(x) og p(x) and the interpolation points
plt.subplot(2,1,2)                  
plt.plot(x, f(x), x, p, xdata, ydata, 'o')
plt.legend(['f(x)','p(x)'])
plt.grid(True)

Solution

  • It's a very simple error. In your function cardinal return l is indented too far, which means it will return on the first value in the for loop rather than at the end. So whatever that function return will be a length 1 list rather than length n.