1.4 Señales Periódicas y No periódicas (aperiódicas)

Señal Periódica

Referencia: Oppenheim 1.2.2 p11, Hsu Cap1.2,F p4, Lathi 1.3.3. p79

Una señal periódica contínua tiene la propiedad que su valor se repite luego de un desplazamiento de tiempo T. El valor de T es conocido como el «periodo de la señal» que es el tiempo en el que se vuelve a repetir la forma de onda a partir de un punto de referencia.

x(t) = x(t+T)

señal periodica vs no periódica

La relación entre el periodo T y la frecuencia f se da por la ecuación:

f = \frac{1}{T} \text{, en Hz} \omega = 2 \pi f = \frac{2 \pi}{T} \text{, en rad/s}

otra forma de escribir la ecuación es:

x(t) = x(t + mT)

para cualquier valor de t y cualquier número entero m. El periodo fundamental T0 de x(t) es el valor positivo más pequeño que hace posible la ecuación descrita.

señal periódica ejemplo

Instrucciones en Python

Las instrucciones son semejantes a graficar señales contínuas. Para el ejemplo se analiza la señal coseno(t), con periodo T=2π para un en un intervalo de dos periodos m=2 y 51 muestras. Se crea el vector ti para el intervalo de observación y se calcula la señal.

# Señales periodicas
import numpy as np
import matplotlib.pyplot as plt

# INGRESO
T = 2*np.pi
f = 1/T
w = 2*np.pi*f
fx = lambda t: np.cos(w*t)
t0 = 0   # intervalo tiempo [t0,tn]
m  = 2   # incluir m periodos en grafica
muestras  = 51
desde = T/4 # marcar periodo [desde,hasta]

# PROCEDIMIENTO
tn = m*T   # vector de tiempo
ti  = np.linspace(t0,tn,muestras)
# dt = ti[1]-ti[0]
dt = (tn-t0)/(muestras-1)

senal = fx(ti)

# marcar un periodo en [desde, hasta]
hasta = desde + T + dt
tperiodo = np.arange(desde,hasta,dt)
periodo  = fx(tperiodo)

La gráfica se conforma de dos partes:

  • la señal calculada
  • la señal marcada en un periodo
# SALIDA
# Grafica
plt.plot(ti,senal)
plt.xlabel('t')
plt.ylabel('señal x(t)')
plt.grid()
plt.axhline(0, color='gray')
plt.axvline(0, color='gray')

# marcar un periodo
plt.title('marcando un periodo')
plt.fill_between(tperiodo,0, periodo,facecolor='green')
plt.show()

Señal periódica discreta

Se define semejante a las señales periódicas contínuas como una secuencia discreta en el tiempo x[n]. La señal es periódica con periodo N si existe un número entero positivo para el que:

x[n + N] = x[n] \text{, para todo n} x[n + mN] = x[n]

para todo n y cualquier entero m

El periodo fundamental N0 de x[n] es el valor positivo mas pequeño para que se cumpla la ecuación en la secuencia de datos de la señal.

Como ejemplo se usa una señal muestreada del coseno:

señal periódica digital

Instrucciones en Python

Semejante al algoritmo del ejercicio anterior, se genera la nueva gráfica en forma discreta.

# Señales periodicas Discretas
import numpy as np
import matplotlib.pyplot as plt

# INGRESO parametros
N  = 8
w  = 2*np.pi/N
fx = lambda n: np.cos(w*n)
n0 = 0   # intervalo [n0,n0+muestras]
m  = 4   # incluir m periodos en grafica

# PROCEDIMIENTO
muestras = m*N+1
ni = np.arange(n0,n0+muestras,1)
senal = fx(ni)

# SALIDA
# Grafica
plt.stem(ni,senal)
plt.xlabel('n')
plt.ylabel('x[n]')
plt.grid()
plt.show()

Señal No periódica o Aperiódica

En éste caso, los valores de la señal x(t) no se repiten para ningún valor de T.

También para algunos problemas se considera que T → ∞.

Un ejemplo del tipo de señal es: x(t)=t^2

señal no periódica o aperiódica

Instrucciones en Python

Usando lo realizado para señales periódicas contínuas, cambiando la función fx y quitando las marcas de un periodo.

# Señales NO periodicas contínuas
import numpy as np
import matplotlib.pyplot as plt

# INGRESO
T = 2*np.pi
f = 1/T
w = 2*np.pi*f
fx = lambda t: t**2
t0 = 0   # intervalo tiempo [t0,tn]
m  = 2   # incluir m periodos en grafica
muestras  = 51

# PROCEDIMIENTO
tn = m*T   # vector de tiempo
ti  = np.linspace(t0,tn,muestras)

senal = fx(ti)

# SALIDA
# Grafica
plt.plot(ti,senal)
plt.xlabel('t')
plt.ylabel('señal x(t)')
plt.grid()
plt.axhline(0, color='gray')
plt.axvline(0, color='gray')
plt.show()

Para el caso de señal discreta, considere el punto de partida del algoritmo correspondiente y modifique:

yn = lambda n: n**2

# SALIDA - Gráfica
plt.stem(ni,yi)
plt.xlabel('n')
plt.ylabel('y[n]')
plt.show()

señal aperiódica discreta


Tarea

Pruebe con otras funciones contínuas para x(t) como:

  • t^3
  • e^t
  • \frac{1}{t}

en Python, el exponente se escribe como: t**3 y en la otra función np.exp(t)

Realizar el mismo paso para sus formas discretas.

1.3 Señales Analógicas y Digitales

Referencia: Lathi 1.3.2 p78, Hsu 1.2.B p2

señal analógica vs digital


1. Señales Analógicas

Una señal se clasifica como analógica cuando su amplitud puede tomar un infinito numero de valores en un rango contínuo de tiempo.

Por ejemplo, una señal de sonido como la del archivo:

Alarm01.wav

Nota: Descargue el archivo use un programa como windows media player para escuchar su contenido.

Instrucciones en Python

Para observar en una gráfica la señal del archivo de sonido anterior, a las librerías numéricas y gráficas, se añade la librería SciPy (scientific Python) que dispone de instrucciones para lecturas de archivos de audio en formato .wav

Nota: Si usa WinPython la librería viene incluida, en otro caso se puede instalar con PIP install scipy en la línea de comandos del sistema.

En el algoritmo se define el nombre del archivo.wav a usar, y mediante la instrucción waves.read() se obtienen los datos de velocidad de muestreo y el arreglo de sonido.

# Señales analógicas
import numpy as np
import matplotlib.pyplot as plt
import scipy.io.wavfile as waves

# INGRESO
# archivo = input('archivo de audio: ')
archivo = 'Alarm01.wav'
muestreo, sonido = waves.read(archivo)

# SALIDA - Observacion intermedia
print('frecuencia de muestreo: ', muestreo)
print('dimensiones de matriz: ', np.shape(sonido))
print('datos de sonido: ')
print(sonido)

el resultado del algoritmo muestra:

frecuencia de muestreo:  22050
dimensiones de matriz:  (122868, 2)
datos de sonido: 
[[0 0]
 [0 0]
 [0 0]
 ..., 
 [0 0]
 [0 0]
 [0 0]]

En caso de requerir revisar más detalles sobre audio.wav se pueden encontrar en el siguiente enlace.

Archivos de Audio.wav – Abrir, extraer una porción

Con los resultados mostrados, se observa que:

  • la señal de audio tiene frecuencia de muestreo de 22050 Hz
  • Las dimensiones de la matriz sonido (122868,2) indican que es de tipo estéreo por usar dos columnas,
  • el valor de 122868 corresponde a la cantidad de muestras por canal,
  • Los índices para seleccionar un canal son 0 ó 1 interpretado como canal izquierdo o derecho.

Para observar la forma del sonido se extrae el canal 0 y solo un segmento o intervalo de tiempo [inicia,termina).

Para observar otros segmentos la señal de audio cambie los valores de  [inicia,termina), añadiendo las instrucciones siguientes:

# segmento de tiempo
canal  = 0
inicia = 2600
termina = 2720

# Extrae el segmento desde sonido
dt = 1/muestreo
ti  = np.arange(inicia*dt,termina*dt,dt)
muestras = len(ti)
segmento = sonido[inicia:inicia+muestras, canal]

#SALIDA
plt.plot(ti,segmento)
plt.xlabel('t segundos')
plt.ylabel('sonido(t)')
plt.show()


2. Señales Digitales

Una señal se clasifica como digital cuando la amplitud  puede tomar solo un número finito de valores, para un número finito de muestras en el tiempo.

Siguiendo el ejemplo de la señal de audio, las señales digitales se las asocia con computadoras. Para almacenar una señal de audio, se la cuantifica en amplitud a espacios iguales de tiempo dt.

Por ejemplo, datos del vector segmento del audio del ejercicio anterior muestran el caracter finito, discreto, por muestras de la señal.

# SALIDA - datos del segmento de audio
print(segmento)
[  -36   -52    11  -280  -595  -186   656   800   141
  -237   -53  -246  -910  -739   569  1347   620  -288
  -195   -57  -812 -1229   -37  1419  1183   -51  -348
    47  -424 -1322  -778   955  1531   432  -363   -62
  -123 -1062 -1189   306  1514   910  -172  -224   -57
  -720 -1191  -164  1241  1134    75  -295  -144  -533
 -1035  -367   953  1144   262  -234  -202  -499  -931
  -423   781  1095   344  -152  -174  -491  -916  -440
   739  1088   353  -149  -158  -467  -901  -472   693
  1116   405  -164  -172  -434  -906  -558   608  1139
   478  -159  -181  -370  -870  -655   494  1151   565
  -130  -180  -307  -812  -735   358  1149   666   -95
  -213  -291  -785  -824   214  1143   784   -31  -217
  -249  -727  -888    54]

los datos del segmento de audio, muestran que la señal de audio se almacena como una señal discreta, o digital, por lo que una gráfica más apropiada es:

# grafica segmento de sonido en forma discreta
ni = np.arange(inicia,inicia+muestras,1)
plt.stem(ni,segmento)
plt.xlabel('n')
plt.ylabel('segmento sonido[n]')
plt.show()

Observaciones

Los términos «contínuo en el tiempo» y «discreto en el tiempo» cuantifican la naturaleza de la señal solo en el eje de las abscisas (horizontal).

Los términos «analógicos» y «digitales» cuantifican la amplitud de la señal o eje de las ordenadas (vertical).

Una señal de audio, por su naturaleza es de tipo analógica, que para almacenarla o procesarla en un computador se convierte a digital al cuantificar sus valores de amplitud, de la forma mostrada en el ejercicio.


Tarea

  • cambie los rangos de observación de la señal de audio y repita las gráficas para su forma analógica aproximada (parte 1) y para su forma digital (parte 2)
  • comente sobre el segmento al inicio y final de todo el audio donde los valores de la señal son 0’s

Instrucciones en Python

# Señales analógicas
import numpy as np
import matplotlib.pyplot as plt
import scipy.io.wavfile as waves

# INGRESO
archivo = 'Alarm01.wav'

# segmento de tiempo
canal   = 0
inicia  = 2600
termina = 2720

# PROCEDIMIENTO
muestreo, sonido = waves.read(archivo)

# Extraer el segmento de sonido
dt = 1/muestreo
ti = np.arange(inicia*dt, termina*dt , dt)
muestras = len(ti)
segmento = sonido[inicia: inicia+muestras,canal]

# SALIDA
print('frecuencia de muestreo:', muestreo)
print('dimensiones de sonido: ',np.shape(sonido))
print('datos del sonido:')
print(sonido)

print('segmento:')
print(segmento)

# Grafica
plt.stem(ti,segmento)
plt.xlabel('t segundos')
plt.ylabel('sonido(t)')
plt.show()

1.2 Señales Discretas con Python

Referencia: Oppenheim 1.3.2 fig.1.25 p24, Lathi 1.3.1 p78, Hsu 1.2.A p1

Las señales discretas tienen un dominio que se especifica únicamente para valores finitos de tiempo, generalmente definidos con números enteros. Por ejemplo, para una señal discreta en un intervalo desde n0, con m muestras, tamaño de paso 1, se genera una secuencia numérica cuya gráfica es:

\sin [\omega n]

señal discreta

El muestreo para cada valor n se establece en el  intervalo [0, m) , para m muestras y con frecuencia ω = 2π/12 radianes/segundo.

Para el ejercicio se usa m=12

Semejante a las gráficas de señales contínua, el bloque de INICIO añade las librerías de Numpy y Matplotlib.

El bloque de INGRESO define los valores de los parámetros, la señal f(x) en formato simplificado lambda, con variable independiente n, el punto inicial n0 y el número de muestras m (recuerde contar el cero)

# Señales discretas
import numpy as np
import matplotlib.pyplot as plt

# INGRESO - parámetros
w  = 2*np.pi/12
fx = lambda n: np.sin(w*n)

n0 = 0  # intervalo en un periodo
muestras = 12+1

En el bloque de Procedimiento, los valores discretos de n se almacenan en un vector de tamaño m. La señal se puede crear usando la función sin() incluida en numpy.

# PROCEDIMIENTO
# vector ni discreto [n0,n0+muestras]
ni = np.arange(n0,n0+muestras,1)

senal = fx(ni)

Observe que los valores para n corresponden a una secuencia numérica.

El bloque de SALIDA puede mostrar los resultados en forma numérica o gráfica.

# SALIDA
np.set_printoptions(precision=4)
print('n: ')
print(ni)
print('señal x[n]: ')
print(senal)
n: 
[ 0  1  2  3  4  5  6  7  8  9 10 11 12]
señal x[n]: 
[ 0.0000e+00  5.0000e-01  8.6603e-01  1.0000e+00
  8.6603e-01  5.0000e-01  1.2246e-16 -5.0000e-01
 -8.6603e-01 -1.0000e+00 -8.6603e-01 -5.0000e-01
 -2.4493e-16]

Para observar el resultado de la señal, se grafica ni vs señal[n], añadiendo las etiquetas para cada eje, y mostrando el resultado con plt.show().

Se usa la gráfica stem() para obtener en la gráfica el punto y una línea que muestre la magnitud, semejante a las gráficas de los libros de texto.

# Gráficas
plt.stem(ni, senal)

plt.xlabel('n')
plt.ylabel('señal x[n]')
plt.grid()

plt.show()

Tarea

Para ésta sección, se cambiarán los parámetros de n y ω.

  • muestras = 50
  • ω0 = π/4 y ω0 = 15π/8
  • cambiar la función a np.cos()
  • ¿se puede cambiar la amplitud de la señal a 2 y ω0=1/6?

Instrucciones Python

# Señales discretas
import numpy as np
import matplotlib.pyplot as plt

# INGRESO - parámetros
w  = 2*np.pi/12
fx = lambda n: np.sin(w*n)

n0 = 0  # intervalo [n0,n0+muestras]
muestras = 12+1

# PROCEDIMIENTO
# vector n de muestras [n0,n0+muestras]
ni = np.arange(n0,n0+muestras,1)

senal = fx(ni)

# SALIDA
np.set_printoptions(precision=4)
print('n: ')
print(ni)
print('señal x[n]: ')
print(senal)

# Gráficas
plt.stem(ni, senal)
plt.xlabel('n')
plt.ylabel('señal x[n]')
plt.grid()
plt.show()

1.1 Señales Contínuas con Python

Referencia: Oppenheim 1.1 p1 pdf32, Lathi 1.3.1 p78, Hsu 1.2.A p1

Un ejemplo clásico de una señal contínua es una de forma sinusoidal.

\sin (\omega t)

La función de la señal en el tiempo se define en el intervalo [t0, tn) para n tramos y una frecuencia angular ω en radianes/segundo. Recordar que ω = 2πf, siendo f la frecuencia en Hz o unidades de 1/s, por si requiere hacer la conversión de frecuencias.

Para facilitar la tarea, en Python se usan las librerías para el manejo de vectores y gráficas:

    • vectores – numpy
    • gráficas – matplotlib.pyplot

Un resumen de gráficas en 2D de línea se presenta también en el curso MATG1052 de métodos numéricos. También se dispone de un video tutorial:  Funciones y Gráficas .

Inicio e Ingreso de parámetros

En el bloque de INICIO se añaden las librerías Numpy y Matplotlib. Luego se definen los parámetros de la señal a usar y se describe la señal con la expresión matemática en su forma simplificada lambda.

Se añade el intervalo de observación y el número de muestras para la gráfica.

# Señales continuas
import numpy as np
import matplotlib.pyplot as plt

# INGRESO
w  = 1
fx = lambda t: np.sin(w*t)

t0 = 0   # intervalo [t0,tn]
tn = 2*np.pi
muestras = 51

Procedimiento – calcular valores

Para la gráfica, las muestras de tiempo t se almacenan en un vector de tamaño n. Entre cada valor de t existe una diferencia dt determinada por n.

# PROCEDIMIENTO
# vector de tiempo
ti = np.linspace(t0,tn,muestras)

# señal
senal = fx(ti)

Salida – valores y gráfica

El resultado puede ser observado de dos formas:
– mostrando sus valores o
– sus gráficas.

Se presentan las dos opciones a escoger.

# SALIDA
np.set_printoptions(precision = 4)
print('tiempo: ')
print(ti)
print('señal: x(t) ')
print(senal)
tiempo: 
[0.     0.1257 0.2513 0.377  0.5027 0.6283 0.754 
 0.8796 1.0053 1.131  1.2566 1.3823 1.508  1.6336
 1.7593 1.885  2.0106 2.1363 2.2619 2.3876 2.5133
 2.6389 2.7646 2.8903 3.0159 3.1416 3.2673 3.3929
 3.5186 3.6442 3.7699 3.8956 4.0212 4.1469 4.2726
 4.3982 4.5239 4.6496 4.7752 4.9009 5.0265 5.1522
 5.2779 5.4035 5.5292 5.6549 5.7805 5.9062 6.0319
 6.1575]
señal: x(t) 
[ 0.0000e+00  1.2533e-01  2.4869e-01  3.6812e-01
  4.8175e-01  5.8779e-01  6.8455e-01  7.7051e-01
  8.4433e-01  9.0483e-01  9.5106e-01  9.8229e-01
  9.9803e-01  9.9803e-01  9.8229e-01  9.5106e-01
  9.0483e-01  8.4433e-01  7.7051e-01  6.8455e-01
  5.8779e-01  4.8175e-01  3.6812e-01  2.4869e-01
  1.2533e-01 -3.2162e-16 -1.2533e-01 -2.4869e-01
 -3.6812e-01 -4.8175e-01 -5.8779e-01 -6.8455e-01
 -7.7051e-01 -8.4433e-01 -9.0483e-01 -9.5106e-01
 -9.8229e-01 -9.9803e-01 -9.9803e-01 -9.8229e-01
 -9.5106e-01 -9.0483e-01 -8.4433e-01 -7.7051e-01
 -6.8455e-01 -5.8779e-01 -4.8175e-01 -3.6812e-01
 -2.4869e-01 -1.2533e-01]

Para observar el resultado de la señal, se grafica t vs señal. Para mejor identificación de ejes, se añade las etiquetas y las líneas de referencia.

# Gráfica
plt.plot(ti,senal)
plt.axhline(0, color='gray')
plt.axvline(0, color='gray')
plt.xlabel('t')
plt.ylabel('señal x(t)')
plt.grid()
plt.show()


Tarea

Para ésta sección, se cambiarán los parámetros de tiempo.

  • tn=8π
  • ω=2
  • cambiar la función a np.cos()
  • ¿se puede cambiar la amplitud de la señal a 4?

Instrucciones en Python

# Señales continuas
import numpy as np
import matplotlib.pyplot as plt

# INGRESO
w  = 1
fx = lambda t: np.sin(w*t)

t0 = 0   # intervalo [t0,tn]
tn = 2*np.pi
muestras = 51

# PROCEDIMIENTO
# vector de tiempo
ti = np.linspace(t0,tn,muestras)

# señal
senal = fx(ti)

# SALIDA
np.set_printoptions(precision = 4)
print('tiempo: ')
print(ti)
print('señal: x(t) ')
print(senal)

# Gráfica
plt.plot(ti,senal)
plt.axhline(0, color='gray')
plt.axvline(0, color='gray')
plt.xlabel('t')
plt.ylabel('señal x(t)')
plt.grid()
plt.show()