{"id":126,"date":"2024-10-14T08:10:19","date_gmt":"2024-10-14T13:10:19","guid":{"rendered":"http:\/\/blog.espol.edu.ec\/telg1034\/?p=126"},"modified":"2026-04-06T10:36:29","modified_gmt":"2026-04-06T15:36:29","slug":"espectro-suma-de-sinusoides","status":"publish","type":"post","link":"https:\/\/blog.espol.edu.ec\/algoritmos101\/dsp-unidades\/espectro-suma-de-sinusoides\/","title":{"rendered":"1.4 Espectro - Suma de sinusoides y la f\u00f3rmula de Euler con Sympy-Python"},"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=\"#espectro\">espectro<\/a><\/p>\n\n\n\n<p><a href=\"#ejercicio\">ejercicio<\/a><\/p>\n\n\n\n<p><a href=\"#analitico\">anal\u00edtico<\/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<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"espectro\">1. Espectro de una suma de sinusoides<\/h2>\n\n\n\n<p><em><strong>Referencia<\/strong><\/em>: McClellan 3.1 p70<\/p>\n\n\n\n<p>El m\u00e9todo mas general para construir nuevas se\u00f1ales a partir de sinusoides es la combinaci\u00f3n lineal, donde una se\u00f1al se compone de la suma de una constante y N sinusoides, cada una con diferente frecuencia, amplitud y fase.<\/p>\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> x(t) = A_0 + \\sum_{k =1}^{N} A_k \\cos ( 2 \\pi f_k t + \\varphi_k) <\/span>\n\n\n\n<p>que como exponenciales complejos<\/p>\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> x(t) = X_0 + \\sum_{k =1}^{N} \\Re \\Big\\{ X_k e^{ j 2 \\pi f_k t } \\Big\\} <\/span>\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> X_k = A_k e^{ \\varphi_k } <\/span>\n\n\n\n<p>donde X<sub>0<\/sub> = A<sub>0<\/sub> corresponde al componente de una constante real.<\/p>\n\n\n\n<p>La f\u00f3rmula inversa de Euler permite escribir la se\u00f1al x(t) como:<\/p>\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> x(t) = X_0 + \\sum_{k =1}^{N} \\Re \\Big\\{ \\frac{X_k}{2} e^{ j 2 \\pi f_k t} + \\frac{X_k^*}{2} e^{ -j 2 \\pi f_k t} \\Big\\} <\/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=\"#espectro\">espectro<\/a><\/p>\n\n\n\n<p><a href=\"#ejercicio\">ejercicio<\/a><\/p>\n\n\n\n<p><a href=\"#analitico\">anal\u00edtico<\/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<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ejercicio\">2. Ejercicio - Espectro de dos lados<\/h2>\n\n\n\n<p><em><strong>Referencia<\/strong><\/em>: McClellan ejemplo 3.1 p71<\/p>\n\n\n\n<p>Determine el espectro de la siguiente se\u00f1al.<\/p>\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> x(t) = 10 + 14 \\cos(200 \\pi t - \\pi\/3) + 8 cos(500 \\pi t + \\pi\/2) <\/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=\"#espectro\">espectro<\/a><\/p>\n\n\n\n<p><a href=\"#ejercicio\">ejercicio<\/a><\/p>\n\n\n\n<p><a href=\"#analitico\">anal\u00edtico<\/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<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"analitico\">3. Desarrollo anal\u00edtico<\/h2>\n\n\n\n<p>La expresi\u00f3n se separa en los componentes de cada t\u00e9rmino de la suma<\/p>\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> x_1(t) = 10 <\/span>\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> x_2(t) = 14 \\cos(200 \\pi t - \\pi\/3) <\/span>\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> x_3(t) = 8 cos(500 \\pi t + \\pi\/2) <\/span>\n\n\n\n<p>se escribe cada t\u00e9rmino en su forma exponencial<\/p>\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> x_1(t) = 10 e^{j0t} = 10<\/span>\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> x_2(t) = 7 e^{- j \\pi\/3} e^{j2\\pi(100) t} + 7 e^{j \\pi\/3} e^{-j 2 \\pi (100) t} <\/span>\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> x_3(t) = 4 e^{- j \\pi\/2} e^{j 2\\pi(250) t} + 4 e^{j \\pi\/2} e^{-j 2 \\pi (250) t} <\/span>\n\n\n\n<p>Para la gr\u00e1fica de espectro de se\u00f1al se requiere frecuencia, amplitud y fasor, que pueden construir con los par\u00e1metros de cada se\u00f1al usando la funci\u00f3n&nbsp; <code>dsp.cos_args_one_term(se\u00f1al)<\/code>.<\/p>\n\n\n\n<p>El resultado del algoritmo para el ejercicio es:<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>x_senales: \nsenal:   10\n  euler: 10\nsenal:   -8*sin(500*pi*t)\n  euler: 4*I*exp(500*I*pi*t) - 4*I*exp(-500*I*pi*t)\nsenal:   14*sin(200*pi*t + pi\/6)\n  euler: 7*exp(-I*pi\/3)*exp(200*I*pi*t) + 7*exp(I*pi\/3)*exp(-200*I*pi*t)\nx_espectro:\nfreq : &#091;-250. -100.    0.  100.  250.]\nampl : &#091;4 7 10 7 4]\nfase : &#091;-pi\/2 pi\/3 0 -pi\/3 pi\/2]\netiq : &#091;'$4$$ e^j(- \\\\frac{\\\\pi}{2})$' '$7$$ e^j(\\\\frac{\\\\pi}{3})$' '$10$'\n '$7$$ e^j(- \\\\frac{\\\\pi}{3})$' '$4$$ e^j(\\\\frac{\\\\pi}{2})$']<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/espectroSenales01.png\"><img loading=\"lazy\" decoding=\"async\" width=\"559\" height=\"445\" src=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/espectroSenales01.png\" alt=\"espectro de se\u00f1ales por frecuencia\" class=\"wp-image-131\" \/><\/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=\"#espectro\">espectro<\/a><\/p>\n\n\n\n<p><a href=\"#ejercicio\">ejercicio<\/a><\/p>\n\n\n\n<p><a href=\"#analitico\">anal\u00edtico<\/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<\/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\">4. Algoritmo con Python<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">4.1 Se\u00f1al suma de t\u00e9rminos<\/h3>\n\n\n\n<p>Para este ejercicio, la se\u00f1al es una suma de varios componentes: constantes y senoidales.<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code><span style=\"color: #ff0000\"># INGRESO<\/span>\nx0 = 10\nx1 = 14*sym.cos(200*pi*t - pi\/3)\nx2 = 8*sym.cos(500*pi*t + pi\/2)\nx = x0 + x1 + x2<\/code><\/pre>\n\n\n\n<p>Para simplificar el an\u00e1lisis como en los ejercicios anteriores se separan los t\u00e9rminos de la suma en una lista <code>x_senales<\/code>, al revisar si x es una suma <code>x.is_Add<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code><span style=\"color: #ff0000\"># Revisa expresi\u00f3n x(t)<\/span>\nx = sym.sympify(x) <span style=\"color: #ff0000\"># expresi\u00f3n a sympy, por si es constante<\/span>\nx = sym.expand(x) <span style=\"color: #ff0000\"># simplific parentesis (A + 3)*(cos(2*pi*f*t +w))<\/span>\n<span style=\"color: #d35400\">if<\/span> x.is_Add: <span style=\"color: #ff0000\"># separa t\u00e9rminos suma<\/span>\n    x_senales = <span style=\"color: #ff00ff\">list<\/span>(x.args)    \n<span style=\"color: #d35400\">else<\/span>:\n    x_senales = &#091;x]<\/code><\/pre>\n\n\n\n<p>Una se\u00f1al de la <code>x_senales<\/code> se convierte al formato Euler con las instrucciones<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>Xj = unasenal.rewrite(sym.exp)  <span style=\"color: #ff0000\"># Xj con forma Euler<\/span>\nXj = sym.expand(Xj)<\/code><\/pre>\n\n\n\n<p>Por ejemplo, si se usa x<sub>1<\/sub>(t), el resultado es la amplitud por la expresi\u00f3n Euler,<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>&gt;&gt;&gt; x1\n14*sin(200*pi*t + pi\/6)\n&gt;&gt;&gt; x1.rewrite(sym.exp)\n-7*I*(-exp(I*(-200*pi*t - pi\/6)) + exp(I*(200*pi*t + pi\/6)))<\/code><\/pre>\n\n\n\n<p>para disponer de t\u00e9rminos suma, se simplifica la expresi\u00f3n con:<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>&gt;&gt;&gt; sym.expand(x1.rewrite(sym.exp))\n-7*I*exp(I*pi\/6)*exp(200*I*pi*t) + 7*I*exp(-I*pi\/6)*exp(-200*I*pi*t)\n&gt;&gt;&gt;<\/code><\/pre>\n\n\n\n<p>Si se aplican las instrucciones dadas a cada se\u00f1al en <code>x_senales<\/code>, se obtiene <code>X_senales<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>x_senales: \nsenal:   10\n  euler: 10\nsenal:   -8*sin(500*pi*t)\n  euler: 4*I*exp(500*I*pi*t) - 4*I*exp(-500*I*pi*t)\nsenal:   14*sin(200*pi*t + pi\/6)\n  euler: 7*exp(-I*pi\/3)*exp(200*I*pi*t) + 7*exp(I*pi\/3)*exp(-200*I*pi*t)<\/code><\/pre>\n\n\n\n<p>Sympy simplifica autom\u00e1ticamente e<sup>(j \u03c0\/2)<\/sup> como <code>I<\/code> y&nbsp; e<sup>(-j \u03c0\/2)<\/sup> como <code>-I<\/code><\/p>\n\n\n\n<p>Las instrucciones en Python requieren los algoritmos <a href=\"https:\/\/blog.espol.edu.ec\/algoritmos101\/dsp-senales\/dsp-algoritmos-telg1034-py\/\" data-type=\"page\" data-id=\"18266\">telg1034.py<\/a>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# ejemplo 3.1 p71 x_senales a formato_euler\n# https:\/\/blog.espol.edu.ec\/algoritmos101\/dsp-senales\/\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport sympy as sym\nimport telg1034 as dsp\n\n# variables\nfrom telg1034 import t,A,w,f,p,pi,DosPi,I,equivalentes\n\n# INGRESO\nx0 = 10\nx1 = 14*sym.cos(200*pi*t - pi\/3)\nx2 = 8*sym.cos(500*pi*t + pi\/2)\nx = x0 + x1 + x2\n\n# PROCEDIMIENTO\n# Revisa expresi\u00f3n x(t)\nx = sym.sympify(x) # expresi\u00f3n a sympy, por si es constante\nx = sym.expand(x) # simplific parentesis (A + 3)*(cos(2*pi*f*t +w))\nif x.is_Add: # separa t\u00e9rminos suma\n    x_senales = list(x.args)    \nelse:\n    x_senales = &#x5B;x]\n# Analiza x_senales\nx_conteo = len(x_senales)\nX_senales = &#x5B;]\nfor i in range(0,x_conteo,1):\n    unasenal = x_senales&#x5B;i]\n    unasenal = sym.sympify(unasenal) # expresi\u00f3n a sympy, por si es constante\n    cond1 = unasenal.has(t)\n    cond2 = unasenal.has(sym.cos) or unasenal.has(sym.sin)\n    if cond1 and cond2: # tiene variable t y es senoidal\n        if unasenal.has(sym.sin): # evita sin()\n            unasenal = unasenal.rewrite(sym.cos)\n        Xj = unasenal.rewrite(sym.exp)  # Xj con forma Euler\n        Xj = sym.expand(Xj)\n    else: # es una constante\n        Xj = unasenal\n    X_senales.append(Xj)\n\n# SALIDA\nprint('x_senales: ')\nfor i in range(x_conteo):\n    print('senal:  ',x_senales&#x5B;i])\n    print('  euler:',X_senales&#x5B;i])\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">4.2. Espectro de frecuencia de dos lados<\/h3>\n\n\n\n<p>Para realizar la gr\u00e1fica de espectro de frecuencias, se requiere obtener las listas de <strong>frecuencia<\/strong>, <strong>amplitud<\/strong>, <strong>fase<\/strong> y etiquetas en un diccionario con las listas de valores correspondientes. La creaci\u00f3n de la gr\u00e1fica se simplifica al usar agrupar las instrucciones en una funci\u00f3n denominada <code><strong>cos_spectrum_list<\/strong>(<strong>x_senales<\/strong>)<\/code>, para obtener los resultados seg\u00fan lo indicado.<\/p>\n\n\n\n<p>Los argumentos de los t\u00e9rminos Euler se interpretan como frecuencia, amplitud y fase, se crea <code>euler_args_one_term(X)<\/code> a partir de lo realizado para la funci\u00f3n coseno. Considerando que para la <code>fase<\/code> es el factor multiplicador con <code>exp(<\/code>) sin variable <code>t<\/code>, puede ajustarse si aparece un factor con <code>I<\/code>, o puede considerar el signo en <code>-I<\/code>.<\/p>\n\n\n\n<p>Tambi\u00e9n, los procedimientos para convertir las se\u00f1ales a la forma Euler, se convierten en funciones de un solo t\u00e9rmino, <code><strong>cos_to_euler_one_term<\/strong>(x_senales)<\/code>, verificando que cada uno sea <strong><code>SinSumas<\/code><\/strong>. En caso de tener sumas se muestra un mensaje que indica los componentes de <code>x_senales<\/code> que requieran corregirse.<\/p>\n\n\n\n<p>El resultado del algoritmo para el ejercicio es:<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>x_senales: \nsenal:   10\n  euler: 10\nsenal:   -8*sin(500*pi*t)\n  euler: 4*I*exp(500*I*pi*t) - 4*I*exp(-500*I*pi*t)\nsenal:   14*sin(200*pi*t + pi\/6)\n  euler: 7*exp(-I*pi\/3)*exp(200*I*pi*t) + 7*exp(I*pi\/3)*exp(-200*I*pi*t)\nx_espectro:\nfreq : &#091;-250. -100.    0.  100.  250.]\nampl : &#091;4 7 10 7 4]\nfase : &#091;-pi\/2 pi\/3 0 -pi\/3 pi\/2]\netiq : &#091;'$4$$ e^j(- \\\\frac{\\\\pi}{2})$' '$7$$ e^j(\\\\frac{\\\\pi}{3})$' '$10$'\n '$7$$ e^j(- \\\\frac{\\\\pi}{3})$' '$4$$ e^j(\\\\frac{\\\\pi}{2})$']<\/code><\/pre>\n\n\n\n<p>Instrucciones en Python<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# ejemplo 3.1 p71 x_senales a formato_euler\n# https:\/\/blog.espol.edu.ec\/algoritmos101\/dsp-senales\/\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport sympy as sym\nimport telg1034 as dsp\n\n# variables\nfrom telg1034 import t,A,w,f,p,pi,DosPi,I,equivalentes\n\n# INGRESO\nx0 = 10\nx1 = 14*sym.cos(200*pi*t - pi\/3)\nx2 = 8*sym.cos(500*pi*t + pi\/2)\nx = x0 + x1 + x2\n\n# PROCEDIMIENTO\ndef x_list_term_Add(x):\n    ''' x(t) separa t\u00e9rminos como suma de componentes,\n    simplifica par\u00e9ntesis\n    '''\n    x = sym.sympify(x) # expresi\u00f3n a sympy, por si es constante\n    x = sym.expand(x) # simplifica par\u00e9ntesis (A + 3)*(cos(2*pi*f*t +w))\n    if x.is_Add: # separa t\u00e9rminos suma\n        x_senales = list(x.args)    \n    else:\n        x_senales = &#x5B;x]\n    return(x_senales)\n    \ndef cos_to_euler_one_term(x_senales):\n    ''' convierte lista x_senales a la forma Euler\n    entregando la lista X_senales de cada se\u00f1al en forma Euler\n    '''\n    x_conteo = len(x_senales)\n    X_senales = &#x5B;]\n    SinSumas = True # Analizar un solo cos o sin\n    SinSumas_cual = &#x5B;]\n    for i in range(0,x_conteo,1):\n        unasenal = x_senales&#x5B;i]\n        unasenal = sym.sympify(unasenal) # expresi\u00f3n a sympy, por si es constante\n        if unasenal.is_Add:\n            SinSumas = False\n        cond1 = unasenal.has(t)\n        cond2 = unasenal.has(sym.cos) or unasenal.has(sym.sin)\n        if cond1 and cond2 and SinSumas: # tiene variable t y es senoidal\n            if unasenal.has(sym.sin): # evita sin()\n                unasenal = unasenal.rewrite(sym.cos)\n            Xj = unasenal.rewrite(sym.exp)  # Xj con forma Euler\n            Xj = sym.expand(Xj)\n        else: # es una constante\n            Xj = unasenal\n        if not(SinSumas):\n            SinSumas_cual.append(i)\n        X_senales.append(Xj)\n    if SinSumas == False:\n        SinSumas_conteo = len(SinSumas_cual)\n        msg ='x_senales tiene '+str(SinSumas_conteo)+'suma de terminos,'\n        msg = msg + 'usar solo un t\u00e9rmino de la forma:'\n        msg = msg + '\\n A*cos(w*t+p) o tambi\u00e9n A*sin(w*t+p) ... \\n'\n        print('cos_to_euler_one_term:',x,msg)\n        for i in SinSumas_cual:\n            print('  revisar: ',x_senales&#x5B;i])\n    return(X_senales)\n\ndef cos_spectrum_list(x_senales):\n    '''dado una lista de se\u00f1ales de un solo t\u00e9rmino,\n    se obtiene la lista de frecuencias, amplitudes y etiquetas\n    para crear la gr\u00e1fica de espectro de frecuencias\n    '''\n    # Analiza x_senales\n    x_conteo = len(x_senales)\n    x_freq_spectr = &#x5B;] ; x_ampl_spectr = &#x5B;]\n    x_etiq_spectr = &#x5B;] ; x_fase_spectr = &#x5B;]\n    for i in range(0,x_conteo,1):\n        unasenal = x_senales&#x5B;i]\n        X_senal = unasenal.rewrite(sym.exp)\n        X_senal = sym.expand(X_senal)\n        if X_senal.is_Add:\n            X_senales = X_senal.args\n        else:\n            X_senales = &#x5B;X_senal]\n        for un_X in X_senales:\n            parametro = euler_args_one_term(un_X)\n            freq_k = float(parametro&#x5B;'freq_Hz'])\n            ampl_k = parametro&#x5B;'amplitud']\n            fase_k = parametro&#x5B;'fase']\n            x_freq_spectr.append(freq_k)\n            x_ampl_spectr.append(ampl_k)\n            x_fase_spectr.append(fase_k)\n            texto = '$' + sym.latex(ampl_k)+'$'\n            if fase_k!=sym.S.Zero:\n                texto = texto+f'$ e^j('+sym.latex(fase_k)+')$'\n            x_etiq_spectr.append(texto)\n    # ordenar por freq_Hz\n    x_freq_spectr = np.array(x_freq_spectr)\n    x_ampl_spectr = np.array(x_ampl_spectr)\n    x_etiq_spectr = np.array(x_etiq_spectr)\n    x_fase_spectr = np.array(x_fase_spectr)\n    orden = np.argsort(x_freq_spectr)\n    x_espectro = {'freq':x_freq_spectr&#x5B;orden],\n                  'ampl':x_ampl_spectr&#x5B;orden],\n                  'fase':x_fase_spectr&#x5B;orden],\n                  'etiq':x_etiq_spectr&#x5B;orden],}\n    return(x_espectro)\n\ndef euler_args_one_term(X):\n    ''' versi\u00f3n 1. Amplitud, frecuencia en Hz y rad, fase de exp()\n    referenciado a un t\u00e9rmino coseno.\n    Entrega diccionario con 'amplitud', 'freq_Hz','freq_rad','fase','periodo'.\n    '''\n    parametro={} # par\u00e1metros en diccionario\n    amplitud = sym.S.One ; T = sym.S.Zero ; fase =  sym.S.Zero\n    freq_Hz = sym.S.Zero ; freq_rad =  sym.S.Zero\n\n    X = sym.sympify(X) # expresi\u00f3n a sympy, por si es constante\n    X = sym.expand(X)  # expresi\u00f3n con al menos una suma\n    SinSumas = True # Analizar un solo exp()\n    if X.is_Add:\n        SinSumas = False\n\n    if SinSumas: # un solo termino: amplitud*exp(Iw*t+I*p)\n        #X = sym.powsimp(X)\n        partes = X.args\n        if len(partes)==0: # amplitud es una constante.\n            amplitud = X  # no tiene args\n        for unaparte in partes:\n            cond1 = unaparte.has(sym.exp)\n            cond2 = unaparte.has(t)\n            if cond1 and cond2: # exp(I*w*t+I*p)\n                argumento_exp = sym.expand(unaparte.args&#x5B;0]\/I)\n                &#x5B;freq_Hz,freq_rad,fase_k] = dsp._cos_arg_freqfase(argumento_exp)\n                fase = fase + fase_k\n            if cond1 and not(cond2): # exp(p*I)\n                argumento_exp = sym.expand(unaparte.args&#x5B;0]\/I)\n                fase = fase+argumento_exp\n            if not(cond1) and not(cond2): # amplitud\n                if not(unaparte.has(I)):\n                    amplitud = amplitud*unaparte\n                else: # amplitud*I o -amplitud*i\n                    amplitud = sym.expand(amplitud*unaparte\/I)\n                    fase = fase + pi\/2\n                    if amplitud&lt;0:\n                        amplitud = abs(amplitud)\n                        fase = fase - pi\n            if not(cond1) and cond2: # I*w*t+I*p\n                argumento_exp = sym.expand(unaparte\/I)\n                &#x5B;freq_Hz,freq_rad,fase] = dsp._cos_arg_freqfase(argumento_exp)\n                \n        # amplitud, revisi\u00f3n num\u00e9rica\n        if amplitud.is_Number:\n            if amplitud&lt;0: # amplitud con signo positivo\n                amplitud = np.abs(amplitud)\n                fase = fase + sym.pi\n            if isinstance(amplitud,sym.Float):\n                amplitud = float(amplitud)\n            if isinstance(amplitud,sym.Integer):\n                amplitud = int(amplitud)\n            # mantiene forma racional (a\/b) de amplitud\n        # periodo T\n        if freq_Hz != sym.S.Zero:\n            T = 1\/freq_Hz\n        else: # es una constante\n            T = sym.S.NaN\n    if not(X.has(t)): # es una constante\n        amplitud = X\n    # parametro fasor y fasor_complex\n    fasor = amplitud*sym.exp(I*fase)\n    fasor_complex = sym.expand(fasor,complex=True).evalf()\n    parametro&#x5B;'amplitud'] = amplitud\n    parametro&#x5B;'freq_Hz']  = freq_Hz\n    parametro&#x5B;'freq_rad'] = freq_rad\n    parametro&#x5B;'fase'] = fase\n    parametro&#x5B;'periodo'] = T\n    parametro&#x5B;'fasor'] = fasor\n    parametro&#x5B;'fasor_complex'] = fasor_complex\n                \n    if SinSumas == False:\n        msg ='x(t) tiene suma de terminos, usar solo un t\u00e9rmino de la forma:'\n        msg = msg + '\\n A*exp(I*(w*t+p)) o tambi\u00e9n A*exp(-I*(w*t+p)) ... \\n'\n        print('euler_args_one_term:',x,msg)\n    return(parametro)\n\n# operaciones con se\u00f1al x(t)\nx_senales = x_list_term_Add(x)\nx_conteo = len(x_senales)\nX_senales = cos_to_euler_one_term(x_senales)\nX_espectro = cos_spectrum_list(x_senales)\n\n# SALIDA\nprint('x_senales: ')\nfor i in range(x_conteo):\n    print('senal:  ',x_senales&#x5B;i])\n    print('  euler:',X_senales&#x5B;i])\nprint('x_espectro:')\nfor unparam in X_espectro:\n    print(unparam,':',X_espectro&#x5B;unparam])\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=\"#espectro\">espectro<\/a><\/p>\n\n\n\n<p><a href=\"#ejercicio\">ejercicio<\/a><\/p>\n\n\n\n<p><a href=\"#analitico\">anal\u00edtico<\/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<\/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\">5. Gr\u00e1fica de espectro de frecuencias<\/h2>\n\n\n\n<p>La gr\u00e1fica de espectro de frecuencias se obtiene con los datos de <code>x_espectro<\/code> realizado en el bloque anterior. Se incorpora cada fasor por frecuencia como las etiquetas creada por la funci\u00f3n <code>cos_spectrum_list(x_senales)<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter\"><a href=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/espectroSenales01.png\"><img loading=\"lazy\" decoding=\"async\" width=\"559\" height=\"445\" src=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2024\/11\/espectroSenales01.png\" alt=\"espectro de se\u00f1ales por frecuencia\" class=\"wp-image-131\" \/><\/a><\/figure>\n\n\n\n<p>Instrucciones adicionales para la gr\u00e1fica<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# GRAFICAS de espectro de frecuencias ---------\nfreq = X_espectro&#x5B;'freq']\nmagnitud = X_espectro&#x5B;'ampl']\netiqueta = X_espectro&#x5B;'etiq']\nmag_max = float(max(magnitud))\nfreq_max = float(max(freq))\n\n# grafica \ngraf_dx = 0.12\nfig_espectro = plt.figure()\ngraf_fasor = fig_espectro.add_subplot()\n# grafica magnitud\ngraf_fasor.set_xlim(&#x5B;-freq_max*(1+graf_dx),freq_max*(1+graf_dx)])\ngraf_fasor.set_ylim(&#x5B;0,mag_max*(1+graf_dx*2)])\ngraf_fasor.axhline(0,color='black')\ngraf_fasor.axvline(0,linestyle='dotted',color='grey')\ngraf_fasor.stem(freq,magnitud)\n# etiquetas de fasor\nfor k in range(0,len(freq),1):\n    texto = etiqueta&#x5B;k]\n    x_text = freq&#x5B;k]\n    y_text = magnitud&#x5B;k]\n    plt.annotate(texto,xy=(x_text,y_text), xytext=(0,5),\n                 textcoords='offset points',ha='center')\ngraf_fasor.grid()\ngraf_fasor.set_xlabel('freq Hz')\ngraf_fasor.set_ylabel('amplitud')\ngraf_fasor.set_title('Espectro: x_senales')\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=\"#espectro\">espectro<\/a><\/p>\n\n\n\n<p><a href=\"#ejercicio\">ejercicio<\/a><\/p>\n\n\n\n<p><a href=\"#analitico\">anal\u00edtico<\/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<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n","protected":false},"excerpt":{"rendered":"<p>espectro ejercicio anal\u00edtico algoritmo gr\u00e1fica 1. Espectro de una suma de sinusoides Referencia: McClellan 3.1 p70 El m\u00e9todo mas general para construir nuevas se\u00f1ales a partir de sinusoides es la combinaci\u00f3n lineal, donde una se\u00f1al se compone de la suma de una constante y N sinusoides, cada una con diferente frecuencia, amplitud y fase. que [&hellip;]<\/p>\n","protected":false},"author":8043,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"wp-custom-template-entrada-dsp-unidades","format":"standard","meta":{"footnotes":""},"categories":[193],"tags":[],"class_list":["post-126","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\/126","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=126"}],"version-history":[{"count":8,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/posts\/126\/revisions"}],"predecessor-version":[{"id":24101,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/posts\/126\/revisions\/24101"}],"wp:attachment":[{"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/media?parent=126"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/categories?post=126"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/tags?post=126"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}