Transformation de Fourier. Le rapide et le furieux

Souvent, lors du dĂ©veloppement d'algorithmes, nous nous heurtons Ă  la limite de la complexitĂ© de calcul, qui, semble-t-il, est impossible Ă  surmonter. La transformĂ©e de Fourier a de la complexitĂ© O(n2), et une version rapide, proposĂ©e vers 1805 par House 1 (et rĂ©inventĂ©e en 1965 par James Cooley et John Tukey) O(nlog(n)). Dans cet article, je veux vous montrer que vous pouvez obtenir les rĂ©sultats de la conversion en temps linĂ©aire O(n)ou mĂȘme atteindre une difficultĂ© constante O(1)sous certaines conditions qui se trouvent dans de vrais problĂšmes.


Lorsque j'ai Ă©tĂ© confrontĂ© Ă  la tĂąche d'Ă©crire un programme pour analyser les fonctions de transfert des systĂšmes de son en temps rĂ©el, je me suis d'abord tournĂ© vers la conversion rapide comme tout le monde. Tout allait bien, mais avec la grande taille de la fenĂȘtre de temps, la charge du processeur est devenue indĂ©cemment importante et quelque chose devait ĂȘtre fait. Il a Ă©tĂ© dĂ©cidĂ© de faire une pause et d'Ă©tudier Ă  nouveau la transformation, tout en cherchant des moyens de rĂ©soudre le problĂšme. Revenons Ă  la transformation originale de Joseph Fourier 2 :

f(x)= sum limits− infty+ inftycke2 piikx/Tck= frac1T int limits0Tf(x)e−2 piikx/Tdx



Nous examinerons attentivement ce qui se passe ici. Chaque valeur de sortie dans le domaine frĂ©quentiel ckest la somme de toutes les valeurs d'entrĂ©e du signal f(x)multipliĂ© par e−2 piikx/T. Pour effectuer des calculs, nous devons parcourir toutes les donnĂ©es d'entrĂ©e pour chaque valeur de sortie, c'est-Ă -dire pour remplir ces n2opĂ©rations.

DĂ©barrassez-vous de n


Permettez-moi de vous rappeler qu'au dĂ©part, la tĂąche consistait Ă  analyser les donnĂ©es sonores en temps rĂ©el. Pour ce faire, la fenĂȘtre temporelle sĂ©lectionnĂ©e (essentiellement un tampon) de taille N est remplie de donnĂ©es avec une frĂ©quence f d correspondant Ă  la frĂ©quence d'Ă©chantillonnage. Avec la pĂ©riode T, les donnĂ©es d'entrĂ©e sont converties de la fenĂȘtre temporelle en fenĂȘtre frĂ©quentielle. Si vous regardez les nombres rĂ©els, alors N varie de 2 14 (16 384) Ă  2 16 (65 536) Ă©chantillons (les valeurs sont hĂ©ritĂ©es de la FFT, oĂč la taille de la fenĂȘtre doit ĂȘtre une puissance de deux). Temps T = 80 ms (12,5 fois par seconde), ce qui vous permet de voir les changements trĂšs facilement et de ne pas surcharger le CPU et le GPU. La frĂ©quence d'Ă©chantillonnage f d est standard et est de 48 kHz. Calculons la quantitĂ© de donnĂ©es dans la fenĂȘtre de temps change entre les dimensions. Pendant le temps T, il entre dans le tampon 48000 $ * 0,08 = 3840 $ Ă©chantillons. Ainsi, seulement 5% Ă  23% des donnĂ©es sont mises Ă  jour dans la fenĂȘtre. Dans le pire des cas, 95% (et au mieux 73%, ce qui est aussi beaucoup!) Des Ă©chantillons traitĂ©s tomberont encore et encore dans la conversion, malgrĂ© le fait qu'ils ont dĂ©jĂ  Ă©tĂ© traitĂ©s dans les itĂ©rations prĂ©cĂ©dentes.

Le lecteur attentif Ă  ce moment lĂšvera la main et dira: "attendez, mais qu'en est-il du coefficient e−2 piikx/T? AprĂšs tout, Ă  chaque nouvelle transformation, les mĂȘmes donnĂ©es seront localisĂ©es aux nouvelles positions de la sĂ©rie et, par consĂ©quent, auront des coefficients diffĂ©rents? » Pour chaque cinq pour leurs soins, rappelons un dĂ©tail important de la transformation qui est souvent oubliĂ©. Dans l'Ă©tude des valeurs de fonction f(t)sur l'intervalle de 0 Ă  t, la fonction est considĂ©rĂ©e comme pĂ©riodique, ce qui vous permet de dĂ©caler sans douleur la fonction vers la gauche ou la droite dans le temps. Par consĂ©quent, nous avons le droit de ne pas insĂ©rer une nouvelle valeur Ă  la fin et de supprimer l'ancienne valeur depuis le dĂ©but, mais de remplacer cycliquement les donnĂ©es dans le tampon.

Pour plus de clarté, vous pouvez écrire sous forme de tableau comment le tampon va changer:
t = 0f (0)f (1)f (2)f (3)f (4)f (5)f (6)f (7)f (8)f (9)
t = 1f (10)f (1)f (2)f (3)f (4)f (5)f (6)f (7)f (8)f (9)
t = 2f (10)f (11)f (2)f (3)f (4)f (5)f (6)f (7)f (8)f (9)
t = 3f (10)f (11)f (12)f (3)f (4)f (5)f (6)f (7)f (8)f (9)
t = 4f (10)f (11)f (12)f (13)f (4)f (5)f (6)f (7)f (8)f (9)

Vous pouvez Ă©crire comment la transformation dans le temps passe de t 1 Ă  t 2 :

Ft=Ft−1+ DeltaF DeltaF: Deltack= frac1T int limitst1t2(ft(x)−ft−1(x))e−2 piikx/Tdx


Valeur Ft−1(x)est le rĂ©sultat de la conversion prĂ©cĂ©dente et la complexitĂ© du calcul  Deltaf(x)ne dĂ©pend pas de la taille de la fenĂȘtre temporelle et est donc constant. En consĂ©quence, la complexitĂ© de la conversion sera O(n)* car il ne nous reste plus qu'Ă  parcourir une fois la fenĂȘtre de frĂ©quence et Ă  appliquer les changements pour les Ă©chantillons T qui ont changĂ© au cours du temps. Je voudrais Ă©galement attirer votre attention sur le fait que les probabilitĂ©s e−2 piikx/Tpeut ĂȘtre calculĂ© Ă  l'avance, ce qui donne un gain supplĂ©mentaire de productivitĂ©, et il ne reste que deux opĂ©rations dans le cycle: soustraire des nombres rĂ©els et multiplier un nombre rĂ©el par un complexe, dans la pratique, ces deux opĂ©rations sont simples et bon marchĂ©.

Pour compléter le tableau, il ne reste plus qu'à indiquer l'état initial, mais ici tout est simple:

F0(x)=0


* - bien sûr, la complexité finale de toute la transformation restera ainsi O(n2), mais il sera exécuté progressivement, sur n itérations, pendant la mise à jour du tampon. O(n)- c'est la complexité de la mise à jour des données, mais c'est exactement ce dont nous avons besoin (lors de l'utilisation de la FFT, la complexité de chaque transformation O(nlog(n)))

Mais que faire si vous creusez plus profondément. Ou se débarrasser du deuxiÚme n


Je veux tout de suite faire une réservation pour que les prochaines étapes ne soient applicables que si vous ne prévoyez pas d'effectuer la transformation inverse pour le résultat (afin de corriger le signal ou d'obtenir une réponse impulsionnelle). Pour commencer, je tiens à vous rappeler qu'à la suite de la conversion, nous obtenons un tableau de données symétrique, ce qui nous permet immédiatement de réduire de moitié le nombre de conversions.

Analysons maintenant l'ensemble de donnĂ©es rĂ©sultant, compte tenu des conditions du problĂšme. Nous avons un ensemble de nombres complexes, chacun dĂ©crivant l'amplitude et la phase des oscillations Ă  une frĂ©quence particuliĂšre. La frĂ©quence peut ĂȘtre dĂ©terminĂ©e par la formule: f[j]=j fracfdNpour j< fracN2. Évaluons l'Ă©tape de la fenĂȘtre de frĂ©quence sur nos donnĂ©es:  Deltaf= fracfdNPour N = 2 14 : 2,93 Hz (et pour 2 16 : 0,73 Hz). Ainsi, dans la plage de 1 kHz Ă  2 kHz, nous obtenons 341 rĂ©sultats. Essayez d'Ă©valuer indĂ©pendamment la quantitĂ© de donnĂ©es dans la plage de 8 kHz Ă  16 kHz pour N = 65536. Beaucoup, non? Beaucoup! Avons-nous besoin de tant de donnĂ©es? Bien sĂ»r, dans les problĂšmes d'affichage des caractĂ©ristiques de frĂ©quence des systĂšmes sonores, la rĂ©ponse est non. Et d'autre part, pour l'analyse dans la rĂ©gion des basses frĂ©quences, un petit pas est trĂšs utile. N'oubliez pas qu'il y a encore un calendrier Ă  prĂ©voir pour ces volumes (  fracN2) convertir en une forme lisible par l'homme (moyennage, spline ou lissage) et les afficher Ă  l'Ă©cran. Et Ă  des frĂ©quences Ă©levĂ©es, mĂȘme avec un Ă©cran 4K et l'affichage du graphique en mode plein Ă©cran avec l'axe de frĂ©quence logarithmique, la taille du pas se rĂ©vĂ©lera rapidement bien infĂ©rieure Ă  1 pixel.

Par expĂ©rience, vous pouvez dĂ©couvrir qu'il suffit d'avoir seulement 48 points par octave, et pour avoir les donnĂ©es un peu plus lisses et plus moyennes, je suggĂšre de s'arrĂȘter Ă  96. Dans la plage de frĂ©quences audio de 20 Hz Ă  20 kHz, il est facile de compter seulement 10 octaves: 20, 40, 80 , 160, 320, 640, 1280, 2560, 5120, 10240, 20480, chacune pouvant ĂȘtre divisĂ©e en un nombre donnĂ© de sous-bandes (n'oubliez pas que la partition doit ĂȘtre faite gĂ©omĂ©triquement et non arithmĂ©tiquement), par consĂ©quent, il est plus que suffisant d'effectuer la conversion uniquement pour 960 frĂ©quences pour obtenir Performan que dans 16 ... 65 fois plus petit que la version originale.

Ainsi, en combinant les deux approches, nous obtenons la complexité constante de l'algorithme de mise à jour des données O(1).

Miel carré et une cuillerée de goudron


Maintenant, nous pouvons dire que la complexité O(n2)nous sommes arrivés à la complexité O(1)en utilisant deux astuces de vie simples:

  • AprĂšs avoir analysĂ© le problĂšme, nous avons remarquĂ© que les donnĂ©es sont ajoutĂ©es progressivement et que la pĂ©riode de mise Ă  jour complĂšte de la fenĂȘtre temporelle est beaucoup plus Ă©levĂ©e que la pĂ©riode de transformations et nous avons ensuite calculĂ© la diffĂ©rence de la transformĂ©e de Fourier.
  • passĂ© de l'Ă©tape arithmĂ©tique dans la fenĂȘtre de frĂ©quence Ă  limitĂ© uniquement par les valeurs spĂ©cifiĂ©es, ce qui peut rĂ©duire considĂ©rablement le nombre de conversions.

Mais, bien sĂ»r, la vie serait vraiment un conte de fĂ©es, sinon un mais. L'application de ces deux approches nous a permis de vraiment dĂ©charger le CPU pour que deviner qu'il calcule la transformĂ©e de Fourier et affiche les rĂ©sultats Ă  l'Ă©cran mĂȘme avec N=220c'Ă©tait difficile. Mais la punition ne s'est pas fait attendre lorsque vos signaux en rĂ©alitĂ© ne sont pas pĂ©riodiques (et cela est nĂ©cessaire pour obtenir les rĂ©sultats de conversion corrects) et qu'il n'est pas possible de sĂ©lectionner la taille de fenĂȘtre appropriĂ©e, il devient nĂ©cessaire d'utiliser diverses fonctions de fenĂȘtre, ce qui ne vous permet plus d'utiliser pleinement la premiĂšre Ă©tape. La pratique a montrĂ© que l'utilisation des fonctions de fenĂȘtre est critique dans l'Ă©tude des signaux avec une frĂ©quence infĂ©rieure Ă  0,1fd. Aux hautes frĂ©quences, le nombre de pĂ©riodes tombant dans la fenĂȘtre temporelle attĂ©nue significativement les distorsions rĂ©sultant de la prĂ©sence d'un Ă©cart de premier ordre (entre f (0) et f (N-1)) dans la fonction d'origine.

Au final, j'ai également refusé la deuxiÚme étape et je suis retourné à la FFT, car le gain dans cette tùche était déjà faible.

En conclusion


La premiĂšre approche peut ĂȘtre appliquĂ©e si vos donnĂ©es sont de nature pĂ©riodique prononcĂ©e et doivent ĂȘtre analysĂ©es dans le temps Ă  l'aide d'une grande fenĂȘtre de temps, qui, je le rappelle, n'a pas besoin d'ĂȘtre de degrĂ© 2, c'est-Ă -dire tout nombre naturel.
La deuxiĂšme approche est applicable (mĂȘme en tenant compte des fonctions de fenĂȘtre) si seul un petit ensemble de frĂ©quences est analysĂ© dans les donnĂ©es.

Hélas, pour moi dans ce problÚme, cela n'est resté qu'un petit divertissement mathématique, mais j'espÚre que cela vous inspirera à étudier d'autres algorithmes en vacances en termes de changements dans les données d'entrée au fil du temps :)

Littérature


  1. Cooley - algorithme Tukey FFT
  2. E.A. Vlasova Rows. Maison d'Ă©dition du MSTU du nom de N.E.Bauman. Moscou 2002

Image tirĂ©e du manga de Michio Shibuya. “MATHÉMATIQUES EXCITANTES. Analyse de Fourier

Source: https://habr.com/ru/post/fr434734/


All Articles