IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Python : interpolation trigonométrique d'une série de points,
Un billet blog de Denis Hulo

Le , par User

0PARTAGES

I. Introduction

Étant donné un ensemble de n points représentant des données périodiques de période T, on recherche une fonction d'interpolation qui passe par tous ces points.


On souhaite en fait implémenter une fonction Python qui réalise une interpolation trigonométrique d'une série de points supposés uniformément répartis dans un intervalle de longueur T.

Note : l'objectif n'est pas de donner des démonstrations rigoureuses des différentes formules employées, mais surtout de montrer comment les implémenter en Python.

II. Interpolation trigonométrique

On va tout d'abord montrer comment obtenir un polynôme trigonométrique permettant d'approcher une fonction de période 2𝜋. Puis, on va généraliser ce résultat pour n'importe quelle période.

II-A. Polynôme trigonométrique

On peut exprimer tout polynôme trigonométrique comme une somme de sinus et de cosinus :



Avec une série de n points, on s'attend à avoir une fonction polynomiale avec n paramètres ou coefficients à identifier.

C'est à dire comportant 1 paramètre initial a0, ensuite, le nombre de coefficients supplémentaires dépend de la parité de n :

  • Si n est pair, on aura m coefficients ak et m-1 coefficients bk, avec m = n/2.
  • Si n est impair, on aura m coefficients ak et bk, avec m = (n-1)/2.


II-A-1. Analogie entre polynôme et série trigonométrique

Soit f une fonction périodique, de période T=2𝜋, et intégrable sur , on appelle série de Fourier de f la série trigonométrique telle que :



On voit tout de suite l'analogie avec un polynôme trigonométrique :



On note cependant que ce type de polynôme possède un nombre fini de termes alors qu'une série de Fourier en possède un nombre infini.

II-A-2. Formules des coefficients du polynôme trigonométrique

Les coefficients d'une série de Fourier pour une fonction de période T=2𝜋 sont donnés par :



Si maintenant on se place sur l'intervalle [0, 2𝜋] (avec 𝛼=0), et si on effectue le changement de variable x = i.2𝜋/n dans les formules précédentes, on peut alors passer d'une variable continue x à une variable discrète i.

Les intégrales définies sur [0, 2𝜋] se transforment en sommes de n termes multipliées par un facteur 2𝜋/n.

La fonction continue f peut alors être approchée par une fonction polynomiale trigonométrique à n paramètres.

Pour k=0, on obtient ainsi :



Et pour 0 < k ≤ (n-1)/2 :



Pour 0 ≤ k ≤ m :



Pour k = n/2, et n donc pair, on peut remarquer que :



Comme les termes en sinus de la fonction polynomiale s'annulent tous, on obtient également :



On en déduit enfin que pour k = n/2 :



Cette formule est également valable pour k=0.

II-B. Interpolation sur une période quelconque

Si f(x) est périodique de période 2𝜋, alors f(ωx) est périodique de période 2𝜋/ω.

Par conséquent, si la fonction polynomiale f(x)=P(x) permet d'approcher une fonction continue de période 2𝜋, alors f(ωx) permet d'approcher une fonction continue de période 2𝜋/ω.

La fonction d'interpolation recherchée f(ωx) de période T=2𝜋/ω que l'on note g(x) est donc définie par :



III. Implémentation en Python

Nous souhaitons maintenant traduire en Python les formules précédentes pour nous permettre de déterminer la fonction d'interpolation passant par une série de points régulièrement répartis.

III-A. Évaluation des coefficients ak

On se base sur les formules des coefficients ak vues précédemment.

Pour 0 < k ≤ (n-1)/2 :



Pour k=0 ou k=n/2 :



On obtient facilement la fonction Python :

Code Python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def coefficient_cosinus(y, k): 
    # calcul du coefficient ak 
    # y : liste des valeurs de y 
    # k : indice du coefficient ak 
  
    # nombre de termes du polynôme trigonométrique ou nombre de valeurs de y 
    n = len(y) 
  
    # initialisation de la variable ak 
    ak =0 
  
    # parcours des indices i : 0 -> n-1 
    for i in range(len(y)): 
        xi=i*2*math.pi/n # xi = i2π/n 
        ak += y[i]*math.cos(k*xi) # ak = ak + yi*cos(k*xi) 
  
    if k>0 and k<=(n-1)/2: 
        ak=ak*2/n 
    else: 
        ak=ak/n 
  
    # retourne la valeur du coefficient ak 
    return round(ak,12)


III-B. Évaluation des Coefficients bk

De la même façon, en se basant sur la formule des coefficients bk :



On obtient le code Python :

Code Python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def coefficient_sinus(y, k): 
    # calcul du coefficient bk 
    # y : liste des valeurs de y 
    # k : indice du coefficient bk 
  
    # nombre de termes du polynôme trigonométrique ou nombre de valeurs de y 
    n = len(y) 
  
    # initialisation de la variable bk 
    bk =0 
  
    # parcours des indices i : 0 -> n-1 
    for i in range(n): 
        xi = i*2*math.pi/n # xi = i2π/n 
        bk += y[i]*math.sin(k*xi) # bk = bk + yi*sin(k*xi) 
  
    bk=bk*2/n 
  
    # retourne la valeur du coefficient bk 
    return round(bk,12)


III-C. Évaluation des coefficients du polynôme

En utilisant les fonctions précédentes, on peut alors écrire le code Python permettant d'obtenir la liste des coefficients de la fonction polynomiale à partir des valeurs de y :

Code Python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def coefs_polynome_trigo(y): 
    # évalue les coefficients du polynôme trigo. 
  
    n=len(y) # nombre de valeurs de y : nombre de paramètres du polynôme 
    m = n//2  
  
    # intialisation de la liste des paires de coefficients (ak, bk) 
    coefs=[] 
  
    # parcours des indices k : 0 -> m 
    for k in range(m+1): 
        # évaluation des coefficients ak et bk 
        ak = coefficient_cosinus(y,k) 
        bk = coefficient_sinus(y,k) 
  
        # ajout de la paire à la liste 
        coefs.append((ak,bk)) 
  
    # retourne la liste des couples de coefficients 
    return coefs


III-D. Evaluation de la fonction d'interpolation

En se basant finalement sur l'expression générale de la fonction d'interpolation :



On aboutit au code Python :

Code Python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
def eval_fonction_interpolation(coefs,T,x): 
  
    ω = 2*math.pi/T # w = 2π/T 
    valeur_polynome = 0 # initialisation de la variable à retourner 
  
    # parcours des indices k : 0 -> m 
    for k in range(len(coefs)): 
        # valeur_polynome = valeur_polynome + ak.cos(kωx) + bk.sin(kωx)  
        valeur_polynome += coefs[k][0]*math.cos(k*ω*x) + coefs[k][1]*math.sin(k*ω*x)  
  
    # retourne la valeur de la fonction d'interpolation pour x 
    return valeur_polynome


III-E Module de test

Nous donnons pour finir le module de test complet permettant d'obtenir à partir d'une série de points la fonction d'interpolation :

Code Python : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import math # module pour disposer des fonctions mathématiques 
import numpy as np 
import matplotlib.pyplot as plt # librairie pour générer le graphique 
  
def f(x): 
    # fonction supposée inconnue que l'on souhaite approcher en réalisant une interpolation trigonométrique de quelques points 
    return 5 + 7*math.cos(2*x) + 2*math.sin(2*x) + 3*math.cos(4*x) + 4*math.sin(4*x) + 5*math.cos(6*x) + 12*math.sin(6*x) + 27*math.cos(8*x) + 35*math.sin(8*x) 
  
  
def coefficient_cosinus(y, k): 
    # calcul du coefficient ak 
    # y : liste des valeurs de y 
    # k : indice du coefficient ak 
  
    # nombre de termes du polynôme trigonométrique ou nombre de valeurs de y 
    n = len(y) 
  
    # initialisation de la variable ak 
    ak =0 
  
    # parcours des indices i : 0 -> n-1 
    for i in range(len(y)): 
        xi=i*2*math.pi/n # xi = i2π/n 
        ak += y[i]*math.cos(k*xi) # ak = ak + yi*cos(k*xi) 
  
    if k>0 and k<=(n-1)/2: 
        ak=ak*2/n 
    else: 
        ak=ak/n 
  
    # retourne la valeur du coefficient ak 
    return round(ak,12) 
  
  
def coefficient_sinus(y, k): 
    # calcul du coefficient bk 
    # y : liste des valeurs de y 
    # k : indice du coefficient bk 
  
    # nombre de termes du polynôme trigonométrique ou nombre de valeurs de y 
    n = len(y) 
  
    # initialisation de la variable bk 
    bk =0 
  
    # parcours des indices i : 0 -> n-1 
    for i in range(n): 
        xi = i*2*math.pi/n # xi = i2π/n 
        bk += y[i]*math.sin(k*xi) # bk = bk + yi*sin(k*xi) 
  
    bk=bk*2/n 
  
    # retourne la valeur du coefficient bk 
    return round(bk,12) 
  
  
def coefs_polynome_trigo(y): 
    # évalue les coefficients du polynôme trigo. 
  
    n=len(y) # nombre de valeurs de y : nombre de paramètres du polynôme 
    m = n//2  
  
    # intialisation de la liste des paires de coefficients (ak, bk) 
    coefs=[] 
  
    # parcours des indices k : 0 -> m 
    for k in range(m+1): 
        # évaluation des coefficients ak et bk 
        ak = coefficient_cosinus(y,k) 
        bk = coefficient_sinus(y,k) 
  
        # ajout de la paire à la liste 
        coefs.append((ak,bk)) 
  
    # retourne la liste des couples de coefficients 
    return coefs 
  
  
def eval_fonction_interpolation(coefs,T,x): 
  
    ω = 2*math.pi/T # w = 2π/T 
    valeur_polynome = 0 # initialisation de la variable à retourner 
  
    # parcours des indices k : 0 -> m 
    for k in range(len(coefs)): 
        # valeur_polynome = valeur_polynome + ak.cos(kωx) + bk.sin(kωx)  
        valeur_polynome += coefs[k][0]*math.cos(k*ω*x) + coefs[k][1]*math.sin(k*ω*x)  
  
    # retourne la valeur de la fonction d'interpolation pour x 
    return valeur_polynome 
  
  
def expr_fonction_interpolation(coefs,T): 
  
    ω = 2*math.pi/T # w = 2π/T 
    expr_polynome = "f(x) = " + str(coefs[0][0]) + " + " # initialise de la variable expression avec a0 
  
    # parcours des indices k : 0 -> len(coefs)-1 
    for k in range(1, len(coefs)): 
        expr_polynome += "{0}.cos({1}x) + {2}.sin({1}x) + ".format(coefs[k][0],k*ω,coefs[k][1]) 
  
    # retourne l'expression de la fonction d'interpolation 
    return expr_polynome[:-3] 
  
  
# initialisation de la liste y 
y=[] 
  
# nombre de termes du polynôme trigonométrique recherché (nombre de points de la série) 
n = 9 
  
# période de la fonction d'interpolation recherchée. Par exemple, la fonction f(x) = a0 + a1.cos(2x) + b1.sin(2x) + a2.cos(4x) + b2.sin(4x) + ... a une période de T=π 
T = math.pi # T=π 
  
# parcours des indices des valeurs de x et de y 
for i in range(n): 
    xi = (i*T/n) # valeur de xi 
    yi = f(xi) # valeur de yi = f(xi), f est supposée inconnue 
  
    # ajout de la valeur yi à la liste y 
    y.append(yi) 
  
# évaluation des coefficients du polynôme trigonométrique 
coefs_polynome=coefs_polynome_trigo(y) 
  
print("I. Expression de la fonction d'interpolation passant par les différents points :") 
print() 
  
# affiche l'exrpession de la fonction d'interpolation passant par les différents points 
print(expr_fonction_interpolation(coefs_polynome,T)) 
  
print();print() 
print("II. Courbe représentative de la fonction d'interpolation passant par les différents points..") 
  
# précision de la trace de la fonction d'interpolation 
precision_trace = 10 # 10*n : ici on multiplie le nombre de points initial n par 10 
  
# génère 10*n valeurs de x entre 0 et T 
x = list(np.linspace(0.0, T, precision_trace*n)) 
  
# initialise la liste y1 avec 10*n cases à None : [None, None, None, ..., None] 
y1=[None]*(precision_trace*n) 
y2=[] 
  
# parcours des indices de x 
for i in range(len(x)): 
    if i % precision_trace==0: # si i modulo 10 = 0 : 0, 10, 20, ... 
        y1[i]=y[i//precision_trace] # copie de la valeur mesurée yi 
    #y1[i]= f(x[i]) # copie de la valeur réelle de la fonction 
  
    # valeur donnée par la fonction d'interpo. 
    yi=eval_fonction_interpolation(coefs_polynome,T,x[i]) 
    # ajout de yi à la liste y2 
    y2.append(yi) 
  
# trace les points de la série en rouge     
plt.plot(x, y1, marker="o", color="r") 
# trace la courbe représentative de la fonction d'interpolation     
plt.plot(x, y2, color="b") 
  
# définit le titre du graphique : Interpolation trigonométrique 
plt.title("Interpolation trigonométrique") 
  
plt.show() # affiche la figure à l'écran

Le code affiche :

I. Expression de la fonction d'interpolation passant par les différents points :

f(x) = 5.0 + 7.0.cos(2.0x) + 2.0.sin(2.0x) + 3.0.cos(4.0x) + 4.0.sin(4.0x) + 5.0.cos(6.0x) + 12.0.sin(6.0x) + 27.0.cos(8.0x) + 35.0.sin(8.0x)


Puis la courbe représentative de la fonction passant par les différents points :



IV. Conclusion

Après avoir montré l'analogie entre les séries de Fourier et les polynômes trigonométriques, nous avons pu obtenir les formules des coefficients du polynôme, puis celle de la fonction d'interpolation.

Enfin, nous avons su traduire ces formules en Python, et les utiliser pour déterminer à partir d'une série de points, la fonction d'interpolation.

Sources :

https://fr.wikipedia.org/wiki/Polyn%...om%C3%A9trique
https://fr.wikipedia.org/wiki/S%C3%A9rie_de_Fourier

Une erreur dans cette actualité ? Signalez-nous-la !