{"id":554,"date":"2024-10-26T12:44:38","date_gmt":"2024-10-26T17:44:38","guid":{"rendered":"http:\/\/blog.espol.edu.ec\/telg1034\/?p=554"},"modified":"2026-03-27T21:23:15","modified_gmt":"2026-03-28T02:23:15","slug":"interpola-con-pulso-rectangular","status":"publish","type":"post","link":"https:\/\/blog.espol.edu.ec\/algoritmos101\/dsp-unidades\/interpola-con-pulso-rectangular\/","title":{"rendered":"2.5 D-to-C - Interpolaci\u00f3n Zero-Order Hold o con pulso rectangular"},"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\">interpola pulso<\/a><\/p>\n\n\n\n<p><a href=\"#pulsorectangular\">pulso rectangular<\/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=\"#graficointeractivo\">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. Interpolaci\u00f3n con Pulsos<\/h2>\n\n\n\n<p><em><strong>Referencia<\/strong><\/em>: McClellan 4-3.1 p141<\/p>\n\n\n\n<p>Un&nbsp; sistema que convierte una se\u00f1al y[n] en forma <strong>D<\/strong>iscreta a la forma <strong>C<\/strong>ont\u00ednua y(t), conocido como D-to-C,&nbsp; usa interpolaci\u00f3n para rellenar los espacios entre muestras. En el proceso se deben considerar efectos como el \"aliasing\" y \"folding\".<\/p>\n\n\n\n<p>La implementaci\u00f3n del concepto D-to-C en un sistema f\u00edsico o \"hardware\" se los conoce como Convertidor Digital-Anal\u00f3gico (DAC) que completa los espacios entre muestras con un pulso p(t)<\/p>\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> y(t) = \\sum_{n=-\\infty}^{\\infty} y[n] p(t-nTs)<\/span>\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\">interpola pulso<\/a><\/p>\n\n\n\n<p><a href=\"#pulsorectangular\">pulso rectangular<\/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=\"#graficointeractivo\">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=\"pulsorectangular\">2. Interpolaci\u00f3n con Pulso rectangular, Zero-Order Hold<\/h2>\n\n\n\n<p>Un pulso simple, sim\u00e9trico es un pulso rectangular de la forma:<\/p>\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> p(t) = \\begin{cases} 1 &amp; -\\frac{1}{2} T_s \\lt t \\leq \\frac{1}{2} T_s \\\\ 0 &amp; otro caso \\end{cases}<\/span>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/PulsoRectangular01.png\"><img loading=\"lazy\" decoding=\"async\" width=\"434\" height=\"394\" src=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/PulsoRectangular01.png\" alt=\"Pulso Rectangular 01\" class=\"wp-image-597\" \/><\/a><\/figure>\n\n\n\n<p>Para una se\u00f1al senoidad de frecuencia 83Hz y amplitud unitaria se obtienen las muestras <strong>x<\/strong>[n]. La frecuencia de muestreo <strong>f<\/strong>s es de 200Hz.&nbsp; El proceso de re-construcci\u00f3n de <strong>x<\/strong>(t) llena los espacios entre muestras usando el pulso descrito en <strong>p<\/strong>(t). En \u00e9ste caso <strong>p<\/strong>(t) es un pulso rectangular.<\/p>\n\n\n\n<p>Los valores de las muestras x[n[ se presentan marcados con puntos para como una referencia en la gr\u00e1fica.<\/p>\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\/2024\/11\/InterpolaPulsoRectangular_animate.gif\" alt=\"Interpola Pulso Rectangular animate\" class=\"wp-image-20608\" \/><\/figure>\n\n\n\n<p>Si consideramos un muestreo de se\u00f1al a frecuencia fs=200Hz, se tiene que el pulso tiene una duraci\u00f3n <strong>T<\/strong>s = 5 ms y amplitud 1. Cada t\u00e9rmino de <code><strong>x<\/strong>[n]<strong>p<\/strong>(t-n<strong>T<\/strong>s)<\/code> crea una secci\u00f3n plana de amplitud x[n] centrada en n<strong>T<\/strong>s, como se muestra en la gr\u00e1fica.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2.1 Algoritmo en Python para un pulso<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# D-to-C, Interpolacion con pulso rectangular\n# ejemplo 4.3.2 p142\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# INGRESO\nfs = 200  # Hz muestreo\nfs_veces = 16 # suavizar x(t), sobremuestreo\ntitulo = 'pulso rectangular'\nnT = 2  # graficar periodos de la se\u00f1al\n\n# pulso rectangular\npulso_causal = True # No causal, pulso centrado en cero\npulso_ancho = 1\ndutyc = 1 # entre &#x5B;0,1] duty_cycle\n\n# PROCEDIMIENTO\nTs = 1\/fs\ndtc = Ts\/fs_veces # suavizar x(t), sobremuestreo\n\n#u = lambda t: np.piecewise(t,t&gt;=0,&#x5B;1,0])\nu = lambda t: np.heaviside(t,1)\n# pulso rectangular\n#dutyc = 1 # entre &#x5B;0,1] duty_cycle\nu1 = lambda t: u(t+Ts*dutyc\/2)\nu2 = lambda t: u(t-Ts*dutyc\/2)\nrectangular = lambda t: u1(t) - u2(t)             \n\n# x&#x5B;n] interpolacion en Ts, a muestreo fs\nt_unpulso = np.arange(-Ts\/2*nT,Ts\/2*nT+dtc,dtc)\nunpulso = rectangular(t_unpulso)\n\n# SALIDA\nprint('muestras:',len(t_unpulso))\nprint('t_unpulso:',t_unpulso)\n\n# GRAFICA de un pulso\nplt.axhline(0,color='Black')\nplt.axvline(-Ts,color='red',linestyle='dotted')\nplt.axvline(Ts,color='red',linestyle='dotted')\n\n# p(t) componentes\nplt.plot(t_unpulso,unpulso, color='green',linestyle='dashed',\n         label='p_rect(t)')\nplt.stem(&#x5B;0],&#x5B;1],linefmt = 'C1:', label='xn&#x5B;0]')\n\n# grafica entorno\nplt.xlabel('t')\nplt.ylabel('amplitud')\ntexto = titulo + ' ; fs='+str(fs)\ntexto = texto +' ; Ts='+str(Ts)\nplt.title(texto)\nplt.grid()\nplt.legend()\nplt.tight_layout()\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\">interpola pulso<\/a><\/p>\n\n\n\n<p><a href=\"#pulsorectangular\">pulso rectangular<\/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=\"#graficointeractivo\">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\">3. Algoritmo en Python Interpola con pulso rectangular<\/h2>\n\n\n\n<p>El algoritmo se divide en:<br>- c\u00e1lculo de x(t)<br>- c\u00e1lculo de x[n]<br>- reconstrucci\u00f3n x(t) a partir de x[n] usando pulsos<br>- gr\u00e1fica x(t)<br>- gr\u00e1fica de x[n]<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/interpolaPulsoRectangular01.png\"><img loading=\"lazy\" decoding=\"async\" width=\"640\" height=\"480\" src=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/interpolaPulsoRectangular01.png\" alt=\"interpola Pulso Rectangular 01\" class=\"wp-image-594\" \/><\/a><\/figure>\n\n\n\n<p>La se\u00f1al x(t) se convierte a discreta usando una tasa de muestras <strong>f<\/strong>s.&nbsp;Para observar la se\u00f1al x(t), se indica el n\u00famero de periodos <strong>nT<\/strong> de la frecuencia <strong>f<\/strong>0. Como ejemplo en la gr\u00e1fica se realizan nT=2.3 periodos de la se\u00f1al cosenoidal.<\/p>\n\n\n\n<p>La se\u00f1al de x(t) se suaviza visualmente al usar el factor <strong>fs_veces<\/strong> como sobre-muestreo respecto a <strong>f<\/strong>s. En este caso se usa fs=16. lo que genera muestras de se\u00f1al cada <code>Ts\/fs_veces<\/code> denominado en el algoritmo como tama\u00f1o de paso dtc.<\/p>\n\n\n\n<p>Para el relleno de los espacios entre muestras x[n] se usa un modelo de pulso rectangular de tama\u00f1o <code>Ts=1\/fs<\/code> que se copia cada vez que se avanza un espacio <strong>T<\/strong>s,<\/p>\n\n\n\n<p>Los valores de tiempo en la gr\u00e1fica deben considerar la cantidad de muestras x[n], el ancho del pulso, el tiempo de inicio si es o no causal y la frecuencia de muestreo. El proceso se lo agrupa en la funci\u00f3n <code>pulso_ti()<\/code>. El ancho del pulso cambia acorde a la forma del pulso a usar, triangular o Sinc(t). El pulso tambi\u00e9n se suaviza para la gr\u00e1fica con fs_veces.<\/p>\n\n\n\n<p>El proceso de reconstrucci\u00f3n de x(t) con pulsos consiste en repetir los valores del vector de <strong>un pulso<\/strong> en los tiempos que se dispone de una nueva muestra <strong>xki<\/strong>. En el caso que el ancho del pulso sea mayor que 1, los valores de los pulsos se traslapan y se requiere sumar los valores en un solo vector <strong>xn_pulsos<\/strong> . El efecto de \u00e9sta operaci\u00f3n se detalla mejor con las se\u00f1ales triangular y Sinc(t) por tener un ancho de pulso mayor a 1.<\/p>\n\n\n\n<p>Por el momento cada pulso se replica en cada muestra x[n] de la primera figura en la gr\u00e1fica usando un color diferente. El resultado final de <strong>xn_pulsos<\/strong> se presenta en la segunda gr\u00e1fica como x(t) pulsos.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# D-to-C, Interpolacion con pulso rectangular\n# ejemplo 4.3.2 p142\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# INGRESO\n# se\u00f1al x(t)\nf0 = 83   # frecuencia de senal\nfase0 = 0 # &#x5B;0,2*np.pi]\nxt = lambda t: np.cos(2*np.pi*f0*t + fase0)\n\nfs = 200  # Hz muestreo\nfs_veces = 16 # suavizar x(t), sobremuestreo\nnT = 2.3  # graficar periodos de la se\u00f1al\n\ntitulo = 'Interpola x(t) pulso rectangular '\n# pulso rectangular\npulso_causal = True # No causal, pulso centrado en cero\npulso_ancho = 1\ndutyc = 1 # entre &#x5B;0,1] duty_cycle\n\ncasicero = 1e-10 # cero para valores menores\n\n# PROCEDIMIENTO\nTs = 1\/fs # tama\u00f1o de paso con fs\nT =  1\/f0 # periodo de se\u00f1al\ndtc = Ts\/fs_veces # suavizar x(t), sobremuestreo\n\n# muestreo x(t)\nti = np.arange(0,nT*T+dtc,dtc)\nxti = xt(ti)\nti_max = max(ti)\n\n# muestreo x&#x5B;n]\nmuestras_n = 2\nif ti_max&gt;=Ts: # varias muestras\n    muestras_n = int(ti_max\/Ts)+1\nki  = np.arange(0,muestras_n,1,dtype=int)\ntki = ki*Ts # muestras x&#x5B;n]\nxki = xt(tki)\ntkj = tki   # x&#x5B;n] alias0\nti_0 = ti   # No Causal, pulso centrado en cero\nif pulso_causal: # Causal\n    tkj = tki + Ts*pulso_ancho\/2 \n    ti_0 = ti + Ts*pulso_ancho\/2\nxti_0 = xti\n\ndef pulso_ti(muestras_n,fs,fs_veces,ancho=1,causal=True):\n    ''' tiempos para las n muestras x(t) con pulsos a frecuencia fs.\n    Para suavizar el pulso se usa fs_veces para el sobremuestreo.\n    El ancho del pulso es veces el periodo de muestreo (1\/Ts)\n    Si es causal el tiempo inicia en t=0, centrado en cero.\n    Si no es causal el tiempo inicia t en mitad de intervalo.\n    '''\n    Ts = 1\/fs # muestreo periodo\n    dtc = Ts\/fs_veces # suavizar pulso(t), sobremuestreo\n    t_Ts = np.arange(0,Ts,dtc) # tiempo en periodo Ts sobremuestreado\n    \n    mitad = Ts*ancho\/2\n    t_mitad = np.arange(0,mitad,dtc)\n    t_pulsos = np.copy(t_mitad) # mitad de primer pulso\n    for i in range(1,muestras_n,1):\n        t_pulsos = np.concatenate((t_pulsos,t_Ts + t_pulsos&#x5B;-1]+dtc))\n    # mitad de \u00faltimo pulso para muestra_n\n    t_pulsos = np.concatenate((t_pulsos,t_mitad + t_pulsos&#x5B;-1]+dtc))\n\n    # https:\/\/blog.espol.edu.ec\/telg1001\/sistemas-causales-y-no-causales\/\n    if causal == False: # centrado en cero\n        t_pulsos = t_pulsos - mitad\n    return(t_pulsos)\n\n# x&#x5B;n] interpolacion en Ts, a muestreo fs\nt_pulsos = pulso_ti(muestras_n,fs,fs_veces,\n                    pulso_ancho,pulso_causal)\n\nhttps:\/\/blog.espol.edu.ec\/algoritmos101\/ss-unidades\/ss-u01\/senales-escalon-e-impulso\/\n#u = lambda t: np.piecewise(t,t&gt;=0,&#x5B;1,0])\nu = lambda t: np.heaviside(t,1)\n# pulso rectangular entre &#x5B;-(1\/fs)\/2,(1\/fs)\/2], no causal\nu1 = lambda t: u(t+Ts*dutyc\/2)\nu2 = lambda t: u(t-Ts*dutyc\/2)\nrectangular = lambda t: u1(t) - u2(t)             \n\n# unpulso muestreo\nt_unpulso = pulso_ti(1,fs,fs_veces,\n                     pulso_ancho,pulso_causal)\nt_pulsoEval= t_unpulso\nif pulso_causal:\n    t_pulsoEval = t_unpulso-Ts*pulso_ancho\/2\nunpulso = rectangular(t_pulsoEval)\nmuestras_pulso = len(t_unpulso)\n\n# reconstruye x(t) con pulsos\nmuestras_N = len(xki)\nmitad_pulso = int(muestras_pulso\/2)\npulsos_vacio = np.zeros(len(t_pulsos),dtype=float)\nxn_pulsos = np.copy(pulsos_vacio)\nxk_pulsos = &#x5B;]\nfor j in range(0,muestras_N,1): # x(t) pulsos\n    k0 = int(j*fs_veces)\n    kn = k0 + muestras_pulso\n    pulsoj = np.copy(pulsos_vacio)\n    pulsoj&#x5B;k0:kn]= pulsoj&#x5B;k0:kn] + unpulso*xki&#x5B;j]\n    xk_pulsos.append(pulsoj)\n    xn_pulsos = xn_pulsos+pulsoj\n    \n# SALIDA\nprint('fs:',fs,'Hz ; Ts:',Ts,' s')\nprint('pulso_causal:',pulso_causal,' : dutycycle:',dutyc)\nprint('muestras_pulso:',muestras_pulso)\nprint('t_unpulso:',t_unpulso)\nprint('muestras_tiempo:',len(t_pulsos))\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\">interpola pulso<\/a><\/p>\n\n\n\n<p><a href=\"#pulsorectangular\">pulso rectangular<\/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=\"#graficointeractivo\">interactiva<\/a><\/p>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"grafica\">3.1 Gr\u00e1fica con Python<\/h3>\n\n\n\n<p>Instrucci\u00f3nes adicionales al algoritmo anterior<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# GRAFICAS ----------------------------\nfig, &#x5B;graf_t,graf_n] = plt.subplots(2,1)\n\n# x(t) grafico entorno\nt_causal = 0\nif pulso_causal:\n    t_causal = Ts*pulso_ancho\/2\ngraf_t.axhline(0,color='black')\ngraf_t.axvline(0,color='black')\ngraf_t.set_xlabel('t')\ngraf_t.set_ylabel('amplitud')\ngraf_t.set_xlim(&#x5B;t_pulsos&#x5B;0]-t_causal,\n                 t_pulsos&#x5B;-1]-t_causal])\ngraf_t.grid()\ntexto = titulo + ' ; f0='+str(f0)\ntexto = texto + ' ; fs='+str(fs)\ntexto = texto + ' ; causal:'+str(pulso_causal)\ngraf_t.set_title(texto)\n# x(t) componentes\ngraf_t.plot(ti,xti,label='x(t)')\ngraf_t.stem(tki,xki,label='x&#x5B;n]',linefmt = 'C1:')\nfor i in range(0,muestras_N,1):\n    graf_t.plot(t_pulsos-t_causal,xk_pulsos&#x5B;i],\n                linestyle='dashed')\ngraf_t.legend()\n\n# x&#x5B;n] grafico entorno\ngraf_n.axhline(0,color='black')\ngraf_n.axvline(0,color='black')\ngraf_n.set_xlabel('t')\ngraf_n.set_ylabel('amplitud')\ngraf_n.set_xlim(&#x5B;t_pulsos&#x5B;0],t_pulsos&#x5B;-1]])\ngraf_n.grid()\n# x&#x5B;n] componentes\ngraf_n.plot(ti_0,xti_0,linestyle='dotted',\n            label='x(t)')\ngraf_n.stem(tkj,xki,label='x&#x5B;n]',linefmt = 'C1:')\ngraf_n.plot(t_pulsos,xn_pulsos,\n            label='x(t) pulso',\n            lw=2, color='orange')\n\ngraf_n.legend()\nplt.tight_layout()\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\">interpola pulso<\/a><\/p>\n\n\n\n<p><a href=\"#pulsorectangular\">pulso rectangular<\/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=\"#graficointeractivo\">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=\"graficointeractivo\">4. Algoritmo en Python para gr\u00e1fico interactivo con fs<\/h2>\n\n\n\n<p>Para fines did\u00e1cticos se a\u00f1ade un control en la gr\u00e1fica para la frecuencia de muestreo <strong>f<\/strong>s, con lo que observa mejor el efecto que sub-muestreo, sobre-muestreo y el uso de 2 veces la frecuencia usada en la se\u00f1al o Nyquist.<\/p>\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\/2024\/11\/InterpolaPulsoRectangular_animate.gif\" alt=\"Interpola Pulso Rectangular animate\" class=\"wp-image-20608\" \/><\/figure>\n\n\n\n<p>Cada cambio de fs tiene efectos sobre las muestras, el ancho de los pulsos y la reconstrucci\u00f3n de x(t). Por tal motivo se agrupan los c\u00e1lculos de x(t) y x[n] en una funci\u00f3n <code>xt_actualiza()<\/code>, y el proceso de reconstrucci\u00f3n y operaciones con x[n] como la funci\u00f3n <code>xn_actualiza()<\/code>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# D-to-C, Interpolacion con pulso rectangular\n# grafico interactivo\n# ejemplo 4.3.2 p142\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# INGRESO\n# se\u00f1al x(t)\nf0 = 83   # frecuencia de senal\nfase0 = 0 # &#x5B;0,2*np.pi]\nxt = lambda t: np.cos(2*np.pi*f0*t + fase0)\n\nfs = 200  # Hz muestreo\nfs_veces = 16 # suavizar x(t), sobremuestreo\nnT = 2.3  # graficar periodos de la se\u00f1al\n\ntitulo = 'Interpola x(t) pulso rectangular '\n# pulso rectangular\npulso_causal = True # No causal, pulso centrado en cero\npulso_ancho = 1\ndutyc = 1 # entre &#x5B;0,1] duty_cycle\n\ncasicero = 1e-10 # cero para valores menores\n\n# PROCEDIMIENTO\nTs = 1\/fs # tama\u00f1o de paso con fs\nT =  1\/f0 # periodo de se\u00f1al\ndtc = Ts\/fs_veces # suavizar x(t), sobremuestreo\n\ndef xt_actualiza(xt,f0,fs,fs_veces,nT,\n                 pulso_ancho=1,pulso_causal=True):\n    ''' x(t) muestreada a fs, para nT periodos de x(t).\n    gr\u00e1fica suavizada con fs_veces. No causal, pulso centrado en cero.\n    Causal el pulso inicia en t=0.\n    '''\n    Ts = 1\/fs # tama\u00f1o de paso con fs\n    T =  1\/f0 # periodo de se\u00f1al\n    dtc = Ts\/fs_veces # suavizar x(t), sobremuestreo\n\n    # muestreo x(t)\n    ti = np.arange(0,nT*T+dtc,dtc)\n    xti = xt(ti)\n    ti_max = max(ti)\n\n    # muestreo x&#x5B;n]\n    muestras_n = 2\n    if ti_max&gt;=Ts: # varias muestras\n        muestras_n = int(ti_max\/Ts)+1\n    ki  = np.arange(0,muestras_n,1,dtype=int)\n    tki = ki*Ts # muestras x&#x5B;n]\n    xki = xt(tki)\n    tkj = tki   # x&#x5B;n] alias0\n    ti_0 = ti   # No Causal, pulso centrado en cero\n    if pulso_causal: # Causal\n        tkj = tki + Ts*pulso_ancho\/2 \n        ti_0 = ti + Ts*pulso_ancho\/2\n    xti_0 = xti\n    return(ti,xti,tki,xki,tkj,ti_0,xti_0)\n\nxt_list = xt_actualiza(xt,f0,fs,fs_veces,nT,\n                       pulso_ancho,pulso_causal)\n&#x5B;ti,xti,tki,xki,tkj,ti_0,xti_0] = xt_list # x(t),x&#x5B;n],x(t)_alias0\nmuestras_n = len(tki)\n\ndef pulso_ti(muestras_n,fs,fs_veces,ancho=1,causal=True):\n    ''' tiempos para las n muestras x(t) con pulsos a frecuencia fs.\n    Para suavizar el pulso se usa fs_veces para el sobremuestreo.\n    El ancho del pulso es veces el periodo de muestreo (1\/Ts)\n    Si es causal el tiempo inicia en t=0, centrado en cero.\n    Si no es causal el tiempo inicia t en mitad de intervalo.\n    '''\n    Ts = 1\/fs # muestreo periodo\n    dtc = Ts\/fs_veces # suavizar pulso(t), sobremuestreo\n    t_Ts = np.arange(0,Ts,dtc) # tiempo en periodo Ts sobremuestreado\n    \n    mitad = Ts*ancho\/2\n    t_mitad = np.arange(0,mitad,dtc)\n    t_pulsos = np.copy(t_mitad) # mitad de primer pulso\n    for i in range(1,muestras_n,1):\n        t_pulsos = np.concatenate((t_pulsos,t_Ts + t_pulsos&#x5B;-1]+dtc))\n    # mitad de \u00faltimo pulso para muestra_n\n    t_pulsos = np.concatenate((t_pulsos,t_mitad + t_pulsos&#x5B;-1]+dtc))\n\n    # https:\/\/blog.espol.edu.ec\/algoritmos101\/senales\/ss-unidades\/ss-unidad-2\/\n    if causal == False: # centrado en cero\n        t_pulsos = t_pulsos - mitad\n    return(t_pulsos)\n\ndef xn_actualiza(fs,fs_veces,xki,dutyc,\n                 pulso_ancho=1,pulso_causal=True):\n    ''' x(t) reconstruida con pulsos\n    '''\n    Ts = 1\/fs # tama\u00f1o de paso con fs\n    T =  1\/f0 # periodo de se\u00f1al\n    dtc = Ts\/fs_veces # suavizar x(t), sobremuestreo\n\n    # https:\/\/blog.espol.edu.ec\/algoritmos101\/senales\/ss-unidades\/ss-unidad-1\/\n    #u = lambda t: np.piecewise(t,t&gt;=0,&#x5B;1,0])\n    u = lambda t: np.heaviside(t,1)\n    # pulso rectangular\n    #dutyc = 1 # entre &#x5B;0,1] duty_cycle\n    u1 = lambda t: u(t+Ts*dutyc\/2)\n    u2 = lambda t: u(t-Ts*dutyc\/2)\n    rectangular = lambda t: u1(t) - u2(t)\n\n    # x&#x5B;n] interpolacion en Ts, a muestreo fs\n    muestras_n = len(xki)\n    t_pulsos = pulso_ti(muestras_n,fs,fs_veces,\n                    pulso_ancho,pulso_causal)\n\n    # unpulso muestreo\n    t_unpulso = pulso_ti(1,fs,fs_veces,\n                         pulso_ancho,pulso_causal)\n    t_pulsoEval= t_unpulso\n    if pulso_causal:\n        t_pulsoEval = t_unpulso-Ts*pulso_ancho\/2\n    unpulso = rectangular(t_pulsoEval)\n    muestras_pulso = len(t_unpulso)\n\n    muestras_N = len(xki)\n    pulsos_vacio = np.zeros(len(t_pulsos),dtype=float)\n    xn_pulsos = np.copy(pulsos_vacio)\n    xk_pulsos = &#x5B;]\n    for j in range(0,muestras_N,1): # x(t) pulsos\n        k0 = int(j*fs_veces)\n        kn = k0 + muestras_pulso\n        pulsoj = np.copy(pulsos_vacio)\n        pulsoj&#x5B;k0:kn]= pulsoj&#x5B;k0:kn] + unpulso*xki&#x5B;j]\n        xk_pulsos.append(pulsoj)\n        xn_pulsos = xn_pulsos+pulsoj\n\n    return(t_pulsos,xn_pulsos,t_unpulso,unpulso)\n\nxn_list = xn_actualiza(fs,fs_veces,xki,dutyc,\n                       pulso_ancho,pulso_causal)\n&#x5B;t_pulsos,x_pulsos,t_unpulso,unpulso] = xn_list # x&#x5B;n] pulsos, pulso\n\n# SALIDA\nprint('fs:',fs,'Hz ; Ts:',Ts,' s')\nprint('pulso_causal:',pulso_causal,' : dutycycle:',dutyc)\nprint('muestras_pulso:',len(t_unpulso))\nprint('t_unpulso:',t_unpulso)\nprint('muestras_tiempo:',len(t_pulsos))\n\n# GRAFICAS  interactivas----------------------------\nfrom matplotlib.widgets import Slider, Button, TextBox\nimport telg1034 as dsp\ngraf_dx = 0.12 # margen en eje x\n\nfig, &#x5B;graf_t,graf_n] = plt.subplots(2,1)\n\n# x(t) grafico entorno\ngraf_t.axhline(0,color='black')\ngraf_t.set_xlabel('t')\ngraf_t.grid()\ntexto = titulo + ' ; f0='+str(f0)\ntexto = texto +' ; fs='+str(fs)\ngraf_t.set_title(texto)\n# x(t) componentes\nlinea_xt, = graf_t.plot(ti,xti,label='x(t)')\npuntos_xn = graf_t.stem(tki,xki,label='x&#x5B;n]',linefmt = 'C1:')\ngraf_t.set_xlim(&#x5B;t_pulsos&#x5B;0],ti&#x5B;-1]])\ngraf_t.legend()\n\n# x&#x5B;n] grafico entorno\ngraf_n.axhline(0,color='black')\ngraf_n.set_xlabel('t_n')\ngraf_n.grid()\n# x&#x5B;n] componentes\nlinea_xt0, = graf_n.plot(ti_0,xti_0,linestyle='dotted',\n                         label='x(t)')\npuntos_xki = graf_n.stem(tkj,xki,linefmt = 'C1:') #, label='x&#x5B;n]')\nlinea_x_pulsos, = graf_n.plot(t_pulsos,x_pulsos,label='x(t) pulsos')\nlinea_pulso, = graf_n.plot(t_unpulso,unpulso,\n                           label='pulso',linestyle='dashed',lw=2)\ngraf_n.set_xlim(&#x5B;t_pulsos&#x5B;0],ti&#x5B;-1]])\ngraf_n.legend()\n\nplt.tight_layout()\n# plt.show()\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                   (f0\/\/df_pasos)*df_pasos,\n                   (max(&#x5B;fs,10*f0])+2*df_pasos),\n                   valinit = fs, valstep = df_pasos,\n                   orientation='horizontal')\n\ndef grafico_actualiza(val):\n    # actualiza valores x,y\n    fs = fs_slider.val\n    \n    xt_list = xt_actualiza(xt,f0,fs,fs_veces,nT,\n                           pulso_ancho,pulso_causal)\n    &#x5B;ti,xti,tki,xki,tkj,ti_0,xti_0] = xt_list # x(t),x&#x5B;n],x(t)_alias0\n    dsp.stem_update(puntos_xn,tki,xki,graf_t) # x&#x5B;n]\n    dsp.stem_update(puntos_xki,tkj,xki,graf_n)\n    linea_xt0.set_xdata(ti_0) #x(t)_alias0\n    linea_xt0.set_ydata(xti_0)\n    \n    xn_list = xn_actualiza(fs,fs_veces,xki,dutyc,pulso_ancho,pulso_causal)\n    &#x5B;t_pulsos,x_pulsos,t_unpulso,unpulso] = xn_list # x&#x5B;n] pulsos, pulso\n    linea_x_pulsos.set_xdata(t_pulsos) # x&#x5B;n] pulsos\n    linea_x_pulsos.set_ydata(x_pulsos)\n    linea_pulso.set_xdata(t_unpulso) # pulso lti\n    linea_pulso.set_ydata(unpulso)\n\n    texto = titulo+' ; f0='+str(f0)\n    texto = texto +' ; fs='+str(fs)\n    graf_t.set_title(texto)\n    \n    graf_t.set_xlim(&#x5B;t_pulsos&#x5B;0],ti&#x5B;-1]])\n    graf_n.set_xlim(&#x5B;t_pulsos&#x5B;0],ti&#x5B;-1]])\n\n    fig.canvas.draw_idle() # actualiza figura\n\n# boton reinicio de gr\u00e1fica\nbtn_rstdonde = plt.axes(&#x5B;0.85, 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\">interpola pulso<\/a><\/p>\n\n\n\n<p><a href=\"#pulsorectangular\">pulso rectangular<\/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=\"#graficointeractivo\">interactiva<\/a><\/p>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n","protected":false},"excerpt":{"rendered":"<p>interpola pulso pulso rectangular algoritmo gr\u00e1fica interactiva 1. Interpolaci\u00f3n con Pulsos Referencia: McClellan 4-3.1 p141 Un&nbsp; sistema que convierte una se\u00f1al y[n] en forma Discreta a la forma Cont\u00ednua y(t), conocido como D-to-C,&nbsp; usa interpolaci\u00f3n para rellenar los espacios entre muestras. En el proceso se deben considerar efectos como el \"aliasing\" y \"folding\". La implementaci\u00f3n [&hellip;]<\/p>\n","protected":false},"author":8043,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"wp-custom-template-entrada-dsp-unidades","format":"standard","meta":{"footnotes":""},"categories":[193],"tags":[],"class_list":["post-554","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\/554","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=554"}],"version-history":[{"count":3,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/posts\/554\/revisions"}],"predecessor-version":[{"id":20610,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/posts\/554\/revisions\/20610"}],"wp:attachment":[{"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/media?parent=554"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/categories?post=554"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/tags?post=554"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}