/* * conv.c * * Created on: May 1, 2013 * Author: Rafat Hussain */ #include "conv.h" int factorf(int M) { int N; N = M; while (N%7 == 0){ N = N/7; } while (N%3 == 0){ N = N/3; } while (N%5 == 0){ N = N/5; } while (N%2 == 0){ N = N/2; } return N; } int findnext(int M) { int N; N = M; while (factorf(N) != 1) { ++N; } return N; } int findnexte(int M) { int N; N = M; while (factorf(N) != 1 || N%2 != 0) { ++N; } return N; } conv_object conv_init(int N, int L) { conv_object obj = NULL; int conv_len; conv_len = N + L - 1; obj = (conv_object) malloc (sizeof(struct conv_set)); //obj->clen = npow2(conv_len); //obj->clen = conv_len; obj->clen = findnexte(conv_len); obj->ilen1 = N; obj->ilen2 = L; obj->fobj = fft_real_init(obj->clen,1); obj->iobj = fft_real_init(obj->clen,-1); return obj; } void conv_directx(fft_type *inp1,int N, fft_type *inp2, int L,fft_type *oup){ int M,k,n; M = N + L - 1; for (k = 0; k < M;++k) { oup[k] = 0.0; for ( n = 0; n < N; ++n) { if ( (k-n) >= 0 && (k-n) < L ) { oup[k]+= inp1[n] * inp2[k-n]; } } } } void conv_direct(fft_type *inp1,int N, fft_type *inp2, int L,fft_type *oup) { int M,k,m,i; fft_type t1,tmin; M = N + L -1; i = 0; if (N >= L) { for (k = 0; k < L; k++) { oup[k] = 0.0; for (m = 0; m <= k;m++) { oup[k]+= inp1[m] * inp2[k-m]; } } for (k = L; k < M; k++) { oup[k] = 0.0; i++; t1 = L + i; tmin = MIN(t1,N); for (m = i; m < tmin;m++) { oup[k]+= inp1[m] * inp2[k-m]; } } } else { for (k = 0; k < N; k++) { oup[k] = 0.0; for (m = 0; m <= k;m++) { oup[k]+= inp2[m] * inp1[k-m]; } } for (k = N; k < M; k++) { oup[k] = 0.0; i++; t1 = N + i; tmin = MIN(t1,L); for (m = i; m < tmin;m++) { oup[k]+= inp2[m] * inp1[k-m]; } } } } void conv_fft(const conv_object obj,fft_type *inp1,fft_type *inp2,fft_type *oup) { int i,N,L1,L2,ls; fft_type* a; fft_type* b; fft_data* c; fft_data* ao; fft_data* bo; fft_type* co; N = obj->clen; L1 = obj->ilen1; L2 = obj->ilen2; ls = L1 + L2 - 1; a = (fft_type*) malloc (sizeof(fft_data) * N); b = (fft_type*) malloc (sizeof(fft_data) * N); c = (fft_data*) malloc (sizeof(fft_data) * N); ao = (fft_data*) malloc (sizeof(fft_data) * N); bo = (fft_data*) malloc (sizeof(fft_data) * N); co = (fft_type*) malloc (sizeof(fft_data) * N); for (i = 0; i < N;i++) { if (i < L1) { a[i] = inp1[i]; } else { a[i] = 0.0; } if (i < L2) { b[i] = inp2[i]; } else { b[i] = 0.0; } } fft_r2c_exec(obj->fobj,a,ao); fft_r2c_exec(obj->fobj,b,bo); for (i = 0; i < N;i++) { c[i].re = ao[i].re * bo[i].re - ao[i].im * bo[i].im; c[i].im = ao[i].im * bo[i].re + ao[i].re * bo[i].im; } fft_c2r_exec(obj->iobj,c,co); for (i = 0; i < ls;i++) { oup[i] = co[i]/N; } free(a); free(b); free(c); free(ao); free(bo); free(co); } void free_conv(conv_object object) { free_real_fft(object->fobj); free_real_fft(object->iobj); free(object); }