X-Git-Url: https://hackdaworld.org/gitweb/?a=blobdiff_plain;f=fourier%2Ffourier.c;h=d322bc03ae0d807ea5e5a4da1a52c801dd704a52;hb=f8382861ee7bff6d129bd149579d26bf9b81ada0;hp=255012bfaa232ce68c4738d03ca6afa908164cc9;hpb=024d1f9a04d8dd291883d1781e671a4eab7b4c9f;p=my-code%2Fapi.git diff --git a/fourier/fourier.c b/fourier/fourier.c index 255012b..d322bc0 100644 --- a/fourier/fourier.c +++ b/fourier/fourier.c @@ -19,15 +19,22 @@ int fourier_init(t_fourier *fourier,int outfd) { int fourier_alloc_data(t_fourier *fourier) { - int i; - - for(i=0;idim;i++) { - fourier->data[i]=(t_complex *)malloc(fourier->data_len[i]*sizeof(t_complex)); - fourier->ftdata[i]=(t_complex *)malloc(fourier->data_len[i]*sizeof(t_complex)); - if((fourier->data[i]==NULL)||(fourier->ftdata[i]==NULL)) { - dprintf(fourier->outfd,"[fourier] malloc failed\n"); - return F_ALLOC_FAIL; - } + int i,size; + + size=1; + for(i=0;idim;i++) size*=fourier->data_len[i]; + + dprintf(fourier->outfd,"[fourier] allocating %d bytes for data ...\n", + 2*size*sizeof(t_complex)); + + fourier->data=(t_complex *)malloc(2*size*sizeof(t_complex)); + fourier->ftdata=&(fourier->data[size]); + + memset(fourier->data,0,2*size*sizeof(t_complex)); + + if(fourier->data==NULL) { + dprintf(fourier->outfd,"[fourier] malloc failed\n"); + return F_ALLOC_FAIL; } return F_SUCCESS; @@ -35,49 +42,115 @@ int fourier_alloc_data(t_fourier *fourier) { int fourier_shutdown(t_fourier *fourier) { - int i; - dprintf(fourier->outfd,"[fourier] shutdown\n"); - for(i=0;idim;i++) { - free(fourier->data[i]); - free(fourier->ftdata[i]); + free(fourier->data); + + return F_SUCCESS; +} + +/* fft functions */ + +int fourier_fft_1d_init(t_fourier *fourier) { + + unsigned int i,j,m,r; + int mask[32]; + + /* calculate m = log 2 (N) + check N = 2^m */ + m=0; + while(m<32) { + if(1<data_len[0]) break; + else m++; } + if(m==32) { + dprintf(fourier->outfd, + "[fourier] fft impossible (N > 2^32 or not a power of 2\n"); + return F_FFT_IMPOSSIBLE; + } + dprintf(fourier->outfd,"[fourier] log2(%d) = %d\n",fourier->data_len[0],m); + fourier->log2len[0]=m; + + /* pointer array which will point to reversed t_complex data */ + fourier->revdata=(t_complex **)malloc(fourier->data_len[0]*sizeof(t_complex *)); + if(fourier->revdata==NULL) { + dprintf(fourier->outfd, + "[fourier] malloc for reversed data pointers failed\n"); + return F_ALLOC_FAIL; + } + + dprintf(fourier->outfd,"[fourier] fft: allocated data pointers\n"); + + /* swap data (bit reversal) */ + for(i=0;idata_len[0];i++) { + r=0; + for(j=0;j>j)<<(m-j-1)); + fourier->revdata[i]=fourier->ftdata+r; + } + + return F_SUCCESS; +} + +int fourier_fft_1d_shutdown(t_fourier *fourier) { + + dprintf(fourier->outfd,"[fourier] fft shutdown\n"); + + free(fourier->revdata); + + return F_SUCCESS; +} + + +int fourier_fft_1d(t_fourier *fourier) { + + int i,j; + + /* copy src to destination, destination is modified in place */ + memcpy(fourier->ftdata,fourier->data,fourier->data_len[0]*sizeof(t_complex)); + /* from now on access bit reversed data by revdata[i]->... */ + + // for(i=0;ilog2len[0];i++) { + + + // } + + + for(i=0;idata_len[0];i++) + dprintf(fourier->outfd,"%f %f\n", + fourier->ftdata[i]->r,fourier->revdata[i]->i); + + return F_NOT_SUPPORTED; return F_SUCCESS; } int fourier_dft_1d(t_fourier *fourier) { - int i,k,dim; + int i,k; double arg; if(fourier->type&FWD) { - for(dim=0;dimdim;dim++) { - for(k=0;kdata_len[dim];k++) { - fourier->ftdata[dim][k].r=0; - fourier->ftdata[dim][k].i=0; - for(i=0;idata_len[dim];i++) { - /* f(k) = 1/N sum(n=0-N) f(n) exp(-i*k*2*PI*n/N) */ - arg=-1.0*k*M_PI*i/fourier->data_len[dim]; - fourier->ftdata[dim][k].r+=(cos(arg)*fourier->data[dim][i].r-sin(arg)*fourier->data[dim][i].i); - fourier->ftdata[dim][k].i+=(sin(arg)*fourier->data[dim][i].r+cos(arg)*fourier->data[dim][i].i); - } - fourier->ftdata[dim][k].r/=fourier->data_len[dim]; - fourier->ftdata[dim][k].i/=fourier->data_len[dim]; + for(k=0;kdata_len[0];k++) { + fourier->ftdata[k].r=0; + fourier->ftdata[k].i=0; + for(i=0;idata_len[0];i++) { + /* f(k) = 1/N sum(n=0-N) f(n) exp(-i*k*2*PI*n/N) */ + arg=-2.0*k*M_PI*i/fourier->data_len[0]; + fourier->ftdata[k].r+=(cos(arg)*fourier->data[i].r-sin(arg)*fourier->data[i].i); + fourier->ftdata[k].i+=(sin(arg)*fourier->data[i].r+cos(arg)*fourier->data[i].i); } + fourier->ftdata[k].r/=fourier->data_len[0]; + fourier->ftdata[k].i/=fourier->data_len[0]; } } else { - for(dim=1;dim<=fourier->dim;dim++) { - for(k=0;kdata_len[dim];k++) { - fourier->data[dim][k].r=0; - fourier->data[dim][k].i=0; - for(i=0;idata_len[dim];i++) { - arg=1.0*k*M_PI*i/fourier->data_len[dim]; - fourier->data[dim][k].r+=(cos(arg)*fourier->ftdata[dim][i].r-sin(arg)*fourier->ftdata[dim][i].i); - fourier->data[dim][k].i+=(sin(arg)*fourier->ftdata[dim][i].r+cos(arg)*fourier->ftdata[dim][i].i); - } + for(k=0;kdata_len[0];k++) { + fourier->data[k].r=0; + fourier->data[k].i=0; + for(i=0;idata_len[0];i++) { + arg=2.0*k*M_PI*i/fourier->data_len[0]; + fourier->data[k].r+=(cos(arg)*fourier->ftdata[i].r-sin(arg)*fourier->ftdata[i].i); + fourier->data[k].i+=(sin(arg)*fourier->ftdata[i].r+cos(arg)*fourier->ftdata[i].i); } } } @@ -86,39 +159,39 @@ int fourier_dft_1d(t_fourier *fourier) { } int fourier_dft_2d(t_fourier *fourier) { - return 0; -} -int fourier_dft_3d(t_fourier *fourier) { - return 0; -} + int off_f,off_r; + int u,v,x,y; + int X,Y; + double arg; -int fourier_calc(t_fourier *fourier) { - - dprintf(fourier->outfd,"[fourier] %d dimensional %c-%cft calculation ...\n", - fourier->dim, - ((fourier->type&FWD)?'f':'b'), - ((fourier->type&DFT)?'d':'f')); - - if(fourier->type&DFT) { - switch(fourier->dim) { - case 1: - fourier_dft_1d(fourier); - break; - case 2: - fourier_dft_2d(fourier); - break; - case 3: - fourier_dft_3d(fourier); - break; - default: - dprintf(fourier->outfd,"[fourier] dimension failure\n"); - return F_DIM_FAILURE; + X=fourier->data_len[0]; + Y=fourier->data_len[1]; + + if(fourier->type&BWD) return F_NOT_SUPPORTED; + + /* stupid way - actually you would do: ft_on_index_1(ft_on_index_2(f(x,y))) */ + for(v=0;vftdata[off+u].r=0; + fourier->ftdata[off+u].i=0; + for(y=0;yftdata[off+u].r+=(cos(arg)*fourier->data[off_r+x].r-sin(arg)*fourier->data[off_r+x].i); + fourier->ftdata[off+u].i+=(sin(arg)*fourier->data[off_r+x].r+cos(arg)*fourier->data[off_r+x].i); + } + } + fourier->ftdata[off_f+u].r/=(X*Y); + fourier->ftdata[off_f+u].i/=(X*Y); } - return F_SUCCESS; - } - else { - dprintf(fourier->outfd,"[fourier] fft not supported by now\n"); - return F_NOT_SUPPORTED; } -} + + return F_SUCCESS; +} + +int fourier_dft_3d(t_fourier *fourier) { + return F_NOT_SUPPORTED; +}