Buscar en este blog....

viernes, 7 de enero de 2011

¿Convolución? ¡Pero si es muy fácil! (Parte 3/3)

Buenas. Hoy voy a terminar con la última parte que había comentado sobre el tema de convolución. Básicamente voy a presentar un pequeño código que hice en C, y que muestra dos formas de realizar la convolución. En la primera de ellas, llamada (Input Side Algorithm) y denominada como input_side_conv() en el código, se puede observar que se obtiene la convolución de una forma muy simple: se recorren todos los puntos de la señal x[n] y h[n], y en base a esto se calcula el y[n] correspondiente.

La segunda función, llamada output_side_conv(), obtiene la convolución con el Output Side Algorithm, la cual varía de la anterior en un punto muy importante. Antes de ver cual es la diferencia importante, veamos el código, ya que es muy simple de entender:


#include <stdio.h>
#include <stdlib.h>

#define PUNTOS_X (6)
#define PUNTOS_H (4)
#define PUNTOS_Y ((PUNTOS_X) + (PUNTOS_H) - 1)

/* Los metodos tienen la misma interfaz:
x, h ---> son las señales de entrada
y ---> es la señal de salida */
void input_side_conv(int *x, int *h, int *y)
{
int i,j;
for(i=0;i<PUNTOS_X; i++)
for(j=0;j<PUNTOS_H;j++)
y[i+j]=y[i+j]+x[i]*h[j];
}

void output_side_conv(int *x, int *h, int *y)
{
int i,j;

for(i=0;i<PUNTOS_Y; i++) {
y[i]=0;
for(j=0;j<PUNTOS_H;j++) {
if(i-j<0 || i-j>=PUNTOS_X) continue;
y[i] = y[i]+h[j]*x[i-j];
}
}
}

int main()
{
int x[PUNTOS_X] = {0,-1,-1,2,1,1};
int h[PUNTOS_H] = {1,0,-1,1};
int y1[PUNTOS_Y] = {0,0,0,0,0,0,0,0,0};
int y2[PUNTOS_Y] = {0,0,0,0,0,0,0,0,0};

int i;

//calculamos la convolucion por el primer metodo
input_side_conv(x, h, y1);
//calculamos la convolucion por el otro metodo
output_side_conv(x, h, y2);

//mostramos las dos respuestas
printf("Input Side Output Side\n");
for(i=0;i<PUNTOS_Y;i++)
printf("[%2d] [%d]\n", y1[i], y2[i]);

return 0;
}


Vemos que he definido 3 constantes simbólicas con #define. Las mismas son PUNTOS_X, PUNTOS_H y PUNTOS_Y. Cada uno denota la cantidad de puntos que tiene cada señal involucrada. En el caso de PUNTOS_Y se puede obtener con la operación que puse, según la fórmula que expliqué en la primera parte de esta serie de artículos.

Luego siguen las definiciones de las funciones que calculan la convolución. Ambas dan el mismo resultado, pero cada una lo calcula de forma distinta.

Finalmente, tenemos un main() que lo unico que hace es fijar valores para x[n] y h[n] y luego realiza la convolución de las mismas en dos señales de salida, y1[n] e y2[n] y muestra en forma "de tabla" el resultado de ambas para simplificar la comparación y ver que dan el mismo resultado.

La diferencia importante de la que hablé recién, es la siguiente: si observamos con detalle cómo se calcula cada convolución, podemos notar que la segunda forma, output_side_conv() tiene una ventaja importante, y ésta es que permite calcular un valor específico de y[n] sin que sea necesario conocer todos los puntos de x[n], sino solo los necesarios. En cambio, en la otra función necestiamos conocer todos los puntos de x[n] de antemano, ya que los recorremos uno a uno, y en base a esto vamos calculando cada valor de y[n]. ¿Por qué esto es tan importante? Porque generalmente, no contamos con todos los puntos de x[n] ya que muchas veces se necesita obtener la convolución a medida que se va obteniendo la señal x[n], es decir, obtener y[n] en tiempo real.

Acá les dejo el código en C para que no tengan que copiarlo a mano: bajar código en C .

Bueno, con esto doy por finalizados los artículos de convolución, espero que les haya resultado interesante, divertido.. o al menos práctico!

9 comentarios:

  1. hola corri el codigo pero no funciona dice que hay un error de sintaxis en el void

    ResponderEliminar
  2. que extraño, lo acabo de probar y compila y corre perfectamente.

    Decime en que linea te tiro el error.
    Además seria bueno saber que compilador estas usando.

    Saludos!

    ResponderEliminar
  3. Muchísimas gracias, me ha quedado todo mucho más claro y para mi proyecto de fin de carrera que necesito implementar una convolución en tiempo real (Es un proyecto de audio) creo que me resultará de muchísima ayuda.

    Un gran aporte, gracias.

    ResponderEliminar
  4. Excelente trabajo!!! muchas gracias por haber hecho esto me ha servido bastante d°.°

    ResponderEliminar
  5. Estimado, muy bueno tu artículo y más aún la programación, que es lo que nos permite aplicar el algoritmo de la convolución. Sólo un detalle: en el rigor de señales,h(n) es la respuesta del sistema LTI al impulso unitario d(n) y no sería una función de entrada. Gracias por el aporte y la programación tan bien explicada, ya que la mayoría de nosotros lo realizamos en matlab.

    ResponderEliminar
  6. Hola Jorge, muchísimas gracias por facilitar esa aclaración, ya que lo que decís es correcto. Me faltó aclarar que x() y h() son parametros de entrada en terminos de "programación", pero en términos matemáticos, h() es la respuesta del sistema del sistema al impulso unitario. Muchas gracias por tomarte el tiempo para aclararlo. Saludos!

    ResponderEliminar
  7. Ignacio, muy buena y didáctica tu explicación y con una visión conceptual. Puesto de convolucion esta lleno de formulas y libros de señales y sistemas, pero la gracia es el entendimiento conceptualizado puesto las matemáticas son solo la herramienta para explicar el proceso físico. Entendiendo el proceso comenzamos según nuestras habilidades a desarrollarlo.

    Reitero mis felicitaciones por el poder de sintesis
    Raul Reyes Valle
    Santiago Chile

    ResponderEliminar
  8. me acabas de ayudar demasiado! gracias infinitas

    ResponderEliminar

Comments are subject to moderation, only in order to avoid insults and disguising things.

Los comentarios están sujetos a moderación, solo con el fin de evitar insultos y cosas por el estilo.