7.1.3 Transformada z unilateral e inversa con Sympy-Python

Referencia: Tabla de transformadas z: Lathi Tabla 5.1 Transformada z p492. Oppenheim tabla 10.2 p776, Schaum Hsu Tabla 4-1 p170. Propiedades:  Schaum Hsu Tabla 4-2 p173. Lathi Tabla 5.2 p509. Oppenheim Tabla 10.3 p793

Usando los algoritmos presentados para transformadas z a partir de la tabla y propiedades, se incorpora en la instrucción z_transform(f,n,z) incorporada en telg1001.py. Para demostración se desarrollan algunos ejemplos que se desarrollan a partir de la tabla de transformadas z.

Transformada z de impulso unitario δ(t)

>>> import sympy as sym
>>> import telg1001_z as fcnm
>>> n = sym.Symbol('n', real=True)
>>> z = sym.Symbol('z')
>>> d = sym.DiracDelta(n)
>>> f = d
>>> fcnm.z_transform(f,n,z)
1
>>>

Transformada z de impulso unitario desplazado δ(t-2) y δ(t+2)

>>> fcnm.z_transform(f.subs(n,n-2),n,z)
z**(-2)
>>> fcnm.z_transform(f.subs(n,n+2),n,z)
z**2
>>>

Tabla de Transformadas z unilateral e Inversas usando algoritmo en telg1001.py

Para comprobar las transformadas de los algoritmos presentados e integrados en telg1001.py, se crea una tabla con expresiones f[n] de prueba en el dominio n de tiempo discreto.

Al resultado se aplica la inversa de F[z] que muestra que la expresión es invertible usando la transformada z unilateral.

El resultado del algoritmo se muestra a continuación y luego el algoritmo.

z_transform :  0
  f[n]: DiracDelta(n)
  F[z]: (1, True, True)
  f[n]: (DiracDelta(n), True, True)

z_transform :  1
  f[n]: DiracDelta(n - 2)
  F[z]: (z**(-2), Abs(z) > 0, True)
  f[n]: (DiracDelta(n - 2), True, True)

z_transform :  2
  f[n]: DiracDelta(n + 2)
  F[z]: (z**2, True, True)
  f[n]: (DiracDelta(n + 2), True, True)

z_transform :  3
  f[n]: 3*DiracDelta(n + 2)
  F[z]: (3*z**2, True, True)
  f[n]: (3*DiracDelta(n + 2), True, True)

z_transform :  4
  f[n]: -3*DiracDelta(n + 2)
  F[z]: (-3*z**2, True, True)
  f[n]: (-3*DiracDelta(n + 2), True, True)

z_transform :  5
  f[n]: Heaviside(n)
  F[z]: (z/(z - 1), Abs(z) > 1, True)
  f[n]: (Heaviside(n), Abs(z) > 1, True)

z_transform :  6
  f[n]: Heaviside(n - 2)
  F[z]: (1/(z*(z - 1)), Abs(z) > 1, True)
  f[n]: [None, [1/(z*(z - 1))]]

z_transform :  7
  f[n]: Heaviside(n + 2)
  F[z]: (z**3/(z - 1), Abs(z) > 1, True)
  f[n]: (Heaviside(n + 2), Abs(z) > 1, True)

z_transform :  8
  f[n]: 3*Heaviside(n + 2)
  F[z]: (3*z**3/(z - 1), Abs(z) > 1, True)
  f[n]: (3*Heaviside(n + 2), Abs(z) > 1, True)

z_transform :  9
  f[n]: n*Heaviside(n)
  F[z]: (z/(z - 1)**2, Abs(z) > 1, True)
  f[n]: (n*Heaviside(n), Abs(z) > 1, True)

z_transform :  10
  f[n]: n**2*Heaviside(n)
  F[z]: (z*(z + 1)/(z - 1)**3, Abs(z) > 1, True)
  f[n]: (n**2*Heaviside(n), Abs(z) > 1, True)

z_transform :  11
  f[n]: n**3*Heaviside(n)
  F[z]: (z*(z**2 + 4*z + 1)/(z - 1)**4, Abs(z) > 1, True)
  f[n]: (n**3*Heaviside(n), Abs(z) > 1, True)

z_transform :  12
  f[n]: 0.5**n*Heaviside(n)
  F[z]: (z/(z - 0.5), Abs(z) > 0.5, True)
  f[n]: (0.5**n*Heaviside(n), Abs(z) > 0.5, True)

z_transform :  13
  f[n]: 0.5**n*Heaviside(n)
  F[z]: (z/(z - 0.5), Abs(z) > 0.5, True)
  f[n]: (0.5**n*Heaviside(n), Abs(z) > 0.5, True)

z_transform :  14
  f[n]: Heaviside(n)/4**n
  F[z]: (z/(z - 1/4), Abs(z) > 1/4, True)
  f[n]: (Heaviside(n)/4**n, Abs(z) > 1/4, True)

z_transform :  15
  f[n]: -0.5**n*Heaviside(-n - 1)
  F[z]: (z/(z - 0.5), Abs(z) < 0.5, True) f[n]: (0.5**n*Heaviside(n), Abs(z) > 0.5, True)

z_transform :  16
  f[n]: 0.5**(n - 1)*Heaviside(n - 1)
  F[z]: (1.0/(z - 0.5), Abs(z) > 0.5, True)
  f[n]: [None, [1/(z - 0.5)]]

z_transform :  17
  f[n]: 4**(1 - n)*Heaviside(n - 1)
  F[z]: (1/(z - 1/4), Abs(z) > 1/4, True)
  f[n]: [None, [1/(z - 1/4)]]

z_transform :  18
  f[n]: 0.5**n*n*Heaviside(n)
  F[z]: (0.5*z/(z - 0.5)**2, Abs(z) > 0.5, True)
  f[n]: (0.5**n*n*Heaviside(n), Abs(z) > 0.5, True)

z_transform :  19
  f[n]: -0.5**n*n*Heaviside(-n - 1)
  F[z]: (0.5*z/(z - 0.5)**2, Abs(z) < 0.5, True) f[n]: (0.5**n*n*Heaviside(n), Abs(z) > 0.5, True)

z_transform :  20
  f[n]: 0.5**n*(n + 1)*Heaviside(n)
  F[z]: z/(z - 0.5) + 0.5*z/(z - 0.5)**2
  f[n]: (2*0.5**(n + 1)*(n + 1)*Heaviside(n + 1), Abs(z) > 0.5, True)

z_transform :  21
  f[n]: 0.5**n*n**2*Heaviside(n)
  F[z]: (0.5*z*(z + 0.5)/(z - 0.5)**3, Abs(z) > 0.5, True)
  f[n]: (0.5**n*n**2*Heaviside(n), Abs(z) > 0.5, True)

z_transform :  22
  f[n]: 1.33333333333333*0.5**n*n*(n - 2)*(n - 1)*Heaviside(n)
  F[z]: 1.33333333333333*z/(z - 0.5)**2 - 2*z*(z + 0.5)/(z - 0.5)**3 + 0.666666666666667*z*(z**2 + 2*z + 0.25)/(z - 0.5)**4
  f[n]: (1.33333333333333*0.5**n*n*(n - 2)*(n - 1)*Heaviside(n), Abs(z) > 1, 0)

z_transform :  23
  f[n]: cos(2*n)*Heaviside(n)
  F[z]: (z*(z - cos(2))/(z**2 - 2*z*cos(2) + 1), Abs(z) > 1, True)
  f[n]: (cos(2*n)*Heaviside(n), Abs(z) > 1, True)

z_transform :  24
  f[n]: 0.5**n*cos(2*n)*Heaviside(n)
  F[z]: (z*(z - 0.5*cos(2))/(z**2 - z*cos(2) + 0.25), Abs(z) > 0.5, True)
  f[n]: (0.5**n*cos(2*n)*Heaviside(n), Abs(z) > 0.5, True)

z_transform :  25
  f[n]: sin(2*n)*Heaviside(n)
  F[z]: (z*sin(2)/(z**2 - 2*z*cos(2) + 1), Abs(z) > 1, True)
  f[n]: (sin(2*n)*Heaviside(n), Abs(z) > 1, True)

z_transform :  26
  f[n]: 0.5**n*sin(2*n)*Heaviside(n)
  F[z]: (0.5*z*sin(2)/(z**2 - z*cos(2) + 0.25), Abs(z) > 0.5, True)
  f[n]: (0.5**n*sin(2*n)*Heaviside(n), Abs(z) > 0.5, True)

z_transform :  27
  f[n]: cos(2*n + 0.25)*Heaviside(n)
  F[z]: (z*(z*cos(0.25) - cos(1.75))/(z**2 - 2*z*cos(2) + 1), Abs(z) > 1, True)
  f[n]: (1.0*cos(2*n + 0.25)*Heaviside(n), Abs(z) > 1, True)

z_transform :  28
  f[n]: 3*0.5**n*cos(2*n + 0.25)*Heaviside(n)
  F[z]: (3*z*(z*cos(0.25) - 0.5*cos(1.75))/(z**2 - z*cos(2) + 0.25), Abs(z) > 0.5, True)
  f[n]: (3.0*0.5**n*cos(2*n + 0.25)*Heaviside(n), Abs(z) > 0.5, True)

Algoritmo en Python

Las intrucciones se pueden modificar para observar una expresión en detalle si se activa la variable sym.SYMPY_DEBUG=True. Por la extensión del resultado se recomienda activarla para una expresión.

import sympy as sym
import telg1001 as fcnm
sym.SYMPY_DEBUG = False

# INGRESO
n = sym.Symbol('n')
z = sym.Symbol('z')
u = sym.Heaviside(n)
d = sym.DiracDelta(n)

a0 = sym.Rational(1,4).limit_denominator(100)

tabla = [
           d,
           d.subs(n,n-2),
           d.subs(n,n+2),
           3*d.subs(n,n+2),
           -3*d.subs(n,n+2),
           u,
           u.subs(n,n-2),
           u.subs(n,n+2),
           3*u.subs(n,n+2),
           n*u,
           (n**2)*u,
           (n**3)*u,
           0.5**n*u,((1/2)**n)*u,(a0**n)*u,
           -(0.5**n)*u.subs(n,-n-1),
           (0.5**(n-1))*u.subs(n,n-1),
           (a0**(n-1))*u.subs(n,n-1),
           n*(0.5**n)*u,
           -n*(0.5**n)*u.subs(n,-n-1),
           (n+1)*(0.5**n)*u,
           n**2*(0.5**n)*u,
           n*(n-1)*(n-2)*(0.5**n)*u/((0.5**3)*6),
           sym.cos(2*n)*u,
           (0.5**n)*sym.cos(2*n)*u,
           sym.sin(2*n)*u,
           (0.5**n)*sym.sin(2*n)*u,
           sym.cos(2*n+0.25)*u,
           3*(0.5**n)*sym.cos(2*n+0.25)*u
           ]
# seleccionar revisar
revisar = tabla[:]

# revisa detalle de una transformada y la inversa
if len(revisar)<2:
    sym.SYMPY_DEBUG = True
else:
    sym.SYMPY_DEBUG = False

# PROCEDIMIENTO
for i in range(0,len(revisar),1):
    f = revisar[i]
    # SALIDA
    print('\nz_transform : ', i)
    print('  f[n]:',f)
    Fz = fcnm.z_transform(f,n,z)
    print('  F[z]:',Fz)
    if type(Fz)==tuple:
        fn = fcnm.inverse_z_transform(Fz[0],z,n)
    else:
        fn = fcnm.inverse_z_transform(Fz,z,n)
    print('  f[n]:',fn)