Convolución Circular

Iniciado por drbeat, 2 Marzo 2011, 13:55 PM

0 Miembros y 1 Visitante están viendo este tema.

drbeat

/*Declaración de funciones*/
void conv(int dim1,int x[],int dim2,int h[],int y[]);


/*Funcion main*/
int main()
{
int i;
 printf("Introduzca la dimension del vector de entrada: ");
 scanf("%d",&dim1);
 
  xn = malloc(dim1 * sizeof (int));

 
  printf("Introduce los valores del primer vector:\n");
  for (i=0; i<dim1; i++) {
    printf("\nElemento %d: ", i+1);
    scanf("%d", &aux);
    *(xn+i)= aux;  
  }
  printf("\n");
 
  printf("Introduzca la dimension del segundo vector: ");
   scanf("%d",&dim2);
 
   hn = malloc(dim2 * sizeof (int));
 
  printf("Introduce los valores del segundo vector:\n");
  for (i=0; i<dim2; i++) {
    printf("\nElemento %d: ", i+1);
    scanf("%d", &aux);
    *(hn+i)=aux;
  }
 
  yn = malloc((dim1+dim2-1) * sizeof (int));

if(dim1<=dim2)
{
int dimcirc=dim2;
conv(dim1,xn,dim2,hn,yn);


printf("Dimension de la Convolucion Circular=%d \n" , dimcirc);
zn = malloc(dimcirc * sizeof (int));
zi=0;


wn = malloc(dimcirc * sizeof (int));
k=dim2-dim1-2;
q=dim1+dim2-2;


for(j=dimcirc-1;j>=0;j--)
{
*(zn+j)=0;
*(wn+j)=0;
*(wn+j)=*((yn+(q%dimcirc))+j);
*(zn+j)=*((yn+(k%dimcirc))-j);
}


for(zi=0;zi<dimcirc;zi++)
{
printf("zn:[%d]=%d \n",zi,(*(zn-zi)+*(wn-zi)));
}
}
else
{
int dimcirc=dim1;
paux = xn;
xn = hn;
hn = paux;
conv(dim2,xn,dim1,hn,yn);
printf("Dimension de la Convolucion Circular=%d \n" , dimcirc);
zn = malloc(dimcirc * sizeof (int));
zi=0;

wn = malloc(dimcirc * sizeof (int));
k=dim1-dim2-2;
q=dim1+dim2-2;


for(j=dimcirc-1;j>=0;j--)
{
*(zn+j)=0;
*(wn+j)=0;
*(wn+j)=*((yn+(q%dimcirc))+j);
*(zn+j)=*((yn+(k%dimcirc))-j);
}
for(zi=0;zi<dimcirc;zi++)
{
printf("zn:[%d]=%d \n",zi,(*(zn-zi)+*(wn-zi)));
}
}



}




void conv(int dim1,int x[],int dim2,int h[],int y[])
{
/*Declaro e Inicializo las variables contador de los vectores*/
int xi=0,yi=0,hi=0;
int dimres=dim1+dim2-1;
printf("Dimensión de la Convolución Lineal=%d \n",dimres);
for(xi=0;xi<dim1;xi++)
{

for(hi=0;hi<dim2;hi++)
{
y[xi+hi]=(y[xi+hi]+x[xi]*h[hi]);


}

}
for(yi=0;yi<dimres;yi++)
{ printf("yn:[%d]=%d \n",yi,y[yi]);
}






}


drbeat

#1
Hola buenas!
A pesar de ser nuevo en el foro a partir de ahora me veréis más por aquí.
Soy estudiante de teleco y estoy tratando de realizar la simulación de la convolución lineal y circular de 2 señales digitales genéricas en código C. A pesar de lo raro que os suene a algunos, no son más que 2 arrays unidimensionales que interactúan entre ellos.  El usuario elige previamente el numero de elementos de cada uno y cada valor.
En la convolucion lineal, se multiplican y se suman siendo el numero de elementos del resultado = numelementos1ºvector + numelementos2ºvector -1    ;y en la circular, el resultado de ésta y el vector mas pequeño deben tener el mismo numero de elementos que el primero y normalmente se implementa en código la Transformada de Fourier Discreta (DFT). Pero para evitar a Fourier, se coge el cacho correspondiente al array resultado de la convolucion lineal que cuadre con el numero de elementos del mayor vector, y al vector mas pequeño se le añaden ceros para despues sumar ambos y obtener el resultado.
Para que me comprendais mejor,  la convolucion se puede comprobar en Matlab haciendo y=conv(a,b) para la lineal  y=ifft(fft(a).*fft(b))   para la circular, siendo a y b dos vectores cualesquiera.

Dado mis conocimientos básiquisimos de programación y que hace años que no me topo con el lenguaje C, posteo este hilo para vuestro deleite.
El problema seguramente lo tenga al operar y en mis bucles "for" irrisorios.
Se agradece un cable ;)

Un saludin :)

drbeat

Nota:

En el código la funcion conv solo hace la convolucion lineal y de momento parece que funciona.
La convolución circular la trato de hacer justo después pero en el cuerpo de la main y no hay manera chico...  :-\

drbeat

No sé si estoy operando correctamente con los punteros *zn y *wn.
Lo que hago es reservar memoria previamente para ellos utilizando malloc, pero me gustaría usar calloc con el puntero *zn y da un error de memoria...  :-\

RyogiShiki

#4
Deberías colocar el código dentro de las etiquetas GeSHi seleccionando la opción para código C:

Solo para que se entienda mejor y no sea tedioso leerlo!
Saludos


drbeat