4.1 FIR – Filtro de Medias Móviles

[ media móvil ] | ejercicio: [ rectangular ] [ 2 componentes ] [ algoritmo ]
..


Referencia: McClellan 5 p167

Se introduce el análisis para un sistema discreto en tiempo con respuesta de impulso finita,  FIR (Finite Impulse Response), también conocido como filtros FIR.

Un filtro es un sistema con valores de salida resultantes de la suma ponderada de un número finito de valores de una secuencia de entrada. Se define como una operación también conocida como ecuación de diferencias.

1. El filtro de Medias Móviles

Una señal discreta se modifica por medio de un filtro que se determina como un promedio de un intervalo que se desplaza en el tiempo. Para un sistema tipo causal, se tiene:

y[n] = \sum_{k=n-M}^{n} b_{n-k} x[k] = b_{(M)} x[n-M ] + b_{(M-1)} x[n-M+1] + \text{...} + b_{(0)} x[n]

cuando los coeficientes de bk no son iguales, se dice que el promedio o media  móvil es ponderado.

[ media móvil ] | ejercicio: [ rectangular ] [ 2 componentes ] [ algoritmo ]
..


2. Ejemplo de señal rectangular

Referencia: McClellan ejemplo 5.1 p174

Considere un sistema con media móvil para 3 puntos que se expresa como una ventana que desplaza.

y[n] = \sum_{k=n-2}^{n} \frac{1}{3} x[k]

con entrada rectangular entre [0,10]

x[n]= \begin{cases} 1, & 0 \le n \le 10 \\0 , & en otro caso\end{cases} FIR media móvilRef: Señales Escalón unitario μ(t) e Impulso unitario δ(t). blog de Señales y Sistemas

La señal se define como un escalón que se compone de dos señales escalón:

x[n]= \mu [n] -\mu [n-11]

Para el algoritmo se define a partir de μ[n] que en Sympy es Heaviside. Se indican la cantidad de muestras a observar.

# INGRESO
u = sym.Heaviside(n)
# señal como suma de las partes
muestrasN = 10 + 1  # # intervalo [0,10]
xn = u - u.subs(n,n-muestrasN)

# FIR media móvil
ventana = 2 + 1 # intervalo [0,2]
bk = np.ones(ventana, dtype=float)/ventana
causal = True  # causal o no causal

En la media móvil se requiere M=2, si el sistema es causal y el vector bk que son los valores de ponderación. Se obtienen los siguientes resultados:

muestreo: 11  ; tamaño ki: 17
x[n]: Heaviside(n) - Heaviside(n - 11)
bk: [0.33333333 0.33333333 0.33333333]

[ media móvil ] | ejercicio: [ rectangular ] [ 2 componentes ] [ algoritmo ]
..


3. Ejercicio  con señal de dos componentes

Considere la señal con un componente exponencial y otro componente senoidal que se considera ruido o interferencia que degrada la señal a observar. Se pretende minimizar o remover el efecto del componente senoidal

x[n]= \begin{cases} (1-02)^n + \frac{1}{2}\cos(2 \pi n /8 + \pi/4), & 0 \le n \le 40 \\0 , & n<0\end{cases}

Realice el ejercicio con media móvil que tiene una ventana de 7 puntos o M=6.

Usando el algoritmo se tiene el siguiente resultado:

FIR media movil 02

muestreo: 41  ; tamaño ki: 55
x[n]: (1.02**n + 0.5*cos(pi*n/4 + pi/4))*(Heaviside(n) - Heaviside(n - 40))
bk: [0.14285714 0.14285714 0.14285714 0.14285714 
     0.14285714 0.14285714 0.14285714]

El bloque de ingreso para el algoritmo es:

# INGRESO
u = sym.Heaviside(n)
# señal como suma de las partes
muestrasN = 40 + 1  # # intervalo [0,40]
x0 = u - u.subs(n,n-muestrasN)
x1 = 1.02**n +0.5*sym.cos(2*pi*n/8 + pi/4)
xn = x1*x0

# FIR media móvil
ventana = 6 + 1 # intervalo [0,6]
bk = np.ones(ventana, dtype=float)/ventana
causal=True  # causal o no causal

[ media móvil ] | ejercicio: [ rectangular ] [ 2 componentes ] [ algoritmo ]
..


4. Algoritmo en Python

El modelo de algoritmo para los ejercicios  se presenta para la señal rectangular. Para otros ejercicios se actualiza la señal en el bloque de ingreso.

La variable causal=True establece el signo de la ventana deslizante, si el sistema es causal, el signo es negativo.

# ejemplo 5.1 p174 FIR - Media Móvil general
# telg1034 DSP fiec-espol edelros@espol.edu.ec
import numpy as np
import matplotlib.pyplot as plt
import sympy as sym
import telg1034 as dsp

# variables continuas
from telg1034 import t,A,w,f,p,pi,DosPi,I,equivalentes
# variables discretas
from telg1034 import n

# INGRESO
u = sym.Heaviside(n)
# señal como suma de las partes
muestrasN = 10 + 1  # # intervalo [0,10]
xn = u - u.subs(n,n-muestrasN)

# FIR media móvil
ventana = 2 + 1 # intervalo [0,2]
bk = np.ones(ventana, dtype=float)/ventana
causal = True  # causal o no causal

# PROCEDIMIENTO ----------------
# muestreo x[n]
ki = np.arange(-ventana,muestrasN + ventana,1,dtype=int)
xni = sym.lambdify(n,xn, modules=equivalentes)
xki = xni(ki) 

# FIR Media Móvil
causal_sign = +1 # sistema causal
if not(causal): # sistema no causal
    causal_sign = -1
    
# ajuste de intervalo con ventana
yki = np.zeros(muestrasN + 2*ventana,dtype=float)
for i in range(-ventana,muestrasN + 2*ventana,1):
    unaventana = 0
    for k in range(0,ventana,1):
        if (i-causal_sign*k)>=0 and (i-causal_sign*k)<=(muestrasN+ventana):
            unaventana = unaventana + xki[i-causal_sign*k]*bk[k]
    yki[i] = unaventana

# SALIDA
print('muestreo:',muestrasN,' ; tamaño ki:',len(ki))
print('x[n]:',xn)
print('bk:',bk)

# GRAFICA FIR
plt.subplot(211) # x[n]
plt.stem(ki,xki,linefmt = 'C0:',
         label='x[n]')
plt.xlabel('n')
plt.ylabel('x[n]')
plt.title('FIR Media Móvil')
plt.legend()

plt.subplot(212) # y[n]
plt.stem(ki,yki,linefmt = 'C2:',label='y[n]')
plt.xlabel('n')
plt.ylabel('y[n]')
plt.legend()
plt.show()

[ media móvil ] | ejercicio: [ rectangular ] [ 2 componentes ] [ algoritmo ]