![]() |
NFFT
3.3.2
|
00001 /* 00002 * Copyright (c) 2002, 2016 Jens Keiner, Stefan Kunis, Daniel Potts 00003 * 00004 * This program is free software; you can redistribute it and/or modify it under 00005 * the terms of the GNU General Public License as published by the Free Software 00006 * Foundation; either version 2 of the License, or (at your option) any later 00007 * version. 00008 * 00009 * This program is distributed in the hope that it will be useful, but WITHOUT 00010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00011 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 00012 * details. 00013 * 00014 * You should have received a copy of the GNU General Public License along with 00015 * this program; if not, write to the Free Software Foundation, Inc., 51 00016 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00027 #include "config.h" 00028 00029 #include <stdio.h> 00030 #include <math.h> 00031 #include <string.h> 00032 #include <stdlib.h> 00033 #ifdef HAVE_COMPLEX_H 00034 #include <complex.h> 00035 #endif 00036 00037 #include "nfft3.h" 00038 #include "infft.h" 00039 00040 #ifdef GAUSSIAN 00041 unsigned test_fg=1; 00042 #else 00043 unsigned test_fg=0; 00044 #endif 00045 00046 #ifdef MEASURE_TIME_FFTW 00047 unsigned test_fftw=1; 00048 #else 00049 unsigned test_fftw=0; 00050 #endif 00051 00052 #ifdef MEASURE_TIME 00053 unsigned test=1; 00054 #else 00055 unsigned test=0; 00056 #endif 00057 00058 static void flags_cp(NFFT(plan) *dst, NFFT(plan) *src) 00059 { 00060 dst->x = src->x; 00061 dst->f_hat = src->f_hat; 00062 dst->f = src->f; 00063 dst->g1 = src->g1; 00064 dst->g2 = src->g2; 00065 dst->my_fftw_plan1 = src->my_fftw_plan1; 00066 dst->my_fftw_plan2 = src->my_fftw_plan2; 00067 } 00068 00069 static void time_accuracy(int d, int N, int M, int n, int m, unsigned test_ndft, 00070 unsigned test_pre_full_psi) 00071 { 00072 int r, NN[d], nn[d]; 00073 R t_ndft, t, e; 00074 C *swapndft = NULL; 00075 ticks t0, t1; 00076 00077 NFFT(plan) p; 00078 NFFT(plan) p_pre_phi_hut; 00079 NFFT(plan) p_fg_psi; 00080 NFFT(plan) p_pre_lin_psi; 00081 NFFT(plan) p_pre_fg_psi; 00082 NFFT(plan) p_pre_psi; 00083 NFFT(plan) p_pre_full_psi; 00084 00085 printf("%d\t%d\t", d, N); 00086 00087 for (r = 0; r < d; r++) 00088 { 00089 NN[r] = N; 00090 nn[r] = n; 00091 } 00092 00093 /* output vector ndft */ 00094 if (test_ndft) 00095 swapndft = (C*) NFFT(malloc)((size_t)(M) * sizeof(C)); 00096 00097 NFFT(init_guru)(&p, d, NN, M, nn, m, 00098 MALLOC_X | MALLOC_F_HAT | MALLOC_F | 00099 FFTW_INIT | FFT_OUT_OF_PLACE, 00100 FFTW_MEASURE | FFTW_DESTROY_INPUT); 00101 00103 NFFT(vrand_shifted_unit_double)(p.x, p.d * p.M_total); 00104 00105 NFFT(init_guru)(&p_pre_phi_hut, d, NN, M, nn, m, PRE_PHI_HUT, 0); 00106 flags_cp(&p_pre_phi_hut, &p); 00107 NFFT(precompute_one_psi)(&p_pre_phi_hut); 00108 00109 if (test_fg) 00110 { 00111 NFFT(init_guru)(&p_fg_psi, d, NN, M, nn, m, FG_PSI, 0); 00112 flags_cp(&p_fg_psi, &p); 00113 NFFT(precompute_one_psi)(&p_fg_psi); 00114 } 00115 00116 NFFT(init_guru)(&p_pre_lin_psi, d, NN, M, nn, m, PRE_LIN_PSI, 0); 00117 flags_cp(&p_pre_lin_psi, &p); 00118 NFFT(precompute_one_psi)(&p_pre_lin_psi); 00119 00120 if (test_fg) 00121 { 00122 NFFT(init_guru)(&p_pre_fg_psi, d, NN, M, nn, m, PRE_FG_PSI, 0); 00123 flags_cp(&p_pre_fg_psi, &p); 00124 NFFT(precompute_one_psi)(&p_pre_fg_psi); 00125 } 00126 00127 NFFT(init_guru)(&p_pre_psi, d, NN, M, nn, m, PRE_PSI, 0); 00128 flags_cp(&p_pre_psi, &p); 00129 NFFT(precompute_one_psi)(&p_pre_psi); 00130 00131 if (test_pre_full_psi) 00132 { 00133 NFFT(init_guru)(&p_pre_full_psi, d, NN, M, nn, m, PRE_FULL_PSI, 0); 00134 flags_cp(&p_pre_full_psi, &p); 00135 NFFT(precompute_one_psi)(&p_pre_full_psi); 00136 } 00137 00138 /* init pseudo random Fourier coefficients */ 00139 NFFT(vrand_unit_complex)(p.f_hat, p.N_total); 00140 00141 /* NDFT */ 00142 if (test_ndft) 00143 { 00144 CSWAP(p.f, swapndft); 00145 00146 t_ndft = K(0.0); 00147 r = 0; 00148 while (t_ndft < K(0.01)) 00149 { 00150 r++; 00151 t0 = getticks(); 00152 NFFT(trafo_direct)(&p); 00153 t1 = getticks(); 00154 t = NFFT(elapsed_seconds)(t1, t0); 00155 t_ndft += t; 00156 } 00157 t_ndft /= (R)(r); 00158 00159 CSWAP(p.f, swapndft); 00160 } 00161 else 00162 t_ndft = MKNAN(""); 00163 00164 /* NFFTs */ 00165 NFFT(trafo)(&p); 00166 NFFT(trafo)(&p_pre_phi_hut); 00167 if (test_fg) 00168 NFFT(trafo)(&p_fg_psi); 00169 else 00170 p_fg_psi.MEASURE_TIME_t[2] = MKNAN(""); 00171 NFFT(trafo)(&p_pre_lin_psi); 00172 if (test_fg) 00173 NFFT(trafo)(&p_pre_fg_psi); 00174 else 00175 p_pre_fg_psi.MEASURE_TIME_t[2] = MKNAN(""); 00176 NFFT(trafo)(&p_pre_psi); 00177 if (test_pre_full_psi) 00178 NFFT(trafo)(&p_pre_full_psi); 00179 else 00180 p_pre_full_psi.MEASURE_TIME_t[2] = MKNAN(""); 00181 00182 if (test_fftw == 0) 00183 p.MEASURE_TIME_t[1] = MKNAN(""); 00184 00185 if (test_ndft) 00186 e = NFFT(error_l_2_complex)(swapndft, p.f, p.M_total); 00187 else 00188 e = MKNAN(""); 00189 00190 printf( 00191 "%.2" __FES__ "\t%d\t%.2" __FES__ "\t%.2" __FES__ "\t%.2" __FES__ "\t%.2" __FES__ "\t%.2" __FES__ "\t%.2" __FES__ "\t%.2" __FES__ "\t%.2" __FES__ "\t%.2" __FES__ "\t%.2" __FES__ "\n", 00192 t_ndft, m, e, p.MEASURE_TIME_t[0], p_pre_phi_hut.MEASURE_TIME_t[0], 00193 p.MEASURE_TIME_t[1], p.MEASURE_TIME_t[2], p_fg_psi.MEASURE_TIME_t[2], 00194 p_pre_lin_psi.MEASURE_TIME_t[2], p_pre_fg_psi.MEASURE_TIME_t[2], 00195 p_pre_psi.MEASURE_TIME_t[2], p_pre_full_psi.MEASURE_TIME_t[2]); 00196 00197 fflush(stdout); 00198 00200 if (test_pre_full_psi) 00201 NFFT(finalize)(&p_pre_full_psi); 00202 NFFT(finalize)(&p_pre_psi); 00203 if (test_fg) 00204 NFFT(finalize)(&p_pre_fg_psi); 00205 NFFT(finalize)(&p_pre_lin_psi); 00206 if (test_fg) 00207 NFFT(finalize)(&p_fg_psi); 00208 NFFT(finalize)(&p_pre_phi_hut); 00209 NFFT(finalize)(&p); 00210 00211 if (test_ndft) 00212 NFFT(free)(swapndft); 00213 } 00214 00215 static void accuracy_pre_lin_psi(int d, int N, int M, int n, int m, int K) 00216 { 00217 int r, NN[d], nn[d]; 00218 R e; 00219 C *swapndft; 00220 00221 NFFT(plan) p; 00222 00223 for (r = 0; r < d; r++) 00224 { 00225 NN[r] = N; 00226 nn[r] = n; 00227 } 00228 00229 /* output vector ndft */ 00230 swapndft = (C*) NFFT(malloc)((size_t)(M) * sizeof(C)); 00231 00232 NFFT(init_guru)(&p, d, NN, M, nn, m, 00233 MALLOC_X | MALLOC_F_HAT | MALLOC_F | 00234 PRE_PHI_HUT | PRE_LIN_PSI | 00235 FFTW_INIT | FFT_OUT_OF_PLACE, 00236 FFTW_MEASURE | FFTW_DESTROY_INPUT); 00237 00239 NFFT(free)(p.psi); 00240 p.K = K; 00241 p.psi = (R*) NFFT(malloc)((size_t)((p.K + 1) * p.d) * sizeof(R)); 00242 00244 NFFT(precompute_one_psi)(&p); 00245 00247 NFFT(vrand_shifted_unit_double)(p.x, p.d * p.M_total); 00248 00250 NFFT(vrand_unit_complex)(p.f_hat, p.N_total); 00251 00253 CSWAP(p.f, swapndft); 00254 NFFT(trafo_direct)(&p); 00255 CSWAP(p.f, swapndft); 00256 00258 NFFT(trafo)(&p); 00259 e = NFFT(error_l_2_complex)(swapndft, p.f, p.M_total); 00260 00261 // printf("%d\t%d\t%d\t%d\t%.2e\n",d,N,m,K,e); 00262 printf("$%.1" __FES__ "$&\t", e); 00263 00264 fflush(stdout); 00265 00267 NFFT(finalize)(&p); 00268 NFFT(free)(swapndft); 00269 } 00270 00271 int main(int argc, char **argv) 00272 { 00273 int l, trial; 00274 00275 if (argc <= 2) 00276 { 00277 fprintf(stderr, "flags type first last trials d m\n"); 00278 return EXIT_FAILURE; 00279 } 00280 00281 if ((test == 0) && (atoi(argv[1]) < 2)) 00282 { 00283 fprintf(stderr, "MEASURE_TIME in infft.h not set\n"); 00284 return EXIT_FAILURE; 00285 } 00286 00287 fprintf(stderr, "Testing different precomputation schemes for the nfft.\n"); 00288 fprintf(stderr, "Columns: d, N=M, t_ndft, e_nfft, t_D, t_pre_phi_hut, "); 00289 fprintf(stderr, "t_fftw, t_B, t_fg_psi, t_pre_lin_psi, t_pre_fg_psi, "); 00290 fprintf(stderr, "t_pre_psi, t_pre_full_psi\n\n"); 00291 00292 int arg2 = atoi(argv[2]); 00293 int arg3 = atoi(argv[3]); 00294 int arg4 = atoi(argv[4]); 00295 00296 /* time vs. N=M */ 00297 if (atoi(argv[1]) == 0) 00298 { 00299 int d = atoi(argv[5]); 00300 int m = atoi(argv[6]); 00301 00302 for (l = arg2; l <= arg3; l++) 00303 { 00304 int N = (int)(1U << l); 00305 int M = (int)(1U << (d * l)); 00306 for (trial = 0; trial < arg4; trial++) 00307 { 00308 time_accuracy(d, N, M, 2 * N, m, 0, 0); 00309 } 00310 } 00311 } 00312 else if (atoi(argv[1]) == 1) /* accuracy vs. time */ 00313 { 00314 int d = atoi(argv[5]); 00315 int N = atoi(argv[6]); 00316 int m; 00317 00318 for (m = arg2; m <= arg3; m++) 00319 { 00320 for (trial = 0; trial < arg4; trial++) 00321 { 00322 time_accuracy(d, N, (int)(LRINT(POW((R)(N), (R)(d)))), 2 * N, m, 1, 1); 00323 } 00324 } 00325 } 00326 else if (atoi(argv[1]) == 2) /* accuracy vs. K for linear interpolation, assumes (m+1)|K */ 00327 { 00328 int d = atoi(argv[5]); 00329 int N = atoi(argv[6]); 00330 int m = atoi(argv[7]); 00331 00332 printf("$\\log_2(K/(m+1))$&\t"); 00333 00334 for (l = arg2; l < arg3; l++) 00335 printf("$%d$&\t", l); 00336 00337 printf("$%d$\\\\\n", arg3); 00338 00339 printf("$\\tilde E_2$&\t"); 00340 for (l = arg2; l <= arg3; l++) 00341 { 00342 int x = (m + 1) * (int)(1U << l); 00343 accuracy_pre_lin_psi(d, N, (int)(LRINT(POW((R)(N), (R)(d)))), 2 * N, m, x); 00344 } 00345 00346 printf("\n"); 00347 } 00348 00349 00350 return EXIT_SUCCESS; 00351 }