{"id":20599,"date":"2024-10-25T10:07:00","date_gmt":"2024-10-25T15:07:00","guid":{"rendered":"https:\/\/blog.espol.edu.ec\/algoritmos101\/?p=20599"},"modified":"2026-03-27T21:23:08","modified_gmt":"2026-03-28T02:23:08","slug":"muestreo-reconstruccion-tiempo-sub-sobre-muestreo","status":"publish","type":"post","link":"https:\/\/blog.espol.edu.ec\/algoritmos101\/dsp-unidades\/muestreo-reconstruccion-tiempo-sub-sobre-muestreo\/","title":{"rendered":"2.4 Muestreo - Reconstrucci\u00f3n en tiempo, sub y sobre muestreo"},"content":{"rendered":"\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<div class=\"wp-block-group has-medium-font-size is-layout-flex wp-block-group-is-layout-flex\">\n<p><a href=\"#concepto\" data-type=\"internal\" data-id=\"#concepto\">reconstrucci\u00f3n<\/a><\/p>\n\n\n\n<p>muestreo:<\/p>\n\n\n\n<p><a href=\"#sobremuestreo\">sobre<\/a><\/p>\n\n\n\n<p><a href=\"#submuestreo\">sub<\/a><\/p>\n\n\n\n<p><a href=\"#algoritmo\">algoritmo<\/a><\/p>\n\n\n\n<p><a href=\"#grafica\">gr\u00e1fica<\/a><\/p>\n\n\n\n<p><a href=\"#interactiva\">interactiva<\/a><\/p>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"concepto\">1. Muestreo y Reconstrucci\u00f3n<\/h2>\n\n\n\n<p>La salida de un convertidor cont\u00ednuo a discreto C-D es una se\u00f1al discreta en tiempo con un n\u00famero infinito de alias. Al observar un gr\u00e1fico de espectro de frecuencias \u03c9 es necesario recordar que existen m\u00e1s se\u00f1ales fuera del intervalo mostrado.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/espectro_n_coseno_animate.gif\"><img decoding=\"async\" src=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/espectro_n_coseno_animate.gif\" alt=\"espectro n coseno animate\" class=\"wp-image-543\" \/><\/a><\/figure>\n\n\n\n<p>Considere una se\u00f1al x(t) simple, de una sola frecuencia, cuyo espectro contiene dos l\u00edneas a \u00b1\u03c9<sub>0<\/sub>\u00a0con amplitudes de <br>(1\/2 A e<sup>\u00b1\u03c9<sub>0<\/sub><\/sup>)<\/p>\n\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> x(t) = A \\cos(\\omega_0 t+\\varphi) <\/span>\n\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> x[n] = x(n\/f_s) A \\cos\\left( (\\omega_0 \/ f_s)n + \\varphi \\right)<\/span>\n\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> = \\frac{1}{2} A e^{j\\varphi} e ^{ j(\\omega_0 \/f_s)n} + \\frac{1}{2} A e^{\u2212j \\varphi} e^{j(\u2212\\omega_0\/f_s)n} <\/span>\n\n\n\n<p>tambi\u00e9n tiene dos frecuencias \u03c9 en \u00b1\u03c9<sub>0<\/sub>\/f<sub>s<\/sub>, con todos los alias en<br>\u00b1\u03c9<sub>0<\/sub>\/f<sub>s<\/sub>&nbsp;+ 2\u03c0k, siendo k= \u00b11, \u00b12, \u00b13, ...<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<div class=\"wp-block-group has-medium-font-size is-layout-flex wp-block-group-is-layout-flex\">\n<p><a href=\"#concepto\" data-type=\"internal\" data-id=\"#concepto\">reconstrucci\u00f3n<\/a><\/p>\n\n\n\n<p>muestreo:<\/p>\n\n\n\n<p><a href=\"#sobremuestreo\">sobre<\/a><\/p>\n\n\n\n<p><a href=\"#submuestreo\">sub<\/a><\/p>\n\n\n\n<p><a href=\"#algoritmo\">algoritmo<\/a><\/p>\n\n\n\n<p><a href=\"#grafica\">gr\u00e1fica<\/a><\/p>\n\n\n\n<p><a href=\"#interactiva\">interactiva<\/a><\/p>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"sobremuestreo\">2. Sobre-muestreo<\/h2>\n\n\n\n<p><em><strong>Referencia<\/strong><\/em>: McClellan ejercicio 4.5 p133<\/p>\n\n\n\n<p>Realice el espectro cont\u00ednuo de la se\u00f1al x(t), la se\u00f1al muestreada a f<sub>s<\/sub>=500 y el espectro discreto resultante. Observe que la frecuencia de muestreo es superior a la frecuencia de la se\u00f1al x(t) para evitar el\u00a0<em>problema de aliasing<\/em>. El proceso se conoce como\u00a0<strong>sobre-muestreo<\/strong>. Para el ejercicio se usa una frecuencia 2.5 veces la recomendada por Nyquist.<\/p>\n\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> x(t) = \\cos( 2\\pi (100)t+\\pi\/3) <\/span>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/espectro_n_coseno_sobremuestreo01.png\"><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"480\" src=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/espectro_n_coseno_sobremuestreo01.png\" alt=\"espectro discreto coseno sobremuestreo 01\" class=\"wp-image-521\" \/><\/a><\/figure>\n\n\n\n<p>Los convertidores D-C trasforman el espectro discreto en tiempo a una salida de espectro cont\u00ednuo en el tiempo, seleccionando solo un par de las l\u00edneas de todas las posibilidades mostradas.<\/p>\n\n\n\n<p>Para ser consistentes con la operaci\u00f3n Digital hacia Anal\u00f3gico (D-A) se tomar\u00e1 siempre la frecuencia mas baja de cada grupo de alias o&nbsp;<em><strong>alias principal&nbsp;<\/strong><\/em>con |\u03c9|&lt;\u03c0.<br>El resultado siempre se encontrar\u00e1 entre [-f<sub>s<\/sub>\/2, +f<sub>s<\/sub>\/2].<\/p>\n\n\n\n<p>En resumen, en&nbsp;<strong>sobre-muestreo<\/strong>&nbsp;la frecuencia original f<sub>0<\/sub>&nbsp;es menor que f<sub>s<\/sub>\/2 permite la reconstrucci\u00f3n mas exacta.<\/p>\n\n\n\n<p>Para el an\u00e1lisis con el algoritmo se obtienen los siguientes par\u00e1metros para realizar la gr\u00e1fica.<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>se\u00f1al(t):   cos(((2*pi)*100)*t + pi\/3)\n espectro_t:\n  freq : &#091;-100.  100.]\n  ampl : &#091;1\/2 1\/2]\n  fase : &#091;-pi\/3 pi\/3]\n  etiq : &#091;'$\\\\frac{1}{2}$$ e^j(- \\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(\\\\frac{\\\\pi}{3})$']\n  freq_max : 100.0\n  freq_min : 100.0\n\nmuestreo <strong>fs: 500<\/strong>  ; dt: 0.002  ; fs_veces: 12\nmuestreo_tipo:  sobre-muestreo\nmuestreo: 11  tama\u00f1o ki: 11 ; tama\u00f1o ti: 121\nx(t): cos(((2*pi)*100)*t + pi\/3)\nx&#091;n]: cos(n*(2*pi)\/5 + pi\/3)\n\nse\u00f1al&#091;n]:   cos(n*(2*pi)\/5 + pi\/3)\n espectro_n:\n  freq : &#091;-2.4 -1.6 -0.4  0.4  1.6  2.4]\n  ampl : &#091;1\/2 1\/2 1\/2 1\/2 1\/2 1\/2]\n  fase : &#091;-pi\/3 pi\/3 -pi\/3 pi\/3 -pi\/3 pi\/3]\n  etiq : &#091;'$\\\\frac{1}{2}$$ e^j(- \\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(\\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(- \\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(\\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(- \\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(\\\\frac{\\\\pi}{3})$']\n  x_expand : cos(2*pi*n\/5 + pi\/3)\n  freq_factor : pi\n  freq_max : 2.4\n  freq_min : 0.4\n  BW : 2.0\n  freq_alias : &#091; True  True False False  True  True]\n\nse\u00f1al reconstruida con alias principal:\ncos(100*t*(2*pi) + pi\/3)<\/code><\/pre>\n\n\n\n<p>Las instrucciones del bloque de ingreso para el algoritmo son:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># INGRESO\nwith sym.evaluate(False): # no simplificar freq angular w &gt;2*pi por Sympy\n    x = sym.cos(DosPi*100*t + pi\/3)\nxt_etiqueta = 'x(t)' ; xn_etiqueta = 'x&#091;n]'\ntitulo = x # copia para titulo de grafico (antes de procesar)\n\n# se\u00f1al muestreada\nfs = 500   # muestreo discreto, freq_sampling &gt;0\nfs_veces = 12  # suavizar x(t), sobremuestreo\nmuestras_n = 10 + 1  # para x&#091;n]\n\naliasn = 1 # alias a\u00f1adidos a x&#091;n]\ntolera = 1e-9 # tolerancia a error, n\u00fameros iguales<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<div class=\"wp-block-group has-medium-font-size is-layout-flex wp-block-group-is-layout-flex\">\n<p><a href=\"#concepto\" data-type=\"internal\" data-id=\"#concepto\">reconstrucci\u00f3n<\/a><\/p>\n\n\n\n<p>muestreo:<\/p>\n\n\n\n<p><a href=\"#sobremuestreo\">sobre<\/a><\/p>\n\n\n\n<p><a href=\"#submuestreo\">sub<\/a><\/p>\n\n\n\n<p><a href=\"#algoritmo\">algoritmo<\/a><\/p>\n\n\n\n<p><a href=\"#grafica\">gr\u00e1fica<\/a><\/p>\n\n\n\n<p><a href=\"#interactiva\">interactiva<\/a><\/p>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"submuestreo\">3. Sub-muestreo y aliasing<\/h2>\n\n\n\n<p>Cuando f<sub>s<\/sub>&nbsp;&lt; 2f<sub>0<\/sub>&nbsp;la se\u00f1al se encuentra&nbsp;<strong>sub-muestreada<\/strong>&nbsp;y se produce el&nbsp;<strong>aliasing<\/strong>. Para el ejercicio anterior, si el ejercicio lo realiza con&nbsp;<strong>fs = 80Hz<\/strong>, siendo f0=100 Hz, la tasa de muestreo es menor que la frecuencia de Nyquist y se presenta la se\u00f1al de alias.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/espectro_n_coseno_submuestreo01.png\"><img decoding=\"async\" src=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/espectro_n_coseno_submuestreo01.png\" alt=\"espectro discreto coseno submuestreo 01\" class=\"wp-image-522\" \/><\/a><\/figure>\n\n\n\n<p>las instrucciones para el bloque de ingreso del algoritmo son las mismas que en el ejercicio anterior, excepto que&nbsp;<strong>f<sub>s<\/sub>&nbsp;= 80 Hz<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># se\u00f1al muestreada\nfs = 80   # muestreo discreto, freq_sampling &gt;0<\/code><\/pre>\n\n\n\n<p>el resultado con el algoritmo es una se\u00f1al reconstruida de tan solo 20Hz<\/p>\n\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> x_0(t)=\\cos(2\\pi(20)t+\\pi\/3) <\/span>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>se\u00f1al(t):   cos(((2*pi)*100)*t + pi\/3)\n espectro_t:\n  freq : &#091;-100.  100.]\n  ampl : &#091;1\/2 1\/2]\n  fase : &#091;-pi\/3 pi\/3]\n  etiq : &#091;'$\\\\frac{1}{2}$$ e^j(- \\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(\\\\frac{\\\\pi}{3})$']\n  freq_max : 100.0\n  freq_min : 100.0\n\nmuestreo <strong>fs: 80<\/strong>  ; dt: 0.0125  ; fs_veces: 12\nmuestreo_tipo:  sub-muestreo\nmuestreo: 11  tama\u00f1o ki: 11 ; tama\u00f1o ti: 121\nx(t): cos(((2*pi)*100)*t + pi\/3)\nx&#091;n]: cos(5*n*(2*pi)\/4 + pi\/3)\n\nse\u00f1al&#091;n]:   cos(5*n*(2*pi)\/4 + pi\/3)\n espectro_n:\n  freq : &#091;-2.5 -1.5 -0.5  0.5  1.5  2.5]\n  ampl : &#091;1\/2 1\/2 1\/2 1\/2 1\/2 1\/2]\n  fase : &#091;-pi\/3 pi\/3 -pi\/3 pi\/3 -pi\/3 pi\/3]\n  etiq : &#091;'$\\\\frac{1}{2}$$ e^j(- \\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(\\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(- \\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(\\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(- \\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(\\\\frac{\\\\pi}{3})$']\n  x_expand : cos(5*pi*n\/2 + pi\/3)\n  freq_factor : pi\n  freq_max : 2.5\n  freq_min : 0.5\n  BW : 2.0\n  freq_alias : &#091; True  True False False  True  True]\n\nse\u00f1al reconstruida con alias principal:\ncos(20*t*(2*pi) + pi\/3)<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<div class=\"wp-block-group has-medium-font-size is-layout-flex wp-block-group-is-layout-flex\">\n<p><a href=\"#concepto\" data-type=\"internal\" data-id=\"#concepto\">reconstrucci\u00f3n<\/a><\/p>\n\n\n\n<p>muestreo:<\/p>\n\n\n\n<p><a href=\"#sobremuestreo\">sobre<\/a><\/p>\n\n\n\n<p><a href=\"#submuestreo\">sub<\/a><\/p>\n\n\n\n<p><a href=\"#algoritmo\">algoritmo<\/a><\/p>\n\n\n\n<p><a href=\"#grafica\">gr\u00e1fica<\/a><\/p>\n\n\n\n<p><a href=\"#interactiva\">interactiva<\/a><\/p>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">4. Folding o plegado de se\u00f1al por sub-muestreo<\/h2>\n\n\n\n<p>Para una se\u00f1al x(t) de 100 Hz se aplica muestreo insuficiente en el intervalo [f<sub>0<\/sub>,2f<sub>0<\/sub>] se presenta aliasing denominado \"<strong>folding<\/strong>\" o plegado de se\u00f1al. Para el ejercicio de prueba y con\u00a0<strong>f<sub>s<\/sub>\u00a0= 125<\/strong>, se tiene:<\/p>\n\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> x(t) = \\cos (2\\pi(100)t+\\pi\/3) <\/span>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"480\" src=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2025\/12\/espectro_n_coseno_folding01.png\" alt=\"espectro n coseno folding 01\" class=\"wp-image-20601\" \/><\/figure>\n\n\n\n<p>Los componentes de frecuencia entre \u00b1\u03c0 tambi\u00e9n son \u00b10.4\u03c0, sin embargo\u00a0 el componente en +0.4\u03c0 es un alias del componente de la frecuencia negativa -1.6\u03c0, que genera el \"plegado\" o \"folding\". La reconstrucci\u00f3n de la se\u00f1al se realiza a f = 0.4(f<sub>s<\/sub>\/2\u03c0) = f<sub>s<\/sub>\/5 = 25 Hz. Tambi\u00e9n se observa una\u00a0<em><strong>inversi\u00f3n de fase<\/strong><\/em>. El resultado es semejante a una se\u00f1al muestreada de 25 Hz con inversi\u00f3n de fase.<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>se\u00f1al(t):   cos(((2*pi)*100)*t + pi\/3)\n espectro_t:\n  freq : &#091;-100.  100.]\n  ampl : &#091;1\/2 1\/2]\n  fase : &#091;-pi\/3 pi\/3]\n  etiq : &#091;'$\\\\frac{1}{2}$$ e^j(- \\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(\\\\frac{\\\\pi}{3})$']\n  freq_max : 100.0\n  freq_min : 100.0\n\nmuestreo <strong>fs: 125<\/strong>  ; dt: 0.008  ; fs_veces: 12\nmuestreo_tipo:  sub-muestreo y folding\nmuestreo: 11  tama\u00f1o ki: 11 ; tama\u00f1o ti: 121\nx(t): cos(((2*pi)*100)*t + pi\/3)\nx&#091;n]: cos(4*n*(2*pi)\/5 + pi\/3)\n\nse\u00f1al&#091;n]:   cos(4*n*(2*pi)\/5 + pi\/3)\n espectro_n:\n  freq : &#091;-2.4 -1.6 -0.4  0.4  1.6  2.4]\n  ampl : &#091;1\/2 1\/2 1\/2 1\/2 1\/2 1\/2]\n  fase : &#091;pi\/3 -pi\/3 pi\/3 -pi\/3 pi\/3 -pi\/3]\n  etiq : &#091;'$\\\\frac{1}{2}$$ e^j(\\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(- \\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(\\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(- \\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(\\\\frac{\\\\pi}{3})$'\n '$\\\\frac{1}{2}$$ e^j(- \\\\frac{\\\\pi}{3})$']\n  x_expand : cos(8*pi*n\/5 + pi\/3)\n  freq_factor : pi\n  freq_max : 2.4\n  freq_min : 0.3999999999999999\n  BW : 2.0\n  freq_alias : &#091; True  True False False  True  True]\n\nse\u00f1al reconstruida con alias principal:\ncos(25*t*(2*pi) - (pi\/3))<\/code><\/pre>\n\n\n\n<p>Otro caso a observar es cuando f<sub>s<\/sub>=100Hz, el resultado es una constante, pues siempre se obtiene la muestra de la se\u00f1al con la misma magnitud.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/espectro_n_coseno_folding02.png\"><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"480\" src=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/espectro_n_coseno_folding02.png\" alt=\"espectro discreto coseno folding 02\" class=\"wp-image-524\" \/><\/a><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<div class=\"wp-block-group has-medium-font-size is-layout-flex wp-block-group-is-layout-flex\">\n<p><a href=\"#concepto\" data-type=\"internal\" data-id=\"#concepto\">reconstrucci\u00f3n<\/a><\/p>\n\n\n\n<p>muestreo:<\/p>\n\n\n\n<p><a href=\"#sobremuestreo\">sobre<\/a><\/p>\n\n\n\n<p><a href=\"#submuestreo\">sub<\/a><\/p>\n\n\n\n<p><a href=\"#algoritmo\">algoritmo<\/a><\/p>\n\n\n\n<p><a href=\"#grafica\">gr\u00e1fica<\/a><\/p>\n\n\n\n<p><a href=\"#interactiva\">interactiva<\/a><\/p>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"algoritmo\">5. Algoritmo en Python<\/h2>\n\n\n\n<p>El algoritmo contiene componentes desarrollados en secciones anteriores. Para el espectro de frecuencias en dominio del tiempo se basa en lo descrito en\u00a0<a href=\"https:\/\/blog.espol.edu.ec\/algoritmos101\/dsp-unidades\/dsp-u01\/espectro-operaciones-tiempo-frecuencia\/\" data-type=\"post\" data-id=\"20576\">Espectro \u2013 Operaciones en dominio de tiempo y frecuencia<\/a>.<\/p>\n\n\n\n<p>El desarrollo del muestreo usando la se\u00f1al x(t) y f<sub>s<\/sub>&nbsp;toma como referencia lo descrito en&nbsp;<a href=\"https:\/\/blog.espol.edu.ec\/telg1034\/muestreo-y-aliasing\/\">Muestreo y aliasing<\/a>.<\/p>\n\n\n\n<p>La construcci\u00f3n del espectro discreto a partir de x[n] usa lo desarrollado en\u00a0<a href=\"https:\/\/blog.espol.edu.ec\/algoritmos101\/dsp-unidades\/dsp-u2\/espectro-xn-senal-discreta-en-tiempo\/\" data-type=\"post\" data-id=\"228\">Espectro x[n] \u2013 Se\u00f1al discreta en tiempo<\/a><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# ejercicio 4.5 p133 Muestreo y Reconstrucci\u00f3n de se\u00f1ales sinusoidales\n# telg1034 DSP fiec-espol edelros@espol.edu.ec\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport sympy as sym\nimport telg1034 as dsp\n\n# variables continuas\nfrom telg1034 import t,A,w,f,p,pi,DosPi,I,equivalentes\n# variables discretas\nfrom telg1034 import n\n\n# INGRESO\nwith sym.evaluate(False): # no simplificar freq angular w &gt;2*pi por Sympy\n    x = sym.cos(DosPi*100*t + pi\/3)\nxt_etiqueta = 'x(t)' ; xn_etiqueta = 'x&#x5B;n]'\ntitulo = x # copia para titulo de grafico (antes de procesar)\n\n# se\u00f1al muestreada\nfs = 500   # muestreo discreto, freq_sampling &gt;0\nfs_veces = 12  # suavizar x(t), sobremuestreo\nmuestras_n = 10 + 1  # para x&#x5B;n]\n\naliasn = 1 # alias a\u00f1adidos a x&#x5B;n]\ntolera = 1e-9 # tolerancia a error, n\u00fameros iguales\n\n# PROCEDIMIENTO ----------------\n# espectro x(t) - operaciones\n# Ref: Blog|Espectro-Operaciones en dominio de tiempo y frecuencia\n# unase\u00f1al = x.subs(pi,np.pi) # mantener valores &gt;2pi como float\nx_term = dsp.x_list_term_Add(x)\nXe_term = dsp.cos_to_euler_one_term(x_term)\nx_term_expand = dsp.euler_to_cos_list(Xe_term)\nun_espectro_t = dsp.cos_spectrum_list(x_term)\n\n# espectro de cada se\u00f1al\nfreq = un_espectro_t&#x5B;'freq']\nampl = un_espectro_t&#x5B;'ampl']\nfase = un_espectro_t&#x5B;'fase']\netiqueta = un_espectro_t&#x5B;'etiq']\n\n# freq_max y freq_min\nfreq_max = float(max(freq))\nif len(freq&#x5B;freq&gt;0])&gt;0:\n    freq_min = float(min(freq&#x5B;freq&gt;0]))\nelse:\n    freq_min = 0\nun_espectro_t&#x5B;'freq_max'] = freq_max\nun_espectro_t&#x5B;'freq_min'] = freq_min\n\n# revisa muestreo Nyquist\nif abs(2*freq_max-fs)&lt;tolera:\n    muestreo_tipo = 'Nyquist'\nif fs&gt;(freq_max*2):\n    muestreo_tipo = 'sobre-muestreo'\nif fs&lt;(freq_max*2):\n    muestreo_tipo = 'sub-muestreo'\nif fs&lt;(freq_max*2) and fs&gt;freq_max:\n    muestreo_tipo = 'sub-muestreo y folding'\n\n# Muestreo de se\u00f1ales sinusoidales\n# Ref: blog|Muestreo con Python\nxt = sym.lambdify(t,x, modules=equivalentes)\nxn = x.subs(t,n\/fs)\n\n# muestreo x&#x5B;n]\ndt = 1\/fs   # tama\u00f1o de paso con fs\nki = np.arange(0,muestras_n,1,dtype=int)\ntki = ki*dt\nxki = xt(tki)\n\nnT = int(np.max(tki)\/dt) # periodos a graficar\n\n# muestreo x(t)\ndtc = dt\/fs_veces # suavizar x(t), sobremuestreo\nti = np.arange(0,(muestras_n-1)*dt+dtc, dtc)\nxti = xt(ti)\n\n# operaciones para espectro x&#x5B;n]\n# Ref: blog|Espectro x&#x5B;n] \u2013 Se\u00f1al discreta en tiempo\n#xn = xn.doit()#.subs(pi,np.pi).doit() # mantener valores &gt;2pi\nx_term = dsp.x_list_term_Add(xn)\nXe_term = dsp.cos_to_euler_one_term(x_term)\nx_term_expand = dsp.euler_to_cos_list(Xe_term)\nun_espectro_n = dsp.cos_spectrum_list(x_term)\n# espectro de cada se\u00f1al\nfreq_n = np.array(un_espectro_n&#x5B;'freq'])\nampl_n = np.array(un_espectro_n&#x5B;'ampl'])\nfase_n = np.array(un_espectro_n&#x5B;'fase'])\netiq_n = np.array(un_espectro_n&#x5B;'etiq'])\nun_espectro_n&#x5B;'x_expand'] = x_term_expand\n\nfreqn_conteo = len(freq_n)\n\n# normaliza w frecuencia angular\nfor i in range(0,freqn_conteo,1):\n    while abs(freq_n&#x5B;i].subs(pi,np.pi))&gt;np.pi:\n        if freq_n&#x5B;i]&gt;0:\n            freq_norm = freq_n&#x5B;i]-2*pi\n        else:\n            freq_norm = freq_n&#x5B;i]+2*pi\n        freq_n&#x5B;i] = freq_norm\n\n# A\u00f1adir alias a se\u00f1al\nfreqn_alias = np.zeros(freqn_conteo,dtype=bool)\nfreq_m = np.zeros(0,dtype=float)\nfor i in range(0,freqn_conteo,1):\n    freq_i = freq_n&#x5B;i]\n    ampl_i = ampl_n&#x5B;i]\n    fase_i = fase_n&#x5B;i]\n    etiq_i = etiq_n&#x5B;i]\n    for k in range(1,aliasn+1,1):\n        freq_k = (freq_i+2*pi*k)\n        if  not((freq_k in freq_n) or (freq_k in freq_m)):\n            # a\u00f1ade freq_n&#x5B;i] + 2*pi*k\n            freq_m = np.concatenate(&#x5B;freq_m,&#x5B;freq_i+2*pi*k]])\n            ampl_n = np.concatenate(&#x5B;ampl_n,&#x5B;ampl_i]])\n            fase_n = np.concatenate(&#x5B;fase_n,&#x5B;fase_i]])\n            etiq_n = np.concatenate(&#x5B;etiq_n,&#x5B;etiq_i]])\n            freqn_alias = np.concatenate(&#x5B;freqn_alias,&#x5B;True]])\n        freq_k = (freq_i-2*pi*k)\n        if not((freq_k in freq_n) or (freq_k in freq_m)):\n            # a\u00f1ade freq_n&#x5B;i] - 2*pi*k\n            freq_m = np.concatenate(&#x5B;freq_m,&#x5B;freq_i-2*pi*k]])\n            ampl_n = np.concatenate(&#x5B;ampl_n,&#x5B;ampl_i]])\n            fase_n = np.concatenate(&#x5B;fase_n,&#x5B;fase_i]])\n            texto = '$' + sym.latex(ampl_i)+'$'\n            if fase_i!=sym.S.Zero:\n                texto = texto+f'$ e^j('+sym.latex(fase_i)+')$'\n            etiq_n = np.concatenate(&#x5B;etiq_n,&#x5B;texto]])\n            freqn_alias = np.concatenate(&#x5B;freqn_alias,&#x5B;True]])\nfreq_n = np.concatenate(&#x5B;freq_n,freq_m])\n\n# ordena frecuencias\norden = np.argsort(freq_n)\nfreq_n = freq_n&#x5B;orden]\nampl_n = ampl_n&#x5B;orden]\nfase_n = fase_n&#x5B;orden]\netiq_n = etiq_n&#x5B;orden]\nfreqn_alias = freqn_alias&#x5B;orden]\n\n# revisa factor pi en freq_n\nunfactor = sym.S.One ; factor_pi = False\nfreqn_conteo = len(freq_n)\nfor i in range(0,freqn_conteo,1):\n    if freq_n&#x5B;i].has(pi):\n        factor_pi = True\nif factor_pi:\n    freq_n = np.array(freq_n\/pi,dtype=float)\n    unfactor = pi\n# actualiza espectro de se\u00f1al con factor pi,alias,orden\nun_espectro_n&#x5B;'freq_factor'] = unfactor\nun_espectro_n&#x5B;'freq'] = freq_n\nun_espectro_n&#x5B;'ampl'] = ampl_n\nun_espectro_n&#x5B;'fase'] = fase_n\nun_espectro_n&#x5B;'etiq'] = etiq_n\n\n# ancho de banda, freq_max y freq_min\nfreq_posi = freq_n&#x5B;freq_n&gt;0]\nfreq_max_n = float(max(freq_posi))\nfreq_min_n = 0\nif len(freq_posi)&gt;0:\n    freq_min_n = float(min(freq_posi))\nfreq_centro_n = (freq_max_n + freq_min_n)\/2\nun_espectro_n&#x5B;'freq_max'] = freq_max_n\nun_espectro_n&#x5B;'freq_min'] = freq_min_n\nun_espectro_n&#x5B;'BW'] = freq_max_n - freq_min_n\n\n# alias principal, Revisa espectro de frecuencias  \nfreq_conteo = len(freq_n)\nfreq_alias = np.zeros(freq_conteo,dtype=bool)\nfor i in range (0,freq_conteo,1):\n    unafreq = freq_n&#x5B;i]\n    if abs(unafreq) &gt; 1:\n        freq_alias&#x5B;i] = True\nfreq_alias_conteo = np.sum(freq_alias)\nun_espectro_n&#x5B;'freq_alias'] = freq_alias\n\n# reconstruye se\u00f1al con alias principal\nfreq_alias0 = np.invert(freq_alias)\nfreq_x0 = freq_n&#x5B;freq_alias0]\nampl_x0 = ampl_n&#x5B;freq_alias0]\nfase_x0 = fase_n&#x5B;freq_alias0]\nx0_cuenta = len(freq_x0)\nx0t = sym.S.Zero\nfor i in range(0,x0_cuenta,1):\n    if freq_x0&#x5B;i]&gt;0:\n        una_freq = float(freq_x0&#x5B;i]*unfactor*(fs\/(2*pi)))\n        x0t = x0t + 2*ampl_x0&#x5B;i]*sym.cos(DosPi*una_freq*t+sym.UnevaluatedExpr(fase_x0&#x5B;i])) \n    if freq_x0&#x5B;i]&gt;=0 and freq_x0&#x5B;i]&lt;tolera: # es cero\n        una_freq = float(freq_x0&#x5B;i]*unfactor*(fs\/(2*pi)))\n        x0t = x0t + ampl_x0&#x5B;i]*sym.cos(DosPi*una_freq*t+sym.UnevaluatedExpr(fase_x0&#x5B;i]))\nx0t = dsp._float_is_int(x0t) # si es entero\nx0tr = x0t.subs(pi,np.pi)\nif x0tr.has(t): # dos componentes en la constante.\n    x0tr = sym.lambdify(t,x0tr,modules=equivalentes)\nelse: # componentes constantes\n    constante = float(x0tr.doit())\n    x0tr = lambda t: constante +0*t\n    x0t = x0t.simplify()\nx0_ti = x0tr(ti)\n\n# SALIDA\nprint('se\u00f1al(t):  ',x)\nprint(' espectro_t:')\nfor parametro in un_espectro_t:\n    print(' ',parametro,':',un_espectro_t&#x5B;parametro])\n\nprint('\\nmuestreo fs:',fs,' ; dt:',dt, ' ; fs_veces:',fs_veces)\nprint('muestreo_tipo: ',muestreo_tipo)\nprint('muestreo:',muestras_n,\n      ' tama\u00f1o ki:',len(ki),'; tama\u00f1o ti:',len(ti))\nprint('x(t):',x)\nprint('x&#x5B;n]:',xn)\n\nprint('\\nse\u00f1al&#x5B;n]:  ',xn)\nprint(' espectro_n:')\nfor parametro in un_espectro_n:\n    print(' ',parametro,':',un_espectro_n&#x5B;parametro])\n\nprint('\\nse\u00f1al reconstruida con alias principal:')\nprint(x0t)\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<div class=\"wp-block-group has-medium-font-size is-layout-flex wp-block-group-is-layout-flex\">\n<p><a href=\"#concepto\" data-type=\"internal\" data-id=\"#concepto\">reconstrucci\u00f3n<\/a><\/p>\n\n\n\n<p>muestreo:<\/p>\n\n\n\n<p><a href=\"#sobremuestreo\">sobre<\/a><\/p>\n\n\n\n<p><a href=\"#submuestreo\">sub<\/a><\/p>\n\n\n\n<p><a href=\"#algoritmo\">algoritmo<\/a><\/p>\n\n\n\n<p><a href=\"#grafica\">gr\u00e1fica<\/a><\/p>\n\n\n\n<p><a href=\"#interactiva\">interactiva<\/a><\/p>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"grafica\">6. Gr\u00e1fica<\/h2>\n\n\n\n<p>Con los componentes descritos en la parte de algoritmos, se ajustan las gr\u00e1ficas de cada secci\u00f3n para cada sub-gr\u00e1fica en la figura.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# GRAFICAS  ----------------------------------------\n# Grafica de espectro de frecuencias\n# Ref: blog|Espectro x&#x5B;n] \u2013 Se\u00f1al discreta en tiempo\ngraf_dx = 0.12 # margen en eje x\nfig_espectro = plt.figure()\n\n# grafica espectro x(t) continuo en tiempo ---------\ngraf_fasor = fig_espectro.add_subplot(311)\nampl_max = float(max(ampl))\nfreq_max = float(max(max(freq),fs))*(1+graf_dx\/2)\nif freq_max!=0:\n    graf_fasor.set_xlim(&#x5B;-freq_max*(1+graf_dx),\n                         freq_max*(1+graf_dx)])\nelse:\n    graf_fasor.set_xlim(&#x5B;-1,1])\ngraf_fasor.set_ylim(&#x5B;0,ampl_max*(1+graf_dx*4)])\ngraf_fasor.grid()\ngraf_fasor.axhline(0,color='black')\ngraf_fasor.axvline(0,linestyle='dotted',color='grey')\ngraf_fasor.set_ylabel('Magnitud '+xt_etiqueta)\ngraf_fasor.set_xlabel('freq Hz', labelpad=0,)\n\n# espectro x(t) continuo en tiempo\ngraf_fasor.stem(freq,ampl) # grafica espectro magnitud\nfor k in range(0,len(freq),1): # etiquetas de fasor\n    graf_fasor.annotate(etiqueta&#x5B;k],xy=(freq&#x5B;k],ampl&#x5B;k]),\n        xytext=(0,5),textcoords='offset points',ha='center')\n    \n# fs frecuencia de muestreo\ngraf_fasor.stem(fs,ampl_max\/2,linefmt = 'C3:', ) # fs\ngraf_fasor.annotate('fs',xy=(fs,ampl_max\/2),\n        xytext=(0,5),textcoords='offset points',ha='center')\ntexto = '$' + sym.latex(titulo)+'$' +'  ; fs='+str(fs)\ntexto = texto + '  ; alias='+str(aliasn)\ngraf_fasor.set_title(texto)\n\n# GRAFICA x(t), x&#x5B;n], x(t)_alias0 ---------\ngraf_xt = fig_espectro.add_subplot(312)\ngraf_xt.set_xlabel('t')\ngraf_xt.set_ylabel('amplitud')\ngraf_xt.grid()\n\ngraf_xt.plot(ti,xti, color='gray',label='x(t)')\ngraf_xt.plot(ti,x0_ti, color='blue',label='x(t)_alias0',\n             linestyle='dotted')\ngraf_xt.stem(tki,xki,linefmt = 'C0:',label='x&#x5B;n]_alias0')\ngraf_xt.legend()\n\n# grafica espectro x&#x5B;n] de frecuencias discretas---------\n# Ref: blog|Espectro x&#x5B;n] \u2013 Se\u00f1al discreta en tiempo\ngraf_fasorn = fig_espectro.add_subplot(313)\n# grafica x&#x5B;n] - entorno\nfreq_n = un_espectro_n&#x5B;'freq']\nampl_n = un_espectro_n&#x5B;'ampl']\netiq_n = un_espectro_n&#x5B;'etiq']\nfreq_alias = un_espectro_n&#x5B;'freq_alias']\nampl_max = float(max(ampl_n))*(1+graf_dx*4)\nfreq_max = float(max(un_espectro_n&#x5B;'freq_max'],1))*(1+graf_dx\/2)\ngraf_fasorn.set_xlim(&#x5B;-freq_max,freq_max])\ngraf_fasorn.set_ylim(&#x5B;min(&#x5B;min(ampl_n),0]),ampl_max])\ngraf_fasorn.grid()\ngraf_fasorn.axhline(0,color='black')\ngraf_fasorn.axvline(0,linestyle='dotted',color='grey')\ngraf_fasorn.set_ylabel('Magnitud '+xn_etiqueta)\ngraf_fasorn.set_xlabel('freq rad')\n\n# grafica x&#x5B;n] - magnitud\nfreq_alias0 = np.invert(freq_alias) \ngraf_fasorn.stem(freq_n&#x5B;freq_alias0],ampl_n&#x5B;freq_alias0],\n                 linefmt = 'C0--',label = 'alias0')\nif len(freq_n&#x5B;freq_alias])&gt;0:\n    graf_fasorn.stem(freq_n&#x5B;freq_alias],ampl_n&#x5B;freq_alias],\n                     linefmt = 'C1--',label = 'alias')\n\nif un_espectro_n&#x5B;'freq_factor'] != sym.S.One:\n    unfactor_txt = r'$'+sym.latex(un_espectro_n&#x5B;'freq_factor'])+'$'\n    freq_etiq = &#x5B;]\n    for un_num in freq_n:\n        freq_etiq.append(f''+str(round(un_num,4))+unfactor_txt)\n    graf_fasorn.set_xticks(ticks=freq_n,labels=freq_etiq)\nfor k in range(0,len(freq_n),1): # etiquetas de fasor\n    graf_fasorn.annotate(etiq_n&#x5B;k],xy=(freq_n&#x5B;k],ampl_n&#x5B;k]),\n                 xytext=(0,5),textcoords='offset points',\n                 ha='center')\ngraf_fasorn.legend()\n\nplt.tight_layout()\nplt.show()\n\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<div class=\"wp-block-group has-medium-font-size is-layout-flex wp-block-group-is-layout-flex\">\n<p><a href=\"#concepto\" data-type=\"internal\" data-id=\"#concepto\">reconstrucci\u00f3n<\/a><\/p>\n\n\n\n<p>muestreo:<\/p>\n\n\n\n<p><a href=\"#sobremuestreo\">sobre<\/a><\/p>\n\n\n\n<p><a href=\"#submuestreo\">sub<\/a><\/p>\n\n\n\n<p><a href=\"#algoritmo\">algoritmo<\/a><\/p>\n\n\n\n<p><a href=\"#grafica\">gr\u00e1fica<\/a><\/p>\n\n\n\n<p><a href=\"#interactiva\">interactiva<\/a><\/p>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"interactiva\">7. Gr\u00e1fica Interactiva con Python<\/h2>\n\n\n\n<p>Se reescribe un poco el algoritmo, agrupando algunos bloques que deben actualizarse al cambiar la variable fs<\/p>\n\n\n\n<p>La frecuencia de muestreo fs se ajusta por medio de una barra de desplazamiento entre los valores de fmax\/2 y 2*fmax*+50.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/espectro_n_coseno_interactivo01.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1536\" height=\"759\" src=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/espectro_n_coseno_interactivo01.png\" alt=\"espectro discreto coseno interactivo 01\" class=\"wp-image-526\" \/><\/a><\/figure>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# ejercicio 4.5 p133 Muestreo y Reconstrucci\u00f3n de se\u00f1ales sinusoidales\n# grafico interactivo\n# telg1034 DSP fiec-espol edelros@espol.edu.ec\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport sympy as sym\nimport telg1034 as dsp\n\n# variables continuas\nfrom telg1034 import t,A,w,f,p,pi,DosPi,I,equivalentes\n# variables discretas\nfrom telg1034 import n\n\n# INGRESO\nwith sym.evaluate(False): # no simplificar freq angular w &gt;2*pi por Sympy\n    x = sym.cos(DosPi*100*t + pi\/3)\nxt_etiqueta = 'x(t)' ; xn_etiqueta = 'x&#x5B;n]'\ntitulo = x # copia para titulo de grafico (antes de procesar)\n\n# se\u00f1al muestreada\nfs = 500   # muestreo discreto, freq_sampling &gt;0\nfs_veces = 12  # suavizar x(t), sobremuestreo\nmuestras_n = 10 + 1  # para x&#x5B;n]\n\naliasn = 1 # alias a\u00f1adidos a x&#x5B;n]\ntolera = 1e-9 # tolerancia a error, n\u00fameros iguales\n\n# PROCEDIMIENTO ----------------\n# espectro x(t) - operaciones\n# Ref: Blog|Espectro-Operaciones en dominio de tiempo y frecuencia\n# unase\u00f1al = x.subs(pi,np.pi) # mantener valores &gt;2pi como float\nx_term = dsp.x_list_term_Add(x)\nXe_term = dsp.cos_to_euler_one_term(x_term)\nx_term_expand = dsp.euler_to_cos_list(Xe_term)\nun_espectro_t = dsp.cos_spectrum_list(x_term)\n\n# espectro de cada se\u00f1al\nfreq = un_espectro_t&#x5B;'freq']\nampl = un_espectro_t&#x5B;'ampl']\nfase = un_espectro_t&#x5B;'fase']\netiqueta = un_espectro_t&#x5B;'etiq']\n\n# freq_max y freq_min\nfreq_max = float(max(freq))\nif len(freq&#x5B;freq&gt;0])&gt;0:\n    freq_min = float(min(freq&#x5B;freq&gt;0]))\nelse:\n    freq_min = 0\nun_espectro_t&#x5B;'freq_max'] = freq_max\nun_espectro_t&#x5B;'freq_min'] = freq_min\n\ndef sampling_type(fs,freq_max,tolera=1e-9):\n    '''revisa muestreo Nyquist\n    '''\n    if abs(2*freq_max-fs)&lt;tolera:\n        muestreo_tipo = 'Nyquist'\n    if fs&gt;(freq_max*2):\n        muestreo_tipo = 'sobre-muestreo'\n    if fs&lt;(freq_max*2):\n        muestreo_tipo = 'sub-muestreo'\n    if fs&lt;(freq_max*2) and fs&gt;freq_max:\n        muestreo_tipo = 'sub-muestreo y folding'\n    return(muestreo_tipo)\n\nmuestreo_tipo = sampling_type(fs,freq_max)\n\n# Muestreo de se\u00f1ales sinusoidales\n# Ref: blog|Muestreo con Python\nxt = sym.lambdify(t,x, modules=equivalentes)\nxn = x.subs(t,n\/fs)\n\n# muestreo x&#x5B;n]\ndt = 1\/fs   # tama\u00f1o de paso con fs\nki = np.arange(0,muestras_n,1,dtype=int)\ntki = ki*dt\nxki = xt(tki)\n\nnT = int(np.max(tki)\/dt) # periodos a graficar\n\n# muestreo x(t)\ndtc = dt\/fs_veces # suavizar x(t), sobremuestreo\nti = np.arange(0,(muestras_n-1)*dt+dtc, dtc)\nxti = xt(ti)\n\ndef espectro_xn_analiza(xn,fs,aliasn):\n    '''operaciones para espectro x&#x5B;n]\n    # Ref: blog|Espectro x&#x5B;n] \u2013 Se\u00f1al discreta en tiempo\n    '''\n    #xn = xn.doit()#.subs(pi,np.pi).doit() # mantener valores &gt;2pi\n    x_term = dsp.x_list_term_Add(xn)\n    Xe_term = dsp.cos_to_euler_one_term(x_term)\n    x_term_expand = dsp.euler_to_cos_list(Xe_term)\n    un_espectro_n = dsp.cos_spectrum_list(x_term)\n    # espectro de cada se\u00f1al\n    freq_n = np.array(un_espectro_n&#x5B;'freq'])\n    ampl_n = np.array(un_espectro_n&#x5B;'ampl'])\n    fase_n = np.array(un_espectro_n&#x5B;'fase'])\n    etiq_n = np.array(un_espectro_n&#x5B;'etiq'])\n    un_espectro_n&#x5B;'x_expand'] = x_term_expand\n\n    freqn_conteo = len(freq_n)\n\n    # normaliza w frecuencia angular\n    for i in range(0,freqn_conteo,1):\n        while abs(freq_n&#x5B;i].subs(pi,np.pi))&gt;np.pi:\n            if freq_n&#x5B;i]&gt;0:\n                freq_norm = freq_n&#x5B;i]-2*pi\n            else:\n                freq_norm = freq_n&#x5B;i]+2*pi\n            freq_n&#x5B;i] = freq_norm\n\n    # A\u00f1adir alias a se\u00f1al\n    freqn_alias = np.zeros(freqn_conteo,dtype=bool)\n    freq_m = np.zeros(0,dtype=float)\n    for i in range(0,freqn_conteo,1):\n        freq_i = freq_n&#x5B;i]\n        ampl_i = ampl_n&#x5B;i]\n        fase_i = fase_n&#x5B;i]\n        etiq_i = etiq_n&#x5B;i]\n        for k in range(1,aliasn+1,1):\n            freq_k = (freq_i+2*pi*k)\n            if  not((freq_k in freq_n) or (freq_k in freq_m)):\n                # a\u00f1ade freq_n&#x5B;i] + 2*pi*k\n                freq_m = np.concatenate(&#x5B;freq_m,&#x5B;freq_i+2*pi*k]])\n                ampl_n = np.concatenate(&#x5B;ampl_n,&#x5B;ampl_i]])\n                fase_n = np.concatenate(&#x5B;fase_n,&#x5B;fase_i]])\n                etiq_n = np.concatenate(&#x5B;etiq_n,&#x5B;etiq_i]])\n                freqn_alias = np.concatenate(&#x5B;freqn_alias,&#x5B;True]])\n            freq_k = (freq_i-2*pi*k)\n            if not((freq_k in freq_n) or (freq_k in freq_m)):\n                # a\u00f1ade freq_n&#x5B;i] - 2*pi*k\n                freq_m = np.concatenate(&#x5B;freq_m,&#x5B;freq_i-2*pi*k]])\n                ampl_n = np.concatenate(&#x5B;ampl_n,&#x5B;ampl_i]])\n                fase_n = np.concatenate(&#x5B;fase_n,&#x5B;fase_i]])\n                texto = '$' + sym.latex(ampl_i)+'$'\n                if fase_i!=sym.S.Zero:\n                    texto = texto+f'$ e^j('+sym.latex(fase_i)+')$'\n                etiq_n = np.concatenate(&#x5B;etiq_n,&#x5B;texto]])\n                freqn_alias = np.concatenate(&#x5B;freqn_alias,&#x5B;True]])\n    freq_n = np.concatenate(&#x5B;freq_n,freq_m])\n\n    # ordena frecuencias\n    orden = np.argsort(freq_n)\n    freq_n = freq_n&#x5B;orden]\n    ampl_n = ampl_n&#x5B;orden]\n    fase_n = fase_n&#x5B;orden]\n    etiq_n = etiq_n&#x5B;orden]\n    freqn_alias = freqn_alias&#x5B;orden]\n\n    # revisa factor pi en freq_n\n    unfactor = sym.S.One ; factor_pi = False\n    freqn_conteo = len(freq_n)\n    for i in range(0,freqn_conteo,1):\n        if freq_n&#x5B;i].has(pi):\n            factor_pi = True\n    if factor_pi:\n        freq_n = np.array(freq_n\/pi,dtype=float)\n        unfactor = pi\n    # actualiza espectro de se\u00f1al con factor pi,alias,orden\n    un_espectro_n&#x5B;'freq_factor'] = unfactor\n    un_espectro_n&#x5B;'freq'] = freq_n\n    un_espectro_n&#x5B;'ampl'] = ampl_n\n    un_espectro_n&#x5B;'fase'] = fase_n\n    un_espectro_n&#x5B;'etiq'] = etiq_n\n\n    # ancho de banda, freq_max y freq_min\n    freq_posi = freq_n&#x5B;freq_n&gt;0]\n    freq_max_n = float(max(freq_posi))\n    freq_min_n = 0\n    if len(freq_posi)&gt;0:\n        freq_min_n = float(min(freq_posi))\n    freq_centro_n = (freq_max_n + freq_min_n)\/2\n    un_espectro_n&#x5B;'freq_max'] = freq_max_n\n    un_espectro_n&#x5B;'freq_min'] = freq_min_n\n    un_espectro_n&#x5B;'BW'] = freq_max_n - freq_min_n\n\n    # alias principal, Revisa espectro de frecuencias  \n    freq_conteo = len(freq_n)\n    freq_alias = np.zeros(freq_conteo,dtype=bool)\n    for i in range (0,freq_conteo,1):\n        unafreq = freq_n&#x5B;i]\n        if abs(unafreq) &gt; 1:\n            freq_alias&#x5B;i] = True\n    freq_alias_conteo = np.sum(freq_alias)\n    un_espectro_n&#x5B;'freq_alias'] = freq_alias\n\n    # reconstruye se\u00f1al con alias principal\n    freq_alias0 = np.invert(freq_alias)\n    freq_x0 = freq_n&#x5B;freq_alias0]\n    ampl_x0 = ampl_n&#x5B;freq_alias0]\n    fase_x0 = fase_n&#x5B;freq_alias0]\n    x0_cuenta = len(freq_x0)\n    x0t = sym.S.Zero\n    print('freq_alias0',freq_alias0)\n    print('x0_cuenta',x0_cuenta,fs,pi)\n    for i in range(0,x0_cuenta,1):\n        print('i',i,'freq_x0&#x5B;i]',freq_x0&#x5B;i],fase_x0&#x5B;i],ampl_x0&#x5B;i], unfactor)\n        if (float(freq_x0&#x5B;i]))&gt;tolera:\n            una_freq = float(freq_x0&#x5B;i]*unfactor*(fs\/(2*pi)))\n            print('una_freq&gt;0',una_freq, unfactor, fs)\n            x0t = x0t + 2*ampl_x0&#x5B;i]*sym.cos(DosPi*una_freq*t+sym.UnevaluatedExpr(fase_x0&#x5B;i])) \n        if freq_x0&#x5B;i]&gt;=0 and freq_x0&#x5B;i]&lt;tolera: # es cero\n            una_freq = float(freq_x0&#x5B;i]*unfactor*(fs\/(2*pi)))\n            print('una_freq&lt;tolera',una_freq, unfactor, fs)\n            x0t = x0t + ampl_x0&#x5B;i]*sym.cos(DosPi*una_freq*t+sym.UnevaluatedExpr(fase_x0&#x5B;i]))\n        print('i',i,'x0t',x0t)\n    x0t = dsp._float_is_int(x0t) # si es entero\n    un_espectro_n&#x5B;'x0t'] = x0t\n    return (un_espectro_n)\n\nun_espectro_n = espectro_xn_analiza(xn,fs,aliasn)\nx0t = un_espectro_n&#x5B;'x0t']\nx0tr = x0t.subs(pi,np.pi)\nif x0tr.has(t): # dos componentes en la constante.\n    x0tr = sym.lambdify(t,x0tr,modules=equivalentes)\nelse: # componentes constantes\n    constante = float(x0tr.doit())\n    x0tr = lambda t: constante +0*t\n    x0t = x0t.simplify()\nx0_ti = x0tr(ti)\n    \n\n# SALIDA\nprint('se\u00f1al(t):  ',x)\nprint(' espectro_t:')\nfor parametro in un_espectro_t:\n    print(' ',parametro,':',un_espectro_t&#x5B;parametro])\n\nprint('\\nmuestreo fs:',fs,' ; dt:',dt, ' ; fs_veces:',fs_veces)\nprint('muestreo_tipo: ',muestreo_tipo)\nprint('muestreo:',muestras_n,\n      ' tama\u00f1o ki:',len(ki),'; tama\u00f1o ti:',len(ti))\nprint('x(t):',x)\nprint('x&#x5B;n]:',xn)\n\nprint('\\nse\u00f1al&#x5B;n]:  ',xn)\nprint(' espectro_n:')\nfor parametro in un_espectro_n:\n    print(' ',parametro,':',un_espectro_n&#x5B;parametro])\n\nprint('\\nse\u00f1al reconstruida con alias principal:')\nprint(x0t)\n\n# GRAFICAS  interactivas----------------------------\nfrom matplotlib.widgets import Slider, Button, TextBox\n# Grafica de espectro de frecuencias\n# Ref: blog|Espectro x&#x5B;n] \u2013 Se\u00f1al discreta en tiempo\ngraf_dx = 0.12 # margen en eje x\nfig_espectro = plt.figure()\n\n# grafica espectro x(t) continuo en tiempo ---------\n# espectro x(t) grafico entorno\ngraf_fasor = fig_espectro.add_subplot(311)\na_max = float(max(ampl))\nf_max = float(max(max(freq),fs))*(1+graf_dx\/2)\nif f_max!=0:\n    graf_fasor.set_xlim(&#x5B;-f_max*(1+graf_dx),\n                         f_max*(1+graf_dx)])\nelse:\n    graf_fasor.set_xlim(&#x5B;-1,1])\ngraf_fasor.set_ylim(&#x5B;0,a_max*(1+graf_dx*4)])\ngraf_fasor.grid()\ngraf_fasor.axhline(0,color='black')\ngraf_fasor.axvline(0,linestyle='dotted',color='grey')\ngraf_fasor.set_ylabel('Magnitud '+xt_etiqueta)\ngraf_fasor.set_xlabel('freq Hz', labelpad=0,)\n\n# espectro x(t) - componentes \npuntos_xt = graf_fasor.stem(freq,ampl) # espectro magnitud\nfor k in range(0,len(freq),1): # etiquetas de fasor\n    graf_fasor.annotate(etiqueta&#x5B;k],xy=(freq&#x5B;k],ampl&#x5B;k]),\n        xytext=(0,5),textcoords='offset points',ha='center')\n    \n# espectro x(t) - fs frecuencia de muestreo\npuntos_fs = graf_fasor.stem(fs,a_max\/2,linefmt = 'C3:', ) # fs\npuntos_fs_etiq = graf_fasor.annotate('fs',xy=(fs,(a_max\/2)),\n        xytext=(0,5),textcoords='offset points',ha='center')\ntexto = '$' + sym.latex(titulo)+'$' +'  ; fs='+str(fs)\ntexto = texto + '  ; alias='+str(aliasn)\ngraf_fasor.set_title(texto)\n\n# grafica x(t), x&#x5B;n], x(t)_alias0 --------------\n# grafica x(t) -  entorno\ngraf_xt = fig_espectro.add_subplot(312)\ngraf_xt.set_xlabel('t')\ngraf_xt.set_ylabel('amplitud')\ngraf_xt.grid()\n# grafica x(t) -  componentes\nlinea_xt, = graf_xt.plot(ti,xti, color='gray',label='x(t)')\nlinea_xt_a0, = graf_xt.plot(ti,x0_ti, color='blue',\n            label='x(t)_alias0',linestyle='dotted')\npuntos_xn = graf_xt.stem(tki,xki,linefmt = 'C0:',label='x&#x5B;n]')\ngraf_xt.legend()\n\n# grafica espectro x&#x5B;n] de frecuencias discretas---------\n# Ref: blog|Espectro x&#x5B;n] \u2013 Se\u00f1al discreta en tiempo\ngraf_fasorn = fig_espectro.add_subplot(313)\n# grafica x&#x5B;n] - entorno\nfreq_n = un_espectro_n&#x5B;'freq']\nampl_n = un_espectro_n&#x5B;'ampl']\netiq_n = un_espectro_n&#x5B;'etiq']\nfreq_alias = un_espectro_n&#x5B;'freq_alias']\nampl_max = float(max(ampl_n))*(1+graf_dx*4)\nw_max = float(max(un_espectro_n&#x5B;'freq_max'],1))*(1+graf_dx\/2)\ngraf_fasorn.set_xlim(&#x5B;-w_max,w_max])\ngraf_fasorn.set_ylim(&#x5B;min(&#x5B;min(ampl_n),0]),ampl_max])\ngraf_fasorn.grid()\ngraf_fasorn.axhline(0,color='black')\ngraf_fasorn.axvline(0,linestyle='dotted',color='grey')\ngraf_fasorn.set_ylabel('Magnitud '+xn_etiqueta)\ngraf_fasorn.set_xlabel('freq rad')\n\n# grafica x&#x5B;n] - magnitud\nfreq_alias0 = np.invert(freq_alias) \npuntos_alias0 = graf_fasorn.stem(freq_n&#x5B;freq_alias0],\n                                 ampl_n&#x5B;freq_alias0],\n                 linefmt = 'C0--',label = 'alias0')\nif len(freq_n&#x5B;freq_alias])&gt;0:\n    puntos_alias = graf_fasorn.stem(freq_n&#x5B;freq_alias],\n                                    ampl_n&#x5B;freq_alias],\n                     linefmt = 'C1--',label = 'alias')\n# actualiza eje x etiquetas\nif un_espectro_n&#x5B;'freq_factor'] != sym.S.One:\n    unfactor_txt = r'$'+sym.latex(un_espectro_n&#x5B;'freq_factor'])+'$'\n    freq_etiq = &#x5B;]\n    for un_num in freq_n:\n        freq_etiq.append(f''+str(round(un_num,4))+unfactor_txt)\n    graf_fasorn.set_xticks(ticks=freq_n,labels=freq_etiq)\n# etiquetas de fasor\na0_etiq = &#x5B;]\nfor k in range(0,len(freq_n),1):\n    puntos_a0_etiq = graf_fasorn.annotate(etiq_n&#x5B;k],\n                    xy=(freq_n&#x5B;k],ampl_n&#x5B;k]),\n                    xytext=(0,5),textcoords='offset points',\n                    ha='center')\n    a0_etiq.append(puntos_a0_etiq)\ngraf_fasorn.legend()\n\nplt.tight_layout()\n\n# grafica interactiva\nplt.subplots_adjust(bottom=0.25) # espacio widgets\n\n# slider: barras para valores \n# amplitud slider &#x5B;x,y,ancho,alto]\nfs_donde = plt.axes(&#x5B;0.2, 0.10, 0.65, 0.03])\ndf_pasos=5\nfs_slider = Slider(fs_donde, 'fs',\n                   freq_max\/2, (max(&#x5B;fs,2*freq_max])+2*df_pasos),\n                   valinit = fs, valstep = df_pasos,\n                   orientation='horizontal')\ntxt_xndonde = plt.axes(&#x5B;0.2, 0.02, 0.55, 0.045])\ntxt_xn = TextBox(txt_xndonde, &quot;alias0 x(t): &quot;,\n                   initial=x0t)\n\ndef grafico_actualiza(val):\n    # actualiza valores x,y\n    fs = fs_slider.val\n    # espectro x(t)\n    dsp.stem_update(puntos_fs,&#x5B;fs],&#x5B;ampl_max\/2],graf_fasor)\n    puntos_fs_etiq.xy = (fs, ampl_max\/2)\n    puntos_fs_etiq.set_visible(True)\n    texto = '$' + sym.latex(titulo)+'$' +'  ; fs='+str(fs)\n    texto = texto + '  ; alias='+str(aliasn)\n    graf_fasor.set_title(texto)\n\n    muestreo_tipo = sampling_type(fs,freq_max)\n    print(' \\n***** fs',fs,muestreo_tipo)\n\n    # grafica x(t), x&#x5B;n] --------------\n    ti_max = max(ti)\n    dt = 1\/fs\n    muestras_n=2\n    if ti_max&gt;=dt:\n        muestras_n = int(ti_max\/dt)+1\n    ki = np.arange(0,muestras_n,1,dtype=int)\n    tki = ki*dt\n    xki = xt(tki)\n    dsp.stem_update(puntos_xn,tki,xki,graf_xt)\n\n    # Nuevo espectro x&#x5B;n]\n    xn = x.subs(t,n\/fs)\n    un_espectro_n = espectro_xn_analiza(xn,fs,aliasn)\n    x0t = un_espectro_n&#x5B;'x0t']\n    print('x0t:',x0t)\n    \n    x0tr = x0t.subs(pi,np.pi)\n    if x0tr.has(t): # dos componentes en la constante.\n        x0tr = sym.lambdify(t,x0tr,modules=equivalentes)\n    else: # componentes constantes\n        constante = float(x0tr.doit())\n        x0tr = lambda t: constante +0*t\n        x0t = x0t.simplify()\n    x0_ti = x0tr(ti)\n\n    linea_xt_a0.set_xdata(ti)\n    linea_xt_a0.set_ydata(x0_ti)\n\n    # grafica x&#x5B;n] - magnitud\n    freq_alias = un_espectro_n&#x5B;'freq_alias']\n    freq_alias0 = np.invert(freq_alias)\n    freq_n = un_espectro_n&#x5B;'freq']\n    ampl_n = un_espectro_n&#x5B;'ampl']\n    dsp.stem_update(puntos_alias0,\n                    freq_n&#x5B;freq_alias0],\n                    ampl_n&#x5B;freq_alias0],graf_fasorn)\n    \n    if len(freq_n&#x5B;freq_alias])&gt;0:\n        dsp.stem_update(puntos_alias,\n                        freq_n&#x5B;freq_alias],\n                        ampl_n&#x5B;freq_alias],graf_fasorn)\n    if un_espectro_n&#x5B;'freq_factor'] != sym.S.One:\n        unfactor_txt = r'$'+sym.latex(un_espectro_n&#x5B;'freq_factor'])+'$'\n        freq_etiq = &#x5B;]\n        for un_num in freq_n:\n            freq_etiq.append(f''+str(round(un_num,4))+unfactor_txt)\n        graf_fasorn.set_xticks(ticks=freq_n,labels=freq_etiq)\n    # etiquetas de fasor\n    etiq_n = un_espectro_n&#x5B;'etiq']\n    for ann in a0_etiq:\n        ann.remove()\n    a0_etiq.clear()\n    for k in range(0,len(freq_n),1):\n        puntos_a0_etiq = graf_fasorn.annotate(etiq_n&#x5B;k],\n                        xy=(freq_n&#x5B;k],ampl_n&#x5B;k]),\n                        xytext=(0,5),textcoords='offset points',\n                        ha='center')\n        a0_etiq.append(puntos_a0_etiq)\n    \n    txt_xn.set_val(x0t)\n    \n    fig_espectro.canvas.draw_idle() # actualiza figura\n\n# boton reinicio de gr\u00e1fica\nbtn_rstdonde = plt.axes(&#x5B;0.8, 0.025, 0.1, 0.04])\nbtn_rst = Button(btn_rstdonde, 'Reset',\n                 hovercolor='0.975')\ndef grafico_reinicia(event):\n    fs_slider.reset()\n    return()\n\n# objetos interactivos\nfs_slider.on_changed(grafico_actualiza)\nbtn_rst.on_clicked(grafico_reinicia)\n\nplt.show()\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<div class=\"wp-block-group has-medium-font-size is-layout-flex wp-block-group-is-layout-flex\">\n<p><a href=\"#concepto\" data-type=\"internal\" data-id=\"#concepto\">reconstrucci\u00f3n<\/a><\/p>\n\n\n\n<p>muestreo:<\/p>\n\n\n\n<p><a href=\"#sobremuestreo\">sobre<\/a><\/p>\n\n\n\n<p><a href=\"#submuestreo\">sub<\/a><\/p>\n\n\n\n<p><a href=\"#algoritmo\">algoritmo<\/a><\/p>\n\n\n\n<p><a href=\"#grafica\">gr\u00e1fica<\/a><\/p>\n\n\n\n<p><a href=\"#interactiva\">interactiva<\/a><\/p>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n","protected":false},"excerpt":{"rendered":"<p>reconstrucci\u00f3n muestreo: sobre sub algoritmo gr\u00e1fica interactiva 1. Muestreo y Reconstrucci\u00f3n La salida de un convertidor cont\u00ednuo a discreto C-D es una se\u00f1al discreta en tiempo con un n\u00famero infinito de alias. Al observar un gr\u00e1fico de espectro de frecuencias \u03c9 es necesario recordar que existen m\u00e1s se\u00f1ales fuera del intervalo mostrado. Considere una se\u00f1al [&hellip;]<\/p>\n","protected":false},"author":8043,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"wp-custom-template-entrada-dsp-unidades","format":"standard","meta":{"footnotes":""},"categories":[193],"tags":[],"class_list":["post-20599","post","type-post","status-publish","format-standard","hentry","category-dsp-unidades"],"_links":{"self":[{"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/posts\/20599","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/users\/8043"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/comments?post=20599"}],"version-history":[{"count":5,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/posts\/20599\/revisions"}],"predecessor-version":[{"id":20606,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/posts\/20599\/revisions\/20606"}],"wp:attachment":[{"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/media?parent=20599"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/categories?post=20599"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/tags?post=20599"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}