![]() |
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 <stdlib.h> 00028 #include <stdio.h> 00029 #include <string.h> 00030 #include <math.h> 00031 #ifdef HAVE_COMPLEX_H 00032 #include <complex.h> 00033 #endif 00034 00035 #ifdef _OPENMP 00036 #include <omp.h> 00037 #endif 00038 00039 #include "fastsum.h" 00040 #include "kernels.h" 00041 #include "infft.h" 00042 00049 int main(int argc, char **argv) 00050 { 00051 int j, k; 00052 int d; 00053 int N; 00054 int M; 00055 int n; 00056 int m; 00057 int p; 00058 const char *s; 00059 C (*kernel)(R, int, const R *); 00060 R c; 00061 fastsum_plan my_fastsum_plan; 00062 C *direct; 00063 ticks t0, t1; 00064 R time; 00065 R error = K(0.0); 00066 R eps_I; 00067 R eps_B; 00069 if (argc != 11) 00070 { 00071 printf("\nfastsum_test d N M n m p kernel c eps_I eps_B\n\n"); 00072 printf(" d dimension \n"); 00073 printf(" N number of source nodes \n"); 00074 printf(" M number of target nodes \n"); 00075 printf(" n expansion degree \n"); 00076 printf(" m cut-off parameter \n"); 00077 printf(" p degree of smoothness \n"); 00078 printf(" kernel kernel function (e.g., gaussian)\n"); 00079 printf(" c kernel parameter \n"); 00080 printf(" eps_I inner boundary \n"); 00081 printf(" eps_B outer boundary \n\n"); 00082 exit(EXIT_FAILURE); 00083 } 00084 else 00085 { 00086 d = atoi(argv[1]); 00087 N = atoi(argv[2]); 00088 c = K(1.0) / POW((R)(N), K(1.0) / ((R)(d))); 00089 M = atoi(argv[3]); 00090 n = atoi(argv[4]); 00091 m = atoi(argv[5]); 00092 p = atoi(argv[6]); 00093 s = argv[7]; 00094 c = (R)(atof(argv[8])); 00095 eps_I = (R)(atof(argv[9])); 00096 eps_B = (R)(atof(argv[10])); 00097 if (strcmp(s, "gaussian") == 0) 00098 kernel = gaussian; 00099 else if (strcmp(s, "multiquadric") == 0) 00100 kernel = multiquadric; 00101 else if (strcmp(s, "inverse_multiquadric") == 0) 00102 kernel = inverse_multiquadric; 00103 else if (strcmp(s, "logarithm") == 0) 00104 kernel = logarithm; 00105 else if (strcmp(s, "thinplate_spline") == 0) 00106 kernel = thinplate_spline; 00107 else if (strcmp(s, "one_over_square") == 0) 00108 kernel = one_over_square; 00109 else if (strcmp(s, "one_over_modulus") == 0) 00110 kernel = one_over_modulus; 00111 else if (strcmp(s, "one_over_x") == 0) 00112 kernel = one_over_x; 00113 else if (strcmp(s, "inverse_multiquadric3") == 0) 00114 kernel = inverse_multiquadric3; 00115 else if (strcmp(s, "sinc_kernel") == 0) 00116 kernel = sinc_kernel; 00117 else if (strcmp(s, "cosc") == 0) 00118 kernel = cosc; 00119 else if (strcmp(s, "cot") == 0) 00120 kernel = kcot; 00121 else 00122 { 00123 s = "multiquadric"; 00124 kernel = multiquadric; 00125 } 00126 } 00127 printf( 00128 "d=%d, N=%d, M=%d, n=%d, m=%d, p=%d, kernel=%s, c=%" __FGS__ ", eps_I=%" __FGS__ ", eps_B=%" __FGS__ " \n", 00129 d, N, M, n, m, p, s, c, eps_I, eps_B); 00130 #ifdef NF_KUB 00131 printf("nearfield correction using piecewise cubic Lagrange interpolation\n"); 00132 #elif defined(NF_QUADR) 00133 printf("nearfield correction using piecewise quadratic Lagrange interpolation\n"); 00134 #elif defined(NF_LIN) 00135 printf("nearfield correction using piecewise linear Lagrange interpolation\n"); 00136 #endif 00137 00138 #ifdef _OPENMP 00139 #pragma omp parallel 00140 { 00141 #pragma omp single 00142 { 00143 printf("nthreads=%d\n", omp_get_max_threads()); 00144 } 00145 } 00146 00147 FFTW(init_threads)(); 00148 #endif 00149 00151 fastsum_init_guru(&my_fastsum_plan, d, N, M, kernel, &c, 0, n, m, p, eps_I, 00152 eps_B); 00153 //fastsum_init_guru(&my_fastsum_plan, d, N, M, kernel, &c, NEARFIELD_BOXES, n, m, p, eps_I, eps_B); 00154 00155 if (my_fastsum_plan.flags & NEARFIELD_BOXES) 00156 printf( 00157 "determination of nearfield candidates based on partitioning into boxes\n"); 00158 else 00159 printf("determination of nearfield candidates based on search tree\n"); 00160 00162 k = 0; 00163 while (k < N) 00164 { 00165 R r_max = K(0.25) - my_fastsum_plan.eps_B / K(2.0); 00166 R r2 = K(0.0); 00167 00168 for (j = 0; j < d; j++) 00169 my_fastsum_plan.x[k * d + j] = K(2.0) * r_max * NFFT(drand48)() - r_max; 00170 00171 for (j = 0; j < d; j++) 00172 r2 += my_fastsum_plan.x[k * d + j] * my_fastsum_plan.x[k * d + j]; 00173 00174 if (r2 >= r_max * r_max) 00175 continue; 00176 00177 k++; 00178 } 00179 00180 for (k = 0; k < N; k++) 00181 { 00182 /* R r=(0.25-my_fastsum_plan.eps_B/2.0)*pow((R)rand()/(R)RAND_MAX,1.0/d); 00183 my_fastsum_plan.x[k*d+0] = r; 00184 for (j=1; j<d; j++) 00185 { 00186 R phi=2.0*KPI*(R)rand()/(R)RAND_MAX; 00187 my_fastsum_plan.x[k*d+j] = r; 00188 for (t=0; t<j; t++) 00189 { 00190 my_fastsum_plan.x[k*d+t] *= cos(phi); 00191 } 00192 my_fastsum_plan.x[k*d+j] *= sin(phi); 00193 } 00194 */ 00195 my_fastsum_plan.alpha[k] = NFFT(drand48)() + II * NFFT(drand48)(); 00196 } 00197 00199 k = 0; 00200 while (k < M) 00201 { 00202 R r_max = K(0.25) - my_fastsum_plan.eps_B / K(2.0); 00203 R r2 = K(0.0); 00204 00205 for (j = 0; j < d; j++) 00206 my_fastsum_plan.y[k * d + j] = K(2.0) * r_max * NFFT(drand48)() - r_max; 00207 00208 for (j = 0; j < d; j++) 00209 r2 += my_fastsum_plan.y[k * d + j] * my_fastsum_plan.y[k * d + j]; 00210 00211 if (r2 >= r_max * r_max) 00212 continue; 00213 00214 k++; 00215 } 00216 /* for (k=0; k<M; k++) 00217 { 00218 R r=(0.25-my_fastsum_plan.eps_B/2.0)*pow((R)rand()/(R)RAND_MAX,1.0/d); 00219 my_fastsum_plan.y[k*d+0] = r; 00220 for (j=1; j<d; j++) 00221 { 00222 R phi=2.0*KPI*(R)rand()/(R)RAND_MAX; 00223 my_fastsum_plan.y[k*d+j] = r; 00224 for (t=0; t<j; t++) 00225 { 00226 my_fastsum_plan.y[k*d+t] *= cos(phi); 00227 } 00228 my_fastsum_plan.y[k*d+j] *= sin(phi); 00229 } 00230 } */ 00231 00233 printf("direct computation: "); 00234 fflush(NULL); 00235 t0 = getticks(); 00236 fastsum_exact(&my_fastsum_plan); 00237 t1 = getticks(); 00238 time = NFFT(elapsed_seconds)(t1, t0); 00239 printf(__FI__ "sec\n", time); 00240 00242 direct = (C *) NFFT(malloc)((size_t)(my_fastsum_plan.M_total) * (sizeof(C))); 00243 for (j = 0; j < my_fastsum_plan.M_total; j++) 00244 direct[j] = my_fastsum_plan.f[j]; 00245 00247 printf("pre-computation: "); 00248 fflush(NULL); 00249 t0 = getticks(); 00250 fastsum_precompute(&my_fastsum_plan); 00251 t1 = getticks(); 00252 time = NFFT(elapsed_seconds)(t1, t0); 00253 printf(__FI__ "sec\n", time); 00254 00256 printf("fast computation: "); 00257 fflush(NULL); 00258 t0 = getticks(); 00259 fastsum_trafo(&my_fastsum_plan); 00260 t1 = getticks(); 00261 time = NFFT(elapsed_seconds)(t1, t0); 00262 printf(__FI__ "sec\n", time); 00263 00265 error = K(0.0); 00266 for (j = 0; j < my_fastsum_plan.M_total; j++) 00267 { 00268 if (CABS(direct[j] - my_fastsum_plan.f[j]) / CABS(direct[j]) > error) 00269 error = CABS(direct[j] - my_fastsum_plan.f[j]) / CABS(direct[j]); 00270 } 00271 printf("max relative error: %" __FES__ "\n", error); 00272 00274 fastsum_finalize(&my_fastsum_plan); 00275 00276 return EXIT_SUCCESS; 00277 } 00278 /* \} */