Los siguientes ejercicios de LTI Discretos muestran los desarrollos cuando el denominador de la función de transferencia tiene:
1. raíces reales diferentes (No repetidas)
2. raíces reales repetidas
3. raíces con números complejos
…
Ejercicio 1. Raíces reales diferentes
Referencia: Lathi Ejemplo 3.13 p271
Para un sistema LTID descrito por la ecuación de diferencias mostrada,
y[n+2] - 0.6 y[n+1] - 0.16 y[n] = 5x[n+2]
encuentre la respuesta a entrada cero y0[n] del sistema dadas las condiciones iniciales y[-1]=0, y[-2] =25/4, ante una entrada
x[n]= 4^{-n} \mu [n]
(El componente de estado cero se calcula en la sección correspondiente)
Para realizar el diagrama, se desplaza la ecuación en dos unidades
y[n] - 0.6 y[n-1] - 0.16 y[n-2] = 5x[n]
y[n] = 0.6 y[n-1] + 0.16 y[n-2] + 5x[n]
Para respuesta a entrada cero se usa x[n] = 0
1.1 Desarrollo analítico
y[n+2] - 0.6 y[n+1] - 0.16 y[n] = 5x[n+2]
La ecuación del sistema en notación de operador E es:
E^2 y[n] - 0.6 E y[n] - 0.16 y[n] = 5 E^2 x[n]
(E^2 - 0.6 E - 0.16) y[n] = 5 E^2 x[n]
que para entrada cero tiene x[n]=0,
(E^2 - 0.6 E - 0.16) y[n] = 0
tiene el polinomio característico,
\gamma^2 - 0.6 \gamma - 0.16 = 0
(\gamma+0.2) (\gamma - 0.8) = 0
con raíces características γ1=-0.2 y γ2=0.8, obtenidas con instrucciones con Python:
raices:
[ 0.8 -0.2]
coeficientes:
[0.8 0.2]
la repuesta a entrada cero tiene la forma
y_0[n] = c_1 (-0.2)^n + c_2 (0.8)^n
se usan las condiciones iniciales para determinar las constantes c1 y c2 aplicadas como:
y_0[-1] = c_1 (-0.2)^{-1} + c_2 (0.8)^{-1}
0 = -5 c_1 + 1.25 c_2
y_0[-2] = c_1 (-0.2)^{-2} + c_2 (0.8)^{-2}
\frac{25}{4} = 25 c_1 + 1.5625 c_2
se tiene el sistema de ecuaciones
0 = -5 c_1 + 1.25 c_2
\frac{25}{4} = 25 c_1 + 1.5625 c_2
resolviendo se encuentra que: c1 = 0.2 c2 = 0.8
con lo que la solución tiene la expresión basado en la sumatoria de ci ϒn, para n≥0
y_0 [n] = \frac{1}{5} (-0.2)^n + \frac{4}{5} (0.8)^n
Instrucciones en Python
import numpy as np
coeficientes = [1.,-0.6,-0.16]
raiz = np.roots(coeficientes)
print('raices:')
print(raiz)
A = np.array([[raiz[0]**(-1) , raiz[1]**(-1)],
[raiz[0]**(-2) , raiz[1]**(-2)]])
B = np.array([0., 25/4])
ci = np.linalg.solve(A,B)
print('coeficientes:')
print(ci)
1.2 Desarrollo con Python
El algoritmo requiere los coeficientes de la ecuación de diferencias Q(E) y P(E) junto a las condiciones iniciales.
QE = [1., -0.6, -0.16]
PE = [5., 0., 0.]
inicial = [25/4, 0.]
que da como resultado:
respuesta entrada cero:
raices: [ 0.8 -0.2]
Matriz:
[[ 1.5625 25. ]
[ 1.25 -5. ]]
Ci: [0.8 0.2]
y0:
n n
0.2*-0.2 + 0.8*0.8
Instrucciones en Python
# Sistema LTID. Respuesta entrada cero
# resultado con raices Reales
# ejercicio Lathi ejemplo 3.13 p271
import numpy as np
import sympy as sym
import matplotlib.pyplot as plt
# INGRESO
# coeficientes E con grado descendente
QE = [1., -0.6, -0.16]
PE = [5., 0., 0.]
# condiciones iniciales ascendente ...,y[-2],y[-1]
inicial = [25/4, 0.]
# PROCEDIMIENTO
# Respuesta a ENTRADA CERO
# raices, revisa numeros complejos
gamma = np.roots(QE)
revisaImag = np.iscomplex(gamma)
escomplejo = np.sum(revisaImag)
# coeficientes de ecuacion
m_q = len(QE)-1
Ac = np.zeros(shape=(m_q,m_q),dtype=float)
if escomplejo == 0:
for i in range(0,m_q,1):
for j in range(0,m_q,1):
Ac[i,j] = gamma[j]**(-m_q+i)
ci = np.linalg.solve(Ac,inicial)
# ecuacion y0
n = sym.Symbol('n')
y0 = 0
if escomplejo == 0:
for i in range(0,m_q,1):
y0 = y0 + ci[i]*(gamma[i]**n)
# SALIDA
print('respuesta entrada cero: ')
print('raices: ', gamma)
if escomplejo == 0:
print('Matriz: ')
print(Ac)
print('Ci: ', ci)
print('y0:')
sym.pprint(y0)
else:
print(' existen raices con números complejos.')
print(' usar algoritmo de la sección correspondiente.')
Raíces: [reales No repetidas] [reales repetidas] [números complejos]
…
2. Raíces repetidas
Referencia: Lathi Ejemplo 3.15 p274
y[n+2] +6 y[n+1] + 9 y[n] = 2 x[n+2] + 6 x[n+1]
con las condiciones iniciales y0[-1] = -1/3 y y0[-2] = -2/9
Para realizar el diagrama de bloques, se desplaza ambos lados de la ecuación en 2 unidades. Luego se despeja y[n]
y[n] +6 y[n-1] + 9 y[n-2] = 2 x[n] + 6 x[n-1]
y[n] = -6 y[n-1] - 9 y[n-2] + 2 x[n] + 6 x[n-1]
2.1 Desarrollo analítico
siguiendo los mismos pasos que en los ejercicios anteriores
E^2 y[n] +6 E y[n] + 9 y[n] = 2 E^2 x[n] + 6 E x[n]
(E^2 +6 E + 9) y[n] = (2 E^2 + 6 E) x[n]
Para entrada cero se tiene x[n] = 0
(E^2 +6 E + 9) y[n] = (2 E^2 + 6 E) (0)
\gamma^2 +6 \gamma + 9 = 0
(\gamma + 3)( \gamma + 3) = 0
de donde se muestra una raiz repetida γ=3, donde los modos característicos hacen que la expresión sea:
y_0[n] = (c_1 + c_2 n) (\gamma)^n
siguiendo el procedimiento realizado para raíces reales se puede determinar los valores de c1=4 y c2=3, con lo que se obtiene la solución:
y_0[n] = (4 + 3n) (-3)^n
los resultados obtenidos con el algoritmo en Python son
respuesta entrada cero:
raices: [-3. -3.]
Raices repetidas: 1
Matriz:
[[ 0.11111111 -0.22222222]
[-0.33333333 0.33333333]]
Ci: [4. 3.]
y0:
n
-3.0 *(3.0*n + 4.0)
>>>
2.2 Instrucciones en Python, integrando raices reales únicas y repetidas
# Sistema LTID. Respuesta entrada cero
# QE con raices Reales NO repetidas Lathi ejemplo 3.13 pdf271
# QE con raices Reales Repetidas Lathi ejemplo 3.15 p274
# blog.espol.edu.ec/telg1001
import numpy as np
import sympy as sym
import matplotlib.pyplot as plt
# INGRESO
# coeficientes E con grado descendente
QE = [1., 6., 9.]
PE = [2., 6., 0.]
# condiciones iniciales ascendente ...,y[-2],y[-1]
inicial = [-2/9, -1/3]
tolera = 1e-6 # casi_cero
# PROCEDIMIENTO
# Respuesta a ENTRADA CERO
# raices, revisa numeros complejos
gamma = np.roots(QE)
revisaImag = np.iscomplex(gamma)
escomplejo = np.sum(revisaImag)
# coeficientes de ecuacion
m_q = len(QE)-1
Ac = np.zeros(shape=(m_q,m_q),dtype=float)
# revisa si parte compleja <tolera o casi_cero
if escomplejo>0:
for i in range(0,m_q,1):
if np.imag(gamma[i]) < tolera:
gamma[i] = float(np.real(gamma[i]))
sumaj = np.sum(np.imag(gamma))
if sumaj <tolera:
gamma = np.real(gamma)
escomplejo = 0
# revisa repetidos
unicoscuenta = np.unique(gamma,return_counts=True)
repetidas = np.sum(unicoscuenta[1]-1)
# raices Reales no repetidas
if escomplejo == 0 and repetidas==0:
for i in range(0,m_q,1):
for j in range(0,m_q,1):
Ac[i,j] = gamma[j]**(-m_q+i)
ci = np.linalg.solve(Ac,inicial)
# raices Reales repetidas
if escomplejo == 0 and repetidas > 0:
for i in range(0,m_q,1):
for j in range(0,m_q,1):
Ac[i,j] = ((-m_q+i)**j)*gamma[j]**(-m_q+i)
ci = np.linalg.solve(Ac,inicial)
# ecuacion y0 entrada cero
n = sym.Symbol('n')
y0 = 0*n
if escomplejo == 0 and repetidas==0:
for i in range(0,m_q,1):
y0 = y0 + ci[i]*(gamma[i]**n)
if escomplejo == 0 and repetidas > 0:
for i in range(0,m_q,1):
y0 = y0 + ci[i]*(n**i)*(gamma[i]**n)
y0 = y0.simplify()
# SALIDA
print('respuesta entrada cero: ')
print('raices: ', gamma)
if escomplejo == 0:
if repetidas>0:
print('Raices repetidas: ', repetidas)
print('Matriz: ')
print(Ac)
print('Ci: ', ci)
print('y0:')
sym.pprint(y0)
else:
print(' existen raices con números complejos.')
print(' usar algoritmo de la sección correspondiente.')
Raíces: [reales No repetidas] [reales repetidas] [números complejos]
…
Ejercicio 3. Raices con números complejos
Referencia: Lathi Ejemplo 3.16 p275
Para el caso de tener raíces con números complejos se muestra el siguiente ejemplo:
y[n+2] - 1.56 y[n+1] + 0.81 y[n] = x[n+1] + 3x[n]
con condiciones iniciales y0[-1]=2 y y0[-2]=1
Para realizar el diagrama de bloques, se desplaza ambos lados de la ecuación en 2 unidades. Luego se despeja y[n]
y[n] - 1.56 y[n-1] + 0.81 y[n-2] = x[n-1] + 3x[n-2]
y[n] = 1.56 y[n-1] - 0.81 y[n-2] + x[n-1] + 3x[n-2]
3.1 Desarrollo analítico
y[n+2] - 1.56 y[n+1] + 0.81 y[n] = x[n+1] + 3x[n]
La expresión usando operador E:
E^2 y[n] - 1.56 E y[n] + 0.81 y[n] = E x[n] + 3x[n]
(E^2 - 1.56 E + 0.81) y[n] = (E+ 3)x[n]
para entrada cero se hace x[n] = 0
(E^2 - 1.56 E + 0.81) y[n] = (E+ 3)(0)
por lo que, el polinomio característico es,}
(\gamma^2 - 1.56 \gamma + 0.81) = 0
con raíces de números complejos
(\gamma - (0.78 + j 0.45))(\gamma - (0.78-j 0.45)) = 0
la raíz también se puede escribir como:
\gamma = 0.9 e^{\pm j\frac{\pi}{6}}
obtenida mediante:
raices:
[0.78+0.44899889j 0.78-0.44899889j]
magnitud: [0.9 0.9]
angulo: [ 0.52231482 -0.52231482]
>>>
Se puede escribir la solución como:
y_0[n] = c(0.9)n e^{j\frac{\pi}{6} } + c^{*} (0.9)n e^{-j\frac{\pi}{6}}
Luego aplicando oas condiciones iniciales se encuentra que
c = 2.34 e^{-j0.17}
c^{*} = 2.34 e^{j0.17}
Otra manera de desarrollo permite encontrar la solución usando la forma real de la solución, conociendo que la solución esta dada por la expresión:
y_0[n] = c(0.9)^n \cos \Big( \frac{\pi}{6}n + \theta \Big)
con lo que se puede crear el sistema de ecuaciones aplicando las condiciones iniciales, ademas de considerar que:
\cos(a \pm b) = \cos(a) \cos(b) \mp \sin(a) \sin(b)
Para y0[-2] = 1
1 = c(0.9)^{-2} \cos \Big( \frac{\pi}{6}(-2) + \theta \Big)
1 = c\frac{1}{(0.9)^2} \Big[ \cos \big(-2\frac{\pi}{6} \big) \cos ( \theta ) - \sin \big(-2\frac{\pi}{6}\big) \sin (\theta) \Big]
1 = c\frac{1}{0.81} \Big[ \frac{1}{2} \cos ( \theta ) - \frac{-\sqrt{3}}{2} \sin (\theta) \Big]
1 = c \Big[ \frac{1}{1.62} \cos ( \theta ) + \frac{\sqrt{3}}{1.62} \sin (\theta) \Big]
Para y0[-1] = 2
2 = c(0.9)^{-1} \cos \Big( \frac{\pi}{6}(-1) + \theta \Big)
2 = c\frac{1}{0.9} \Big[ \cos \big(-\frac{\pi}{6} \big) \cos ( \theta ) - \sin \big(-\frac{\pi}{6}\big) \sin (\theta) \Big]
2 = c\frac{1}{0.9} \Big[ \frac{\sqrt{3}}{2} \cos ( \theta ) - \frac{-1}{2} \sin (\theta) \Big]
2 = c\Big[ \frac{\sqrt{3}}{1.8} \cos ( \theta ) + \frac{1}{1.8} \sin (\theta) \Big]
con lo que se puede determinar los valores para [c cos(θ)] y [c sin(θ)]
usando una matriz A y vector B a partir de las ecuaciones
c \cos ( \theta ) = 2.31
c \sin ( \theta ) = -0.4049
al dividir [c sin(θ)]/[c cos(θ)] = tan (θ), con lo que se obtiene el ángulo en radianes.
\frac{ c \sin ( \theta )} {c \cos ( \theta )} = \frac{-0.4049}{2.31} = -0.17528
\theta = \tan ^{-1} (-0.17528) = -0.1735
al sustituir el valor en c cos(θ) = 2.31 se tiene,
c = \frac{2.31}{ \cos (-0.1735)} = 2.3452
con lo que la solución se puede escribir mediante:
y_0[n] = 2.3452 (0.9)^n \cos \Big( \frac{\pi}{6}n - 0.1735 \Big)
para n≥0
Instrucciones de cálculo
import numpy as np
coeficientes = [1.,-1.56,0.81]
raiz = np.roots(coeficientes)
print('raices:')
print(raiz)
g_magnitud = np.absolute(raiz)
g_angulo = np.angle(raiz)
print('magnitud: ',g_magnitud)
print('angulo: ',g_angulo)
3.2 Algoritmo en Python, integrando raices reales y complejas
usando el algoritmo se obtienen los siguientes resultados:
Respuesta entrada cero:
raices : [0.78+0.44899889j 0.78-0.44899889j]
raices complejas: 2
magnitud: [0.9 0.9]
theta: [ 0.52231482 -0.52231482]
Matriz:
[[0.62002743 1.06757851]
[0.96296296 0.55431961]]
Cj: [ 2.31 -0.40490078]
Ci: 2.345217397781524
y0:
n
2.34521739778152*0.9 *cos(0.522314821806049*n + 0.173519005551295)
>>>
Para el caso de raíces complejas, se añade al algoritmo anterior las instrucciones en Python:
# Sistema LTID. Respuesta entrada cero
# QE con raices Reales NO repetidas Lathi ejemplo 3.13 pdf271
# QE con raices Reales Repetidas Lathi ejemplo 3.15 p274
# QE con raices Complejas Lathi ejemplo 3.16 p275
# blog.espol.edu.ec/telg1001
import numpy as np
import sympy as sym
import matplotlib.pyplot as plt
# INGRESO
# coeficientes E con grado descendente
QE = [1.0, -1.56, 0.81]
PE = [0., 1., 3.]
# condiciones iniciales ascendente ...,y[-2],y[-1]
inicial = [1.,2.]
tolera = 1e-6 # casi_cero
muestras = 10 # para grafica
# PROCEDIMIENTO
# Respuesta a ENTRADA CERO
# raices, revisa numeros complejos
gamma = np.roots(QE)
revisaImag = np.iscomplex(gamma)
escomplejo = np.sum(revisaImag)
# coeficientes de ecuacion
m_q = len(QE)-1
Ac = np.zeros(shape=(m_q,m_q),dtype=float)
# revisa si parte compleja <tolera o casi_cero
if escomplejo>0:
for i in range(0,m_q,1):
valorimag = np.imag(gamma[i])
if np.abs(valorimag)<tolera:
gamma[i] = float(np.real(gamma[i]))
sumaj = np.sum(np.abs(np.imag(gamma)))
if sumaj <tolera:
print(sumaj)
gamma = np.real(gamma)
escomplejo = 0
# revisa repetidos
unicoscuenta = np.unique(gamma,return_counts=True)
repetidas = np.sum(unicoscuenta[1]-1)
# Determina coeficientes ci de Y[n]
# raices Reales no repetidas
if escomplejo == 0 and repetidas==0:
for i in range(0,m_q,1):
for j in range(0,m_q,1):
Ac[i,j] = gamma[j]**(-m_q+i)
ci = np.linalg.solve(Ac,inicial)
# raices Reales repetidas
if escomplejo == 0 and repetidas > 0:
for i in range(0,m_q,1):
for j in range(0,m_q,1):
Ac[i,j] = ((-m_q+i)**j)*gamma[j]**(-m_q+i)
ci = np.linalg.solve(Ac,inicial)
# raices Complejas
if escomplejo > 0:
g_magnitud = np.absolute(gamma)
g_angulo = np.angle(gamma)
for i in range(0,m_q,1):
k = -(m_q-i)
a = np.cos(np.abs(g_angulo[i])*(k))*(g_magnitud[i]**(k))
b = -np.sin(np.abs(g_angulo[i])*(k))*(g_magnitud[i]**(k))
Ac[i] = [a,b]
Ac = np.array(Ac)
cj = np.linalg.solve(Ac,inicial)
theta = np.arctan(cj[1]/cj[0])
ci = cj[0]/np.cos(theta)
# ecuacion y0 entrada cero
n = sym.Symbol('n')
y0 = 0*n
if escomplejo == 0 and repetidas==0:
for i in range(0,m_q,1):
y0 = y0 + ci[i]*(gamma[i]**n)
if escomplejo == 0 and repetidas > 0:
for i in range(0,m_q,1):
y0 = y0 + ci[i]*(n**i)*(gamma[i]**n)
y0 = y0.simplify()
if escomplejo > 0:
y0 = ci*(g_magnitud[0]**n)*sym.cos(np.abs(g_angulo[i])*n - theta)
# SALIDA
print('respuesta entrada cero: ')
print('raices: ', gamma)
if escomplejo == 0:
if repetidas>0:
print('Raices repetidas: ', repetidas)
print('Matriz: ')
print(Ac)
print('Ci: ', ci)
print('y0:')
sym.pprint(y0)
if escomplejo > 0:
print('raices complejas: ', escomplejo)
print('magnitud:',g_magnitud)
print('theta:',g_angulo)
print('Matriz: ')
print(Ac)
print('Cj: ', cj)
print('Ci: ',ci)
print('y0: ')
sym.pprint(y0)
# grafica datos
ki = np.arange(-m_q,muestras,1)
y0i = np.zeros(muestras+m_q)
# valores iniciales
y0i[0:m_q] = inicial[0:m_q]
# evaluación de y0[n]
y0n = sym.lambdify(n,y0)
y0i[m_q:] = y0n(ki[m_q:])
# grafica y[n] ante x[n]=0
plt.stem(ki,y0i)
plt.xlabel('ki')
plt.ylabel('y0[n]')
plt.title('y0[n]='+str(y0))
plt.grid()
plt.show()
Raíces: [reales No repetidas] [reales repetidas] [números complejos]