![]() |
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 00025 #include "config.h" 00026 00027 #include <stdio.h> 00028 #include <math.h> 00029 #include <string.h> 00030 #include <stdlib.h> 00031 #ifdef HAVE_COMPLEX_H 00032 #include <complex.h> 00033 #endif 00034 00035 #include "nfft3.h" 00036 #include "infft.h" 00037 00038 static void ndft_horner_trafo(NFFT(plan) *ths) 00039 { 00040 INT j, k; 00041 C *f_hat_k, *f_j; 00042 C exp_omega_0; 00043 00044 for (j = 0, f_j = ths->f; j < ths->M_total; j++, f_j++) 00045 (*f_j) = K(0.0); 00046 00047 for (j = 0, f_j = ths->f; j < ths->M_total; j++, f_j++) 00048 { 00049 exp_omega_0 = CEXP(+K2PI * II * ths->x[j]); 00050 for (k = 0, f_hat_k = ths->f_hat; k < ths->N[0]; k++, f_hat_k++) 00051 { 00052 (*f_j) += (*f_hat_k); 00053 (*f_j) *= exp_omega_0; 00054 } 00055 (*f_j) *= CEXP(-KPI * II * (R)(ths->N[0]) * ths->x[j]); 00056 } 00057 } /* ndft_horner_trafo */ 00058 00059 static void ndft_pre_full_trafo(NFFT(plan) *ths, C *A) 00060 { 00061 INT j, k; 00062 C *f_hat_k, *f_j; 00063 C *A_local; 00064 00065 for (j = 0, f_j = ths->f; j < ths->M_total; j++, f_j++) 00066 (*f_j) = K(0.0); 00067 00068 for (j = 0, f_j = ths->f, A_local = A; j < ths->M_total; j++, f_j++) 00069 for (k = 0, f_hat_k = ths->f_hat; k < ths->N[0]; k++, f_hat_k++, A_local++) 00070 (*f_j) += (*f_hat_k) * (*A_local); 00071 } /* ndft_pre_full_trafo */ 00072 00073 static void ndft_pre_full_init(NFFT(plan) *ths, C *A) 00074 { 00075 INT j, k; 00076 C *f_hat_k, *f_j, *A_local; 00077 00078 for (j = 0, f_j = ths->f, A_local = A; j < ths->M_total; j++, f_j++) 00079 for (k = 0, f_hat_k = ths->f_hat; k < ths->N[0]; k++, f_hat_k++, A_local++) 00080 (*A_local) = CEXP( 00081 -K2PI * II * ((R) (k) - (R) (ths->N[0]) / K(2.0)) * ths->x[j]); 00082 00083 } /* ndft_pre_full_init */ 00084 00085 static void ndft_time(int N, int M, unsigned test_ndft, unsigned test_pre_full) 00086 { 00087 int r; 00088 R t, t_ndft, t_horner, t_pre_full, t_nfft; 00089 C *A = NULL; 00090 ticks t0, t1; 00091 00092 NFFT(plan) np; 00093 00094 printf("%d\t%d\t", N, M); 00095 00096 NFFT(init_1d)(&np, N, M); 00097 00098 /* Initialize pseudo random nodes. */ 00099 NFFT(vrand_shifted_unit_double)(np.x, np.M_total); 00100 00101 if (test_pre_full) 00102 { 00103 A = (C*) NFFT(malloc)((size_t)(N * M) * sizeof(R)); 00104 ndft_pre_full_init(&np, A); 00105 } 00106 00107 /* Initialize pseudo random Fourier coefficients. */ 00108 NFFT(vrand_unit_complex)(np.f_hat, np.N_total); 00109 00110 /* NDFT */ 00111 if (test_ndft) 00112 { 00113 t_ndft = K(0.0); 00114 r = 0; 00115 while (t_ndft < K(0.1)) 00116 { 00117 r++; 00118 t0 = getticks(); 00119 NFFT(trafo_direct)(&np); 00120 t1 = getticks(); 00121 t = NFFT(elapsed_seconds)(t1, t0); 00122 t_ndft += t; 00123 } 00124 t_ndft /= (R) (r); 00125 00126 printf("%.2" __FES__ "\t", t_ndft); 00127 } 00128 else 00129 printf("N/A\t\t"); 00130 00131 /* Horner NDFT */ 00132 t_horner = K(0.0); 00133 r = 0; 00134 while (t_horner < K(0.1)) 00135 { 00136 r++; 00137 t0 = getticks(); 00138 ndft_horner_trafo(&np); 00139 t1 = getticks(); 00140 t = NFFT(elapsed_seconds)(t1, t0); 00141 t_horner += t; 00142 } 00143 t_horner /= (R)(r); 00144 00145 printf("%.2" __FES__ "\t", t_horner); 00146 00147 /* Fully precomputed NDFT */ 00148 if (test_pre_full) 00149 { 00150 t_pre_full = K(0.0); 00151 r = 0; 00152 while (t_pre_full < K(0.1)) 00153 { 00154 r++; 00155 t0 = getticks(); 00156 ndft_pre_full_trafo(&np, A); 00157 t1 = getticks(); 00158 t = NFFT(elapsed_seconds)(t1, t0); 00159 t_pre_full += t; 00160 } 00161 t_pre_full /= (R)(r); 00162 00163 printf("%.2" __FES__ "\t", t_pre_full); 00164 } 00165 else 00166 printf("N/A\t\t"); 00167 00168 t_nfft = K(0.0); 00169 r = 0; 00170 while (t_nfft < K(0.1)) 00171 { 00172 r++; 00173 t0 = getticks(); 00174 NFFT(trafo)(&np); 00175 t1 = getticks(); 00176 t = NFFT(elapsed_seconds)(t1, t0); 00177 t_nfft += t; 00178 } 00179 t_nfft /= (R)(r); 00180 00181 printf("%.2" __FES__ "\n", t_nfft); 00182 00183 fflush(stdout); 00184 00185 if (test_pre_full) 00186 NFFT(free)(A); 00187 00188 NFFT(finalize)(&np); 00189 } 00190 00191 int main(int argc, char **argv) 00192 { 00193 int l, trial; 00194 00195 if (argc < 4) 00196 { 00197 fprintf(stderr, "ndft_fast type first last trials\n"); 00198 return EXIT_FAILURE; 00199 } 00200 else 00201 { 00202 int arg2 = (atoi(argv[2])); 00203 int arg3 = (atoi(argv[3])); 00204 int arg4 = (atoi(argv[4])); 00205 fprintf(stderr, "Testing ndft, Horner-like ndft, fully precomputed ndft.\n"); 00206 fprintf(stderr, "Columns: N, M, t_ndft, t_horner, t_pre_full, t_nfft\n\n"); 00207 00208 /* time vs. N=M */ 00209 if (atoi(argv[1]) == 0) 00210 { 00211 for (l = arg2; l <= arg3; l++) 00212 { 00213 for (trial = 0; trial < arg4; trial++) 00214 { 00215 int N = (int)(1U << l); 00216 int M = (int)(1U << l); 00217 ndft_time(N, M, l <= 15 ? 1 : 0, l <= 13 ? 1 : 0); 00218 } 00219 } 00220 } 00221 } 00222 00223 return EXIT_SUCCESS; 00224 }