WhatsApp

  

Filtros Digitales con Matrices: Algoritmos y Ejemplos en Python

Guía completa sobre el algoritmo de filtros digitales usando matrices, con teoría, implementación en Python (NumPy y SciPy), ejemplos prácticos y buenas prácticas.

Filtros Digitales con Matrices: Algoritmos y Ejemplos en Python

Introducción

Los filtros digitales son la columna vertebral del procesamiento de señales (DSP). En su forma más elemental, un filtro FIR (Finite Impulse Response) se implementa mediante una convolución discreta entre la señal de entrada y un conjunto de coeficientes (el kernel del filtro). Cuando trabajamos con matrices podemos expresar tanto la señal como el kernel como vectores y aprovechar operaciones lineales optimizadas (BLAS, SIMD, etc.) que ofrecen librerías como NumPy o SciPy.

Conceptos básicos

  • Señal discreta: vector x[n] de longitud N.
  • Kernel del filtro (coeficientes): vector h[k] de longitud M.
  • Convolución:

    y[n] = \sum_{k=0}^{M-1} h[k] \cdot x[n-k]

  • Representación matricial: la operación anterior puede escribirse como y = X @ h, donde X es una matriz Toeplitz construida a partir de x.

Algoritmo de convolución mediante matrices

Construir la matriz Toeplitz permite aplicar la convolución como un producto matricial, lo que facilita el uso de batch processing y la paralelización en GPUs.

import numpy as np
def toeplitz_matrix(x, M):
    """Construye una matriz Toeplitz de x con M columnas.
    Cada fila corresponde a un segmento desplazado de la señal.
    """
    N = len(x)
    # Padding al final para manejar los bordes
    x_padded = np.concatenate([x, np.zeros(M-1)])
    return np.lib.stride_tricks.as_strided(
        x_padded,
        shape=(N, M),
        strides=(x_padded.strides[0], x_padded.strides[0])
    )
# Ejemplo rápido
x = np.arange(1, 9)          # Señal de 8 muestras
h = np.array([0.2, 0.5, 0.3]) # Kernel de 3 coeficientes
X = toeplitz_matrix(x, len(h))
y = X @ h
print(y)

El resultado y es idéntico al obtenido con np.convolve(x, h, mode='full')[:len(x)], pero la representación matricial abre la puerta a optimizaciones avanzadas.

Implementación práctica en Python

Ejemplo 1: Filtro pasa‑bajo FIR con NumPy

import numpy as np
import matplotlib.pyplot as plt
# Señal de prueba: suma de dos senoidales
fs = 1000                     # Hz
t = np.arange(0, 1, 1/fs)
signal = np.sin(2*np.pi*50*t) + 0.5*np.sin(2*np.pi*200*t)
# Coeficientes FIR (windowed‑sinc)
cutoff = 100 / (fs/2)        # Normalizado (Nyquist)
numtaps = 31
h = np.sinc(2*cutoff*(np.arange(numtaps)- (numtaps-1)/2))
window = np.hamming(numtaps)
h = h * window
h /= np.sum(h)               # Normalizar ganancia DC
# Convolución mediante matriz Toeplitz
X = toeplitz_matrix(signal, len(h))
filtered = X @ h
plt.figure(figsize=(10,4))
plt.plot(t, signal, label='Original')
plt.plot(t, filtered, label='Filtrado (FIR)', alpha=0.8)
plt.legend(); plt.title('Filtro pasa‑bajo FIR con matrices'); plt.xlabel('Tiempo (s)'); plt.show()

Ejemplo 2: Comparativa con scipy.signal.lfilter (IIR)

from scipy import signal as sp
# Diseño de un filtro Butterworth IIR de orden 4
b, a = sp.butter(N=4, Wn=cutoff, btype='low', analog=False)
filtered_iir = sp.lfilter(b, a, signal)
plt.figure(figsize=(10,4))
plt.plot(t, signal, label='Original')
plt.plot(t, filtered_iir, label='IIR (Butterworth)', alpha=0.8)
plt.legend(); plt.title('Filtro IIR Butterworth con SciPy'); plt.xlabel('Tiempo (s)'); plt.show()

En la tabla siguiente se comparan métricas clave entre la implementación matricial FIR y la solución IIR de SciPy.

MétricaFIR (NumPy)IIR (SciPy)
Orden del filtro30 (coeficientes)4 (polo‑cero)
Retardo de grupo≈15 samples≈0 samples (casi sin retardo)
Estabilidad numéricaGarantizada (coeficientes finitos)Depende de la colocación de polos
Rendimiento (CPU, 1 M muestras)≈12 ms (NumPy BLAS)≈6 ms (C‑optimizado)
Facilidad de paralelismo GPUAlta (matriz‑vector)Media (kernel interno)

Optimización y rendimiento

  • Uso de numpy.dot vs numpy.matmul: dot es ligeramente más rápido para vectores 1‑D, mientras que matmul aprovecha @ y se adapta mejor a GPU con cupy.
  • Batch processing: Si se procesan múltiples canales simultáneamente, construya una tensor 3‑D y use einsum para evitar bucles explícitos.
  • Precisión: Para filtros de orden elevado, prefiera float64 o float128 para evitar errores de redondeo, especialmente en IIR.
  • Memoria: La matriz Toeplitz ocupa N×M elementos; para señales muy largas (≥10⁶) utilice bloques deslizantes (overlap‑add) o la FFT (np.fft.fft) para reducir complejidad a O(N log N).

Seguridad y buenas prácticas

  • Valide siempre la longitud del kernel: M <= N para evitar index out of bounds al crear la matriz Toeplitz.
  • Sanitice los datos de entrada (escala a [-1, 1]) para evitar saturación en filtros de tipo IIR.
  • Utilice np.seterr(divide='raise') durante el desarrollo para detectar divisiones por cero en filtros IIR.
  • Documente la respuesta en frecuencia (sp.freqz) y compárela contra especificaciones de diseño.

Depuración (troubleshooting)

Algunos síntomas comunes y sus soluciones:

  • Respuesta distorsionada: Verifique que el kernel esté correctamente normalizado y que no haya aliasing (frecuencia de Nyquist).
  • Retardo inesperado: Recuerde que un FIR introduce un retardo de (M‑1)/2 muestras; compense con un desplazamiento temporal.
  • Desbordamiento de memoria: Para N×M grande, cambie a overlap‑add o FFT‑based convolution (scipy.signal.fftconvolve).

Conclusiones

Los filtros digitales basados en matrices ofrecen una visión algebraica clara del proceso de convolución y facilitan la paralelización en CPUs y GPUs. Si bien la implementación directa con np.convolve es suficiente para prototipos, la construcción de la matriz Toeplitz abre puertas a:

  • Batch processing multi‑canal.
  • Integración con frameworks de aprendizaje profundo (torch.nn.Conv1d).
  • Optimización mediante BLAS/LAPACK o kernels CUDA.

Combine la claridad de los FIR matriciales con la eficiencia de los IIR cuando el retardo sea crítico, y siempre valide la respuesta en frecuencia para cumplir los requisitos de su aplicación.



Filtros Digitales con Matrices: Algoritmos y Ejemplos en Python
ASIMOV Ingeniería S. de R.L. de C.V., Emiliano Nava 13 noviembre, 2025
Compartir
Iniciar sesión dejar un comentario

  
Algoritmos de Optimización Lineal: Fundamentos de Álgebra Lineal y Ejemplos Prácticos en Python
Guía completa sobre cómo aplicar álgebra lineal a la optimización lineal, con teoría, ejemplos en Python, mejores prácticas, comparativas y estrategias de troubleshooting.