Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lagrange interpolation in Python

I want to interpolate a polynomial with the Lagrange method, but this code doesn't work:

def interpolate(x_values, y_values):
    def _basis(j):
        p = [(x - x_values[m])/(x_values[j] - x_values[m]) for m in xrange(k + 1) if m != j]
        return reduce(operator.mul, p)

    assert len(x_values) != 0 and (len(x_values) == len(y_values)), 'x and y cannot be empty and must have the same length'

    k = len(x_values)
    return sum(_basis(j) for j in xrange(k))

I followed Wikipedia, but when I run it I receive an IndexError at line 3!

Thanks

like image 601
rubik Avatar asked Oct 23 '10 11:10

rubik


1 Answers

I'm almost a decade late to the party, but I found this searching for a simple implementation of Lagrange interpolation. @smichr's answer is great, but the Python is a little outdated, and I also wanted something that would work nicely with np.ndarrays so I could do easy plotting. Maybe others will find this useful:

import numpy as np
import matplotlib.pyplot as plt


class LagrangePoly:

    def __init__(self, X, Y):
        self.n = len(X)
        self.X = np.array(X)
        self.Y = np.array(Y)

    def basis(self, x, j):
        b = [(x - self.X[m]) / (self.X[j] - self.X[m])
             for m in range(self.n) if m != j]
        return np.prod(b, axis=0) * self.Y[j]

    def interpolate(self, x):
        b = [self.basis(x, j) for j in range(self.n)]
        return np.sum(b, axis=0)


X  = [-9, -4, -1, 7]
Y  = [5, 2, -2, 9]

plt.scatter(X, Y, c='k')

lp = LagrangePoly(X, Y)

xx = np.arange(-100, 100) / 10

plt.plot(xx, lp.basis(xx, 0))
plt.plot(xx, lp.basis(xx, 1))
plt.plot(xx, lp.basis(xx, 2))
plt.plot(xx, lp.basis(xx, 3))
plt.plot(xx, lp.interpolate(xx), linestyle=':')
plt.show()
like image 79
jds Avatar answered Oct 08 '22 06:10

jds