Le formule de Moivre : (cosφ+isinφ)n=(eiφ)n=einφ=cos(nφ)+isin(nφ)
Exercice
Soit j=ei32π.
Calculer 1+j+j2.
Exercices de 1 à 3 page 300
Racines de unité
On cherche à résoudre dans C l'équation zn=1, c'est à dire "trouver les racines de l'unité".
Pour n=2, l'équation z2=1 possède 2 solutions : 1 et −1
soit 1=ei22π×0 et −1=ei22π×1
Pour n=4, l'équation z4=1 possède 4 solutions : 1, i, −1 et −i
soit 1=ei42π×0, i=ei42π×1, −1=ei42π×2, −i=ei42π×3.
Cas n=3:
On cherche z∈C tel que z3=1. En écrivant z=reiθ, il vient r3ei3θ=1ei×0.
Ainsi il faut pour le réel r=1, et pour 3θ=0(2π)=2kπ avec k∈Z.
Ainsi les 3solutions sont z=ei32kπ avec k=0;1;2.
Cas général :
Les solutions complexes de l'équation zn=1 sont les n nombres complexes :
zk=ein2kπ pour k de 0 à n.
En notant ω=ein2π, ces solutions sont les puissances de ω, de k=0 à n−1:
1;ω;ω2;…;ωk;…;ωn−1.
On les appelles les racines nième de l'unité.
Exercice
Déterminer les racines sixièmes de l'unité et les représenter dans le plan complexe.
En remarquant la somme de termes consécutifs d'une suite géométrique, démontrer que si ω est une racine sixième de l'unité, alors 1+ω+ω2+ω3+ω4+ω5=0.
Transformée de Fourier Discrète
Définition
Exemple : TFD pour n = 3
La transformée de Fourier Discrète consiste à obtenir à partir d'une séquence de 3 nombres complexes (x0;x1;x2) une séquence de 3 nouveaux nombres complexes (X0;X1;X2).
On procède de la façon suivante :
On pose ω=ei32π, et alors :
X0=x0×ω−0×0+x1×ω−0×1+x2×ω−0×2
X1=x0×ω−1×0+x1×ω−1×1+x2×ω−1×2
X2=x0×ω−2×0+x1×ω−2×1+x2×ω−2×2
Remarque : on a X0=x0+x1+x2
Exemple corrigé :
Calculer la transformée de Fourier Discrète : TFD(2, 0, 1)
a) Écrire la matrice M=(ω−i×j)
b) Calculer M×x0x1x2
c) Que retrouve-ton ?
Cas général
Pour n∈N, on pose ω=ein2π.
TFD(x0;x1;…;xn−1)=(X0;X1;…;Xn−1)
Avec Xi=∑j=0n−1xj×ω−i×j=x0×ω−i×0+x1×ω−i×1+⋯+xn−1×ω−i×(n−1)
Exercice
Donner la forme algébrique de ω=ei42π .
Calculer la TFD(1,−2,1,3)
Vérifier par le calcul matriciel
Exercices :
À la main : TFD(1;2), TFD(0;1), TDF(4;2), TFD(1;0;0), TFD(1;0;1)
Avec une calculatrice : TFD(0;21;23)
Travaux pratiques
TP 1 : Xcas, Python et propriétés de la TFD
La Transformée de Fourier Discrète en PYTHON
Le package cmath permet d'effectuer des calculs avec les nombres complexes.
Le nombre complexe i est codé par 1j . Essayez !
from cmath import *
print(1j)
print((1j)**2)
print((2-3j)*(-1+2j))
print(e**(1j*pi/2))
print((sqrt(2)/2+sqrt(2)*1j/2)**2)
2. Recopier et compléter le programme suivant. La procédure TFD doit calculer la Transformée de Fourier Discrète de la séquence [x0,x1,…,xn−1].
from cmath import *
def tfd(x): # x est un tableau [a, b, ..., c]
n = len(x) # nombre d'éléments du tableau
X = []
w = exp(2*pi*1j/n)
for i in range(n): # i = 0 à n-1
Xi = 0
for j in range(n):
Xi = Xi +x[j]*...
X.append(...) # Ajoute un élément au tableau X
return X
print(tfd([1,2,3]))
Vérifier en comparant les résultats du programme avec ceux obtenus par Xcas pour différentes séquences comme ici pour TFD(1,2,3) :
Les propriétés de la TDF
Avec Xcas comparer :
4*fft(1,-0.5) et fft(1,-0.5)
fft(1,-1,2)+fft(2,1,-1) et fft(3,0,1)
Comment écrire fft(1,0,0)+2fft(0,1,0)+3fft(0,0,1) en une seule commande fft ?
Cette propriété s'appelle linéarité de la TFD.
La formule de Bessel
Pour TFD(x0;x1;x2;…;xn−1)=(X0;X1;X2;…;Xn−1)
on a ∑k=0n−1∣xk∣2=n1∑k=0n−1∣Xk∣2
Nous allons vérifier cette propriété à l'aide de programmes PYTHON.
Recopiez ce programme, analysez-le et utilisez-le avec la procédure TFD pour vérifier cette formule pour la séquence [1 ; 2 ; 3 ]. Essayez avec d'autres séquences.
def somme_des_carrés(x):
S = 0
for xi in x:
S = S + abs(xi)**2
return S
print(somme_des_carrés([1,2,3]))
La transformée de Fourier Discrète Inverse
Pour TFD(x0;x1;x2;…;xn−1)=(X0;X1;X2;…;Xn−1), on peut retrouver (x0;x1;x2;…;xn−1) à partir de (X0;X1;X2;…;Xn−1) en utilisant la transformée inverse donnée par la formule (avec ω=ein2π) :
Les moins en exposant ont disparu et il est apparuun facteurn1.
Étudiez ce petit programme. Que permet-il de faire ?
liste1 = [1, 2, 3, 4]
liste2 = [element/2 for element in liste1]
print(liste1)
print(liste2)
En copiant et modifiant le programme tfd, codez le programme tfd_inv et vérifiez qu'il fonctionne bien avec la séquence [1, 2, 3]. Essayez avec d'autres séquences.
def tfd_inv(X):
n = len(X)
x = []
w = ...
for i in range(n):
xi = 0;
for j in range(n):
xi = xi + ...
x.append(xi)
x = [xi/... for xi in x]
return x
print(tfd_inv(tfd([1,2,3])))
TP2 : Débruiter un signal
Comment passer de ça à ça ?
Dans les programmes PYTHON qui vont suivre, nous importeront les deux packages :
from matplotlib.pyplot import *
from numpy import *
A - Définir un signal, l'échantillonner, le représenter
Un signal sinusoïdal de fréquence f est défini par s(t)=sin(2π×f×t)
Pour échantillonner ce signal sur 1 seconde à une fréquence Fe=1000, on prend 1000 abscisses également espacées de l'intervalle [0;1], pour lesquelles on récupère les images par le signal s.
1. Taper dans la console repl.it la commande linspace(0, 0.999, 1000)
2. La commande
def s(t):
return sin(2*pi*t)
permet de définir un signal de fréquence 1.
Copier-coller le programme ci-dessous et le compléter pour qu'il représente un signal sinusoïdal de fréquence 15 hertz, sur 1 seconde, échantillonné à 1000 Hertz :
(le fichier signal.png contiendra la représentation attendue : l'ouvrir après l'exécution du programme)
import os
os.environ['MPLCONFIGDIR'] = os.getcwd() + "/configs/"
from matplotlib.pyplot import *
from numpy import *
l = ... # Longueur du signal (secondes)
Fe = ... # Freq échantillonage
Te = 1/Fe # Période échantillonage
N = int(l*Fe) # Nombre d'échantillons
# signal à échantillonner
def s(t):
return ...
# variable t sur [0, l-Te] au pas l/N
t = linspace(0, l-Te, N)
''' Signal '''
fig = figure()
plot(t, s(t), label='Signal')
legend(loc='upper center', shadow=True, fontsize='x-small')
title("Signal")
xlabel("Temps")
fig.savefig('signal.png')
B - Transformée de Fourier Discrète d'un signal
En PYTHON, à l'aide du package numpy, on peut calculer la transformée de Fourier discrète d'une séquence : fft.fft([1,2,3])
Essayez dans repl.it en ayant chargé le package numpy :
from numpy import *
Obtenir le spectre des fréquences d'un signal s consiste à
échantillonner ce signal
calculer la transformée de Fourier discrète de cet échantillon
représenter la séquence obtenue
Utiliser le programme suivant pour obtenir le spectre des fréquences du signal s.
import os
os.environ['MPLCONFIGDIR'] = os.getcwd() + "/configs/"
from matplotlib.pyplot import *
from numpy import *
l = 0.6 # Longueur du signal (secondes)
Fe = 1000.0 # Freq échantillonnage
Te = 1/Fe # Période échantillonnage
N = int(l*Fe) # Nombre d'échantillons
# signal à échantillonner
def s(t):
return sin(2*pi*40*t) + .5*sin(2*pi*90*t+pi/4) + .7*sin(2*pi*120*t-pi/2)
# variable t sur [0, l-Te] au pas l/N
t = linspace(0, l-Te, N)
# On ne garde que la moitié des points (symétrie)
N1 = floor(N/2);
# Fréquences en abscisse
fr = linspace(0, int(N1 -1), int(N1))*Fe/N
''' Spectre du signal '''
y = fft.fft(s(t)) # TFD du signal
fig = figure()
plot(fr[0:int(N1 -1)], abs(y[0:int(N1 -1)]))
title("Spectre des fréquences du signal")
xlabel("Fréquences")
fig.savefig('spectre-signal.png')
Expliquer le spectre des fréquences obtenu :
quelles fréquences contient ce spectre ?
où retrouve-t-on ces fréquences dans le signal ?
comment expliquer les différences d'amplitude d'une fréquence à une autre dans le spectre ?
quel est l'effet sur le spectre des déphasages +4π et −2π dans les composantes du signal ?
C - Bruitage d'un signal
On souhaite maintenant "bruiter" un signal et obtenir un spectre de fréquences comme celui-ci :
Notre signal de départ est le suivant :
s(t)=sin(2π×40×t)+sin(2π×90×t+π/4)
La commande random.normal(0, 1, N) fournit une séquence aléatoire de N nombres distribués selon la loi normale.
Essayez-la dans la console sans oublier le package numpy.
Copier-coller et compléter le programme suivant pour qu'il affiche le spectre du signal bruité. Pour bruiter le signal, on ajoutera cette séquence aléatoire au signal initial.
import os
os.environ['MPLCONFIGDIR'] = os.getcwd() + "/configs/"
from matplotlib.pyplot import *
from numpy import *
l = 0.6 # Longueur du signal (secondes)
Fe = 1000.0 # Freq échantillonnage
Te = 1/Fe # Période échantillonnage
N = int(l*Fe) # Nombre d'échantillons
# signal à échantillonner
def s(t):
return ...
# variable t sur [0, l-Te] au pas l/N
t = linspace(0, l-Te, N)
# On ne garde que la moitié des points (symétrie)
N1 = floor(N/2);
# Fréquences en abscisse
fr = linspace(0, int(N1 -1), int(N1))*Fe/N
''' Spectre du signal bruité '''
fig = figure()
sb = s(t) + ... # bruitage du signal
yb = ... # TFD du signal bruité
plot(fr[0:int(N1 -1)], abs(yb[0:int(N1 -1)]))
title("Spectre des fréquences du signal bruité")
xlabel("Fréquences")
fig.savefig('spectre-signal-bruité.png')
D - Débruitage du signal
Travail préparatoire :
copier-coller le code suivant et répondre aux questions :
from numpy import *
# Que fait zeros ?
l1 = zeros(shape= 5)
print('l1')
print(l1)
print()
# random.normal(0, 1, 5) fournit une séquence aléatoire
l2 = random.normal(0, 1, 5)
print('l2')
print(l2)
print()
# Que fait abs ?
l3 = zeros(shape= 5)
for k in range(l3.size):
l3[k] = abs(l2[k])
print('l3')
print(l3)
print()
# Expliquez le résultat
l4 = zeros(shape= 5)
for k in range(l4.size):
l4[k] = (abs(l2[k]) > 0.7)
print('l4')
print(l4)
print()
# Expliquez le résultat
l5 = zeros(shape= 5)
for k in range(l5.size):
l5[k] = l2[k]*(abs(l2[k]) > 0.7)
print('l5')
print(l5)
print()
Le principe du "débruitage" d'un signal, consiste à ne garder que les fréquences du spectre supérieures à un certain seuil (fixé ici à 55).
À l'aide des instructions découvertes précédemment, copiez et complétez le programme suivant. Il doit afficher le spectre des fréquences du signal débruité. :
import os
os.environ['MPLCONFIGDIR'] = os.getcwd() + "/configs/"
from ... import *
from ... import *
l = 0.6 # Longueur du signal (secondes)
Fe = 1000.0 # Freq échantillonnage
Te = 1/Fe # Période échantillonnage
N = int(l*Fe) # Nombre d'échantillons
# signal à échantillonner
def s(t):
return sin(2*pi*40*t) + sin(2*pi*90*t+pi/4)
# variable t sur [0, l-Te] au pas l/N
t = linspace(0, l-Te, N)
# On ne garde que la moitié des points (symétrie)
N1 = floor(N/2);
# Fréquences en abscisse
fr = linspace(0, int(N1 -1), int(N1))*Fe/N
# bruitage du signal
sb = s(t) + random.normal(0, 1, N)
# TDF du signal bruité
yb = fft.fft(sb)
''' Spectre du signal débruité '''
fig = figure()
# débruitage
seuil = 55
y_debruite = zeros(shape=(yb.size), dtype=clongdouble)
for k in range(...):
y_debruite[k]=(yb[k])*...
plot(fr[0:int(N1 -1)], abs(y_debruite[0:int(N1 -1)]))
title("Spectre des fréquences du signal débruité")
xlabel("Fréquences")
fig.savefig('spectre-signal-débruité.png')
La commande ifft permet de calculer la Transformée de Fourier Discrète Inverse. Ajouter ces lignes de code en fin de programme. Exécuter-le plusieurs fois. Que fait-il ?