NFFT  3.3.2
fastsum_test.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 
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 /* \} */