NFFT Logo 3.0 API Reference
Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals

linogram_fft_test.c

Go to the documentation of this file.
00001 
00009 #include <math.h>
00010 #include <stdlib.h>
00011 #include "util.h"
00012 #include "nfft3.h"
00013 
00020 double GLOBAL_elapsed_time;
00021 
00025 int linogram_grid(int T, int R, double *x, double *w)
00026 {
00027   int t, r;
00028   double W=(double)T*(((double)R/2.0)*((double)R/2.0)+1.0/4.0);
00029 
00030   for(t=-T/2; t<T/2; t++)
00031   {
00032     for(r=-R/2; r<R/2; r++)
00033     {
00034       if(t<0)
00035       {
00036         x[2*((t+T/2)*R+(r+R/2))+0] = (double)r/R;
00037         x[2*((t+T/2)*R+(r+R/2))+1] = (double)4*(t+T/4)/T*r/R;
00038       }
00039       else
00040       {
00041         x[2*((t+T/2)*R+(r+R/2))+0] = -(double)4*(t-T/4)/T*r/R;
00042         x[2*((t+T/2)*R+(r+R/2))+1] = (double)r/R;
00043       }
00044       if (r==0)
00045         w[(t+T/2)*R+(r+R/2)] = 1.0/4.0/W;
00046       else
00047         w[(t+T/2)*R+(r+R/2)] = fabs((double)r)/W;
00048     }
00049   }
00050 
00051   return T*R;                           
00052 }
00053 
00055 int linogram_dft(fftw_complex *f_hat, int NN, fftw_complex *f, int T, int R, int m)
00056 {
00057   int j,k;                              
00058   nfft_plan my_nfft_plan;               
00060   double *x, *w;                        
00062   int N[2],n[2];
00063   int M=T*R;                            
00065   N[0]=NN; n[0]=2*N[0];                 
00066   N[1]=NN; n[1]=2*N[1];                 
00068   x = (double *)malloc(2*T*R*(sizeof(double)));
00069   if (x==NULL)
00070     return -1;
00071 
00072   w = (double *)malloc(T*R*(sizeof(double)));
00073   if (w==NULL)
00074     return -1;
00075 
00077   nfft_init_guru(&my_nfft_plan, 2, N, M, n, m,
00078                   PRE_PHI_HUT| PRE_PSI| MALLOC_X | MALLOC_F_HAT| MALLOC_F| FFTW_INIT | FFT_OUT_OF_PLACE,
00079                   FFTW_MEASURE| FFTW_DESTROY_INPUT);
00080 
00082   linogram_grid(T,R,x,w);
00083   for(j=0;j<my_nfft_plan.M_total;j++)
00084   {
00085     my_nfft_plan.x[2*j+0] = x[2*j+0];
00086     my_nfft_plan.x[2*j+1] = x[2*j+1];
00087   }
00088 
00089 
00091   for(k=0;k<my_nfft_plan.N_total;k++)
00092     my_nfft_plan.f_hat[k] = f_hat[k];
00093 
00095   GLOBAL_elapsed_time=nfft_second();
00096   ndft_trafo(&my_nfft_plan);
00097   GLOBAL_elapsed_time=nfft_second()-GLOBAL_elapsed_time;
00098 
00100   for(j=0;j<my_nfft_plan.M_total;j++)
00101     f[j] = my_nfft_plan.f[j];
00102 
00104   nfft_finalize(&my_nfft_plan);
00105   free(x);
00106   free(w);
00107 
00108   return EXIT_SUCCESS;
00109 }
00110 
00112 int linogram_fft(fftw_complex *f_hat, int NN, fftw_complex *f, int T, int R, int m)
00113 {
00114   int j,k;                              
00115   nfft_plan my_nfft_plan;               
00117   double *x, *w;                        
00119   int N[2],n[2];
00120   int M=T*R;                            
00122   N[0]=NN; n[0]=2*N[0];                 
00123   N[1]=NN; n[1]=2*N[1];                 
00125   x = (double *)malloc(2*T*R*(sizeof(double)));
00126   if (x==NULL)
00127     return -1;
00128 
00129   w = (double *)malloc(T*R*(sizeof(double)));
00130   if (w==NULL)
00131     return -1;
00132 
00134   nfft_init_guru(&my_nfft_plan, 2, N, M, n, m,
00135                   PRE_PHI_HUT| PRE_PSI| MALLOC_X | MALLOC_F_HAT| MALLOC_F| FFTW_INIT | FFT_OUT_OF_PLACE,
00136                   FFTW_MEASURE| FFTW_DESTROY_INPUT);
00137 
00139   linogram_grid(T,R,x,w);
00140   for(j=0;j<my_nfft_plan.M_total;j++)
00141   {
00142     my_nfft_plan.x[2*j+0] = x[2*j+0];
00143     my_nfft_plan.x[2*j+1] = x[2*j+1];
00144   }
00145 
00147   if(my_nfft_plan.nfft_flags & PRE_LIN_PSI)
00148     nfft_precompute_lin_psi(&my_nfft_plan);
00149 
00150   if(my_nfft_plan.nfft_flags & PRE_PSI)
00151     nfft_precompute_psi(&my_nfft_plan);
00152 
00153   if(my_nfft_plan.nfft_flags & PRE_FULL_PSI)
00154     nfft_precompute_full_psi(&my_nfft_plan);
00155 
00157   for(k=0;k<my_nfft_plan.N_total;k++)
00158     my_nfft_plan.f_hat[k] = f_hat[k];
00159 
00161   GLOBAL_elapsed_time=nfft_second();
00162   nfft_trafo(&my_nfft_plan);
00163   GLOBAL_elapsed_time=nfft_second()-GLOBAL_elapsed_time;
00164 
00166   for(j=0;j<my_nfft_plan.M_total;j++)
00167     f[j] = my_nfft_plan.f[j];
00168 
00170   nfft_finalize(&my_nfft_plan);
00171   free(x);
00172   free(w);
00173 
00174   return EXIT_SUCCESS;
00175 }
00176 
00178 int inverse_linogram_fft(fftw_complex *f, int T, int R, fftw_complex *f_hat, int NN, int max_i, int m)
00179 {
00180   int j,k;                              
00181   nfft_plan my_nfft_plan;               
00182   infft_plan my_infft_plan;             
00184   double *x, *w;                        
00185   int l;                                
00187   int N[2],n[2];
00188   int M=T*R;                            
00190   N[0]=NN; n[0]=2*N[0];                 
00191   N[1]=NN; n[1]=2*N[1];                 
00193   x = (double *)malloc(2*T*R*(sizeof(double)));
00194   if (x==NULL)
00195     return -1;
00196 
00197   w = (double *)malloc(T*R*(sizeof(double)));
00198   if (w==NULL)
00199     return -1;
00200 
00202   nfft_init_guru(&my_nfft_plan, 2, N, M, n, m,
00203                   PRE_PHI_HUT| PRE_PSI| MALLOC_X | MALLOC_F_HAT| MALLOC_F| FFTW_INIT | FFT_OUT_OF_PLACE,
00204                   FFTW_MEASURE| FFTW_DESTROY_INPUT);
00205 
00207   infft_init_advanced(&my_infft_plan,&my_nfft_plan, CGNR | PRECOMPUTE_WEIGHT );
00208 
00210   linogram_grid(T,R,x,w);
00211   for(j=0;j<my_nfft_plan.M_total;j++)
00212   {
00213     my_nfft_plan.x[2*j+0] = x[2*j+0];
00214     my_nfft_plan.x[2*j+1] = x[2*j+1];
00215     my_infft_plan.y[j]    = f[j];
00216     my_infft_plan.w[j]    = w[j];
00217   }
00218 
00220   if(my_nfft_plan.nfft_flags & PRE_LIN_PSI)
00221     nfft_precompute_lin_psi(&my_nfft_plan);
00222 
00223   if(my_nfft_plan.nfft_flags & PRE_PSI)
00224     nfft_precompute_psi(&my_nfft_plan);
00225 
00226   if(my_nfft_plan.nfft_flags & PRE_FULL_PSI)
00227     nfft_precompute_full_psi(&my_nfft_plan);
00228 
00230   if(my_infft_plan.flags & PRECOMPUTE_DAMP)
00231     for(j=0;j<my_infft_plan.mv->N[0];j++)
00232       for(k=0;k<my_infft_plan.mv->N[1];k++)
00233   {
00234     my_infft_plan.w_hat[j*my_infft_plan.mv->N[1]+k]=
00235         (sqrt(pow(j-my_infft_plan.mv->N[0]/2,2)+pow(k-my_infft_plan.mv->N[1]/2,2))>(my_infft_plan.mv->N[0]/2)?0:1);
00236   }
00237 
00239   for(k=0;k<my_nfft_plan.N_total;k++)
00240     my_infft_plan.f_hat_iter[k] = 0.0 + I*0.0;
00241 
00242   GLOBAL_elapsed_time=nfft_second();
00244   infft_before_loop(&my_infft_plan);
00245 
00246   if (max_i<1)
00247   {
00248     l=1;
00249     for(k=0;k<my_nfft_plan.N_total;k++)
00250       my_infft_plan.f_hat_iter[k] = my_infft_plan.p_hat_iter[k];
00251   }
00252   else
00253   {
00254     for(l=1;l<=max_i;l++)
00255     {
00256       infft_loop_one_step(&my_infft_plan);
00257     }
00258   }
00259 
00260   GLOBAL_elapsed_time=nfft_second()-GLOBAL_elapsed_time;
00261 
00263   for(k=0;k<my_nfft_plan.N_total;k++)
00264     f_hat[k] = my_infft_plan.f_hat_iter[k];
00265 
00267   infft_finalize(&my_infft_plan);
00268   nfft_finalize(&my_nfft_plan);
00269   free(x);
00270   free(w);
00271 
00272   return EXIT_SUCCESS;
00273 }
00274 
00276 int comparison_fft(FILE *fp, int N, int T, int R)
00277 {
00278   fftw_plan my_fftw_plan;
00279   fftw_complex *f_hat,*f;
00280   int m,k;
00281   double t_fft, t_dft_linogram;
00282 
00283   f_hat = (fftw_complex *)fftw_malloc(sizeof(fftw_complex)*N*N);
00284   f     = (fftw_complex *)fftw_malloc(sizeof(fftw_complex)*(T*R/4)*5);
00285 
00286   my_fftw_plan = fftw_plan_dft_2d(N,N,f_hat,f,FFTW_BACKWARD,FFTW_MEASURE);
00287 
00288   for(k=0; k<N*N; k++)
00289     f_hat[k] = (((double)rand())/RAND_MAX) + I* (((double)rand())/RAND_MAX);
00290   
00291   GLOBAL_elapsed_time=nfft_second();
00292   for(m=0;m<65536/N;m++)
00293     {
00294       fftw_execute(my_fftw_plan);
00295       /* touch */
00296       f_hat[2]=2*f_hat[0];
00297     }
00298   GLOBAL_elapsed_time=nfft_second()-GLOBAL_elapsed_time;
00299   t_fft=N*GLOBAL_elapsed_time/65536;
00300 
00301   if(N<256)
00302     {
00303       linogram_dft(f_hat,N,f,T,R,m);
00304       t_dft_linogram=GLOBAL_elapsed_time;
00305     }
00306       
00307   for (m=3; m<=9; m+=3)
00308     {
00309       if((m==3)&&(N<256))
00310         fprintf(fp,"%d\t&\t&\t%1.1e&\t%1.1e&\t%d\t",N,t_fft,t_dft_linogram,m);
00311       else
00312         if(m==3)
00313     fprintf(fp,"%d\t&\t&\t%1.1e&\t       &\t%d\t",N,t_fft,m);
00314   else
00315     fprintf(fp,"  \t&\t&\t       &\t       &\t%d\t",m);  
00316 
00317       printf("N=%d\tt_fft=%1.1e\tt_dft_linogram=%1.1e\tm=%d\t",N,t_fft,t_dft_linogram,m);              
00318    
00319       linogram_fft(f_hat,N,f,T,R,m);
00320       fprintf(fp,"%1.1e&\t",GLOBAL_elapsed_time);
00321       printf("t_linogram=%1.1e\t",GLOBAL_elapsed_time);
00322       inverse_linogram_fft(f,T,R,f_hat,N,m+3,m);
00323       if(m==9)
00324   fprintf(fp,"%1.1e\\\\\\hline\n",GLOBAL_elapsed_time);
00325       else
00326   fprintf(fp,"%1.1e\\\\\n",GLOBAL_elapsed_time);
00327       printf("t_ilinogram=%1.1e\n",GLOBAL_elapsed_time);
00328     }
00329 
00330   fflush(fp);
00331 
00332   fftw_free(f);
00333   fftw_free(f_hat);  
00334 
00335   return EXIT_SUCCESS;
00336 }
00337 
00339 int main(int argc,char **argv)
00340 {
00341   int N;                                
00342   int T, R;                             
00343   int M;                                
00344   double *x, *w;                        
00345   fftw_complex *f_hat, *f, *f_direct, *f_tilde;
00346   int k;
00347   int max_i;                            
00348   int m;
00349   double temp1, temp2, E_max=0.0;
00350   FILE *fp1, *fp2;
00351   char filename[30];
00352   int logN;
00353 
00354   if( argc!=4 )
00355   {
00356     printf("linogram_fft_test N T R \n");
00357     printf("\n");
00358     printf("N          linogram FFT of size NxN    \n");
00359     printf("T          number of slopes          \n");
00360     printf("R          number of offsets         \n");
00361 
00363     printf("\nHence, comparison FFTW, linogram FFT and inverse linogram FFT\n");
00364     fp1=fopen("linogram_comparison_fft.dat","w");
00365     if (fp1==NULL)
00366   return(-1);
00367     for (logN=4; logN<=8; logN++)
00368   comparison_fft(fp1,(1U<< logN), 3*(1U<< logN), 3*(1U<< (logN-1)));
00369     fclose(fp1);
00370 
00371     exit(-1);
00372   }
00373 
00374   N = atoi(argv[1]);
00375   T = atoi(argv[2]);
00376   R = atoi(argv[3]);
00377   printf("N=%d, linogram grid with T=%d, R=%d => ",N,T,R);
00378 
00379   x = (double *)malloc(2*1.25*T*R*(sizeof(double)));
00380   w = (double *)malloc(1.25*T*R*(sizeof(double)));
00381 
00382   f_hat    = (fftw_complex *)fftw_malloc(sizeof(fftw_complex)*N*N);
00383   f        = (fftw_complex *)fftw_malloc(sizeof(fftw_complex)*1.25*T*R);  /* 4/pi*log(1+sqrt(2)) = 1.122... < 1.25 */
00384   f_direct = (fftw_complex *)fftw_malloc(sizeof(fftw_complex)*1.25*T*R);
00385   f_tilde  = (fftw_complex *)fftw_malloc(sizeof(fftw_complex)*N*N);
00386 
00388   M=linogram_grid(T,R,x,w); printf("M=%d.\n",M);
00389 
00391   fp1=fopen("input_data_r.dat","r");
00392   fp2=fopen("input_data_i.dat","r");
00393   if ((fp1==NULL) || (fp2==NULL))
00394     return(-1);
00395   for(k=0;k<N*N;k++)
00396   {
00397     fscanf(fp1,"%le ",&temp1);
00398     fscanf(fp2,"%le ",&temp2);
00399     f_hat[k]=temp1+I*temp2;
00400   }
00401   fclose(fp1);
00402   fclose(fp2);
00403 
00405       linogram_dft(f_hat,N,f_direct,T,R,m);
00406   //  linogram_fft(f_hat,N,f_direct,T,R,12);
00407 
00409   printf("\nTest of the linogram FFT: \n");
00410   fp1=fopen("linogram_fft_error.dat","w+");
00411   for (m=1; m<=12; m++)
00412   {
00414     linogram_fft(f_hat,N,f,T,R,m);
00415 
00417     E_max=nfft_error_l_infty_complex(f_direct,f,M);
00418     //E_max=nfft_error_l_2_complex(f_direct,f,M);
00419 
00420     printf("m=%2d: E_max = %e\n",m,E_max);
00421     fprintf(fp1,"%e\n",E_max);
00422   }
00423   fclose(fp1);
00424 
00426   for (m=3; m<=9; m+=3)
00427   {
00428     printf("\nTest of the inverse linogram FFT for m=%d: \n",m);
00429     sprintf(filename,"linogram_ifft_error%d.dat",m);
00430     fp1=fopen(filename,"w+");
00431     for (max_i=0; max_i<=20; max_i+=2)
00432     {
00434       inverse_linogram_fft(f_direct,T,R,f_tilde,N,max_i,m);
00435 
00437       E_max=nfft_error_l_infty_complex(f_hat,f_tilde,N*N);
00438       printf("%3d iterations: E_max = %e\n",max_i,E_max);
00439       fprintf(fp1,"%e\n",E_max);
00440     }
00441     fclose(fp1);
00442   }
00443 
00445   free(x);
00446   free(w);
00447   free(f_hat);
00448   free(f);
00449   free(f_direct);
00450   free(f_tilde);
00451 
00452   return 0;
00453 }
00454 /* \} */

Generated on 1 Nov 2006 by Doxygen 1.4.4