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)
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*deftfd(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 inrange(n):# i = 0 à n-1 Xi =0for j inrange(n): Xi = Xi +x[j]*... X.append(...)# Ajoute un élément au tableau Xreturn Xprint(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.
defsomme_des_carrés(x): S =0for xi in x: S = S +abs(xi)**2return Sprint(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/2for 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.
deftfd_inv(X): n =len(X) x = [] w = ...for i inrange(n): xi =0;for j inrange(n): xi = xi + ... x.append(xi) x = [xi/... for xi in x]return xprint(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 osos.environ['MPLCONFIGDIR']= os.getcwd()+"/configs/"from matplotlib.pyplot import*from numpy import*l = ... # Longueur du signal (secondes)Fe = ... # Freq échantillonageTe =1/Fe # Période échantillonageN =int(l*Fe)# Nombre d'échantillons# signal à échantillonnerdefs(t):return ...# variable t sur [0, l-Te] au pas l/Nt =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 osos.environ['MPLCONFIGDIR']= os.getcwd()+"/configs/"from matplotlib.pyplot import*from numpy import*l =0.6# Longueur du signal (secondes)Fe =1000.0# Freq échantillonnageTe =1/Fe # Période échantillonnageN =int(l*Fe)# Nombre d'échantillons# signal à échantillonnerdefs(t):returnsin(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/Nt =linspace(0, l-Te, N)# On ne garde que la moitié des points (symétrie)N1 =floor(N/2);# Fréquences en abscissefr =linspace(0, int(N1 -1), int(N1))*Fe/N''' Spectre du signal '''y = fft.fft(s(t))# TFD du signalfig =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 osos.environ['MPLCONFIGDIR']= os.getcwd()+"/configs/"from matplotlib.pyplot import*from numpy import*l =0.6# Longueur du signal (secondes)Fe =1000.0# Freq échantillonnageTe =1/Fe # Période échantillonnageN =int(l*Fe)# Nombre d'échantillons# signal à échantillonnerdefs(t):return ...# variable t sur [0, l-Te] au pas l/Nt =linspace(0, l-Te, N)# On ne garde que la moitié des points (symétrie)N1 =floor(N/2);# Fréquences en abscissefr =linspace(0, int(N1 -1), int(N1))*Fe/N''' Spectre du signal bruité '''fig =figure()sb =s(t)+ ... # bruitage du signalyb = ... # 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éatoirel2 = random.normal(0, 1, 5)print('l2')print(l2)print()# Que fait abs ?l3 =zeros(shape=5)for k inrange(l3.size): l3[k]=abs(l2[k])print('l3')print(l3)print()# Expliquez le résultatl4 =zeros(shape=5)for k inrange(l4.size): l4[k]= (abs(l2[k])>0.7)print('l4')print(l4)print()# Expliquez le résultatl5 =zeros(shape=5)for k inrange(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 osos.environ['MPLCONFIGDIR']= os.getcwd()+"/configs/"from...import*from...import*l =0.6# Longueur du signal (secondes)Fe =1000.0# Freq échantillonnageTe =1/Fe # Période échantillonnageN =int(l*Fe)# Nombre d'échantillons# signal à échantillonnerdefs(t):returnsin(2*pi*40*t)+sin(2*pi*90*t+pi/4)# variable t sur [0, l-Te] au pas l/Nt =linspace(0, l-Te, N)# On ne garde que la moitié des points (symétrie)N1 =floor(N/2);# Fréquences en abscissefr =linspace(0, int(N1 -1), int(N1))*Fe/N# bruitage du signalsb =s(t)+ random.normal(0, 1, N)# TDF du signal bruitéyb = fft.fft(sb)''' Spectre du signal débruité '''fig =figure()# débruitageseuil =55y_debruite =zeros(shape=(yb.size), dtype=clongdouble)for k inrange(...): 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 ?