{"id":2060,"date":"2022-08-23T21:00:22","date_gmt":"2022-08-23T20:00:22","guid":{"rendered":"http:\/\/www.fabienm.eu\/flf\/?p=2060"},"modified":"2023-02-02T14:38:38","modified_gmt":"2023-02-02T13:38:38","slug":"traitement-numerique-du-signal-prise-de-notes","status":"publish","type":"post","link":"http:\/\/www.fabienm.eu\/flf\/traitement-numerique-du-signal-prise-de-notes\/","title":{"rendered":"Traitement num\u00e9rique du signal, prise de notes"},"content":{"rendered":"\n<p>On dit souvent que pour bien apprendre un sujet en informatique il faut \u00e9crire une doc. Pour des besoins pro j&rsquo;ai du me re-mettre au traitement num\u00e9rique du signal. Je commence en g\u00e9n\u00e9ral par un bouquin et un projet. Pour le projet comme c&rsquo;est du pro je c&rsquo;est \u00e0 ma discr\u00e9tion, par contre pour le bouquin je me suis plong\u00e9 dans le livre de <strong>Richard G.Lyons <\/strong>\u00ab<em><a href=\"https:\/\/www.pearson.com\/us\/higher-education\/program\/Lyons-Understanding-Digital-Signal-Processing-3rd-Edition\/PGM202823.html\">Understanding digital signal processing<\/a><\/em>\u00bb qui  a le m\u00e9rite d&rsquo;\u00eatre richement illustr\u00e9 de graphes et d&rsquo;\u00e9quations avec beaucoup d&rsquo;explications visuelles et \u00abavec les mains\u00bb.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/FSKAAAqWUAE1gLy.jpeg\"><img loading=\"lazy\" decoding=\"async\" width=\"768\" height=\"1024\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/FSKAAAqWUAE1gLy-768x1024.jpeg\" alt=\"\" class=\"wp-image-2061\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/FSKAAAqWUAE1gLy-768x1024.jpeg 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/FSKAAAqWUAE1gLy-225x300.jpeg 225w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/FSKAAAqWUAE1gLy-1152x1536.jpeg 1152w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/FSKAAAqWUAE1gLy.jpeg 1536w\" sizes=\"auto, (max-width: 768px) 100vw, 768px\" \/><\/a><figcaption class=\"wp-element-caption\">Du bon soleil pour apprendre<\/figcaption><\/figure>\n\n\n\n<p>L&rsquo;id\u00e9e de cette note est donc de faire des exercices en rapport avec ce qui est dans ce livre mais pas que, le tout de mani\u00e8re pratique en python et de voir les implications que \u00e7a peut avoir avec les FPGA.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Un signal discret<\/h2>\n\n\n\n<p>Dans un premier temps nous aurons besoin de <strong>numpy<\/strong> et <strong>pylab<\/strong> en python3 <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import numpy as np\nimport pylab as plt<\/code><\/pre>\n\n\n\n<p>Le signal de base est une sinuso\u00efde. Pour repr\u00e9senter un signal de 1 Hertz en python on va d&rsquo;abord cr\u00e9er un tableau d&rsquo;un certain nombre de valeur de 0 \u00e0 1&nbsp;secondes :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Freq\nf0 = 1\n# 40 points de 0 \u00e0 39\nt = np.linspace(0, 1, 40)<\/code><\/pre>\n\n\n\n<p>Puis calculer le sinus <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>y = np.sin(2*math.pi*f0*t)<\/code><\/pre>\n\n\n\n<p>Signal qu&rsquo;il est facile de \u00abplotter\u00bb ensuite :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>plt.plot(t, y)\nplt.show()<\/code><\/pre>\n\n\n\n<p>Ce qui nous donne cette belle courbe de sinus :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/sinuscontinu.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/sinuscontinu.png\" alt=\"\" class=\"wp-image-2064\" width=\"634\" height=\"475\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/sinuscontinu.png 640w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/sinuscontinu-300x225.png 300w\" sizes=\"auto, (max-width: 634px) 100vw, 634px\" \/><\/a><figcaption class=\"wp-element-caption\">D&rsquo;apr\u00e8s Richard il ne faut pas relier les points<\/figcaption><\/figure>\n\n\n\n<p>Mais pour bien se repr\u00e9senter un signal <strong>num\u00e9rique<\/strong> il ne faut pas relier les points. Il vaut mieux mettre des points avec des lignes verticales comme ceci :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fix, ax = plt.subplots()\nax.stem(t, y, 'b', markerfmt=\"b.\")\nplt.show()<\/code><\/pre>\n\n\n\n<p>Ce qui nous donne la figure suivante :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/sinuspoinligne.png\"><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"480\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/sinuspoinligne.png\" alt=\"\" class=\"wp-image-2065\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/sinuspoinligne.png 640w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/sinuspoinligne-300x225.png 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><figcaption class=\"wp-element-caption\">Les points non reli\u00e9s entre eux donnent une meilleur vision d&rsquo;un signal num\u00e9rique (discret)<\/figcaption><\/figure>\n\n\n\n<p>Cette derni\u00e8re figure illustre bien la notion d&rsquo;\u00e9chantillonnage avec une fr\u00e9quence d\u2019\u00e9chantillonnage fs de 40Hertz (temps en secondes et 40 points) soit :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Freq\nf0 = 1\n# Temps total\nT = 1\n# Nombre de points:\nN = 40\n# Fr\u00e9quence d\u2019\u00e9chantillonnage :\nprint(f\"fs = {N\/T} Hertz\")\n# fs = 40.0 Hertz<\/code><\/pre>\n\n\n\n<p>Ici, la fr\u00e9quence d&rsquo;\u00e9chantillonnage (40Hertz) est largement sup\u00e9rieur \u00e0 la fr\u00e9quence du signal enregistr\u00e9 (1 Hertz). On peut s&rsquo;amuser maintenant \u00e0 monter la fr\u00e9quence du signal \u00e0 la fr\u00e9quence de Nyquist :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs5.png\"><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"480\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs5.png\" alt=\"\" class=\"wp-image-2068\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs5.png 640w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs5-300x225.png 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><figcaption class=\"wp-element-caption\">f0 = 5<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs10.png\"><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"480\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs10.png\" alt=\"\" class=\"wp-image-2069\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs10.png 640w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs10-300x225.png 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><figcaption class=\"wp-element-caption\">f0 = 10<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs20.png\"><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"480\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs20.png\" alt=\"\" class=\"wp-image-2070\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs20.png 640w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs20-300x225.png 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><figcaption class=\"wp-element-caption\">f0 = 20<\/figcaption><\/figure>\n\n\n\n<p>Ce que nous dit Nyquist, c&rsquo;est qu&rsquo;avec tous les signaux ci-dessus, il est possible de retrouver la sinuso\u00efde du d\u00e9but. Mais si on augmente encore la fr\u00e9quence on obtient un <strong>repliement<\/strong> du spectre.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs30.png\"><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"480\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs30.png\" alt=\"\" class=\"wp-image-2071\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs30.png 640w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs30-300x225.png 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><figcaption class=\"wp-element-caption\">f0  = 30<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs40.png\"><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"480\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs40.png\" alt=\"\" class=\"wp-image-2072\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs40.png 640w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/fs40-300x225.png 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><figcaption class=\"wp-element-caption\">f0 = 40<\/figcaption><\/figure>\n\n\n\n<p>On peut ajouter le l&rsquo;analyse de spectre en augmentant \u00e9galement le nombre de points mesur\u00e9 :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Freq\nf0 = 1\n# Temps total\nT = 1\n# Nombre de points:\nN = 100\n# 100 points de 0 \u00e0 99\nt = np.linspace(0, T, N)\ny = np.sin(2*np.pi*f0*t)\nfix, ax = plt.subplots(1,2)\nax&#91;0].stem(t, y, 'b', markerfmt=\"b.\")\nax&#91;1].magnitude_spectrum(y, Fs=N\/T, ds=\"steps-mid\")\nplt.show()<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/traitement_Figure_100.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"581\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/traitement_Figure_100-1024x581.png\" alt=\"\" class=\"wp-image-2074\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/traitement_Figure_100-1024x581.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/traitement_Figure_100-300x170.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/traitement_Figure_100-768x436.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/05\/traitement_Figure_100.png 1350w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">(f0=1) \u00c0 gauche le signal sur 100 points, \u00e0 droite l&rsquo;analyse des fr\u00e9quences <\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Ondelettes<\/h2>\n\n\n\n<p>Pour faire une ondelette (wavelet) on multiplie un cosinus (p\u00e9riodique) avec une gaussienne (exp(-t\u00b2\/2)) :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># D\u00e9calage en seconde:\nretard = 5\ny = np.cos(2*np.pi*f0*t)*np.exp(-np.power(t-retard,2)\/2)<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/wavelet_python.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"530\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/wavelet_python-1024x530.png\" alt=\"\" class=\"wp-image-2117\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/wavelet_python-1024x530.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/wavelet_python-300x155.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/wavelet_python-768x398.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/wavelet_python-1536x795.png 1536w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/wavelet_python.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">La fr\u00e9quence du signal est toujours de 1Hz mais le signal n&rsquo;est plus p\u00e9riodique \u00e0 l&rsquo;infini<\/figcaption><\/figure>\n\n\n\n<p>La <a href=\"https:\/\/www.youtube.com\/watch?v=jnxqHcObNK4&amp;t=819s\">vid\u00e9o suivante<\/a> explique tout ce que vous avez toujours voulu savoir sur les ondelettes.<\/p>\n\n\n\n<p>Si on change la fr\u00e9quence du signal, en passant \u00e0 2Hz par exemple. On se rend compte que l&rsquo;\u00e9chantillonnage tronque les maximum locaux :<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/wavelette_2Hz.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"530\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/wavelette_2Hz-1024x530.png\" alt=\"\" class=\"wp-image-2122\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/wavelette_2Hz-1024x530.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/wavelette_2Hz-300x155.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/wavelette_2Hz-768x398.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/wavelette_2Hz-1536x795.png 1536w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/wavelette_2Hz.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">La courbe n&rsquo;est plus sym\u00e9trique<\/figcaption><\/figure>\n\n\n\n<p>Ce qui casse la sym\u00e9trie de la courbe.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Hilbert avec scipy<\/h2>\n\n\n\n<p>La <a href=\"https:\/\/geophydog.cool\/post\/hilbert_transform\/\">transform\u00e9e de hilbert <\/a>permet de calculer la partie imaginaire du signal r\u00e9el. Le package python nomm\u00e9 <a href=\"https:\/\/docs.scipy.org\/doc\/scipy\/reference\/generated\/scipy.signal.hilbert.html\">scipy<\/a> inclue la fonction qui la calcule.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;...]\nfrom scipy import signal\n&#91;...]\n# morlet wavelet\ny = np.cos(2*np.pi*f0*t)*np.exp(-np.power(t-retard,2)\/2)\n\nhimg = signal.hilbert(y).imag\nhreal = signal.hilbert(y).real\n&#91;...]<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_scipy.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"530\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_scipy-1024x530.png\" alt=\"\" class=\"wp-image-2128\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_scipy-1024x530.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_scipy-300x155.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_scipy-768x398.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_scipy-1536x795.png 1536w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_scipy.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">On distingue bien la partie r\u00e9el (le signal d&rsquo;origine) et la partie imaginaire en orange<\/figcaption><\/figure>\n\n\n\n<p>Comme nous avons la partie r\u00e9elle et la partie imaginaire de notre signal, il est possible d\u00e9sormais de calculer son module pour en tirer l&rsquo;enveloppe:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># morlet wavelet\ny = np.cos(2*np.pi*f0*t)*np.exp(-np.power(t-retard,2)\/2)\n\nhimg = signal.hilbert(y).imag\nhreal = signal.hilbert(y).real\n\nhabs = np.sqrt(np.power(himg, 2) + np.power(hreal, 2))<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_enveloppe.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"530\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_enveloppe-1024x530.png\" alt=\"\" class=\"wp-image-2133\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_enveloppe-1024x530.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_enveloppe-300x155.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_enveloppe-768x398.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_enveloppe-1536x795.png 1536w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_enveloppe.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">L&rsquo;enveloppe du signal en vert (habs)<\/figcaption><\/figure>\n\n\n\n<p>Si l&rsquo;on diminue la fr\u00e9quence d\u2019\u00e9chantillonnage (division par 10) on remarque que l&rsquo;enveloppe ne passe plus par les maximums. La transform\u00e9e de Hilbert semble les avoirs tout de m\u00eame d\u00e9duit :<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_low_echfreq.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"530\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_low_echfreq-1024x530.png\" alt=\"\" class=\"wp-image-2139\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_low_echfreq-1024x530.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_low_echfreq-300x155.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_low_echfreq-768x398.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_low_echfreq-1536x795.png 1536w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/hilbert_low_echfreq.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Avec une fr\u00e9quence de pulsation de 2 Hertz et une division de la fr\u00e9quence \u00e9chantillonnage par 10 on constate que l&rsquo;enveloppe demeure alors que les maximums r\u00e9el et imaginaire sont tronqu\u00e9s. <\/figcaption><\/figure>\n\n\n\n<p>Peut-on calculer l&rsquo;enveloppe sans racine carr\u00e9 et carr\u00e9 ?<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>habs = np.abs(himg) + np.abs(hreal)<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2023\/02\/hilbert_no_square.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"530\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2023\/02\/hilbert_no_square-1024x530.png\" alt=\"\" class=\"wp-image-2284\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2023\/02\/hilbert_no_square-1024x530.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2023\/02\/hilbert_no_square-300x155.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2023\/02\/hilbert_no_square-768x398.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2023\/02\/hilbert_no_square-1536x795.png 1536w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2023\/02\/hilbert_no_square.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Hmmm \u00e7a marche moins bien sans carr\u00e9 (courbe rouge)<\/figcaption><\/figure>\n\n\n\n<p>Et juste avec des carr\u00e9s ?<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>hsquare= np.power(himg, 2) + np.power(hreal, 2)<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2023\/02\/hilbert_envelloppe_carres_sum.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"530\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2023\/02\/hilbert_envelloppe_carres_sum-1024x530.png\" alt=\"\" class=\"wp-image-2285\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2023\/02\/hilbert_envelloppe_carres_sum-1024x530.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2023\/02\/hilbert_envelloppe_carres_sum-300x155.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2023\/02\/hilbert_envelloppe_carres_sum-768x398.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2023\/02\/hilbert_envelloppe_carres_sum-1536x795.png 1536w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2023\/02\/hilbert_envelloppe_carres_sum.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Hmm c&rsquo;est pas magique non plus<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Transform\u00e9e de Fourrier<\/h2>\n\n\n\n<p>Mais que faites vous encore sur ce blog ! Vite allez visionner<a href=\"https:\/\/www.youtube.com\/watch?v=spUNpyF58BY&amp;t=1s\"> l&rsquo;excellente vid\u00e9o<\/a> de <a href=\"https:\/\/www.youtube.com\/c\/3blue1brown\">3Blue1Brown<\/a> qui parle de la transform\u00e9e de Fourrier avec force de graphes et de dessins. Vous ne verrez plus la transform\u00e9e de fourrier comme avant \ud83d\ude09<\/p>\n\n\n\n<p>Sinon y a aussi cette formule trouv\u00e9e sur <a href=\"https:\/\/twitter.com\/Rainmaker1973\/status\/1555608630107553793\">twitter<\/a> qui est vraiment tr\u00e8s parlante :<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/FZahzLUX0Ac7a-Y.png\"><img loading=\"lazy\" decoding=\"async\" width=\"680\" height=\"340\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/FZahzLUX0Ac7a-Y.png\" alt=\"\" class=\"wp-image-2141\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/FZahzLUX0Ac7a-Y.png 680w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/09\/FZahzLUX0Ac7a-Y-300x150.png 300w\" sizes=\"auto, (max-width: 680px) 100vw, 680px\" \/><\/a><figcaption class=\"wp-element-caption\">Trouv\u00e9e sur <a href=\"https:\/\/twitter.com\/Rainmaker1973\/status\/1555608630107553793\">twitter<\/a><\/figcaption><\/figure>\n\n\n\n<p>Jusqu&rsquo;\u00e0 pr\u00e9sent, pour calculer et afficher la transform\u00e9e de fourrier de notre signal, nous nous sommes servi exclusivement de la fonction <code>magnitude_spectrum()<\/code> inclue dans <code>pylab<\/code>. C&rsquo;est int\u00e9ressant pour avoir un aper\u00e7u du spectre, mais \u00e7a ne permet pas de dire que l&rsquo;on ma\u00eetrise \u00e7a.<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<h3 class=\"wp-block-heading\">Nombre complexes en python<\/h3>\n\n\n\n<p>Python permet visiblement d&rsquo;utiliser nativement des nombres complexes avec &lsquo;j&rsquo; \u00e0 condition d&rsquo;y mettre un nombre devant :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>In &#91;2]: j                                                                                                                                                                                                          \n---------------------------------------------------------------------------\nNameError                                 Traceback (most recent call last)\n&lt;ipython-input-2-3eedd8854d1e&gt; in &lt;module&gt;\n----&gt; 1 j\n\nNameError: name 'j' is not defined\n\nIn &#91;3]: 1j                                                                                                                                                                                                         \nOut&#91;3]: 1j\n\nIn &#91;4]: 0.02j                                                                                                                                                                                                      \nOut&#91;4]: 0.02j\n\nIn &#91;5]: -3j                                                                                                                                                                                                        \nOut&#91;5]: (-0-3j)\n\nIn &#91;7]: np.exp(1j)                                                                                                                                                                                                 \nOut&#91;7]: (0.5403023058681398+0.8414709848078965j)\n<\/code><\/pre>\n<\/div><\/div>\n\n\n\n<p>Tentons donc de calculer la transform\u00e9e de fourrier en mode \u00abbrute de force\u00bb pour voir:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\n#temps: 0 points de 0 \u00e0 N-1\nt = np.linspace(0, T, N)\n# morlet wavelet\ny = np.cos(2*np.pi*f0*t)*np.exp(-np.power(t-retard,2)\/2)\n\n# transform\u00e9e de fourrier\nfreqs = np.array(&#91;])\nfor k in range(N):\n    listexp = &#91;y&#91;n]*np.exp(1j*2*np.pi*k*n\/N) for n in range(N)]\n    xk = (1\/N)*np.array(listexp).sum()\n    freqs = np.append(freqs, xk)\n\n#fr\u00e9quence: 0 points de 0 \u00e0 N-1\nk = np.linspace(0, T, N)<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_calcule_complex.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"530\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_calcule_complex-1024x530.png\" alt=\"\" class=\"wp-image-2154\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_calcule_complex-1024x530.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_calcule_complex-300x155.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_calcule_complex-768x398.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_calcule_complex-1536x795.png 1536w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_calcule_complex.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Visiblement nous avons un probl\u00e8me \u00abcomplexe\u00bb<\/figcaption><\/figure>\n\n\n\n<p>L\u00e0 ce que nous venons de calculer est la version complexe de la transform\u00e9e de fourrier dont pylab nous \u00abplot\u00bb la partie r\u00e9elle. Voyons voir le module :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fourrier_module = np.sqrt(np.power(freqs.imag, 2) + np.power(freqs.real, 2))<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_module_harmonique.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"530\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_module_harmonique-1024x530.png\" alt=\"\" class=\"wp-image-2155\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_module_harmonique-1024x530.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_module_harmonique-300x155.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_module_harmonique-768x398.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_module_harmonique-1536x795.png 1536w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_module_harmonique.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Mais pourquoi ce deuxi\u00e8me pic ?<\/figcaption><\/figure>\n\n\n\n<p>Nous avons donc toujours deux pics, sachant que le second pic est au del\u00e0 de la fr\u00e9quence de Nyquist (Fs=10Hz) et semble \u00abnormal\u00bb. <\/p>\n\n\n\n<p>Par contre nous avons un facteur 2 entre le calcul de magnitude de python et celui que l&rsquo;on vient de calculer.<\/p>\n\n\n\n<p>Peut-\u00eatre parce que la formule de l&rsquo;image est celle de la transform\u00e9e inverse ? La transform\u00e9e discr\u00e8te donn\u00e9e dans le livre est plut\u00f4t celle l\u00e0 :<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_formula_book_page60.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"127\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_formula_book_page60-1024x127.png\" alt=\"\" class=\"wp-image-2163\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_formula_book_page60-1024x127.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_formula_book_page60-300x37.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_formula_book_page60-768x95.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_formula_book_page60-1536x190.png 1536w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_formula_book_page60-2048x253.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Page 60: On retrouve encore moins le facteur 2 sur cette formule.<\/figcaption><\/figure>\n\n\n\n<p>Voyons voir avec cette nouvelle formule :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># transform\u00e9e de fourrier\nfreqs = np.array(&#91;])\nfor k in range(N):\n    listexp = &#91;y&#91;n]*np.exp(-1j*2*np.pi*k*n\/N) for n in range(N)]\n    xk = np.array(listexp).sum()\n    freqs = np.append(freqs, xk)\n\nfourrier_module = np.sqrt(np.power(freqs.imag, 2) + np.power(freqs.real, 2))<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_formule_book.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"530\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_formule_book-1024x530.png\" alt=\"\" class=\"wp-image-2166\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_formule_book-1024x530.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_formule_book-300x155.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_formule_book-768x398.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_formule_book-1536x795.png 1536w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_formule_book.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Bon c&rsquo;est pas un facteur 2&nbsp;cette fois!<\/figcaption><\/figure>\n\n\n\n<p>Si on veut \u00abmatcher\u00bb la courbe de magnitude il faut ajouter un facteur 2\/N au calcul du module :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fourrier_module = (2\/N)*np.sqrt(np.power(freqs.imag, 2) + np.power(freqs.real, 2))<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_module_matched.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"530\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_module_matched-1024x530.png\" alt=\"\" class=\"wp-image-2169\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_module_matched-1024x530.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_module_matched-300x155.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_module_matched-768x398.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_module_matched-1536x795.png 1536w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_module_matched.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Avec le facteur (2\/N) on obtient une superposition des courbes.<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">cos &#8211; sin<\/h2>\n\n\n\n<p>Pour faire entrer le calcul de la transform\u00e9e dans un FPGA, l&rsquo;exponentielle d&rsquo;un complexe n&rsquo;est pas super pratique. D\u00e9composons donc en diff\u00e9rence cos-sin avec la <a href=\"https:\/\/fr.wikipedia.org\/wiki\/Formule_d'Euler\">formule d&rsquo;Euler<\/a>, on devrait obtenir le m\u00eame r\u00e9sultat:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># transform\u00e9e de fourrier\nfreqs = np.array(&#91;])\nfor k in range(N):\n    listexp = &#91;]\n    for n in range(N):\n        angle = 2*np.pi*k*n\/N\n        listexp.append(y&#91;n]*(np.cos(angle) - 1j*np.sin(angle)))\n    xk = np.array(listexp).sum()\n    freqs = np.append(freqs, xk)<\/code><\/pre>\n\n\n\n<p>Et nous obtenons exactement le m\u00eame graphe qu&rsquo;avant.<\/p>\n\n\n\n<p>C&rsquo;est sans surprise qu&rsquo;on obtient  la m\u00eame chose en sommant ind\u00e9pendamment partie r\u00e9elle et partie imaginaire :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># transform\u00e9e de fourrier\nfreqs_real = np.array(&#91;])\nfreqs_img = np.array(&#91;])\nfor k in range(N):\n    listreal = &#91;]\n    listimg = &#91;]\n    for n in range(N):\n        angle = 2*np.pi*k*n\/N\n        listreal.append(y&#91;n]*(np.cos(angle)))\n        listimg.append(y&#91;n]*(-np.sin(angle)))\n    xkreal = np.array(listreal).sum()\n    xkimg = np.array(listimg).sum()\n    freqs_real = np.append(freqs_real, xkreal)\n    freqs_img = np.append(freqs_img, xkimg)\n\nfourrier_module = (2\/N)*np.sqrt(np.power(freqs_img, 2) + np.power(freqs_real, 2))<\/code><\/pre>\n\n\n\n<p>Nous permettant au passage de d\u00e9gager le &lsquo;j&rsquo; des nombres complexes qui ne passe pas tr\u00e8s bien dans un FPGA.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Des entiers ou des virgules fixes<\/h2>\n\n\n\n<p>Pour le moment c&rsquo;\u00e9tait facile: on avait les flottant de python. Seulement voil\u00e0, dans un FPGA, les flottants ne sont pas simple.  Nous avons besoin de fixer la taille (en bits) des variables\/registres utilis\u00e9s. Il faut \u00e9galement fixer la position de la virgule si l&rsquo;on souhaite simplifier le calcul.<\/p>\n\n\n\n<p>Le second probl\u00e8me nous vient des fonctions sin() et cos() qui ne sont pas calculables simplement. L&rsquo;astuce consiste \u00e0 pr\u00e9-calculer les valeurs et les stocker dans une table qui ira remplir une ROM du FPGA. <\/p>\n\n\n\n<p>Pour g\u00e9rer des entiers en virgule fixe et de taille h\u00e9t\u00e9rog\u00e8ne on installera le module <a href=\"https:\/\/github.com\/francof2a\/fxpmath\">fxpmath<\/a> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ git clone https:\/\/github.com\/francof2a\/fxpmath.git\n$ cd fxpmath\/\n$ python -m pip install -e .<\/code><\/pre>\n\n\n\n<p>Pour commencer on va passer le signal &lsquo;y&rsquo; en entier sign\u00e9 sur 16bits avec <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># morlet wavelet\ny = np.cos(2*np.pi*f0*t)*np.exp(-np.power(t-retard,2)\/2)\n\nYTYPE=\"S1.15\"\nysint = Fxp(y, dtype=YTYPE)<\/code><\/pre>\n\n\n\n<p>Le signal se trouvant entre -1 et 1 nous choisirons un format sign\u00e9 sur 16 bits avec tous les chiffres derri\u00e8re la virgule &lsquo;S1.15&rsquo;.<\/p>\n\n\n\n<p>Pour les calculs interm\u00e9diaires on va rester sur du sign\u00e9 16&nbsp;bits mais avec la virgule au milieu cette fois, soit &lsquo;S8.8&rsquo;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># transform\u00e9e de fourrier\nfreqs_real = np.array(&#91;])\nfreqs_img = np.array(&#91;])\nfor k in range(N):\n    listreal = &#91;]\n    listimg = &#91;]\n    for n in range(N):\n        angle = Fxp(2*fixpi*Fxp(k, dtype=DTYPE)*Fxp(n, dtype=DTYPE)\/N,\n                dtype=DTYPE)\n        listreal.append(Fxp(y&#91;n]*( np.cos(angle)), dtype=DTYPE))\n        listimg.append (Fxp(y&#91;n]*(-np.sin(angle)), dtype=DTYPE))\n    xkreal = Fxp(np.array(listreal).sum(), dtype=DTYPE)\n    xkimg  = Fxp(np.array(listimg ).sum(), dtype=DTYPE)\n    print(f\"Freq {k} -&gt; {xkreal}({xkreal.dtype}) + {xkimg}j ({xkimg.dtype})\")\n    freqs_real = np.append(freqs_real, xkreal)\n    freqs_img = np.append(freqs_img, xkimg)\n\n#fourrier_module = (2\/N)*np.sqrt(np.power(freqs_img, 2) + np.power(freqs_real, 2))\nfourrier_power = Fxp(Fxp(freqs_img*freqs_img, dtype=DTYPE) + Fxp(freqs_real*freqs_real, dtype=DTYPE), dtype=DTYPE)\nfourrier_module = Fxp((2\/N)*Fxp(np.sqrt(fourrier_power), dtype=DTYPE), dtype=DTYPE)<\/code><\/pre>\n\n\n\n<p>La premi\u00e8re surprise de cette m\u00e9thode est le temps de calcul: on passe d&rsquo;un calcul de la transform\u00e9e quasi instantan\u00e9e \u00e0 un calcul qui prend presque une minute.<\/p>\n\n\n\n<p>La seconde surprise vient avec le \u00abbruit haute fr\u00e9quence\u00bb qui appara\u00eet dans le r\u00e9sultat et le second pic qui dispara\u00eet.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_fixed_point.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"530\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_fixed_point-1024x530.png\" alt=\"\" class=\"wp-image-2182\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_fixed_point-1024x530.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_fixed_point-300x155.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_fixed_point-768x398.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_fixed_point-1536x795.png 1536w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_fixed_point.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Avec les calculs interm\u00e9diaire en S8.8 on parvient \u00e0 la m\u00eame courbe, modulo le bruit en haute fr\u00e9quences.<\/figcaption><\/figure>\n\n\n\n<p>Le probl\u00e8me de ce bruit vient de l&rsquo;arrondi calcul\u00e9 sur Pi, si on ajuste la virgule de Pi comme ceci :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Frequence du signal\nSf0 = 2\n\nf0 = (Sf0 * Fs)\/T\n\n# D\u00e9calage en seconde:\nretard = 5\n\n#temps: 0 points de 0 \u00e0 N-1\nt = np.linspace(0, T, N)\n# morlet wavelet\ny = np.cos(2*np.pi*f0*t)*np.exp(-np.power(t-retard,2)\/2)\n\nYTYPE=\"S1.15\"\nysint = Fxp(y, dtype=YTYPE)\n\nDTYPE=\"S8.8\"\nD2TYPE=\"S16.16\"\n\nfixpi = Fxp(np.pi, dtype=\"U3.13\")\n\n# transform\u00e9e de fourrier\nfreqs_real = np.array(&#91;])\nfreqs_img = np.array(&#91;])\nfor k in range(N):\n    listreal = &#91;]\n    listimg = &#91;]\n    for n in range(N):\n        angle = Fxp(2*fixpi*Fxp(k*n, dtype=\"U16.0\")\/N, dtype=D2TYPE)\n        listreal.append(Fxp(y&#91;n], dtype=YTYPE)*Fxp( np.cos(angle), dtype=YTYPE))\n        listimg.append (Fxp(y&#91;n], dtype=YTYPE)*Fxp(-np.sin(angle), dtype=YTYPE))\n    xkreal = Fxp(np.array(listreal).sum(), dtype=DTYPE)\n    xkimg  = Fxp(np.array(listimg ).sum(), dtype=DTYPE)\n    print(f\"Freq {k}\/{Fs} ({k*T\/N}) -&gt; {np.sqrt(xkreal*xkreal + xkimg*xkimg)})\")\n    freqs_real = np.append(freqs_real, xkreal)\n    freqs_img = np.append(freqs_img, xkimg)\n\nfourrier_power = Fxp(Fxp(freqs_img*freqs_img, dtype=DTYPE) + Fxp(freqs_real*freqs_real, dtype=DTYPE), dtype=DTYPE)\nfourrier_module = Fxp((2\/N)*Fxp(np.sqrt(fourrier_power), dtype=DTYPE), dtype=DTYPE)\n\n<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_128.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"530\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_128-1024x530.png\" alt=\"\" class=\"wp-image-2186\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_128-1024x530.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_128-300x155.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_128-768x398.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_128-1536x795.png 1536w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_128.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Avec 128 \u00e9chantillons (2^7)<\/figcaption><\/figure>\n\n\n\n<p>Par contre on a un d\u00e9calage de fr\u00e9quence avec la fonction magnitude_spectrum() de pylab :<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/Figure_1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"523\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/Figure_1-1024x523.png\" alt=\"\" class=\"wp-image-2189\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/Figure_1-1024x523.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/Figure_1-300x153.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/Figure_1-768x392.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/Figure_1-1536x784.png 1536w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/Figure_1.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Mais d&rsquo;o\u00f9 vient ce d\u00e9calage ?<\/figcaption><\/figure>\n\n\n\n<p>Ce d\u00e9calage provient de l&rsquo;axe des x qui n&rsquo;est pas le m\u00eame pour le calcul de python et le calcul maison. En effet, notre calcul \u00ab\u00e0 la main\u00bb s&rsquo;\u00e9tend sur tout l&rsquo;espace \u00abde nyquist\u00bb (0 \u00e0 N-1) alors que la fonction magnitude_spectrum() n&rsquo;affiche le spectre que sur la moit\u00e9e.<\/p>\n\n\n\n<p>Pour recentrer tout \u00e7a on peut simplement r\u00e9cup\u00e9rer la table des fr\u00e9quences fournie par magnitude_spectrum() et l&rsquo;utiliser comme axe des x dans l&rsquo;affichage de notre spectre :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#...\nmagnitude, freqs, _ = ax&#91;1].magnitude_spectrum(y, Fs=N\/T, ds=\"steps-mid\", label=f\"fft (Fs={Fs} Hz)\")\n#...\nax&#91;1].plot(freqs, fourrier_module&#91;:len(freqs)], label = \"freqs (calcul\u00e9e)\")<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_freqs_fixed.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"530\" src=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_freqs_fixed-1024x530.png\" alt=\"\" class=\"wp-image-2211\" srcset=\"http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_freqs_fixed-1024x530.png 1024w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_freqs_fixed-300x155.png 300w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_freqs_fixed-768x398.png 768w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_freqs_fixed-1536x795.png 1536w, http:\/\/www.fabienm.eu\/flf\/wp-content\/uploads\/2022\/10\/fourrier_freqs_fixed.png 1920w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">La fr\u00e9quence est maintenant correcte, reste un probl\u00e8me de magnitude. Probl\u00e8me d&rsquo;arrondi ?<\/figcaption><\/figure>\n\n\n\n<p>Et nous obtenons la bonne fr\u00e9quence pour les deux modes de calculs. Reste maintenant un probl\u00e8me de magnitude maximum, est-ce un probl\u00e8me d&rsquo;arrondi de la virgule fixe ? Possible.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Ressources<\/h2>\n\n\n\n<p>Le code de cet article se trouve sur le d\u00e9p\u00f4t github <a href=\"https:\/\/github.com\/Martoni\/traitement_numerique_du_signal\">suivant<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>On dit souvent que pour bien apprendre un sujet en informatique il faut \u00e9crire une doc. Pour des besoins pro j&rsquo;ai du me re-mettre au traitement num\u00e9rique du signal. Je commence en g\u00e9n\u00e9ral par un bouquin et un projet. Pour le projet comme c&rsquo;est du pro je c&rsquo;est \u00e0 ma discr\u00e9tion, par contre pour le &hellip; <a href=\"http:\/\/www.fabienm.eu\/flf\/traitement-numerique-du-signal-prise-de-notes\/\" class=\"more-link\">Continuer la lecture de <span class=\"screen-reader-text\">Traitement num\u00e9rique du signal, prise de notes<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","footnotes":""},"categories":[22,1],"tags":[220,56,221],"class_list":["post-2060","post","type-post","status-publish","format-standard","hentry","category-blog","category-non-classe","tag-math","tag-python","tag-signalprocessing"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false,"post-thumbnail":false},"uagb_author_info":{"display_name":"Fabien Marteau","author_link":"http:\/\/www.fabienm.eu\/flf\/author\/admin\/"},"uagb_comment_info":1,"uagb_excerpt":"On dit souvent que pour bien apprendre un sujet en informatique il faut \u00e9crire une doc. Pour des besoins pro j&rsquo;ai du me re-mettre au traitement num\u00e9rique du signal. Je commence en g\u00e9n\u00e9ral par un bouquin et un projet. Pour le projet comme c&rsquo;est du pro je c&rsquo;est \u00e0 ma discr\u00e9tion, par contre pour le\u2026","_links":{"self":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/2060","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/comments?post=2060"}],"version-history":[{"count":48,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/2060\/revisions"}],"predecessor-version":[{"id":2286,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/2060\/revisions\/2286"}],"wp:attachment":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/media?parent=2060"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/categories?post=2060"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/tags?post=2060"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}