Ir al contenido

IDEAS PRÁCTICAS · ASIMOV INGENIERÍA

Transformada de Hadamard: teoría, implementación en Python y comparativas con otras transformadas

Guía completa sobre la Transformada de Hadamard, su fundamento matemático, casos de uso, implementación paso a paso en Python y comparativas con FFT, DCT y Walsh.

Imagen ilustrativa · Chris Ried / Unsplash.

Table of contents

No titles in the blog post

1. Introducción

La Transformada de Hadamard (también conocida como Walsh‑Hadamard Transform o WHT) es una herramienta de procesamiento de señales que convierte una secuencia de valores en una combinación lineal de funciones ortogonales de forma binaria (valores +1 y –1). A diferencia de la Transformada de Fourier, que emplea senos y cosenos continuos, la WHT utiliza únicamente sumas y restas, lo que la hace extremadamente rápida y adecuada para hardware de bajo consumo.

Computadora portátil con código junto a una planta
Imagen ilustrativa · James Harrison / Unsplash.

2. Fundamento matemático

Una matriz de Hadamard Hn de orden n = 2^k se define recursivamente:

H₁ = [1]
H₂ₖ = \begin{bmatrix} Hₖ & Hₖ \\ Hₖ & -Hₖ \end{bmatrix}

Para una señal x = [x₀, x₁, …, x_{n-1}], la transformada se calcula como:

y = Hₙ · x

Donde · indica el producto matricial. Como Hₙ es ortogonal, la inversa es simplemente Hₙ / n.

3. Propiedades clave

  • Ortogonalidad: Hₙ·Hₙᵀ = n·Iₙ.
  • Complejidad O(n log n): La versión fast (FWHT) reduce la complejidad a n·log₂ n, idéntica a la FFT.
  • Operaciones binarias: Solo suma y resta, sin multiplicaciones por constantes complejas.
  • Espectro real y simétrico: Útil para análisis de señales binarias y datos de imagen.

4. Implementación en Python (FWHT)

La versión iterativa más eficiente se basa en el algoritmo de “divide‑y‑vencerás”. A continuación, un ejemplo limpio y documentado.

import numpy as np

def fwht(x: np.ndarray) -> np.ndarray:
    """Fast Walsh‑Hadamard Transform (in‑place).

    Parámetros
    ----------
    x : np.ndarray
        Vector de longitud 2ⁿ (se lanza ValueError si la longitud no es potencia de 2).

    Returns
    -------
    np.ndarray
        Transformada de Hadamard del vector ``x``.
    """
    n = x.shape[0]
    if n & (n - 1) != 0:
        raise ValueError('La longitud del vector debe ser una potencia de 2')
    h = 1
    y = x.astype(float).copy()
    while h < n:
        for i in range(0, n, h * 2):
            for j in range(i, i + h):
                a = y[j]
                b = y[j + h]
                y[j] = a + b      # suma
                y[j + h] = a - b  # resta
        h *= 2
    return y

# Ejemplo de uso
if __name__ == '__main__':
    signal = np.array([1, 2, 3, 4, 0, 1, 0, 1])
    transformed = fwht(signal)
    print('Señal original :', signal)
    print('Transformada   :', transformed)
    # Inversa (dividir por n)
    inverse = fwht(transformed) / signal.size
    print('Reconstruida   :', inverse)

El algoritmo funciona in‑place, lo que reduce la huella de memoria, y su complejidad es O(n log n).

5. Comparativa con otras transformadas

Ventajas de Hadamard vs FFT
  • Solo operaciones aritméticas simples (suma/resta).
  • Sin números complejos → menos errores de redondeo.
  • Ideal para datos binarios (imágenes en blanco‑negro, señales de comunicaciones).
  • Menor consumo de energía en hardware FPGA/ASIC.
Desventajas de Hadamard vs FFT
  • No captura componentes de frecuencia continua como la FFT.
  • Menos útil para análisis espectral de señales analógicas.
  • Requiere longitud potencia de 2 (aunque se pueden zero‑pad).
Hadamard vs DCT (Discrete Cosine Transform)
  • Hadamard: bases {+1, -1}. DCT: bases sinusoidales reales.
  • DCT suele dar mejor compresión en JPEG por su correlación con la percepción visual.
  • Hadamard es más rápida en hardware de bajo nivel.
Hadamard vs Walsh (orden natural)
  • Walsh es una permutación de Hadamard ordenada por “secuencia de Gray”.
  • Ambas comparten la misma matriz base; la diferencia está en el orden de los coeficientes.
  • En aplicaciones de multiplexado, la versión Walsh‑ordered es preferida.

6. Casos de uso reales

  1. Compresión de imágenes binarias: La WHT reduce la entropía de imágenes de texto o diagramas.
  2. Comunicación por línea de visión (Li-Fi) y CDMA: Codificación y decodificación de secuencias de chips.
  3. Algoritmos de aprendizaje rápido: Kernels basados en Hadamard para SVM y redes neuronales (Fastfood).
  4. Generación de patrones de prueba en hardware: Señales de pseudo‑aleatoriedad con bajo coste.

7. Buenas prácticas y optimizaciones

  • Uso de NumPy vectorizado: Para vectores muy grandes (> 2⁲⁰) considere scipy.fftpack con ``dtype=np.int8`` y luego convierta a float para evitar overflow.
  • Pre‑alocar buffers: Evite crear copias dentro del bucle; pasar un buffer pre‑inicializado a la función.
  • Paralelismo con Numba o Cython: Decorar la función con @njit(parallel=True) puede reducir el tiempo de ejecución en un 30‑50%.
  • Gestión de overflow: Para datos enteros de gran magnitud, convierta a ``float64`` antes de la transformación o normalice la señal.

8. Depuración y troubleshooting

Los problemas más frecuentes y sus soluciones:

ProblemaPosible causaSolución
Resultado inesperado (todos ceros)Longitud del vector no es potencia de 2Zero‑pad hasta la siguiente potencia de 2 o lanzar excepción.
Overflow en enteros de 16‑bitSumas/Restas superan el rangoConvertir a ``float64`` antes de la WHT.
Desfase entre señal original y reconstruidaNo dividir por n al aplicar la inversaMultiplicar por ``1/n`` después de la segunda llamada a ``fwht``.
Rendimiento pobre para vectores pequeñosOverhead de PythonUsar la versión recursiva para n ≤ 1024 o emplear C‑extensions.

9. Compatibilidad, rendimiento y escalabilidad

La WHT está disponible en la mayoría de los entornos de cálculo numérico:

  • Python: Implementación pura (como la mostrada) o pywt (Wavelet Toolbox) que incluye hadamard.
  • MATLAB/Octave: hadamard y wht (Signal Processing Toolbox).
  • R: Paquete pracma con hadamard.
  • Hardware: FPGA/ASIC pueden ejecutar la WHT en < 10 ns para bloques de 1024 bits.

En clústeres de cómputo distribuido, la transformación se paraleliza fácilmente dividiendo el vector en sub‑bloques y combinando resultados con un reduce de tipo suma.

10. Conclusiones

La Transformada de Hadamard sigue siendo una alternativa poderosa a la FFT cuando:

  • Se trabaja con datos binarios o de bajo ancho de banda.
  • Se requiere una implementación ultra‑rápida y de bajo consumo.
  • Se desea evitar la complejidad de números complejos.

Con la implementación en Python presentada, puedes experimentar rápidamente, ajustar el algoritmo con Numba o Cython y aplicar la WHT a problemas de compresión, comunicaciones y aprendizaje automático.