73. Polynomial interpolation: Newton interpolation#
Anne Kværnø (modified by André Massing)
Date: Jan 18, 2021
If you want to have a nicer theme for your jupyter notebook, download the cascade stylesheet file tma4125.css and execute the next cell:
import matplotlib.pyplot as plt
import numpy as np
from IPython.core.display import HTML
from numpy import pi
from numpy.linalg import norm, solve # Solve linear systems and compute norms
def css_styling():
try:
with open("tma4125.css") as f:
styles = f.read()
return HTML(styles)
except FileNotFoundError:
pass # Do nothing
# Comment out next line and execute this cell to restore the default notebook style
css_styling()
And of course we want to import the required modules.
%matplotlib inline
newparams = {
"figure.figsize": (6.0, 6.0),
"axes.grid": True,
"lines.markersize": 8,
"lines.linewidth": 2,
"font.size": 14,
}
plt.rcParams.update(newparams)
73.1. Newton interpolation#
This is an alternative approach to find the interpolation polynomial.
Let
or in more compact notation
The so-called
Newton form of a polynomial of degree
or more explicitly
In the light of this form of writing a polynomial, the polynomial
interpolation problem leads to the following observations. Let us
start with a single node
Going one
step further and consider two nodes
Given three nodes
we deduce the coefficient
Playing with this quotient gives the much more structured expression
This procedure can be continued and yields a so-called triangular
systems that permits to define the remaining coefficients
We introduce the folllwing so-called finite difference notation for a
function
The second order finite difference is defined by
In general, the nth order finite difference of the function
Newton’s method to solve the polynomial interpolation problem can be
summarized as follows. Given
then the coefficients
for
In fact, a recursion is in place
It is common to write the finite differences in a table, which for
Example 1 again: Given the points in Example 1. The corresponding table of divided differences becomes:
and the interpolation polynomial becomes
73.2. Implementation#
The method above is implemented as two functions:
divdiff(xdata, ydata)
: Create the table of divided differencesnewtonInterpolation(F, xdata, x)
: Evaluate the interpolation polynomial.
Here, xdata
and ydata
are arrays with the interpolation points, and x
is an
array of values in which the polynomial is evaluated.
def divdiff(xdata, ydata):
# Create the table of divided differences based
# on the data in the arrays x_data and y_data.
n = len(xdata)
F = np.zeros((n, n))
F[:, 0] = ydata # Array for the divided differences
for j in range(n):
for i in range(n - j - 1):
F[i, j + 1] = (F[i + 1, j] - F[i, j]) / (xdata[i + j + 1] - xdata[i])
return F # Return all of F for inspection.
# Only the first row is necessary for the
# polynomial.
def newton_interpolation(F, xdata, x):
# The Newton interpolation polynomial evaluated in x.
n, m = np.shape(F)
xpoly = np.ones(len(x)) # (x-x[0])(x-x[1])...
newton_poly = F[0, 0] * np.ones(len(x)) # The Newton polynomial
for j in range(n - 1):
xpoly = xpoly * (x - xdata[j])
newton_poly = newton_poly + F[0, j + 1] * xpoly
return newton_poly
Run the code on the example above:
# Example: Use of divided differences and the Newton interpolation
# formula.
xdata = [0, 2 / 3, 1]
ydata = [1, 1 / 2, 0]
F = divdiff(xdata, ydata) # The table of divided differences
print("The table of divided differences:\n", F)
x = np.linspace(0, 1, 101) # The x-values in which the polynomial is evaluated
p = newton_interpolation(F, xdata, x)
plt.plot(x, p) # Plot the polynomial
plt.plot(xdata, ydata, "o") # Plot the interpolation points
plt.title("The interpolation polynomial p(x)")
plt.grid(True)
plt.xlabel("x");