{"id":17803,"date":"2017-04-18T11:00:07","date_gmt":"2017-04-18T16:00:07","guid":{"rendered":"http:\/\/blog.espol.edu.ec\/telg1001\/?p=4707"},"modified":"2026-04-06T10:18:33","modified_gmt":"2026-04-06T15:18:33","slug":"busca-impulso-escalon-unitario-sympy","status":"publish","type":"post","link":"https:\/\/blog.espol.edu.ec\/algoritmos101\/ss-u03\/busca-impulso-escalon-unitario-sympy\/","title":{"rendered":"3.6 Busca impulso unitario \u03b4(t) o escal\u00f3n unitario \u03bc(t) con Sympy-Python"},"content":{"rendered":"\n<p>En los sistemas lineales, la causalidad se muestra con respuestas para t\u22650, por lo que se usan t\u00e9rminos multiplicados por escal\u00f3n unitario \u03bc(t). Mientras que la respuesta al impulso genera al menos un t\u00e9rmino con impulso unitario&nbsp;\u03b4(t) con un coeficiente constante.<\/p>\n\n\n\n<p>Para el desarrollo de los ejercicios, es de gran utilidad disponer de una funci\u00f3n que permita buscar el impulso unitario dentro de una expresi\u00f3n de varios t\u00e9rminos. Listar las ubicaciones de los impulsos es un resultado que se usa en la generaci\u00f3n de gr\u00e1ficas, pues no siempre la muestra en el intervalo de tiempo usado se encuentra exactamente sobre la aplicaci\u00f3n del impulso unitario.<\/p>\n\n\n\n<p>Se propone usar dos funciones. una para encontrar d\u00f3nde ocurre el impulso y otra para buscar donde y el sentido del escal\u00f3n unitario.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">1. Busca impulso unitario, DiracDelta(t) o \u03b4(t) con Sympy<\/h2>\n\n\n\n<p>Si f(t) fuese solo \u03b4(t), \u03b4(t-1) o \u03b4(t+1), el valor de desplazamiento de obtiene con el primer argumento de la funci\u00f3n mediante ft.args[0] que al evaluarlo en cero y multiplicarlo por (-1) se tendr\u00eda <code>donde<\/code> se aplica.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ecuacion = sym.Eq(ft.args&#091;0],0)\ndonde = sym.solve(ecuacion,t)<\/code><\/pre>\n\n\n\n<p>Para los casos como \u03b4(-t-1), \u03b4(-t+1) es necesario trabajar con el signo de la variable <code>t<\/code>. Una forma de evaluar la expresi\u00f3n interiores de los impulsos es obtener la ecuaci\u00f3n de la forma <code>at+b=0<\/code> con <code>sym.Eq(ft.args[0],0)<\/code> y luego despejar el valor de <code>t<\/code> con la instrucci\u00f3n <code>sym.solve(ecuacion,t)<\/code>.<\/p>\n\n\n\n<p>En expresiones simples de un solo t\u00e9rmino con coeficientes, se tiene:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>h = 2*sym.pi*d.subs(t,t-2)<\/code><\/pre>\n\n\n\n<p>con resultados como:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>h(t):\n2*pi*DiracDelta(t - 2)\nbusca_impulso(h):  &#091;2]<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"545\" height=\"437\" src=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2017\/04\/busca_impulso_sympy_01.png\" alt=\"busca impulso Sympy 01\" class=\"wp-image-19669\" \/><\/figure>\n\n\n\n<p>En el caso que se usen t\u00e9rminos de varios impulsos, el valor de inter\u00e9s se encuentra usando el m\u00ednimo de la lista <code>donde<\/code> y observando que a\u00fan sea \u22650.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>h = d.subs(t,t-1) + 2*sym.pi*d.subs(t,t-2)<\/code><\/pre>\n\n\n\n<p>con resultado esperado de algoritmo<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>h(t):\n2*pi*DiracDelta(t - 2) + DiracDelta(t - 1)\nbusca_impulso(h):  &#091;1, 2]<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"544\" height=\"436\" src=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2017\/04\/busca_impulso_sympy_02.png\" alt=\"busca impulso Sympy 02\" class=\"wp-image-19671\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Algoritmo en Python<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# Busca impulso unitario en h(t)\n# https:\/\/blog.espol.edu.ec\/algoritmos101\/senales\/ss-unidades\nimport sympy as sym\nimport matplotlib.pyplot as plt\nimport telg1001 as ss\n\n# INGRESO\nt = sym.Symbol('t',real=True)\nu = sym.Heaviside(t)\nd = sym.DiracDelta(t)\na = sym.Symbol('a',real=True)\n\n# busca impulso en h(t)\n# h = d\n# h = 2*sym.pi*d.subs(t,t-2)\nh = d.subs(t,t-1) + 2*sym.pi*d.subs(t,t-2)\n# h = 3*d.subs(t,t+1)\n# h = 5*sym.exp(-t)*d\n# h = 4\n\n# grafica intervalo &#x5B;t_a,t_b] simetrico a 0\nt_b = 4 ; t_a = -t_b\nmuestras = 51\n\n# PROCEDIMIENTO\ndef busca_impulso(ft):\n    ''' busca en f(t) impulsos sym.DiracDelta\n        entrega una lista ordenada de resultados\n    '''\n    def impulso_donde(ft):\n        ''' busca posicion de impulso en ft simple d, d**2\n            un solo termino,sin factores\n        '''\n        ft = sym.sympify(ft,t) # convierte a sympy si es constante\n        donde = &#x5B;] # revisar f(t) sin impulsos\n        if ft.has(sym.DiracDelta):\n            if not(ft.is_Pow): # sin exponentes\n                ecuacion = sym.Eq(ft.args&#x5B;0],0)\n            else: # con exponentes d**2\n                ecuacion = sym.Eq(ft.args&#x5B;0].args&#x5B;0],0)\n            donde = sym.solve(ecuacion,t)\n        return(donde)\n    \n    def impulso_donde_unterm(ft):\n        ''' revisa impulso en un termino suma de ft\n        '''\n        donde = &#x5B;] # revisar f(t) sin impulsos\n        factor_mul = sym.Mul.make_args(ft)\n        for factor_k in factor_mul:\n            if factor_k.has(sym.DiracDelta):\n                donde_k = impulso_donde(factor_k)\n                if len(donde) == 0: # vacio\n                    donde.extend(donde_k)\n                if len(donde)&gt;0: # sin repetir\n                    if not(donde_k&#x5B;0] in donde): \n                        donde = &#x5B;] # anulado por d(t-a)*d(t-b)\n        return(donde)\n\n    # revisa terminos suma\n    ft = sym.sympify(ft,t) # convierte a sympy si es constante\n    ft = sym.expand(ft)\n    respuesta = &#x5B;]\n    term_suma = sym.Add.make_args(ft)\n    for term_k in term_suma:\n        donde = impulso_donde_unterm(term_k)\n        if not(donde in respuesta) and len(donde)&gt;0:\n            respuesta.extend(donde)\n    if len(respuesta)&gt;1: # ordena ascendente\n        respuesta.sort()\n    respuesta = list(respuesta)\n    return(respuesta)\n\ndonde_d = busca_impulso(h)\n\n# SALIDA\nprint('h(t):')\nsym.pprint(h)\nprint('busca_impulso(h): ',donde_d)\n\n# Grafica\nfigura_h = ss.graficar_ft(h,t_a,t_b,muestras,f_nombre='h')\nplt.show()\n<\/pre><\/div>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Busca escal\u00f3n unitario, Heaviside(t) o \u03bc(t) con Sympy<\/h2>\n\n\n\n<p>Para pruebas se tienen algunas expresiones de h(t), recordando que se analiza expresiones de un solo t\u00e9rmino, sin sumas o multiplicaciones.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># entrada x(t)\n# h = u\nh = u.subs(t,t-1)\n# h = u.subs(t,t+1)\n# h = 5<\/code><\/pre>\n\n\n\n<p>Semejante al ejemplo anterior, se busca d\u00f3nde se produce la transici\u00f3n del escal\u00f3n unitario y el sentido si es de subida o de bajada como el signo de 't'.<\/p>\n\n\n<span class=\"wp-katex-eq katex-display\" data-display=\"true\"> \\frac{d}{dt}\\mu (t) = \\delta(t) <\/span>\n\n\n\n<p>Con la funci\u00f3n busca_impulso() obtiene <em><strong>donde<\/strong><\/em> se produce el impulso.<\/p>\n\n\n\n<p>El sentido del escal\u00f3n se obtiene al derivar la expresi\u00f3n del argumento. Si el escal\u00f3n se desarrolla hacia de <em><strong>donde<\/strong><\/em> se produce, ser\u00e1 positivo, y hacia la izquierda ser\u00e1 negativo. Al aplicar <code>escalon_donde(ft)<\/code> permite determinar el punto de subida y bajada.<\/p>\n\n\n\n<p>Para determinar el sentido del escal\u00f3n unitario, se procede a tomar la expresi\u00f3n del argumento <code>ft.args[0]<\/code> y luego derivar&nbsp;con la&nbsp; instrucci\u00f3n <code>sym.diff(ft.args[0])<\/code> para obtener el <code>signo_t<\/code>. con esto se observa si el desarrollo es hacia el lado derecho del plano (RHS). Con los par\u00e1metros de donde y el sentido del escal\u00f3n se puede aplicar un criterio de causalidad.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n    def escalon_donde(ft):\n        ''' ft sin factores o terminos suma\n        '''\n        ft = sym.sympify(ft,t) # convierte a sympy si es constante\n        respuesta = &#x5B;]\n        if ft.has(sym.Heaviside):\n            eq_u      = sym.Eq(ft.args&#x5B;0],0)\n            sentido   = sym.diff(eq_u.lhs,t,1)\n            donde     = sym.solve(eq_u,t)&#x5B;0]\n            respuesta = &#x5B;donde,sentido]\n        return(respuesta)\n<\/pre><\/div>\n\n\n<p>Algoritmo en Python<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# Busca escalon unitario en h(t)\n# https:\/\/blog.espol.edu.ec\/algoritmos101\/senales\/ss-unidades\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport sympy as sym\nequivalentes = &#x5B;{'DiracDelta': lambda x: 1*(x==0)},\n                {'Heaviside': lambda x,y: np.heaviside(x, 1)},\n                'numpy',]\nimport telg1001 as ss\n\n# INGRESO\nt = sym.Symbol('t',real=True)\nk = sym.Symbol('k',real=True)\nu = sym.Heaviside(t)\nd = sym.DiracDelta(t)\n\n# entrada h(t)\n# h = u\nh = u.subs(t,t-1)\n# h = u.subs(t,t+1)\n# h = 5\n# h = u + d\n# h = 3*sym.pi*u.subs(t,t-1)+ 2*d\n# h = sym.exp(-2*t)*u.subs(t,t+1) + sym.exp(-4*t)*u.subs(t,t-3)\n# h = sym.exp(-2*t)*sym.cos(t) + 4\n\n# h = u.subs(t,-t+2)*u.subs(t,-t+1)\n# h = u.subs(t,-t+1)*u.subs(t,-t+1)\n# h = 3*u.subs(t,-t+1)*u.subs(t,-t+1)\n# h = u.subs(t,t-1)-u.subs(t,t-2)\n\n# grafica intervalo &#x5B;t_a,t_b] simetrico a 0\nt_b = 4 ; t_a = -t_b\nmuestras = 51\n\n# PROCEDIMIENTO\ndef busca_escalon(ft):\n    ''' busca en f(t) el donde,sentido de escalon unitario\n        en un termino simple  sin sumas, para ubicar\n        lado del plano de f(t)\n    '''\n    \n    def escalon_donde(ft):\n        ''' ft sin factores o terminos suma\n        '''\n        ft = sym.sympify(ft,t) # convierte a sympy si es constante\n        respuesta = &#x5B;]\n        if ft.has(sym.Heaviside):\n            eq_u      = sym.Eq(ft.args&#x5B;0],0)\n            sentido   = sym.diff(eq_u.lhs,t,1)\n            donde     = sym.solve(eq_u,t)&#x5B;0]\n            respuesta = &#x5B;donde,sentido]\n        return(respuesta)\n\n    def escalon_donde_unterm(ft):\n        '''revisa termino de factores multiplica\n        '''\n        respuesta = &#x5B;]\n        factor_mul = sym.Mul.make_args(ft)\n        for factor_k in factor_mul:\n            if factor_k.has(sym.Heaviside):\n                ubicado = &#x5B;]\n                if not(factor_k.is_Pow): # sin exponente\n                    ubicado = escalon_donde(factor_k)\n                else:  # con exponentes d**k\n                    ubicado = escalon_donde(factor_k.args&#x5B;0])\n                if len(ubicado)&gt;0:\n                    respuesta.append(ubicado)\n        return(respuesta)\n        \n    # revisa terminos suma\n    ft = sym.sympify(ft,t) # convierte a sympy si es constante\n    ft = sym.expand(ft)\n    respuesta = &#x5B;]\n    term_suma = sym.Add.make_args(ft)\n    for term_k in term_suma:\n        donde = escalon_donde_unterm(term_k)\n        if not(donde in respuesta) and len(donde)&gt;0:\n            respuesta.extend(donde)\n    if len(respuesta)&gt;1: # ordena ascendente\n        respuesta = np.array(respuesta)\n        columna   = respuesta&#x5B;:,0]\n        ordena    = np.argsort(columna)\n        respuesta = respuesta&#x5B;ordena]\n\n    return(respuesta)\n\ndonde_u = busca_escalon(h)\n\n# SALIDA\nprint('h(t):')\nsym.pprint(h)\nprint('busca_impulso:',ss.busca_impulso(h))\nif len(donde_u)&lt;=1:\n    print('busca_escalon:',donde_u)\nelse:\n    print('busca_escalon:')\n    print(busca_escalon(h))\n\n# Grafica\nfigura_h = ss.graficar_ft(h,t_a,t_b,f_nombre='h')\nplt.show()\n<\/pre><\/div>\n\n\n<p>Las funciones se las incorpora a los <a href=\"https:\/\/blog.espol.edu.ec\/algoritmos101\/senales\/algoritmos-telg1001-py\/\" data-type=\"page\" data-id=\"17852\">algoritmos telg1001.py<\/a><\/p>\n\n\n\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En los sistemas lineales, la causalidad se muestra con respuestas para t\u22650, por lo que se usan t\u00e9rminos multiplicados por escal\u00f3n unitario \u03bc(t). Mientras que la respuesta al impulso genera al menos un t\u00e9rmino con impulso unitario&nbsp;\u03b4(t) con un coeficiente constante. Para el desarrollo de los ejercicios, es de gran utilidad disponer de una funci\u00f3n [&hellip;]<\/p>\n","protected":false},"author":8043,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"wp-custom-template-entrada-ss-unidades","format":"standard","meta":{"footnotes":""},"categories":[171],"tags":[],"class_list":["post-17803","post","type-post","status-publish","format-standard","hentry","category-ss-u03"],"_links":{"self":[{"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/posts\/17803","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=17803"}],"version-history":[{"count":5,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/posts\/17803\/revisions"}],"predecessor-version":[{"id":24088,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/posts\/17803\/revisions\/24088"}],"wp:attachment":[{"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/media?parent=17803"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/categories?post=17803"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/tags?post=17803"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}