NFFT 3.6.0
fastsum_test.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2002, 2017 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
25#include "config.h"
26
27#include <stdlib.h>
28#include <stdio.h>
29#include <string.h>
30#include <math.h>
31#ifdef HAVE_COMPLEX_H
32 #include <complex.h>
33#endif
34
35#ifdef _OPENMP
36 #include <omp.h>
37#endif
38
39#include "fastsum.h"
40#include "kernels.h"
41#include "infft.h"
42
49int main(int argc, char **argv)
50{
51 int j, k;
52 int d;
53 int N;
54 int M;
55 int n;
56 int m;
57 int p;
58 const char *s;
59 C (*kernel)(R, int, const R *);
60 R c;
61 fastsum_plan my_fastsum_plan;
62 C *direct;
63 ticks t0, t1;
64 R time;
65 R error = K(0.0);
66 R eps_I;
67 R eps_B;
69 if (argc != 11)
70 {
71 printf("\nfastsum_test d N M n m p kernel c eps_I eps_B\n\n");
72 printf(" d dimension \n");
73 printf(" N number of source nodes \n");
74 printf(" M number of target nodes \n");
75 printf(" n expansion degree \n");
76 printf(" m cut-off parameter \n");
77 printf(" p degree of smoothness \n");
78 printf(" kernel kernel function (e.g., gaussian)\n");
79 printf(" c kernel parameter \n");
80 printf(" eps_I inner boundary \n");
81 printf(" eps_B outer boundary \n\n");
82 exit(EXIT_FAILURE);
83 }
84 else
85 {
86 d = atoi(argv[1]);
87 N = atoi(argv[2]);
88 c = K(1.0) / POW((R)(N), K(1.0) / ((R)(d)));
89 M = atoi(argv[3]);
90 n = atoi(argv[4]);
91 m = atoi(argv[5]);
92 p = atoi(argv[6]);
93 s = argv[7];
94 c = (R)(atof(argv[8]));
95 eps_I = (R)(atof(argv[9]));
96 eps_B = (R)(atof(argv[10]));
97 if (strcmp(s, "gaussian") == 0)
98 kernel = gaussian;
99 else if (strcmp(s, "multiquadric") == 0)
100 kernel = multiquadric;
101 else if (strcmp(s, "inverse_multiquadric") == 0)
102 kernel = inverse_multiquadric;
103 else if (strcmp(s, "logarithm") == 0)
104 kernel = logarithm;
105 else if (strcmp(s, "thinplate_spline") == 0)
106 kernel = thinplate_spline;
107 else if (strcmp(s, "one_over_square") == 0)
108 kernel = one_over_square;
109 else if (strcmp(s, "one_over_modulus") == 0)
110 kernel = one_over_modulus;
111 else if (strcmp(s, "one_over_x") == 0)
112 kernel = one_over_x;
113 else if (strcmp(s, "inverse_multiquadric3") == 0)
114 kernel = inverse_multiquadric3;
115 else if (strcmp(s, "sinc_kernel") == 0)
116 kernel = sinc_kernel;
117 else if (strcmp(s, "cosc") == 0)
118 kernel = cosc;
119 else if (strcmp(s, "cot") == 0)
120 kernel = kcot;
121 else if (strcmp(s, "one_over_cube") == 0)
122 kernel = one_over_cube;
123 else if (strcmp(s, "log_sin") == 0)
124 kernel = log_sin;
125 else if (strcmp(s, "laplacian_rbf") == 0)
126 kernel = laplacian_rbf;
127 else if (strcmp(s, "der_laplacian_rbf") == 0)
128 kernel = der_laplacian_rbf;
129 else if (strcmp(s, "xx_gaussian") == 0)
130 kernel = xx_gaussian;
131 else if (strcmp(s, "absx") == 0)
132 kernel = absx;
133 else
134 {
135 s = "multiquadric";
136 kernel = multiquadric;
137 }
138 }
139 printf(
140 "d=%d, N=%d, M=%d, n=%d, m=%d, p=%d, kernel=%s, c=%" __FGS__ ", eps_I=%" __FGS__ ", eps_B=%" __FGS__ " \n",
141 d, N, M, n, m, p, s, c, eps_I, eps_B);
142#ifdef NF_KUB
143 printf("nearfield correction using piecewise cubic Lagrange interpolation\n");
144#elif defined(NF_QUADR)
145 printf("nearfield correction using piecewise quadratic Lagrange interpolation\n");
146#elif defined(NF_LIN)
147 printf("nearfield correction using piecewise linear Lagrange interpolation\n");
148#endif
149
150#ifdef _OPENMP
151#pragma omp parallel
152 {
153#pragma omp single
154 {
155 printf("nthreads=%d\n", omp_get_max_threads());
156 }
157 }
158
159 #ifdef HAVE_FFTW_THREADS
160 FFTW(init_threads)();
161 #endif
162#endif
163
165 fastsum_init_guru(&my_fastsum_plan, d, N, M, kernel, &c, 0, n, m, p, eps_I,
166 eps_B);
167 //fastsum_init_guru(&my_fastsum_plan, d, N, M, kernel, &c, NEARFIELD_BOXES, n, m, p, eps_I, eps_B);
168
169 if (my_fastsum_plan.flags & NEARFIELD_BOXES)
170 printf(
171 "determination of nearfield candidates based on partitioning into boxes\n");
172 else
173 printf("determination of nearfield candidates based on search tree\n");
174
176 k = 0;
177 while (k < N)
178 {
179 R r_max = K(0.25) - my_fastsum_plan.eps_B / K(2.0);
180 R r2 = K(0.0);
181
182 for (j = 0; j < d; j++)
183 my_fastsum_plan.x[k * d + j] = K(2.0) * r_max * NFFT(drand48)() - r_max;
184
185 for (j = 0; j < d; j++)
186 r2 += my_fastsum_plan.x[k * d + j] * my_fastsum_plan.x[k * d + j];
187
188 if (r2 >= r_max * r_max)
189 continue;
190
191 k++;
192 }
193
194 for (k = 0; k < N; k++)
195 {
196 /* R r=(0.25-my_fastsum_plan.eps_B/2.0)*pow((R)rand()/(R)RAND_MAX,1.0/d);
197 my_fastsum_plan.x[k*d+0] = r;
198 for (j=1; j<d; j++)
199 {
200 R phi=2.0*KPI*(R)rand()/(R)RAND_MAX;
201 my_fastsum_plan.x[k*d+j] = r;
202 for (t=0; t<j; t++)
203 {
204 my_fastsum_plan.x[k*d+t] *= cos(phi);
205 }
206 my_fastsum_plan.x[k*d+j] *= sin(phi);
207 }
208 */
209 my_fastsum_plan.alpha[k] = NFFT(drand48)() + II * NFFT(drand48)();
210 }
211
213 k = 0;
214 while (k < M)
215 {
216 R r_max = K(0.25) - my_fastsum_plan.eps_B / K(2.0);
217 R r2 = K(0.0);
218
219 for (j = 0; j < d; j++)
220 my_fastsum_plan.y[k * d + j] = K(2.0) * r_max * NFFT(drand48)() - r_max;
221
222 for (j = 0; j < d; j++)
223 r2 += my_fastsum_plan.y[k * d + j] * my_fastsum_plan.y[k * d + j];
224
225 if (r2 >= r_max * r_max)
226 continue;
227
228 k++;
229 }
230 /* for (k=0; k<M; k++)
231 {
232 R r=(0.25-my_fastsum_plan.eps_B/2.0)*pow((R)rand()/(R)RAND_MAX,1.0/d);
233 my_fastsum_plan.y[k*d+0] = r;
234 for (j=1; j<d; j++)
235 {
236 R phi=2.0*KPI*(R)rand()/(R)RAND_MAX;
237 my_fastsum_plan.y[k*d+j] = r;
238 for (t=0; t<j; t++)
239 {
240 my_fastsum_plan.y[k*d+t] *= cos(phi);
241 }
242 my_fastsum_plan.y[k*d+j] *= sin(phi);
243 }
244 } */
245
247 printf("direct computation: ");
248 fflush(NULL);
249 t0 = getticks();
250 fastsum_exact(&my_fastsum_plan);
251 t1 = getticks();
252 time = NFFT(elapsed_seconds)(t1, t0);
253 printf(__FI__ "sec\n", time);
254
256 direct = (C *) NFFT(malloc)((size_t)(my_fastsum_plan.M_total) * (sizeof(C)));
257 for (j = 0; j < my_fastsum_plan.M_total; j++)
258 direct[j] = my_fastsum_plan.f[j];
259
261 printf("pre-computation: ");
262 fflush(NULL);
263 t0 = getticks();
264 fastsum_precompute(&my_fastsum_plan);
265 t1 = getticks();
266 time = NFFT(elapsed_seconds)(t1, t0);
267 printf(__FI__ "sec\n", time);
268
270 printf("fast computation: ");
271 fflush(NULL);
272 t0 = getticks();
273 fastsum_trafo(&my_fastsum_plan);
274 t1 = getticks();
275 time = NFFT(elapsed_seconds)(t1, t0);
276 printf(__FI__ "sec\n", time);
277
279 error = K(0.0);
280 for (j = 0; j < my_fastsum_plan.M_total; j++)
281 {
282 if (CABS(direct[j] - my_fastsum_plan.f[j]) / CABS(direct[j]) > error)
283 error = CABS(direct[j] - my_fastsum_plan.f[j]) / CABS(direct[j]);
284 }
285 printf("max relative error: %" __FES__ "\n", error);
286
288 fastsum_finalize(&my_fastsum_plan);
289
290 return EXIT_SUCCESS;
291}
292/* \} */
Header file for the fast NFFT-based summation algorithm.
void fastsum_precompute(fastsum_plan *ths)
precomputation for fastsum
Definition fastsum.c:1173
C inverse_multiquadric(R x, int der, const R *param)
K(x)=1/sqrt(x^2+c^2)
Definition kernels.c:90
int M_total
number of target knots
Definition fastsum.h:89
C logarithm(R x, int der, const R *param)
K(x)=log |x|.
Definition kernels.c:116
C multiquadric(R x, int der, const R *param)
K(x)=sqrt(x^2+c^2)
Definition kernels.c:64
void fastsum_init_guru(fastsum_plan *ths, int d, int N_total, int M_total, kernel k, R *param, unsigned flags, int nn, int m, int p, R eps_I, R eps_B)
initialization of fastsum plan
Definition fastsum.c:987
R * x
source knots in d-ball with radius 1/4-eps_b/2
Definition fastsum.h:94
C one_over_cube(R x, int der, const R *param)
K(x) = 1/x^3.
Definition kernels.c:374
C one_over_square(R x, int der, const R *param)
K(x) = 1/x^2.
Definition kernels.c:177
C sinc_kernel(R x, int der, const R *param)
K(x) = sin(cx)/x.
Definition kernels.c:287
C der_laplacian_rbf(R x, int der, const R *param)
K(x) = |x|/c exp(-|x|/c)
Definition kernels.c:434
C kcot(R x, int der, const R *param)
K(x) = cot(cx)
Definition kernels.c:346
C one_over_modulus(R x, int der, const R *param)
K(x) = 1/|x|.
Definition kernels.c:205
C * f
target evaluations
Definition fastsum.h:92
C * alpha
source coefficients
Definition fastsum.h:91
R eps_B
outer boundary
Definition fastsum.h:114
C thinplate_spline(R x, int der, const R *param)
K(x) = x^2 log |x|.
Definition kernels.c:149
void fastsum_trafo(fastsum_plan *ths)
fast NFFT-based summation
Definition fastsum.c:1180
void fastsum_exact(fastsum_plan *ths)
direct computation of sums
Definition fastsum.c:1056
unsigned flags
flags precomp.
Definition fastsum.h:100
void fastsum_finalize(fastsum_plan *ths)
finalization of fastsum plan
Definition fastsum.c:1048
C inverse_multiquadric3(R x, int der, const R *param)
K(x) = 1/sqrt(x^2+c^2)^3.
Definition kernels.c:261
C absx(R x, int der, const R *param)
K(x) = |x|.
Definition kernels.c:476
C gaussian(R x, int der, const R *param)
K(x)=exp(-x^2/c^2)
Definition kernels.c:38
C one_over_x(R x, int der, const R *param)
K(x) = 1/x.
Definition kernels.c:233
C cosc(R x, int der, const R *param)
K(x) = cos(cx)/x.
Definition kernels.c:314
C xx_gaussian(R x, int der, const R *param)
K(x) = x^2/c^2 exp(-x^2/c^2)
Definition kernels.c:450
R * y
target knots in d-ball with radius 1/4-eps_b/2
Definition fastsum.h:95
C log_sin(R x, int der, const R *param)
K(x) = log(|sin(cx)|)
Definition kernels.c:402
C laplacian_rbf(R x, int der, const R *param)
K(x) = exp(-|x|/c)
Definition kernels.c:417
Internal header file for auxiliary definitions and functions.
Header file with predefined kernels for the fast summation algorithm.
plan for fast summation algorithm
Definition fastsum.h:83