NFFT Logo 3.2.3
fastsum_test.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002, 2012 Jens Keiner, Stefan Kunis, Daniel Potts
3  *
4  * This program is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU General Public License as published by the Free Software
6  * Foundation; either version 2 of the License, or (at your option) any later
7  * version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc., 51
16  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 /* $Id: fastsum_test.c 3896 2012-10-10 12:19:26Z tovo $ */
20 
27 #include "config.h"
28 
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <math.h>
33 #ifdef HAVE_COMPLEX_H
34  #include <complex.h>
35 #endif
36 
37 #ifdef _OPENMP
38  #include <omp.h>
39 #endif
40 
41 #include "fastsum.h"
42 #include "kernels.h"
43 #include "infft.h"
44 
51 int main(int argc, char **argv)
52 {
53  int j,k,t;
54  int d;
55  int N;
56  int M;
57  int n;
58  int m;
59  int p;
60  char *s;
61  double _Complex (*kernel)(double , int , const double *);
62  double c;
63  fastsum_plan my_fastsum_plan;
64  double _Complex *direct;
65  ticks t0, t1;
66  double time;
67  double error=0.0;
68  double eps_I;
69  double eps_B;
71  if (argc!=11)
72  {
73  printf("\nfastsum_test d N M n m p kernel c eps_I eps_B\n\n");
74  printf(" d dimension \n");
75  printf(" N number of source nodes \n");
76  printf(" M number of target nodes \n");
77  printf(" n expansion degree \n");
78  printf(" m cut-off parameter \n");
79  printf(" p degree of smoothness \n");
80  printf(" kernel kernel function (e.g., gaussian)\n");
81  printf(" c kernel parameter \n");
82  printf(" eps_I inner boundary \n");
83  printf(" eps_B outer boundary \n\n");
84  exit(-1);
85  }
86  else
87  {
88  d=atoi(argv[1]);
89  N=atoi(argv[2]); c=1.0/pow((double)N,1.0/(double)d);
90  M=atoi(argv[3]);
91  n=atoi(argv[4]);
92  m=atoi(argv[5]);
93  p=atoi(argv[6]);
94  s=argv[7];
95  c=atof(argv[8]);
96  eps_I=atof(argv[9]);
97  eps_B=atof(argv[10]);
98  if (strcmp(s,"gaussian")==0)
99  kernel = gaussian;
100  else if (strcmp(s,"multiquadric")==0)
101  kernel = multiquadric;
102  else if (strcmp(s,"inverse_multiquadric")==0)
103  kernel = inverse_multiquadric;
104  else if (strcmp(s,"logarithm")==0)
105  kernel = logarithm;
106  else if (strcmp(s,"thinplate_spline")==0)
107  kernel = thinplate_spline;
108  else if (strcmp(s,"one_over_square")==0)
109  kernel = one_over_square;
110  else if (strcmp(s,"one_over_modulus")==0)
111  kernel = one_over_modulus;
112  else if (strcmp(s,"one_over_x")==0)
113  kernel = one_over_x;
114  else if (strcmp(s,"inverse_multiquadric3")==0)
115  kernel = inverse_multiquadric3;
116  else if (strcmp(s,"sinc_kernel")==0)
117  kernel = sinc_kernel;
118  else if (strcmp(s,"cosc")==0)
119  kernel = cosc;
120  else if (strcmp(s,"cot")==0)
121  kernel = kcot;
122  else
123  {
124  s="multiquadric";
125  kernel = multiquadric;
126  }
127  }
128  printf("d=%d, N=%d, M=%d, n=%d, m=%d, p=%d, kernel=%s, c=%g, eps_I=%g, eps_B=%g \n",d,N,M,n,m,p,s,c,eps_I,eps_B);
129 #ifdef NF_KUB
130  printf("nearfield correction using piecewise cubic Lagrange interpolation\n");
131 #elif defined(NF_QUADR)
132  printf("nearfield correction using piecewise quadratic Lagrange interpolation\n");
133 #elif defined(NF_LIN)
134  printf("nearfield correction using piecewise linear Lagrange interpolation\n");
135 #endif
136 
137 #ifdef _OPENMP
138  #pragma omp parallel
139  {
140  #pragma omp single
141  {
142  printf("nthreads=%d\n", omp_get_max_threads());
143  }
144  }
145 
146  fftw_init_threads();
147 #endif
148 
150  fastsum_init_guru(&my_fastsum_plan, d, N, M, kernel, &c, 0, n, m, p, eps_I, eps_B);
151  //fastsum_init_guru(&my_fastsum_plan, d, N, M, kernel, &c, NEARFIELD_BOXES, n, m, p, eps_I, eps_B);
152 
153  if (my_fastsum_plan.flags & NEARFIELD_BOXES)
154  printf("determination of nearfield candidates based on partitioning into boxes\n");
155  else
156  printf("determination of nearfield candidates based on search tree\n");
157 
159  k = 0;
160  while (k < N)
161  {
162  double r_max = 0.25 - my_fastsum_plan.eps_B/2.0;
163  double r2 = 0.0;
164 
165  for (j=0; j<d; j++)
166  my_fastsum_plan.x[k*d+j] = 2.0 * r_max * (double)rand()/(double)RAND_MAX - r_max;
167 
168  for (j=0; j<d; j++)
169  r2 += my_fastsum_plan.x[k*d+j] * my_fastsum_plan.x[k*d+j];
170 
171  if (r2 >= r_max * r_max)
172  continue;
173 
174  k++;
175  }
176 
177  for (k=0; k<N; k++)
178  {
179 /* double r=(0.25-my_fastsum_plan.eps_B/2.0)*pow((double)rand()/(double)RAND_MAX,1.0/d);
180  my_fastsum_plan.x[k*d+0] = r;
181  for (j=1; j<d; j++)
182  {
183  double phi=2.0*PI*(double)rand()/(double)RAND_MAX;
184  my_fastsum_plan.x[k*d+j] = r;
185  for (t=0; t<j; t++)
186  {
187  my_fastsum_plan.x[k*d+t] *= cos(phi);
188  }
189  my_fastsum_plan.x[k*d+j] *= sin(phi);
190  }
191 */
192  my_fastsum_plan.alpha[k] = (double)rand()/(double)RAND_MAX + _Complex_I*(double)rand()/(double)RAND_MAX;
193  }
194 
196  k = 0;
197  while (k < M)
198  {
199  double r_max = 0.25 - my_fastsum_plan.eps_B/2.0;
200  double r2 = 0.0;
201 
202  for (j=0; j<d; j++)
203  my_fastsum_plan.y[k*d+j] = 2.0 * r_max * (double)rand()/(double)RAND_MAX - r_max;
204 
205  for (j=0; j<d; j++)
206  r2 += my_fastsum_plan.y[k*d+j] * my_fastsum_plan.y[k*d+j];
207 
208  if (r2 >= r_max * r_max)
209  continue;
210 
211  k++;
212  }
213 /* for (k=0; k<M; k++)
214  {
215  double r=(0.25-my_fastsum_plan.eps_B/2.0)*pow((double)rand()/(double)RAND_MAX,1.0/d);
216  my_fastsum_plan.y[k*d+0] = r;
217  for (j=1; j<d; j++)
218  {
219  double phi=2.0*PI*(double)rand()/(double)RAND_MAX;
220  my_fastsum_plan.y[k*d+j] = r;
221  for (t=0; t<j; t++)
222  {
223  my_fastsum_plan.y[k*d+t] *= cos(phi);
224  }
225  my_fastsum_plan.y[k*d+j] *= sin(phi);
226  }
227  } */
228 
230  printf("direct computation: "); fflush(NULL);
231  t0 = getticks();
232  fastsum_exact(&my_fastsum_plan);
233  t1 = getticks();
234  time=nfft_elapsed_seconds(t1,t0);
235  printf("%fsec\n",time);
236 
238  direct = (double _Complex *)nfft_malloc(my_fastsum_plan.M_total*(sizeof(double _Complex)));
239  for (j=0; j<my_fastsum_plan.M_total; j++)
240  direct[j]=my_fastsum_plan.f[j];
241 
243  printf("pre-computation: "); fflush(NULL);
244  t0 = getticks();
245  fastsum_precompute(&my_fastsum_plan);
246  t1 = getticks();
247  time=nfft_elapsed_seconds(t1,t0);
248  printf("%fsec\n",time);
249 
251  printf("fast computation: "); fflush(NULL);
252  t0 = getticks();
253  fastsum_trafo(&my_fastsum_plan);
254  t1 = getticks();
255  time=nfft_elapsed_seconds(t1,t0);
256  printf("%fsec\n",time);
257 
259  error=0.0;
260  for (j=0; j<my_fastsum_plan.M_total; j++)
261  {
262  if (cabs(direct[j]-my_fastsum_plan.f[j])/cabs(direct[j])>error)
263  error=cabs(direct[j]-my_fastsum_plan.f[j])/cabs(direct[j]);
264  }
265  printf("max relative error: %e\n",error);
266 
268  fastsum_finalize(&my_fastsum_plan);
269 
270  return 0;
271 }
272 /* \} */

Generated on Tue Apr 30 2013 by Doxygen 1.8.1