7.1.1 Transformada z – Pares f[n] y F[z] con match() de Sympy-Python

Para facilitar el uso de la Transformada z se usa la Tabla de Pares f[n] y F[z], donde se busca una expresión semejante que permite cambiar del dominio_n al dominio_z. Los Pares se usan en conjunto con la tabla de propiedades de la Transformada z con lo que se extiende las posibilidades de uso para la tabla.

Se propone primero usar la tabla de pares con Sympy para buscar las expresiones semejantes, usando la instrucción ‘f.match()‘, donde f es la función en el dominio_n y F es la función en el domino_z. En la siguiente sección se incorpora la tabla de propiedades, para en conjunto realizar una búsqueda más completa de las transformadas z o de sus inversas.

Referencia: Schaum Hsu Tabla 4-1 p170. Lathi Tabla 5.1 Transformada z p492. Oppenheim tabla 10.2 p776


Ejercicio 1. transformada z de f[n] = cos(2n) con Sympy y la instrucción f.match()

Revise si existe una expresión para f[n] en una pequeña lista de pares de transformadas:

f[n] = \cos [2n]

Algoritmo en Python

El algoritmo inicia con las variables a usar para cada dominio y la expresión de Heaviside como en los ejemplos de las unidades anteriores.

En la tabla se requiere unas variables tipo «comodín» (Wild) para buscar la semejanza de las expresiones, se usan como sym.Wild('a', exclude=[n]) de la que se excluye la variable de tiempo discreto n.

Se incluye una pequeña lista como tabla de pares de transformadas como un ejemplo básico, que luego puede ser ampliada. Los pares se incluyen como tuplas con las expresiones para cada domino.

Para encontrar semejanzas, se recorre cada par de transformadas, comparando las expresiones con f.match(par_nz[0]), que para revisar la expresión del domino n, solo toma la primera parte de la tupla. Si existe coincidencia, se crea un diccionario que indica los valores comodín que hacen que las expresiones sean iguales.

Resultado del algoritmo

 se encontró expresión similar:
  f:            cos(2*n)
  z_pares f[n]: cos(n*a_)
   similar con: {a_: 2}
  z_pares F[z]: (z**2 - z*cos(a_))/(z**2 - 2*z*cos(a_) + 1)
  Fz:         : (z**2 - z*cos(2))/(z**2 - 2*z*cos(2) + 1)
>>> 

Instrucciones en Python

# transformada z con f.match de Sympy
# expresiones similares o semejantes f.match
import sympy as sym

# INGRESO
n = sym.Symbol('n', real=True)
z = sym.Symbol('z')
u = sym.Heaviside(n)

#f = u
#f = 5*u
f = sym.cos(2*n)
#f = sym.sin(2*n)

# PROCEDIMIENTO
# para revisar semejanza de expresiones fn y n_dom
a = sym.Wild('a', exclude=[n])
b = sym.Wild('b', exclude=[n])

# tabla de pares [(n_dom, z_dom)]
z_pares = [
    # impulso unitario d[n], DiracDelta
    (DiracDelta(n),
     S.One,
     S.true, S.Zero, dco),
    (DiracDelta(a*n),
     S.One,
     Abs(a)>0, S.Zero, dco),
    # escalon unitario u[n], Heaviside
    (Heaviside(n),
     z/(z-1),
     S.true, Abs(z) > 1, dco),
    # cos[n], sin[n] ,trigonometricas
    (cos(a*n),
     (z*(z-cos(a)))/(z**2-(2*cos(a))*z+1),
     Abs(a)>0, Abs(z) > 1, dco),
    (sin(a*n),
     (sin(a)*z+0)/(z**2-(2*cos(a))*z+1),
     Abs(a)>0, Abs(z) > 1, dco),
    ]

Fz = None; f_pares = None # sin similar
z_pares_len = len(z_pares) ; i=0
while i<z_pares_len and Fz==None:
    par_nz = z_pares[i]
    n_dom = par_nz[0]
    z_dom = par_nz[1]
    similar = f.match(n_dom)
    # entrega diccionario de expresion similar
    # si el diccionario es vacio, es coincidente
    if similar or similar=={}:
        f_pares = par_nz
        f_args = similar
        Fz_ = z_dom
        Fz  = z_dom.xreplace(similar)
    i = i+1 # siguiente par

# SALIDA
if not(Fz==None):
    print(' se encontró expresión similar:')
    print('  f:           ',f)
    print('  z_pares f[n]:',f_pares[0])
    print('   similar con:',f_args)
    print('  z_pares F[z]:',f_pares[1])
    print('  Fz:         :',Fz)
else:
    print(' NO se encontró una expresión similar...')

El concepto de expresiones similares se prueba con:

f[n] = \mu [n]

donde se observa que a respuesta es un diccionario vacío

 se encontró expresión similar:
  f:            Heaviside(n)
  z_pares f[n]: Heaviside(n)
   similar con: {}
  z_pares F[z]: z/(z - 1)
  Fz:         : z/(z - 1)
>>> 

mientras que para una función que no se encuentra en la tabla, el resultado debe ser Fz=None

f[n] = \sin [2n]
 NO se encontró una expresión similar...
>>> type(Fz)
<class 'NoneType'>
>>> 

El concepto básico del algoritmo se extiende para las tablas de Pares de transformadas que se adjuntan en un archivo de funciones telg1001.py.


Ejercicio 2. Transformada z inversa de F[z] = z/(z-1) con Sympy y la instrucción f.match()

Revisar si existe una expresión para F[z] en una pequeña lista de pares de transformadas:

F[z] = \frac{z}{z-1}

Algoritmo en Python

Semejante al ejercicio 1 para f[n] a F[z], el algoritmo inicia con las variables a usar para cada dominio y de F[z].

Para encontrar semejanzas, se recorre cada par de transformadas, comparando las expresiones con F.match(par_nz[1]), que para revisar la expresión del domino z, solo toma la segunda parte de la tupla. Si existe coincidencia, se crea un diccionario que indica los valores comodín que hacen que las expresiones sean iguales.

Resultado del algoritmo

 se encontró expresión similar:
  F:            z/(z - 1)
  z_pares F[z]: z/(z - 1)
   similar con: {}
  z_pares f[n]: Heaviside(n)
  fn:         : Heaviside(n)
>>> 

Instrucciones en Python

# transformada z inversa con F.match de Sympy
# expresiones similares o semejantes F.match
import sympy as sym

# INGRESO
n = sym.Symbol('n', real=True)
z = sym.Symbol('z')
u = sym.Heaviside(n)

F = z/(z-1)
#F = (z**2 - z*sym.cos(2))/(z**2 - 2*z*sym.cos(2) + 1)

# PROCEDIMIENTO
# para revisar semejanza de expresiones fn y n_dom
a = sym.Wild('a', exclude=[n])
b = sym.Wild('b', exclude=[n])

# tabla de pares [(n_dom, z_dom)]
z_pares = [
    # impulso unitario d[n], DiracDelta
    (DiracDelta(n),
     S.One,
     S.true, S.Zero, dco),
    (DiracDelta(a*n),
     S.One,
     Abs(a)>0, S.Zero, dco),
    # escalon unitario u[n], Heaviside
    (Heaviside(n),
     z/(z-1),
     S.true, Abs(z) > 1, dco),
    # cos[n], sin[n] ,trigonometricas
    (cos(a*n),
     (z*(z-cos(a)))/(z**2-(2*cos(a))*z+1),
     Abs(a)>0, Abs(z) > 1, dco),
    (sin(a*n),
     (sin(a)*z+0)/(z**2-(2*cos(a))*z+1),
     Abs(a)>0, Abs(z) > 1, dco),
    ]

fn = None; F_pares = None # sin similar
z_pares_len = len(z_pares) ; i=0
while i<z_pares_len and fn==None:
    par_nz = z_pares[i]
    n_dom = par_nz[0]
    z_dom = par_nz[1]
    similar = F.match(z_dom)
    # entrega diccionario de expresion similar
    # si el diccionario es vacio, es coincidente
    if similar or similar=={}:
        F_pares = par_nz
        F_args = similar
        fn_ = n_dom
        fn  = n_dom.xreplace(similar)
    i = i+1 # siguiente par

# SALIDA
if not(fn==None):
    print(' se encontró expresión similar:')
    print('  F:           ',F)
    print('  z_pares F[z]:',F_pares[1])
    print('   similar con:',F_args)
    print('  z_pares f[n]:',F_pares[0])
    print('  fn:         :',fn)
else:
    print(' NO se encontró una expresión similar...')

otros ejercicios realizados con

F[z] =\frac{z^2 - zcos(2)}{z^2 - 2zcos(2) + 1}

resultado del algoritmo

 se encontró expresión similar:
  F:            (z**2 - z*cos(2))/(z**2 - 2*z*cos(2) + 1)
  z_pares F[z]: (z**2 - z*cos(a_))/(z**2 - 2*z*cos(a_) + 1)
   similar con: {a_: 2}
  z_pares f[n]: cos(n*a_)
  fn:         : cos(2*n)
>>> 

Referencias: Sympy: match(pattern, old=False) https://docs.sympy.org/latest/modules/core.html?highlight=match#sympy.core.basic.Basic.match