4.2.1 Transformada de Laplace f(t) con Sympy



1. Transformada de Laplace en Sympy

Sympy ofrece la instrucción sym.laplace_transform(ft,t,s) para expresiones de f(t) con términos simples. La instrucción desarrolla el integral unilateral con t entre [0,∞], es decir con entradas tipo causal con t>0 o con términos μ(t) y los desplazados hacia la derecha μ(t-1).

Partiendo de las variable 't' y 's' como símbolos , se establece la expresión correspondiente en f(t) para determinar F(s). La transformada se obtiene al usar la instrucción:

Fs_L = sym.laplace_transform(ft,t,s)
Fs = Fs_L[0] # solo expresion

El resultado contiene la expresión, el valor de un polo del plano de convergencia y una condición de convergencia auxiliar. Para los objetivos de los ejercicios el enfoque es sobre el primer componente Fs = Fs_L[0].

Para simplificar el análisis y desarrollo de algoritmos, lo relacionado a polos y ceros se realiza en la sección de estabilidad del sistema con Python

Los ejercicios son de complejidad progresiva, mostrando la necesidad de partes adicionales en el algoritmo presentadas como funciones.



2. Transformada de Laplace de una exponencial decreciente, un solo termino

Transformada Laplace ft Ej01

Referencia: Lathi ejemplo 4.1. p331, Oppenheim Ejemplo 9.2 p656, Hsu Ejemplo 3.1 p111

Para una señal f(t),

f(t) = e^{-at} \mu (t)

se tiene la transformada F(s),

F(s) = \frac{1}{s+a}

Realizar la transformada con la instrucción directa de Sympy:

Siendo t una variable tipo símbolo, u la función escalón o Heaviside, la función f(t) para el algoritmo se expresa con las instrucciones:

u = sym.Heaviside(t)
ft = sym.exp(-a*t)*u

el resultado de la operación será:

 f(t): 
 -a⋅t     
ℯ    ⋅θ(t)

 F(s): 
  1  
─────
a + s

Se puede verificar el resultado en la Tabla para Transformada de Laplace

1.1 Algoritmo con Python de la Transformada de Laplace

La librería Sympy simplifica el proceso de la transformada de Laplace usado como en el integral descrito en la sección anterior.

# Transformadas de Laplace Unilateral con Sympy
# supone f(t) causal, usa escalón u(t)
import sympy as sym

# INGRESO
t = sym.Symbol('t', real=True)
a = sym.Symbol('a', real=True)
s = sym.Symbol('s')
u = sym.Heaviside(t)  # escalon unitario
d = sym.DiracDelta(t) # impulso unitario

ft = sym.exp(-a*t)*u

# PROCEDIMIENTO
ft = sym.expand(ft,t) # términos de suma
Fs_L = sym.laplace_transform(ft,t,s)
Fs = Fs_L[0] # solo expresion
Fs = sym.simplify(Fs)

# SALIDA
print('\n f(t): ')
sym.pprint(ft)
print('\n F(s): ')
sym.pprint(Fs)

El algoritmo es el primer ejemplo con las instrucciones Sympy, que es el punto de partida y guía para continuar con otros casos de ejercicios y las instrucciones que se añaden para cuando se usan más términos en f(t) y casos con desplazamiento en tiempo, etc.

Grafica de f(t) en Python

Las instrucciones para las gráficas se pueden simplificar para f(t), usando la instrucción de la función ss.graficar_ft() desarrollada en la unidad 3 desde 3.2.1 LTI CT y disponible en telg1001.py.

# GRAFICA ------------------
import numpy as np
import matplotlib.pyplot as plt
import telg1001 as ss

a_k = 2 # valor de 'a' constante
# Grafica, intervalo tiempo [t_a,t_b]
t_a = -1
t_b = 10
muestras = 101  # resolucion grafica

#grafica de f(t)
fig_ft = ss.graficar_ft(ft,t_a,t_b,
                        muestras = muestras,
                        f_nombre='f')
plt.show()


3. Transformada de Laplace para suma de términos f(t) con desplazamiento, o función «gate» o compuerta

Referencia: Lathi práctica 4.1.a p337

x(t) = \mu (t) - \mu (t-2)
Transformada Laplace ft Ej03 gate compuerta

Como el pulso rectangular, compuerta o "gate" se puede formar como la suma de señales escalón o "Heaviside", el bloque de ingreso se expresa como:

u = sym.Heaviside(t)
ft = u - u.subs(t,t-2)

Al aplicar el algoritmo anterior, modificando la expresión ft, la Transformada de Laplace muestra que el término desplazamiento tiene un componente exponencial.

 f(t): 
θ(t) - θ(t - 2)

 F(s): 
     -2⋅s
1   ℯ    
─ - ─────
s     s   
>>> 

Para considerar el término exponencial en el cálculo de polos,  se separa el ejercicio en partes con o sin  sym.exp(-a*s) cuando se realice el análisis de estabilidad del sistema.



4. Transformada de Laplace con cos(t)

Referencia: Oppenheim Ejemplo 9.4 p658

Encontrar la transformada de Laplace para:

x(t) = e^{-2t}\mu (t) + e^{-t} \cos (3t) \mu (t)
Transformada Laplace ft j05 cos(t)

Para el algoritmo, la expresión se escribe como

ft = sym.exp(-2*t)*u + sym.exp(-t)*sym.cos(3*t)*u

Al usar el algoritmo básico, se obtiene una respuesta que incluye raíces complejas que se expresa de forma diferente a la del libro,

 f(t): 
 -t                  -2⋅t     
ℯ  ⋅cos(3⋅t)⋅θ(t) + ℯ    ⋅θ(t)

 F(s): 
       1                 1            1  
─────────────── + ─────────────── + ─────
 2⋅(s + 1 + 3⋅ⅈ)    2⋅(s + 1 - 3⋅ⅈ)   s + 2

Una forma de simplificar la expresión, de tal forma que sea semejante a la respuesta teórica del libro es usar

Fs = sym.simplify(Fs)

con lo que se obtiene como resultado:

 f(t): 
 -t                  -2⋅t     
ℯ  ⋅cos(3⋅t)⋅θ(t) + ℯ    ⋅θ(t)

 F(s): 
      2              
   2⋅s  + 5⋅s + 12   
─────────────────────
 3      2            
s  + 4⋅s  + 14⋅s + 20
>>> 

Para disponer de expresiones mas simples de F(s) en fracciones parciales, se añade la instrucción

Fs = sym.apart(Fs) # separa en fracciones parciales

con lo que se obtiene el siguiente resultado para F(s),

 F(s): 
    s + 1         1  
───────────── + ─────
 2              s + 2
s  + 2⋅s + 10      
>>> 

El primer componente de la suma corresponde a la parte de sym.exp(-t)*sym.cos(3*t) y la segunda parte corresponde a sym.exp(-2*t)

Las instrucciones se añaden al algoritmo general en la seccion algoritmo Sympy



5. Transformada de Laplace con Impulso unitario δ(t) y suma de exponenciales

Referencia: Oppenheim ejemplo 9.5 p661

x(t) = \delta(t) -\frac{4}{3} e^{-t} \mu (t) + \frac{1}{3} e^{2t} \mu (t)

La expresión de f(t) podría escribirse directamente como:

d = sym.DiracDelta(t)
u = sym.Heaviside(t)
ft = d - (4/3)*sym.exp(-t)*u + (1/3)*sym.exp(2*t)*u

Al usar la instrucción sym.laplace_transform(ft,t,s)  convierte las fracciones a números reales o con decimales.

 f(t): 
                2⋅t                                 -t     
0.333333333333⋅ℯ   ⋅θ(t) + δ(t) - 1.33333333333⋅ℯ  ⋅θ(t)

 F(s): 
-s + (s - 2)⋅(s + 1) + 3.0
──────────────────────────
     (s - 2)⋅(s + 1) 

usando fracciones parciales se reescribe como:

sym.pprint(sym.apart(Fs))
      1.33333333333333   0.166666666666667
1.0 - ──────────────── + ─────────────────
           s + 1            0.5⋅s - 1.0   


Nota: Sympy hasta la versión 1.12.1, las operaciones en el dominio 's' para la Transformadas Inversas de Laplace se encuentran implementadas para manejar principalmente números enteros y fracciones. Los resultados de expresiones combinadas con coeficientes enteros y coeficientes reales no necesariamente se simplifican entre si, pues se manejan diferentes dominios 'ZZ' o 'QQ'. (Revisión 2023-Nov)

Para optimizar la simplificación de expresiones con coeficientes entre enteros y reales, los números reales se convierten a su aproximación racional con la instrucción sym.Rational(0.333333).limit_denominator(100).

u = sym.Heaviside(t)
d = sym.DiracDelta(t)

# coeficientes como racional en dominio 'ZZ' enteros
k1 = sym.Rational(1/3).limit_denominator(100)
k2 = sym.Rational(4/3).limit_denominator(100)

ft = d - k2*sym.exp(-t)*u + k1*sym.exp(2*t)*u

Convirtiendo los coeficientes a racionales, se define ft como:

 f(t): 
 2⋅t                  -t     
ℯ   ⋅θ(t)          4⋅ℯ  ⋅θ(t)
───────── + δ(t) - ──────────
    3                  3     

 F(s): 
 2          
s  - 2⋅s + 1
────────────
  2         
 s  - s - 2 

>>> sym.pprint(sym.apart(Fs))

F(s):
        4           1    
1 - ───────── + ─────────
    3⋅(s + 1)   3⋅(s - 2)
>>>


6. f(t) con Impulsos unitarios desplazados

Referencia:  Lathi Ej 4.9c p355

Considera la entrada x(t) como una suma de impulsos desplazados en tiempo y de diferente magnitud.

x(t) = \delta (t) - 3 \delta (t-2) + 2 \delta (t-3)
Transformada Laplace Ej07 suma de impulsos unitarios

para el algoritmo del ejercicio 4, se modifica la línea de ingreso a:

ft = d - 3*d.subs(t,t-2) + 2*d.subs(t,t-3)

obteniendo como resultado del algoritmo anterior:

 f(t): 
δ(t) + 2⋅δ(t - 3) - 3⋅δ(t - 2)

 F(s): 
       -2⋅s      -3⋅s
1 - 3⋅ℯ     + 2⋅ℯ   
>>> 



Algoritmo para versiones previas a 1.12.1 de Sympy

Para los siguientes ejercicios, se describen las ventajas y restricciones al usar las instrucciones de la librería Sympy, versión 1.12.1. En la que se pueden presentar partes en desarrollo con algunos inconveniente como los resuelto en la versión 1.12 22/11/2022 https://github.com/sympy/sympy/issues/24294

Para revisar la versión de Sympy se dispone de la instrucción:

sym.__version__                        
'1.12.1'
>>>

Se encuentra que en la versión 1.11.1, la instrucción sym.laplace_transform(ft,t,s) no ha procesado la constante cuando f(t) tiene mas de dos términos suma. El algoritmo presenta una función separa constante para solucionar ese inconveniente. La version 1.12.1 ya implementa esa corrección, segun lo revisado hasta 2025-Nov, según lo publicado en el enlace:

https://github.com/sympy/sympy/issues/23360

Para la versión 1.11.1, para obtener resultados e identificado el asunto, se creó una función separa_constante() para un término, donde se separa la constante como el término multiplicador de las partes (args) que no contienen la variable 't'.

    def separa_constante(termino):
        ''' separa constante antes de usar
            sym.laplace_transform(term_suma,t,s)
            para incorporarla luego de la transformada
            inconveniente revisado en version 1.11.1
        '''
        constante = 1
        if termino.is_Mul:
            factor_mul = sym.Mul.make_args(termino)
            for factor_k in factor_mul:
                if not(factor_k.has(t)):
                    constante = constante*factor_k
            termino = termino/constante
        return([termino,constante])

usando el resultado previo del algoritmo, se prueba la función con el último termino de la suma. Luego de separar la constante, se aplica la transformada de Laplace de Sympy y se incorpora la constante al resultado.

>>> k1 = sym.Rational(1/3).limit_denominator(100)
>>> ft = k1*sym.exp(2*t)*u
>>> sym.laplace_transform(ft,t,s)
(1/(s - 2), 2, True)
>>> [termino,constante] = separa_constante(ft)
>>> termino
exp(2*t)*Heaviside(t)
>>> constante
1/3
>>> sym.laplace_transform(termino,t,s)[0]*constante
1/(3*(s - 2))

En el ejemplo se muestra que es necesario separar la constante en al menos dos términos de suma, por lo que  se debe considerar el caso de que f(t) sea de uno o varios términos suma. Para simplificar el proceso en los próximos ejercicios se crea la función laplace_term_suma(ft) que se encargará de realizar el proceso término a término.

    ft = sym.expand(ft)  # expresion de sumas
    ft = sym.powsimp(ft) # simplifica exponentes

    term_suma = sym.Add.make_args(ft)
    Fs = 0
    for term_k in term_suma:
        [term_k,constante] = separa_constante(term_k)
        Fsk = sym.laplace_transform(term_k,t,s)
        Fs  = Fs + Fsk[0]*constante

Al incorporar las funciones al algoritmo, se puede verificar que se obtienen los resultados obtenidos en la forma analítica.

Algoritmo para versiones previas de Sympy 1.12.1

# Transformadas de Laplace Unilateral con Sympy
# Algoritmo para versiones previas de Sympy 1.12.1
# supone f(t) causal, usa escalón u(t)
import sympy as sym

# INGRESO
t = sym.Symbol('t', real=True)
s = sym.Symbol('s')
u = sym.Heaviside(t)
d = sym.DiracDelta(t)

# coeficientes como racional en dominio 'ZZ' enteros
k1 = sym.Rational(1/3).limit_denominator(100)
k2 = sym.Rational(4/3).limit_denominator(100)

ft = d - k2*sym.exp(-t)*u + k1*sym.exp(2*t)*u

#ft = d - 3*d.subs(t,t-2) + 2*d.subs(t,t-3)
#ft = k2*sym.exp(-2*t)*u - k1*sym.exp(-2*t)*u.subs(t,t-5)
#ft = k2*sym.exp(-2*t)*u.subs(t,t-5)
#ft = d.subs(t,t-2)
#ft = d
#ft = 3*sym.exp(-2*t)*u + sym.exp(-t)*sym.cos(3*t)*u
#ft = u
#ft = u - u.subs(t,t-2)
#ft = u.subs(t,t-2)

# PROCEDIMIENTO
def laplace_transform_suma(ft):
    '''transformada de Laplace de suma de terminos
       separa constantes para conservar en resultado
    '''
    def separa_constante(termino):
        ''' separa constante antes de usar
            sym.laplace_transform(term_suma,t,s)
            para incorporarla luego de la transformada
            inconveniente revisado en version 1.11.1
        '''
        constante = 1
        if termino.is_Mul:
            factor_mul = sym.Mul.make_args(termino)
            for factor_k in factor_mul:
                if not(factor_k.has(t)):
                    constante = constante*factor_k
            termino = termino/constante
        return([termino,constante])
    
    # transformadas de Laplace por términos suma
    ft = sym.expand(ft)  # expresion de sumas
    ft = sym.powsimp(ft) # simplifica exponentes

    term_suma = sym.Add.make_args(ft)
    Fs = 0
    for term_k in term_suma:
        [term_k,constante] = separa_constante(term_k)
        Fsk = sym.laplace_transform(term_k,t,s)
        Fs  = Fs + Fsk[0]*constante
    
    # separa exponenciales constantes
    Fs = sym.expand_power_exp(Fs)
    return(Fs)

Fs = laplace_transform_suma(ft)

# SALIDA
print('\n f(t): ')
sym.pprint(ft)
print('\n F(s): ')
sym.pprint(Fs)

Unidades SS