Série 6 : Interpolation, Splines et Moindres carrés
1. Interpolation
Solution
a) On peut calculer le polynôme \(\Pi_2\) interpolant la fonction \(f\) en utilisant les polynômes de la base de Lagrange associée aux nœuds \(x_0, x_1, x_2\). Polynômes de la base de Lagrange :
Le polynôme cherché est donc
b) Il suffit d’observer que \(f(x)\) est un polynôme de degré trois et donc on a \(\Pi_3 f(x)=f(x)\). c) On peut construire les polynômes de la base de Lagrange et utiliser la même démarche que au point a). On note \(x_0=0, x_1=1, x_2=2\) et \(x_3=3\). On a alors
Finalement, le polynôme interpolant est \(\Pi_3 g(x)=x^3-\frac{5}{2} x^2-\frac{1}{2} x+3\) et sa valeur en \(x=1.5\) est \(\Pi_3 g(1.5)=0\).
Notons que, afin de calculer \(\Pi_3 g(x)\), on pourrait imposer directement les conditions d’interpolation. Soit \(\Pi_3 g(x)=a_0+a_1 x+a_2 x^2+a_3 x^3\), avec \(a_j(j=0, \ldots, 3)\) coefficients inconnus. Les conditions d’interpolation \(\Pi_3 g\left(x_i\right)=g\left(x_i\right)(i=0, \ldots, 3)\) nous donnent le système \(4 \times 4\) suivant :
On voit donc que cette méthode pour calculer \(\Pi_3 g(x)\) est beaucoup plus coûteuse que celle basée sur les polynômes \(\varphi_i\).
Solution
a) En général, pour estimer l’erreur d’interpolation d’une fonction continue par un polynôme de degré \(n\) dans le cas de nœuds équidistribués sur l’intervalle \([a, b\)], on peut utiliser l’inégalité
où \((b-a)\) est la longueur de l’intervalle d’interpolation. Pour la fonction \(f(x)=\sin \left(\frac{x}{3}\right)\), on a que
et donc on obtient immédiatement
Dans ce cas, on a donc l’estimation suivante :
qui tend vers zéro quand \(n \rightarrow \infty\).
b) On a la condition suivante à satisfaire :
D’abord, on peut essayer pour \(n=1\) et \(n=2\), mais on voit que l’inégalité (3) n’est pas vérifié. Finalement, pour \(n=3\), on trouve
Solution
Solution
2. Moindres carrés
Solution
a) On utilise l’estimation de l’erreur qui suit :
Soit \(N\) le nombre de sous-intervalles de \(I=[0,1\)] de longueur \(h=1 / N\). On rappelle que pour l’erreur d’interpolation linéaire par intervalles, on peut fournir l’estimation suivante :
On a
Pour satisfaire la condition demandée par l’exercice on doit donc prendre
et donc \(N \geq \sqrt{0.25 \cdot 10^5} \sim 159\).
b) On calcule les dérivées de la fonction \(\Phi\left(a_0, a_1\right)\) :
Donc les coefficients \(a_0\) et \(a_1\) du polynôme sont les solutions du système linéaire que l’on obtient en imposant les conditions de minimisation de la "distance polynôme-données", c’est-à-dire \(\frac{\partial \Phi}{\partial a_0}=0\) et \(\frac{\partial \Phi}{\partial a_1}=0\) :
La solution est
Le polynôme cherché est donc \(p(x)=-\frac{35}{36}-\frac{1}{2} x\).
On peut remarquer que la matrice \(A=\left(\begin{array}{cc}3 & 3 / 2 \\ 3 / 2 & 5 / 4\end{array}\right)\) du système (4) est bien la matrice 3 \(B^{\top} B\) des équations normales (voir notes du cours), \(B\) étant donnée dans notre cas par
Solution
a) En procédant comme dans les exercices précédents, on trouve le code Python suivant pour calculer les polynômes interpolants de différents degrés :
import numpy as np
from numpy.polynomial.polynomial import Polynomial
import plotly.graph_objects as go
# Données
x = np.linspace(0, 1, 10)
f = 10 * x**2 + 2 * (np.random.rand(x.size) - 0.5)
# Calcul des polynômes interpolants
c2 = np.polyfit(x, f, 2)
c3 = np.polyfit(x, f, 3)
c4 = np.polyfit(x, f, 4)
c9 = np.polyfit(x, f, 9)
# Noms des polynômes pour la légende
names = ['n=2', 'n=3', 'n=4', 'n=9', 'data']
colors = ['blue', 'green', 'black', 'red', 'black']
Results
b) Tracé des Graphes
Voici le code Python utilisant Plotly pour tracer les graphes des polynômes interpolants :
# Points pour l'évaluation des polynômes
x100 = np.linspace(0, 1, 100)
# Tracé avec Plotly
fig = go.Figure()
fig.add_trace(go.Scatter(x=x100, y=np.polyval(c2, x100), mode='lines', name='n=2', line=dict(color='blue')))
fig.add_trace(go.Scatter(x=x100, y=np.polyval(c3, x100), mode='lines', name='n=3', line=dict(color='green')))
fig.add_trace(go.Scatter(x=x100, y=np.polyval(c4, x100), mode='lines', name='n=4', line=dict(color='black')))
fig.add_trace(go.Scatter(x=x100, y=np.polyval(c9, x100), mode='lines', name='n=9', line=dict(color='red')))
fig.add_trace(go.Scatter(x=x, y=f, mode='markers', name='data', marker=dict(color='black')))
fig.update_layout(title='Polynômes interpolants de degré 2 et 9 pour les données f')
fig.show()
Results
b) Extrapolation
On calcule la valeur de f
au point x=1.2
:
x = 1.2
f_exact = 10 * x**2
estimations = [np.polyval(c, x) for c in [c2, c3, c4, c9]]
print(f"Valeur exacte : {f_exact}")
print(f"Estimations : {estimations}")
Results
Valeur exacte : 14.399999999999999 Estimations : [np.float64(11.88640889014812), np.float64(12.20174762673811), np.float64(13.239912549778104), np.float64(-2034.7378534462014)]
On voit donc que seules les approximations aux moindres carrés nous donnent des extrapolations fiables (respectivement 15.310, 15.69, 16.54, la valeur "exacte" sans bruit étant 14.4); le polynôme d’interpolation de Lagrange, par contre, lorsque on l’utilise pour extrapoler la valeur correspondante à x=1.2
, donne une prévision complètement erronée.
# Points pour l'évaluation des polynômes
x100 = np.linspace(0, 1.3, 100)
# Tracé avec Plotly
fig = go.Figure()
fig.add_trace(go.Scatter(x=x100, y=np.polyval(c2, x100), mode='lines', name='n=2', line=dict(color='blue')))
fig.add_trace(go.Scatter(x=x100, y=np.polyval(c3, x100), mode='lines', name='n=3', line=dict(color='green')))
fig.add_trace(go.Scatter(x=x100, y=np.polyval(c4, x100), mode='lines', name='n=4', line=dict(color='black')))
fig.add_trace(go.Scatter(x=x100, y=np.polyval(c9, x100), mode='lines', name='n=9', line=dict(color='red')))
fig.add_trace(go.Scatter(x=x, y=f, mode='markers', name='data', marker=dict(color='black')))
fig.update_layout(title='Polynômes interpolants de degré 2 et 9 pour les données f')
fig.show()