On considère une fonction f(x) dont on connaît les valeurs aux N points
On pose
Pour calculer f(x) pour x quelconque, on peut effectuer une interpolation polynomiale, qui consiste à calculer f(x) en utilisant l'unique polynôme de degré N-1 qui passe par les points
On présente ici l'algorithme de Neville, qui permet de faire efficacement une interpolation polynomiale lorsque le nombre de valeurs de x est faible.
L'algorithme de Neville ([1]) construit les polynômes par récurrence. On commence par les polynômes de degré 0. Le polynôme de degré 0 qui passe par le point (xi,yi) est :
Partant de ces N polynômes de degré 0, on construit les polynômes de degré 1. Le polynôme de degré 1 passant par les points (xi,yi),(xi+1,yi+1) est :
On a en effet :
La relation de récurrence permettant de passer de deux polynômes de degré m-1 à un polynôme de degré m est :
Pour le démontrer, on raisonne par récurrence, en supposant que les deux polynômes de degré m-1 apparaissant dans la relation ci-dessus passent par les m points figurant en indice. On vérifie alors que le polynôme de degré m passe par les m+1 points d'indices i,i+1,...i+m. Pour le premier point, on a en effet :
La vérification est similaire pour le point xi+m. Pour un point xi+k (commun aux deux polynômes de degré m-1), on a :
Le tableau suivant montre l'enchaînement des calculs jusqu'au polynôme de degré N-1, dans le cas N=4 :
L'algorithme de Neville est aisément programmé de manière récursive. Pour cela, on définit une fonction r(i,m,x) qui calcule la valeur du polynôme de degré m en fonction des valeurs des deux polynômes de degré m-1
Si m=0, la fonction renvoie yi. Sinon, elle renvoie :
On définit une classe dont le constructeur prend en argument les valeurs de x et y sous forme de listes.
class Neville: def __init__(self,x,y): self.x = x self.y = y self.N = len(x)
La fonction suivante définit la récurrence, en s'appelant récursivement deux fois :
def recurrence(self,i,m,x): if m==0: return self.y[i] else: return ((x-self.x[i+m])*self.recurrence(i,m-1,x)+\ (self.x[i]-x)*self.recurrence(i+1,m-1,x))/(self.x[i]-self.x[i+m])
Voici la fonction qui effectue l'interpolation :
def interpoler(self,x): return self.recurrence(0,self.N-1,x)
Pour tester l'algorithme, la fonction suivante effectue l'évaluation d'un polynôme dont les coefficients sont donnés dans une liste c (rangés par degré croissant) :
def eval_polynome(self,c,x): p = len(c) i = p-1 y = c[i] while i>0: i -= 1 y = y*x+c[i] return y
La fonction suivante calcule les valeurs des listes x et y à partir d'un polynôme donné, sur un intervalle donné :
def polynome(self,c,xmin,xmax): p = len(c) dx = (xmax-xmin)/p for k in range(p): self.x[k] = xmin+k*dx self.y[k] = self.eval_polynome(c,self.x[k])
Faisons un test avec un polynôme de degré 4 :
import neville x=[0,0,0,0] y=[0,0,0,0] nev = neville.Neville(x,y) c = [1,2,-3,2] nev.polynome(c,0.0,10.0) x0 = 3.564 y0 = nev.interpoler(x0)
print(y0) --> 60.562252287999996
print(y0-nev.eval_polynome(c,x0)) --> -1.4210854715202004e-14