Interpolation and Approximation

ENPC Course — Scientific Computing in Practice

General Framework of Interpolation

Let

  • a segment \([a,b]\) of \({\mathbb{{R}}}\)

  • \(n+1\) distinct points \(a=x_0< x_1< \dotsc < x_n=b\)

  • \(n+1\) values \(u_0, u_1, \dotsc, u_n\)

  • a subspace \(\mathop{\mathrm{Vect}}(φ_0,φ_1,\dotsc,φ_n)\) of the vector space of continuous functions on \([a,b]\)

We look for an element of \(\mathop{\mathrm{Vect}}(φ_0,φ_1,\dotsc,φ_n)\), i.e. \[ \fcolorbox{bleu_C}{bleu_light_C}{$ \widehat u(x) = α_0 φ_0(x) + \dotsb + α_n φ_n(x) $} \] such that \[ \fcolorbox{bleu_C}{bleu_light_C}{$ \forall i \in \{0, \dotsc, n\}, \qquad \widehat u(x_i) = u_i $} \] \[ \fcolorbox{bleu_C}{bleu_light_C}{$ \mathsf A \mathbf{\boldsymbol{\alpha }}:= \begin{pmatrix} \varphi_0(x_0) & \varphi_1(x_0) & \dots & \varphi_n(x_0) \\ \varphi_0(x_1) & \varphi_1(x_1) & \dots & \varphi_n(x_1) \\ \vdots & \vdots & & \vdots \\ \varphi_0(x_n) & \varphi_1(x_n) & \dots & \varphi_n(x_n) \end{pmatrix} \begin{pmatrix} \alpha_0 \\ \alpha_1 \\ \vdots \\ \alpha_n \end{pmatrix} = \begin{pmatrix} u_0 \\ u_1 \\ \vdots \\ u_n \end{pmatrix} := \mathbf{\boldsymbol{b}} $} \]

Equally spaced nodes

\[x_k=a+(b-a)\frac{k}{n}\]

Chebyshev nodes

\[x_k=a + (b-a) \frac{1 - \cos \left(\pi \frac{k + \frac{1}{2}}{n+1} \right)}{2}\]

Polynomial Families

Canonical basis

\[ φ_i(x)=x^i \quad⇒\quad \mathsf A= \begin{pmatrix} 1 & x_0 & \dots & x_0^n \\ 1 & x_1 & \dots & x_1^n \\ \vdots & \vdots & & \vdots \\ 1 & x_n & \dots & x_n^n \end{pmatrix} \]

Code
pl = Plots.plot(size=(450,300), bottom_margin=4Plots.mm)
for d in 0:10
    p(x) = x^d
    Plots.plot!(p, 0, 1, )
end
Plots.plot!(xlims=(0, 1), xlabel="x",
    legend=false)

Lagrange polynomials

\[ φ_{i}(x) = \prod_{\substack{j = 0\\ j ≠ i}}^{n} \frac {x - x_j} {x_i - x_j} \quad⇒\quad \mathsf A=\mathsf I \]

Code
xs = LinRange(0, 1, 11)
pl = Plots.plot(size=(450,300), bottom_margin=4Plots.mm)
for d in eachindex(xs)
    p(x) = prod(x .- xs[1:end .!= d]) / prod(xs[d] .- xs[1:end .!= d])
    Plots.plot!(p, extrema(xs)...)
end
Plots.scatter!(xs, 0*xs .+ 1, )
Plots.plot!(xlims=(0, 1), xlabel="x",
    title="$(length(xs)) equally spaced nodes",
    legend=false)

Staircase polynomials (generalized Gregory-Newton)

\[ φ_{i}(x) = (x-x_0) (x-x_1) (x-x_2) \dots (x-x_{i-1}) \]

\(\quad⇒\quad \mathsf A\) lower triangular

Code
xs = LinRange(0, 1, 11)
pl = Plots.plot(size=(450,300), bottom_margin=4Plots.mm)
for d in eachindex(xs)
    p(x) = prod(x .- xs[1:d-1])
    Plots.plot!(p, extrema(xs)...)
end
Plots.scatter!(xs, zero(xs), )
Plots.plot!(xlims=(0, 1), xlabel="x",
    title="$(length(xs)) equally spaced nodes",
    legend=false)

Error Control

Theorem

  • \(u\colon [a, b] \to {\mathbb{{R}}}\) is a function in \(\mathcal{C}^{n+1}([a, b])\)

  • \(a=x_0< x_1< \dotsc < x_n=b\) are \(n+1\) distinct nodes

  • \(\widehat u\) is a polynomial of degree at most \(n\), interpolating \(u\) at the points \(x_0, x_1, \dotsc, x_n\), i.e. \(\widehat u(x_i) = u(x_i)\) for all \(i ∈ \{0,\dotsc,n\}\)

Then \(\quad∀\, x ∈ [a,b],\quad ∃\, ξ=ξ(x) ∈ [a,b]\) \[ \fcolorbox{bleu_C}{bleu_light_C}{$ e_n(x) := u(x) - \widehat u(x) = \frac{u^{(n+1)}(\xi)}{(n+1)!} (x-x_0) \dotsc (x - x_n) $} \]

Exercise: prove the theorem

  1. Examine the case where \(x\) is one of the \(x_i\).

  2. Setting \(ω_n(x) = \prod_{i=0}^n (x - x_i)\) and \(g(t) = e_n(t) ω_n(x) - e_n(x) ω_n(t)\) for a given \(x\) different from the \(x_i\), show that \(g^{(k)}(t)\) for \(0≤k≤n+1\) has \(n+2-k\) distinct roots in \([a,b]\).

  3. Conclude.

  4. What can be said when \(u\) is a polynomial of degree at most \(n\)?

  5. Assuming \(u\) is in \(\mathcal{C}^{∞}([a, b])\), does the error necessarily tend to \(0\) as the number of nodes tends to infinity?

Corollary of the theorem (same hypotheses)

  • We set \(C_{n+1} = \sup_{x ∈ [a, b]} \left\lvert u^{(n+1)}(x) \right\rvert\) and \(h = \max_{i ∈ \{0, \dotsc, n-1\}} \lvert x_{i+1} - x_i\rvert\)

Then one shows that \(E_n := \sup_{x ∈ [a, b]} \bigl\lvert e_n(x) \bigr\rvert \leqslant\frac{C_{n+1}}{4(n+1)} h^{n+1}\)

  • Hints:
    • if \(x ∈ [x_{i},x_{i+1}]\), \((x-x_{i})(x_{i+1}-x)=\left(\frac{x_{i+1}-x_{i}}{2}\right)^2-\left(x-\frac{x_{i}+x_{i+1}}{2}\right)^2 ≤ \frac{h^2}{4}\)
    • \(\lvert ω_n(x)\rvert ≤ \frac{h^2}{4} × 2h × 3h × 4h × \dotsb × nh\)

Remarks

  • \(h\) depends on \(n\) and the choice of nodes (order \(1/n\) for equally spaced nodes)

  • \(C_{n}\) cannot be controlled a priori

  • In some cases, \(C_{n}\) does not grow too fast with \(n\), so that \(E_n\underset{n→∞}{→}0\) (e.g. sine)

  • Counterexample: the Runge function \(u(x)=\frac{1}{1+25x^2}\), for which the upper bound of \(E_n\) tends to infinity with equally spaced nodes

  • Optimize the interpolation? → node optimization or piecewise interpolation

Sine Function with Equally Spaced Nodes

\[ \fcolorbox{orange_C}{orange_light_C}{$ u(x)=\sin{x} $} \] \[ \fcolorbox{pistache_C}{pistache_light_C}{$ x_k=a + (b-a) \frac{k}{n} \quad (0 ≤ k ≤ n) $} \]

Runge Function with Equally Spaced Nodes

\[ \fcolorbox{orange_C}{orange_light_C}{$ u(x)=\frac{1}{1+25x^2} $} \] \[ \fcolorbox{pistache_C}{pistache_light_C}{$ x_k=a + (b-a) \frac{k}{n} \quad (0 ≤ k ≤ n) $} \]

Node Optimization: Chebyshev Nodes

Controlling the error bound

\[ \fcolorbox{bleu_C}{bleu_light_C}{$ e_n(x) := u(x) - \widehat u(x) = \frac{u^{(n+1)}(\xi)}{(n+1)!} (x-x_0) \dotsc (x - x_n) $} \]

  • Increasing the number of nodes \(n+1\) changes \(u^{(n+1)}\) ⇒ difficult to control

  • Idea: for given \(n\), choose nodes to minimize \(\sup_{x∈[a,b]} \lvert(x-x_0) \dotsc (x - x_n)\rvert\)

  • For any monic polynomial \(p\) of degree \(n\), one shows that \(\sup_{x∈[-1,1]} \lvert p(x)\rvert ≥ \frac{1}{2^{n-1}}\)

  • The bound \(\frac{1}{2^{n-1}}\) is achieved by \(\frac{T_{n}(x)}{2^{n-1}}\) where \(T_n(x)=\cos(n\arccos x)\) (Chebyshev polynomial)

  • The zeros of \(T_n\) are therefore \(x_k=-\cos (\pi \frac{k + \frac{1}{2}}{n} ) \; (0 ≤ k < n)\) (minus sign for ordering)

  • Hence \(x_k=-\cos (\pi \frac{k + \frac{1}{2}}{n+1} ) \; (0 ≤ k ≤ n)\) for \(n+1\) points

  • In the case \([a,b]\), for \(n\) points \[ \fcolorbox{pistache_C}{pistache_light_C}{$ x_k=a + (b-a) \frac{1 - \cos (\pi \frac{k + \frac{1}{2}}{n} )}{2} \quad (0 ≤ k < n) $} \]

  • Application to the Runge function \(u(x)=\frac{1}{1+25x^2}\)

Piecewise Interpolation

Continuous piecewise interpolation

\[ \fcolorbox{bleu_C}{bleu_light_C}{$ e_n(x) := u(x) - \widehat u(x) = \frac{u^{(n+1)}(\xi)}{(n+1)!} (x-x_0) \dotsc (x - x_n) $} \]

\[ \fcolorbox{bleu_C}{bleu_light_C}{$ \begin{align} &E_n := \sup_{x ∈ [a, b]} \bigl\lvert e_n(x) \bigr\rvert \leqslant\frac{C_{n+1}}{4(n+1)} h^{n+1}\\ &\text{with } C_{n+1} = \sup_{x ∈ [a, b]} \left\lvert u^{(n+1)}(x) \right\rvert \text{ and } h = \max_{i ∈ \{0, \dotsc, n-1\}} \lvert x_{i+1} - x_i\rvert \end{align} $} \]

Idea to control the bound:

  • split the interval \([a,b]\) with \(n+1\) nodes, for example \(h=\frac{b-a}{n}\)

  • interpolate with a polynomial of degree \(m\) on \([x_{i},x_{i+1}]\)

    #| echo: false
    #| eval: true
    #| code-fold: false
    #| code-line-numbers: false
    
    δ = 0.2
    pl = Plots.plot(size = (700,100), ylim =(-δ,δ))
    xs = LinRange(-1, 1, 37)
    Plots.plot!(xs, zero(xs),)
    Plots.scatter!(xs, zero(xs), markersize=6, markershape=:diamond,)
    xs = LinRange(-1, 1, 13)
    Plots.scatter!(xs, zero(xs), markersize=8,)
    Plots.plot!(axis = false, grid = false, legend = false, ticks = false)

    \[ \fcolorbox{bleu_C}{bleu_light_C}{$ \sup_{x ∈ [x_{i},x_{i+1}]} \bigl\lvert e_n(x) \bigr\rvert \leqslant\frac{C_{m+1}}{4(m+1)} \left(\frac{h}{m}\right)^{m+1} $} \]

  • \(m\) is kept small, so the error is uniformly bounded by \(C h^{m+1}\)

Higher regularity

  • The previous interpolation only ensures continuity \(\widehat u(x_i^-)=\widehat u(x_i^+)\)

  • To improve regularity, conditions can be imposed on higher derivatives

    → cubic splines:

    • degree-3 polynomial on each subinterval: \(4n\) unknowns

    • interpolation at nodes \(x_i\) (\(0 ≤ i ≤ n\)): \(2n\) equations

    • matching of derivatives at nodes \(x_i\) (\(0 < i < n\)): \(n-1\) equations

    • matching of second derivatives at nodes \(x_i\) (\(0 < i < n\)): \(n-1\) equations

    • total number of equations: \(4n-2\) ⇒ 2 more are needed (usually zero second derivatives at the endpoints)

Least Squares Approximation

Problem statement

  • \(n+1\) distinct nodes \(a=x_0< x_1< \dotsc < x_n=b\)

  • \(n+1\) values \(u_0, u_1, \dotsc, u_n\)

  • a subspace \(\mathop{\mathrm{Vect}}(φ_0,φ_1,\dotsc,φ_m)\) of the vector space of continuous functions on \([a,b]\) (usually polynomials) but here \(\color{red}{m<n}\)

We look for an element of \(\mathop{\mathrm{Vect}}(φ_0,φ_1,\dotsc,φ_m)\), i.e. \[ \fcolorbox{bleu_C}{bleu_light_C}{$ \widehat u(x) = α_0 φ_0(x) + \dotsb + α_m φ_m(x) $} \] such that \[ \fcolorbox{bleu_C}{bleu_light_C}{$ \forall i \in \{0, \dotsc, n\}, \qquad \widehat u(x_i) \, {\color{red}{\approx}} \, u_i $} \] \[ \fcolorbox{bleu_C}{bleu_light_C}{$ \mathsf A \mathbf{\boldsymbol{\alpha }}:= \begin{pmatrix} \varphi_0(x_0) & \varphi_1(x_0) & \dots & \varphi_m(x_0) \\ \varphi_0(x_1) & \varphi_1(x_1) & \dots & \varphi_m(x_1) \\ \varphi_0(x_2) & \varphi_1(x_2) & \dots & \varphi_m(x_2) \\ \vdots & \vdots & & \vdots \\ \varphi_0(x_{n-2}) & \varphi_1(x_{n-2}) & \dots & \varphi_m(x_{n-2}) \\ \varphi_0(x_{n-1}) & \varphi_1(x_{n-1}) & \dots & \varphi_m(x_{n-1}) \\ \varphi_0(x_n) & \varphi_1(x_n) & \dots & \varphi_m(x_n) \end{pmatrix} \begin{pmatrix} \alpha_0 \\ \alpha_1 \\ \vdots \\ \alpha_m \end{pmatrix} {\color{red}{\approx}} \begin{pmatrix} u_0 \\ u_1 \\ u_2 \\ \vdots \\ u_{n-2} \\ u_{n-1} \\ u_n \end{pmatrix} =: \mathbf{\boldsymbol{b}} $} \]

Minimization of \[ \fcolorbox{bleu_C}{bleu_light_C}{$ J(\mathbf{\boldsymbol{\alpha}})= \frac{1}{2}\,\sum_{i=0}^{n} {\lvert {\widehat u(x_i) - u_i} \rvert}^2 = \frac{1}{2}\,\sum_{i=0}^{n} \left( \sum_{j=0}^{m} \alpha_j \varphi_j(x_i) - u_i\right)^2 =\frac{1}{2}\,{\lVert {\mathsf A \mathbf{\boldsymbol{\alpha}}-\mathbf{\boldsymbol{b}}} \rVert}^2 $} \]

We therefore look for \(\alpha\) such that \[ \nabla J(\mathbf{\boldsymbol{\alpha}})=\frac{1}{2}\,\nabla \Bigl( (\mathsf A \mathbf{\boldsymbol{\alpha }}- \mathbf{\boldsymbol{b}})^T(\mathsf A \mathbf{\boldsymbol{\alpha }}- \mathbf{\boldsymbol{b}}) \Bigr)=\mathbf{\boldsymbol{0}} \] i.e. \[ \mathrm dJ=(\mathsf A \mathrm d\mathbf{\boldsymbol{\alpha}})^T(\mathsf A \mathbf{\boldsymbol{\alpha }}- \mathbf{\boldsymbol{b}}) =\mathrm d\mathbf{\boldsymbol{\alpha}}^T\mathsf A^T(\mathsf A \mathbf{\boldsymbol{\alpha }}- \mathbf{\boldsymbol{b}}) \Rightarrow \nabla J(\mathbf{\boldsymbol{\alpha}})=\mathsf A^T(\mathsf A \mathbf{\boldsymbol{\alpha }}- \mathbf{\boldsymbol{b}}) =\mathbf{\boldsymbol{0}} \] which gives the system to solve \[ \fcolorbox{bleu_C}{bleu_light_C}{$ \mathsf A^T\mathsf A \mathbf{\boldsymbol{\alpha }}= \mathsf A^T\mathbf{\boldsymbol{b}} $} \] with \(\mathsf A^T\mathsf A\) an \(m×m\) invertible matrix if \(\mathsf A\) has rank \(m\) (independent columns)

Remark

In Julia the result of the computation \(\alpha=(\mathsf A^T\mathsf A)^{-1} \mathsf A^T\mathbf{\boldsymbol{b}}\) can simply be obtained by

α = A\b

Package Polynomials.jl

Example usage of fit

using Plots, Polynomials
xs = range(0, 10, length=10)
ys = @. exp(-xs)
f = fit(xs, ys) # degree = length(xs) - 1
f2 = fit(xs, ys, 2) # degree = 2

scatter(xs, ys, label="Data")
plot!(f, extrema(xs)..., label="Fit")
plot!(f2, extrema(xs)..., label="Quadratic Fit")
width, height = 750, 500 ; plot!(size = (width, height), legend = :topright)

Package Interpolations.jl

Example usage here (section Convenience Constructors)

using Interpolations, Plots
a = 1.0 ; b = 10.0 ; xᵢ = a:1.0:b # bounds and knots
F(x) = cos(x^2/9)
yᵢ = F.(xᵢ) # function application by broadcasting
itp_linear = linear_interpolation(xᵢ,yᵢ) ; itp_cubic = cubic_spline_interpolation(xᵢ,yᵢ)
F_linear(x) = itp_linear(x) ; F_cubic(x) = itp_cubic(x)
x_new = a:0.1:b # smoother interval, necessary for cubic spline
scatter(xᵢ, yᵢ, markersize=10,label="Data points")
plot!(F_linear, x_new, w=4,label="Linear interpolation")
plot!(F_cubic, x_new, linestyle=:dash, w=4, label="Cubic Spline interpolation")
plot!(F, x_new, linestyle=:dot, w=4, label="Initial function")
width, height = 750, 500 ; plot!(size = (width, height), legend = :bottomleft)