NFFT  3.3.2
flags.c
Go to the documentation of this file.
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 }