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
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);
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
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
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