CE7453: Interpolation
Published:
This post summarizes key concepts of interpolation methods covered in CE7453, based on the lecture notes “05-interpolation”.
Key Concepts
Interpolation is the process of estimating unknown values between known data points. It’s a fundamental technique in numerical methods with applications in data analysis, computer graphics, physical simulation, and many other fields.
Mathematical Definition
Given a set of n+1 distinct points (x₀, y₀), (x₁, y₁), …, (xₙ, yₙ), interpolation seeks to find a function f(x) that passes through all these points, i.e., f(xᵢ) = yᵢ for all i = 0, 1, …, n.
Real-world Applications
- Digital Signal Processing: Reconstructing continuous signals from discrete samples
- Computer Graphics: Smooth animation transitions, curve generation
- Medical Imaging: Reconstruction of high-resolution images from lower-resolution scans
- Geospatial Analysis: Creating elevation models from sampled points
- Engineering Design: Creating smooth curves through design constraints
Polynomial Interpolation
1. Lagrange Interpolation
- Form: P(x) = Σi=0n yi Li(x)
- Basis Functions: Li(x) = Πj≠i (x-xj)/(xi-xj)
- Properties:
- Exact fit through all data points
- Degree n polynomial for n+1 points
- Limitations:
- High oscillations (Runge phenomenon)
- Computationally intensive for large datasets
- Sensitive to changes in data points
Derivation of Lagrange Basis Functions
For each point (xᵢ, yᵢ), we need a basis function Lᵢ(x) that equals 1 at x = xᵢ and 0 at all other data points xⱼ where j ≠ i.
The formula: Li(x) = Πj≠i (x-xj)/(xi-xj)
satisfies these properties:
- When x = xᵢ, each term in the product becomes (xᵢ-xⱼ)/(xᵢ-xⱼ) = 1, so Lᵢ(xᵢ) = 1
- When x = xₖ where k ≠ i, one term becomes (xₖ-xₖ)/(xᵢ-xₖ) = 0, making Lᵢ(xₖ) = 0
Worked Example: Lagrange Interpolation
Consider the data points: (0, 1), (1, 3), (2, 2).
Step 1: Calculate Lagrange basis functions
- L₀(x) = ((x-1)(x-2))/((0-1)(0-2)) = (x-1)(x-2)/2
- L₁(x) = ((x-0)(x-2))/((1-0)(1-2)) = (x)(x-2)/(-1) = -x(x-2)
- L₂(x) = ((x-0)(x-1))/((2-0)(2-1)) = (x)(x-1)/2
Step 2: Form the interpolating polynomial P(x) = 1·L₀(x) + 3·L₁(x) + 2·L₂(x) = 1·((x-1)(x-2))/2 + 3·(-x(x-2)) + 2·(x(x-1))/2 = (x²-3x+2)/2 - 3x² + 6x + x²/2 - x/2 = -x² + 4.5x + 1
Step 3: Verify the result
- P(0) = 1 ✓
- P(1) = -1 + 4.5 + 1 = 3 ✓
- P(2) = -4 + 9 + 1 = 2 ✓
Python Implementation
import numpy as np
def lagrange_interpolation(x_points, y_points, x):
"""
Compute the value of the Lagrange interpolation polynomial at point x.
Parameters:
- x_points: Array of x coordinates of data points
- y_points: Array of y coordinates of data points
- x: Point at which to evaluate the polynomial
Returns:
- y: Interpolated value at x
"""
n = len(x_points)
y = 0.0
for i in range(n):
# Calculate Lagrange basis polynomial L_i(x)
L_i = 1.0
for j in range(n):
if j != i:
L_i *= (x - x_points[j]) / (x_points[i] - x_points[j])
y += y_points[i] * L_i
return y
2. Newton’s Divided Differences
- Form: P(x) = a0 + a1(x-x0) + a2(x-x0)(x-x1) + …
- Coefficients: Calculated using divided differences table
- Advantages:
- Easy to add new points without recalculating
- More numerically stable than Lagrange
- More efficient evaluation
Divided Differences Formula
The first divided difference is: f[xi, xi+1] = (f(xi+1) - f(xi))/(xi+1 - xi)
Higher-order divided differences are calculated recursively: f[xi, …, xi+k] = (f[xi+1, …, xi+k] - f[xi, …, xi+k-1])/(xi+k - xi)
Worked Example: Newton’s Divided Differences
Using the same data points: (0, 1), (1, 3), (2, 2)
Step 1: Build the divided differences table
x | f(x) | 1st differences | 2nd differences |
---|---|---|---|
0 | 1 | ||
(3-1)/(1-0) = 2 | |||
1 | 3 | ((2-3)/(2-1) - (3-1)/(1-0))/(2-0) = -1.5 | |
(2-3)/(2-1) = -1 | |||
2 | 2 |
Step 2: Form the interpolating polynomial using Newton’s form P(x) = f(x₀) + fx₀,x₁ + fx₀,x₁,x₂(x-x₁) = 1 + 2(x-0) + (-1.5)(x-0)(x-1) = 1 + 2x - 1.5x(x-1) = 1 + 2x - 1.5x² + 1.5x = 1 + 3.5x - 1.5x² = -1.5x² + 3.5x + 1
This matches our result from Lagrange interpolation.
Python Implementation
def newton_divided_differences(x_points, y_points):
"""
Compute the coefficients of Newton's divided differences form.
Parameters:
- x_points: Array of x coordinates of data points
- y_points: Array of y coordinates of data points
Returns:
- coef: Array of coefficients for Newton's interpolation formula
"""
n = len(x_points)
coef = np.copy(y_points)
# Create the divided differences table
for j in range(1, n):
for i in range(n-1, j-1, -1):
coef[i] = (coef[i] - coef[i-1]) / (x_points[i] - x_points[i-j])
return coef
def newton_interpolation(x_points, y_points, x):
"""
Evaluate Newton's interpolation polynomial at point x.
Parameters:
- x_points: Array of x coordinates of data points
- y_points: Array of y coordinates of data points
- x: Point at which to evaluate the polynomial
Returns:
- y: Interpolated value at x
"""
n = len(x_points)
coef = newton_divided_differences(x_points, y_points)
# Evaluate using Horner's rule
result = coef[n-1]
for i in range(n-2, -1, -1):
result = result * (x - x_points[i]) + coef[i]
return result
3. Hermite Interpolation
- Concept: Interpolates both function values and derivatives
- Order: Higher continuity at interpolation points
- Applications: Smooth curve generation, physical simulations
Hermite Interpolation Formula
For each point xᵢ, we need to match both f(xᵢ) and f’(xᵢ). For two points x₀ and x₁ with values f(x₀), f’(x₀), f(x₁), f’(x₁), the cubic Hermite interpolant is:
P(x) = h₀₀(t)f(x₀) + h₁₀(t)(x₁-x₀)f’(x₀) + h₀₁(t)f(x₁) + h₁₁(t)(x₁-x₀)f’(x₁)
where t = (x-x₀)/(x₁-x₀) and the basis functions are:
- h₀₀(t) = 2t³ - 3t² + 1
- h₁₀(t) = t³ - 2t² + t
- h₀₁(t) = -2t³ + 3t²
- h₁₁(t) = t³ - t²
Worked Example: Cubic Hermite Interpolation
Given two points:
- (x₀, f(x₀), f’(x₀)) = (0, 1, 2)
- (x₁, f(x₁), f’(x₁)) = (1, 3, -1)
For x = 0.5, t = (0.5-0)/(1-0) = 0.5
Calculate basis functions:
- h₀₀(0.5) = 2(0.5)³ - 3(0.5)² + 1 = 0.25 - 0.75 + 1 = 0.5
- h₁₀(0.5) = (0.5)³ - 2(0.5)² + 0.5 = 0.125 - 0.5 + 0.5 = 0.125
- h₀₁(0.5) = -2(0.5)³ + 3(0.5)² = -0.25 + 0.75 = 0.5
- h₁₁(0.5) = (0.5)³ - (0.5)² = 0.125 - 0.25 = -0.125
The interpolated value is: P(0.5) = 0.5(1) + 0.125(1)(2) + 0.5(3) + (-0.125)(1)(-1) = 0.5 + 0.25 + 1.5 - 0.125 = 2.125
Piecewise Interpolation
1. Linear Interpolation
- Form: P(x) = yi + (yi+1-yi)/(xi+1-xi) × (x-xi)
- Properties:
- C0 continuity at knots
- Simple and efficient
- Limited accuracy
Linear Interpolation Formula
For x ∈ [xi, xi+1]: P(x) = yi + (yi+1 - yi)/(xi+1 - xi) × (x - xi)
This can be rewritten as: P(x) = (1-t)yi + tyi+1
where t = (x-xi)/(xi+1-xi)
Python Implementation
def linear_interpolation(x_points, y_points, x):
"""
Perform linear interpolation at point x.
Parameters:
- x_points: Array of x coordinates of data points
- y_points: Array of y coordinates of data points
- x: Point at which to evaluate
Returns:
- y: Interpolated value at x
"""
# Find the interval containing x
i = 0
while i < len(x_points) - 1 and x > x_points[i+1]:
i += 1
# Check if x is within range
if i >= len(x_points) - 1:
return y_points[-1] # Return last point if beyond range
# Linear interpolation formula
t = (x - x_points[i]) / (x_points[i+1] - x_points[i])
return (1 - t) * y_points[i] + t * y_points[i+1]
2. Cubic Spline Interpolation
- Types:
- Natural Splines: Second derivatives are zero at endpoints
- Clamped Splines: First derivatives specified at endpoints
- Not-a-knot: Third derivatives match at first and last interior points
- Properties:
- C2 continuity across all points
- Minimizes oscillation (minimum curvature)
- Efficiently representable as piecewise cubics
- Matrix Form: Tridiagonal system for coefficient calculation
Cubic Spline Conditions
For n+1 data points, we construct n cubic polynomials S₁(x), S₂(x), …, Sₙ(x) where Sᵢ(x) interpolates the interval [xi-1, xi].
Each cubic polynomial has the form: Sᵢ(x) = aᵢ + bᵢ(x-xi-1) + cᵢ(x-xi-1)² + dᵢ(x-xi-1)³
The conditions imposed are:
- Sᵢ(xi-1) = yi-1 and Sᵢ(xi) = yi (interpolation)
- S’ᵢ(xi) = S’i+1(xi) (C¹ continuity)
- S’‘ᵢ(xi) = S’‘i+1(xi) (C² continuity)
- Plus two additional conditions (typically natural or clamped)
Worked Example: Natural Cubic Spline
Consider the data points: (0, 1), (1, 3), (2, 2)
With the natural spline condition: S’‘(x₀) = S’‘(xₙ) = 0
Step 1: Set up the tridiagonal system to solve for the second derivatives M₀, M₁, M₂
For n = 2, we have the tridiagonal system: [h₀ | h₀/3 | 0 ] [M₀] = [d₁ - d₀] [h₀/3 | 2(h₀+h₁)/3 | h₁/3 ] [M₁] = [d₂ - d₁] [0 | h₁/3 | h₁ ] [M₂] = [0 ]
where:
- hᵢ = xi+1 - xi
- dᵢ = (yi+1 - yi)/hᵢ
Substituting our values:
- h₀ = 1 - 0 = 1, h₁ = 2 - 1 = 1
- d₀ = (3 - 1)/1 = 2, d₁ = (2 - 3)/1 = -1
For natural splines, M₀ = M₂ = 0, so we only need to solve for M₁: (2(h₀+h₁)/3)M₁ = d₁ - d₀ (2(1+1)/3)M₁ = -1 - 2 (4/3)M₁ = -3 M₁ = -9/4 = -2.25
Step 2: Calculate the coefficients for each spline segment
For segment S₁ (between x₀ and x₁): a₁ = y₀ = 1 b₁ = (y₁ - y₀)/h₀ - h₀(2M₀ + M₁)/6 = (3 - 1)/1 - 1(2(0) + (-2.25))/6 = 2 + 0.375 = 2.375 c₁ = M₀/2 = 0 d₁ = (M₁ - M₀)/(6h₀) = (-2.25 - 0)/(6(1)) = -0.375
For segment S₂ (between x₁ and x₂): a₂ = y₁ = 3 b₂ = (y₂ - y₁)/h₁ - h₁(2M₁ + M₂)/6 = (2 - 3)/1 - 1(2(-2.25) + 0)/6 = -1 + 0.75 = -0.25 c₂ = M₁/2 = -2.25/2 = -1.125 d₂ = (M₂ - M₁)/(6h₁) = (0 - (-2.25))/(6(1)) = 0.375
Step 3: The cubic spline is: S₁(x) = 1 + 2.375(x - 0) + 0(x - 0)² - 0.375(x - 0)³ for x ∈ [0, 1] S₂(x) = 3 - 0.25(x - 1) - 1.125(x - 1)² + 0.375(x - 1)³ for x ∈ [1, 2]
Python Implementation
def cubic_spline(x_points, y_points, x, boundary_type='natural'):
"""
Compute cubic spline interpolation at point x.
Parameters:
- x_points: Array of x coordinates of data points
- y_points: Array of y coordinates of data points
- x: Point at which to evaluate
- boundary_type: 'natural', 'clamped', or 'not-a-knot'
Returns:
- y: Interpolated value at x
"""
n = len(x_points) - 1 # Number of intervals
# Step 1: Compute interval lengths and divided differences
h = [x_points[i+1] - x_points[i] for i in range(n)]
d = [(y_points[i+1] - y_points[i]) / h[i] for i in range(n)]
# Step 2: Set up tridiagonal system for second derivatives
A = np.zeros((n+1, n+1))
b = np.zeros(n+1)
# Set up equations for interior points
for i in range(1, n):
A[i, i-1] = h[i-1] / 6
A[i, i] = (h[i-1] + h[i]) / 3
A[i, i+1] = h[i] / 6
b[i] = d[i] - d[i-1]
# Set up boundary conditions
if boundary_type == 'natural':
A[0, 0] = 1
A[n, n] = 1
elif boundary_type == 'clamped':
# Would need first derivative values at endpoints
pass
# Step 3: Solve for second derivatives
M = np.linalg.solve(A, b)
# Step 4: Find interval containing x
i = 0
while i < n and x > x_points[i+1]:
i += 1
# Step 5: Compute spline value
t = (x - x_points[i]) / h[i]
a = y_points[i]
b = d[i] - h[i] * (2 * M[i] + M[i+1]) / 6
c = M[i] / 2
d_coef = (M[i+1] - M[i]) / (6 * h[i])
return a + b * (x - x_points[i]) + c * (x - x_points[i])**2 + d_coef * (x - x_points[i])**3
3. Cubic Hermite Splines
- Form: Local hermite interpolation between adjacent points
- Parametrization: Often uses normalized parameter t ∈ [0,1]
- Basis Functions: Hermite basis functions Hi(t)
- Applications: Path interpolation, animation
Piecewise Cubic Hermite Interpolation
For data points (x₀, y₀, m₀), (x₁, y₁, m₁), …, (xₙ, yₙ, mₙ) where mi are the specified derivatives, the cubic Hermite spline over [xi, xi+1] is:
P(x) = H₀₀(t)yi + H₁₀(t)himi + H₀₁(t)yi+1 + H₁₁(t)himi+1
where t = (x-xi)/hi and hi = xi+1 - xi
Estimating Derivatives for Cubic Hermite Splines
If derivatives are not provided, we can estimate them using the centered finite difference:
mi = (yi+1 - yi-1)/(xi+1 - xi-1)
For endpoints, we use one-sided differences: m₀ = (y₁ - y₀)/(x₁ - x₀) mₙ = (yₙ - yn-1)/(xₙ - xn-1)
This creates what’s known as a “Cardinal spline”.
Multivariate Interpolation
1. Bilinear Interpolation
- Concept: Extension of linear interpolation to 2D grid
- Process: Interpolate along rows, then along resulting column
- Applications: Image scaling, texture mapping
Bilinear Interpolation Formula
For a point (x, y) in the rectangle with corners (x₁, y₁), (x₂, y₁), (x₁, y₂), (x₂, y₂) and function values f₁₁, f₂₁, f₁₂, f₂₂:
- Interpolate along the top edge: f(x, y₁) = f₁₁ + (x - x₁)/(x₂ - x₁) × (f₂₁ - f₁₁)
- Interpolate along the bottom edge: f(x, y₂) = f₁₂ + (x - x₁)/(x₂ - x₁) × (f₂₂ - f₁₂)
- Interpolate between these values: f(x, y) = f(x, y₁) + (y - y₁)/(y₂ - y₁) × (f(x, y₂) - f(x, y₁))
Worked Example: Bilinear Interpolation
Given values at four corners of a unit square:
- f(0, 0) = 10
- f(1, 0) = 20
- f(0, 1) = 15
- f(1, 1) = 25
Find the interpolated value at (0.6, 0.4):
Step 1: Interpolate along x at y = 0 f(0.6, 0) = 10 + 0.6 × (20 - 10) = 10 + 6 = 16
Step 2: Interpolate along x at y = 1 f(0.6, 1) = 15 + 0.6 × (25 - 15) = 15 + 6 = 21
Step 3: Interpolate along y at x = 0.6 f(0.6, 0.4) = 16 + 0.4 × (21 - 16) = 16 + 2 = 18
Python Implementation
def bilinear_interpolation(x, y, points):
"""
Perform bilinear interpolation at point (x, y).
Parameters:
- x, y: Coordinates at which to interpolate
- points: Dictionary with (x,y) tuples as keys and function values as values
Returns:
- Interpolated value
"""
# Extract corners of rectangle containing (x, y)
x1, y1 = math.floor(x), math.floor(y)
x2, y2 = math.ceil(x), math.ceil(y)
# Handle case where point is exactly on a grid point
if x == x1 and y == y1:
return points[(x1, y1)]
# Extract function values at corners
f11 = points[(x1, y1)]
f21 = points[(x2, y1)]
f12 = points[(x1, y2)]
f22 = points[(x2, y2)]
# Normalize coordinates to [0,1]
x_ratio = (x - x1) / (x2 - x1) if x2 != x1 else 0
y_ratio = (y - y1) / (y2 - y1) if y2 != y1 else 0
# Bilinear interpolation formula
result = (1 - x_ratio) * (1 - y_ratio) * f11 + \
x_ratio * (1 - y_ratio) * f21 + \
(1 - x_ratio) * y_ratio * f12 + \
x_ratio * y_ratio * f22
return result
2. Bicubic Interpolation
- Concept: Extension of cubic interpolation to 2D
- Data Required: Function values, partial derivatives, and cross derivatives
- Applications: Image processing, terrain modeling
Bicubic Interpolation Formula
Bicubic interpolation requires 16 coefficients, determined by:
- Function values f(x, y) at the four corners
- Partial derivatives ∂f/∂x and ∂f/∂y at the four corners
- Cross derivatives ∂²f/∂x∂y at the four corners
The interpolating function has the form: f(x, y) = Σi=03 Σj=03 aij xi yj
3. Radial Basis Functions
Form: s(x) = Σi=1n λi φ( x-xi ) - Common RBFs: Gaussian, Multiquadric, Thin-plate spline
- Applications: Scattered data interpolation, mesh deformation
Common Radial Basis Functions
- Gaussian: φ(r) = exp(-r²/σ²)
- Multiquadric: φ(r) = √(r² + σ²)
- Inverse Multiquadric: φ(r) = 1/√(r² + σ²)
- Thin-plate spline: φ(r) = r² log(r)
Where r = | x-xi | is the distance from the evaluation point to the data point, and σ is a shape parameter. |
Example: RBF Interpolation Process
For data points (x₁, y₁), (x₂, y₂), …, (xₙ, yₙ) with values f₁, f₂, …, fₙ:
- Choose a radial basis function φ(r)
Set up the system of equations: Σj=1n λj φ( xi-xj ) = fi for i = 1, 2, …, n - Solve for the weights λj
Use the weights to evaluate the interpolant at any point: s(x) = Σj=1n λj φ( x-xj )
Error Analysis
- Error Bound: |f(x) - P(x)| ≤ (M/(n+1)!) × Πi=0n |x-xi| where M is bound on (n+1)th derivative
- Runge Phenomenon: High oscillations near edges with equidistant points
- Chebyshev Nodes: Optimal node placement to minimize error
Error Formula Derivation
For an interpolating polynomial P(x) of degree n, the error at point x is:
E(x) = f(x) - P(x) = (f(n+1)(ξ)/(n+1)!) × Πi=0n (x-xi)
for some ξ in the range of the data points. If | f(n+1)(x) | ≤ M, then: |
E(x) | ≤ (M/(n+1)!) × Πi=0n | x-xi |
Runge Phenomenon
When using high-degree polynomials with equally spaced points, severe oscillations can occur near the endpoints of the interval. This is known as the Runge phenomenon.
For example, interpolating f(x) = 1/(1+25x²) over [-1, 1] with equally spaced points can lead to errors that grow exponentially with the number of points.
Chebyshev Nodes
To mitigate the Runge phenomenon, we can use Chebyshev nodes:
xi = cos((2i+1)π/(2n+2)) for i = 0, 1, …, n
These nodes are concentrated at the endpoints and minimize the maximum interpolation error.
Error Comparison: Equally Spaced vs. Chebyshev Nodes
When interpolating f(x) = 1/(1+25x²) over [-1, 1] with 10 points:
- Maximum error with equally spaced points: ~10²
- Maximum error with Chebyshev nodes: ~10⁻¹
Exam Focus Areas
- Basis Construction: Deriving basis functions for different methods
- Error Analysis: Understanding and calculating interpolation error
- Algorithm Implementation: Steps for constructing and evaluating interpolants
- Method Selection: Choosing appropriate interpolation methods
- Continuity Analysis: Determining and ensuring continuity properties
Sample Exam Questions
- Derive the Lagrange basis function for a specific data point.
- Calculate the divided differences table for a set of data points.
- Determine the error bound for a polynomial interpolation.
- Construct a cubic spline with specific boundary conditions.
- Compare the accuracy of different interpolation methods for a given function.
Practice Problems
- Construct a Lagrange polynomial for a given dataset
- Set up and solve the tridiagonal system for natural cubic splines
- Compare errors between different interpolation methods
- Implement bilinear interpolation for a 2D grid of values
Challenge Problem
A rocket’s position (in meters) is measured at three time points:
- t = 0s: x = 0m
- t = 1s: x = 10m
- t = 3s: x = 90m
- Find the Lagrange polynomial that interpolates this data
- Estimate the position at t = 2s
- Calculate the velocity (first derivative) at t = 1.5s
- Discuss whether this interpolation is physically realistic and why
Solution:
- The Lagrange polynomial is P(t) = 10t² + 0t + 0 = 10t²
- At t = 2s: P(2) = 10(2)² = 40m
- Velocity at t = 1.5s: P’(t) = 20t, so P’(1.5) = 20(1.5) = 30m/s
- This interpolation suggests constant acceleration, which is physically plausible for a rocket during a phase of constant thrust.
Original lecture notes are available at: /files/CE7453/CE7453/05-interpolation-4slides1page(1).pdf