5. Polynomial Interpolation#
In this chapter we provide basic implementation of polynomial interpolation methods.
5.1. Polynomials in Newton’s form#
We begin by providing the implementation of the nested-multiplication method for the evaluation of a polynomial at a given input point.
def evaluate_by_nested_multiplication(t:float,x:list,c:list):
'''
Evaluates the polynomial at a given point t.
:param t: the point at which the polynomial must be evaluated.
:param x: the n+1-dimensional vector of x, [x_0,\ldots,x_n]
:param c: the n+1-dimensional vector of coefficients, [c_0,\ldots,c_n]
:return: the value of the polynomial at t.
'''
# Identifies the lenght of x
n = len(x) # n+1 dimensional
# Initializes u=c_n
u = c[n - 1]
# For i = n-1,...,0 (with decrements of -1)
for i in range((n - 1) - 1, 0 - 1, -1):
u = c[i] + (t - x[i]) * u
return u
5.1.1. Example 1#
Assume we have a polynomial of degree \(n=2\) in Newton’s form, defined by the coefficients \(c=[3.75,-1.5,1]\) and by the values \(x=[-1/2,0,1/2,2]\). The polynomial is
Let us evaluate the polynomial at the \(x\) points.
X = [-1/2,0,1/2]
c = [3.75,-1.5,1]
for t in X:
print(f'p_2({t})={evaluate_by_nested_multiplication(t,X,c)}')
p_2(-0.5)=3.75
p_2(0)=3.0
p_2(0.5)=2.75
5.2. Computation of the coefficients by nested multiplication#
We now turn our attention to the computation of the coefficients. We extend the nested multiplication algorithm to compute the coefficients.
def coefficients_by_nested_multiplication(x:list, y:list):
'''
Computes the coefficients of the Newton interpolating polynomial.
:param x: List of x-coordinates of the data points.
:param y: List of y-coordinates of the data points.
:return: List of coefficients of the Newton interpolating polynomial.
'''
# Identifies the number of points
n = len(x)
# Initializes the vector of coefficients
c = [0] * n
# Inizializes c_0
c[0] = y[0]
# For k = 1,...,n
for k in range(1, n):
# Populates d
d = x[k] - x[k - 1]
# Populates u
u = c[k - 1]
# For i = k-2,...,0
for i in range(k - 2, -1, -1):
a = x[k] - x[i]
u = c[i] + u * a
d = a * d
c[k] = (y[k] - u) / d
return c
5.2.1. Example 1#
Let us use the same example we have seen for the evaluation of a given polynomial. This time, assume we are give the points \(x=[-0.5, 0, 0.5, 2]\) and \(y=[3.75, 3, 2.75, 5]\) and we wish to find the interpolating polynomial in Newton’s form.
x = [-0.5, 0, 0.5, 2]
y = [3.75, 3, 2.75, 5]
# Let us find the coefficients of the Newton's polynomial which interpolates the points.
c = coefficients_by_nested_multiplication(x,y)
print(c)
[3.75, -1.5, 1.0, 0.0]
Let us now verify that the Newton’s polynomial defined by these coefficients indeed interpolates the three points.
for t in x:
print(f'p({t})={evaluate_by_nested_multiplication(t,x,c)}')
p(-0.5)=3.75
p(0)=3.0
p(0.5)=2.75
p(2)=5.0
5.3. Computation of the coefficients by the divided differences method#
We proceed by implementing the divided differences method.
import numpy as np
def coefficients_by_divided_differences(x:list,y:list):
'''
Computes the coefficients of the Newton interpolating polynomial using the divided differences table.
:param x: List of x-coordinates of the data points.
:param y: List of y-coordinates of the data points.
:return: List of coefficients of the Newton interpolating polynomial.
'''
# Finds the number of interpolation points
n = len(x)
# Initializes the divided differences table as an np.array of zeros.
f = np.zeros((n, n))
# Sets the first column of the table
for row in range(0,n):
f[row,0] = y[row]
# Populates the remaining columns
for column in range(1,n):
for row in range(0,n-column):
f[row,column] = (f[row+1,column-1] - f[row,column-1])/(x[column+row]-x[row])
# Returns the divided differences table.
return f
Observe that the method returns the entire divided differences table. This can be useful in case we later want to extend the polynomial to interpolate an additional point.
5.3.1. Example 1#
Let us consider the same example we used with the nested multiplication method. This time we apply the divided differences method.
x = [-0.5, 0, 0.5, 2]
y = [3.75, 3, 2.75, 5]
# Let us find the coefficients of the Newton's polynomial which interpolates the points.
c = coefficients_by_divided_differences(x,y)
print(c)
[[ 3.75 -1.5 1. 0. ]
[ 3. -0.5 1. 0. ]
[ 2.75 1.5 0. 0. ]
[ 5. 0. 0. 0. ]]
The coefficients of the polynomial are given in the first row of the divided differences table.
c[0]
array([ 3.75, -1.5 , 1. , 0. ])
5.4. Exercises#
Exercise 5.1
Assume you have found the divided differences table for the polynomial which interpolates the points with coordinates \(x=[x_0,\ldots,x_n]\), \(Y=[y_0,\ldots,y_n]\). Implement a function that takes the following input
The divided differences
The vector \(x\)
An additional point \((x_{n+1},y_{n+1})\). The function must the divided differences table for the polynomial which interpolates the points with coordinates \([x_0,\ldots,x_n,x_{n+1}]\), \(Y=[y_0,\ldots,y_n,y_{n+1}]\).