44 enum boolean {NO = 0, YES = 1};
50 enum gridtype {GRID_GAUSS_LEGENDRE = 0, GRID_CLENSHAW_CURTIS = 1,
51 GRID_HEALPIX = 2, GRID_EQUIDISTRIBUTION = 3, GRID_EQUIDISTRIBUTION_UNIFORM = 4};
54 enum functiontype {FUNCTION_RANDOM_BANDLIMITED = 0, FUNCTION_F1 = 1,
55 FUNCTION_F2 = 2, FUNCTION_F3 = 3, FUNCTION_F4 = 4, FUNCTION_F5 = 5,
59 enum modes {USE_GRID = 0, RANDOM = 1};
69 int main (
int argc,
char **argv)
101 double _Complex *f_grid;
102 double _Complex *f_compare;
104 double _Complex *f_hat_gen;
106 double _Complex *f_hat;
113 double err_infty_avg;
136 double x1,x2,x3,temp;
145 fscanf(stdin,
"testcases=%d\n",&tc_max);
146 fprintf(stdout,
"%d\n",tc_max);
149 for (tc = 0; tc < tc_max; tc++)
152 fscanf(stdin,
"nfsft=%d\n",&use_nfsft);
153 fprintf(stdout,
"%d\n",use_nfsft);
157 fscanf(stdin,
"nfft=%d\n",&use_nfft);
158 fprintf(stdout,
"%d\n",use_nfsft);
162 fscanf(stdin,
"cutoff=%d\n",&cutoff);
163 fprintf(stdout,
"%d\n",cutoff);
172 fscanf(stdin,
"fpt=%d\n",&use_fpt);
173 fprintf(stdout,
"%d\n",use_fpt);
177 fscanf(stdin,
"threshold=%lf\n",&threshold);
178 fprintf(stdout,
"%lf\n",threshold);
198 fscanf(stdin,
"testmode=%d\n",&testmode);
199 fprintf(stdout,
"%d\n",testmode);
201 if (testmode == ERROR)
204 fscanf(stdin,
"gridtype=%d\n",&gridtype);
205 fprintf(stdout,
"%d\n",gridtype);
208 fscanf(stdin,
"testfunction=%d\n",&testfunction);
209 fprintf(stdout,
"%d\n",testfunction);
212 if (testfunction == FUNCTION_RANDOM_BANDLIMITED)
215 fscanf(stdin,
"bandlimit=%d\n",&N);
216 fprintf(stdout,
"%d\n",N);
224 fscanf(stdin,
"repetitions=%d\n",&repetitions);
225 fprintf(stdout,
"%d\n",repetitions);
227 fscanf(stdin,
"mode=%d\n",&mode);
228 fprintf(stdout,
"%d\n",mode);
233 fscanf(stdin,
"points=%d\n",&m_compare);
234 fprintf(stdout,
"%d\n",m_compare);
235 x_compare = (
double*)
nfft_malloc(2*m_compare*
sizeof(
double));
237 while (d < m_compare)
239 x1 = 2.0*(((double)rand())/RAND_MAX) - 1.0;
240 x2 = 2.0*(((double)rand())/RAND_MAX) - 1.0;
241 x3 = 2.0*(((double)rand())/RAND_MAX) - 1.0;
242 temp = sqrt(x1*x1+x2*x2+x3*x3);
245 x_compare[2*d+1] = acos(x3);
246 if (x_compare[2*d+1] == 0 || x_compare[2*d+1] == KPI)
248 x_compare[2*d] = 0.0;
252 x_compare[2*d] = atan2(x2/sin(x_compare[2*d+1]),x1/sin(x_compare[2*d+1]));
254 x_compare[2*d] *= 1.0/(2.0*KPI);
255 x_compare[2*d+1] *= 1.0/(2.0*KPI);
259 f_compare = (
double _Complex*)
nfft_malloc(m_compare*
sizeof(
double _Complex));
260 f = (
double _Complex*)
nfft_malloc(m_compare*
sizeof(
double _Complex));
269 fscanf(stdin,
"bandwidths=%d\n",&iNQ_max);
270 fprintf(stdout,
"%d\n",iNQ_max);
275 if (testmode == TIMING)
281 for (iNQ = 0; iNQ < iNQ_max; iNQ++)
283 if (testmode == TIMING)
286 fscanf(stdin,
"%d %d %d\n",&NQ[iNQ],&SQ[iNQ],&RQ[iNQ]);
287 fprintf(stdout,
"%d %d %d\n",NQ[iNQ],SQ[iNQ],RQ[iNQ]);
288 NQ_max = MAX(NQ_max,NQ[iNQ]);
289 SQ_max = MAX(SQ_max,SQ[iNQ]);
294 fscanf(stdin,
"%d %d\n",&NQ[iNQ],&SQ[iNQ]);
295 fprintf(stdout,
"%d %d\n",NQ[iNQ],SQ[iNQ]);
296 NQ_max = MAX(NQ_max,NQ[iNQ]);
297 SQ_max = MAX(SQ_max,SQ[iNQ]);
307 if (testmode == TIMING)
311 f = (
double _Complex*)
nfft_malloc(SQ_max*
sizeof(
double _Complex));
312 x_grid = (
double*)
nfft_malloc(2*SQ_max*
sizeof(
double));
313 for (d = 0; d < SQ_max; d++)
315 f[d] = (((double)rand())/RAND_MAX)-0.5 + _Complex_I*((((double)rand())/RAND_MAX)-0.5);
316 x_grid[2*d] = (((double)rand())/RAND_MAX) - 0.5;
317 x_grid[2*d+1] = (((double)rand())/RAND_MAX) * 0.5;
324 for (iNQ = 0; iNQ < iNQ_max; iNQ++)
326 if (testmode == TIMING)
338 nfsft_precompute_x(&plan);
342 for (i = 0; i < RQ[iNQ]; i++)
354 nfsft_adjoint_direct(&plan);
361 t_avg = t_avg/((double)RQ[iNQ]);
365 fprintf(stdout,
"%+le\n", t_avg);
366 fprintf(stderr,
"%d: %4d %4d %+le\n", tc, NQ[iNQ], SQ[iNQ], t_avg);
373 case GRID_GAUSS_LEGENDRE:
375 m_theta = SQ[iNQ] + 1;
376 m_phi = 2*SQ[iNQ] + 2;
377 m_total = m_theta*m_phi;
379 case GRID_CLENSHAW_CURTIS:
381 m_theta = 2*SQ[iNQ] + 1;
382 m_phi = 2*SQ[iNQ] + 2;
383 m_total = m_theta*m_phi;
387 m_phi = 12*SQ[iNQ]*SQ[iNQ];
388 m_total = m_theta * m_phi;
391 case GRID_EQUIDISTRIBUTION:
392 case GRID_EQUIDISTRIBUTION_UNIFORM:
395 for (k = 1; k < SQ[iNQ]; k++)
397 m_theta += (int)floor((2*KPI)/acos((cos(KPI/(
double)SQ[iNQ])-
398 cos(k*KPI/(
double)SQ[iNQ])*cos(k*KPI/(
double)SQ[iNQ]))/
399 (sin(k*KPI/(
double)SQ[iNQ])*sin(k*KPI/(
double)SQ[iNQ]))));
404 m_total = m_theta * m_phi;
410 x_grid = (
double*)
nfft_malloc(2*m_total*
sizeof(
double));
416 case GRID_GAUSS_LEGENDRE:
421 for (k = 0; k < m_theta; k++)
423 fscanf(stdin,
"%le\n",&w[k]);
424 w[k] *= (2.0*KPI)/((
double)m_phi);
430 theta = (
double*)
nfft_malloc(m_theta*
sizeof(
double));
441 for (k = 0; k < m_theta; k++)
443 fscanf(stdin,
"%le\n",&theta[k]);
447 for (n = 0; n < m_phi; n++)
449 phi[n] = n/((double)m_phi);
450 phi[n] -= ((phi[n]>=0.5)?(1.0):(0.0));
458 for (k = 0; k < m_theta; k++)
460 for (n = 0; n < m_phi; n++)
462 x_grid[2*d] = phi[n];
463 x_grid[2*d+1] = theta[k];
476 case GRID_CLENSHAW_CURTIS:
479 theta = (
double*)
nfft_malloc(m_theta*
sizeof(
double));
483 for (k = 0; k < m_theta; k++)
485 theta[k] = k/((double)2*(m_theta-1));
489 for (n = 0; n < m_phi; n++)
491 phi[n] = n/((double)m_phi);
492 phi[n] -= ((phi[n]>=0.5)?(1.0):(0.0));
496 fplan = fftw_plan_r2r_1d(SQ[iNQ]+1, w, w, FFTW_REDFT00, 0U);
497 for (k = 0; k < SQ[iNQ]+1; k++)
499 w[k] = -2.0/(4*k*k-1);
504 for (k = 0; k < SQ[iNQ]+1; k++)
506 w[k] *= (2.0*KPI)/((
double)(m_theta-1)*m_phi);
507 w[m_theta-1-k] = w[k];
509 fftw_destroy_plan(fplan);
513 for (k = 0; k < m_theta; k++)
515 for (n = 0; n < m_phi; n++)
517 x_grid[2*d] = phi[n];
518 x_grid[2*d+1] = theta[k];
532 for (k = 1; k <= SQ[iNQ]-1; k++)
534 for (n = 0; n <= 4*k-1; n++)
536 x_grid[2*d+1] = 1 - (k*k)/((
double)(3.0*SQ[iNQ]*SQ[iNQ]));
537 x_grid[2*d] = ((n+0.5)/(4*k));
538 x_grid[2*d] -= (x_grid[2*d]>=0.5)?(1.0):(0.0);
545 for (k = SQ[iNQ]; k <= 3*SQ[iNQ]; k++)
547 for (n = 0; n <= 4*SQ[iNQ]-1; n++)
549 x_grid[2*d+1] = 2.0/(3*SQ[iNQ])*(2*SQ[iNQ]-k);
550 x_grid[2*d] = (n+((k%2==0)?(0.5):(0.0)))/(4*SQ[iNQ]);
551 x_grid[2*d] -= (x_grid[2*d]>=0.5)?(1.0):(0.0);
556 for (k = 1; k <= SQ[iNQ]-1; k++)
558 for (n = 0; n <= 4*k-1; n++)
560 x_grid[2*d+1] = -x_grid[2*d2+1];
561 x_grid[2*d] = x_grid[2*d2];
567 for (d = 0; d < m_total; d++)
569 x_grid[2*d+1] = acos(x_grid[2*d+1])/(2.0*KPI);
572 w[0] = (4.0*KPI)/(m_total);
575 case GRID_EQUIDISTRIBUTION:
576 case GRID_EQUIDISTRIBUTION_UNIFORM:
579 if (gridtype == GRID_EQUIDISTRIBUTION)
581 w_temp = (
double*)
nfft_malloc((SQ[iNQ]+1)*
sizeof(double));
582 fplan = fftw_plan_r2r_1d(SQ[iNQ]/2+1, w_temp, w_temp, FFTW_REDFT00, 0U);
583 for (k = 0; k < SQ[iNQ]/2+1; k++)
585 w_temp[k] = -2.0/(4*k*k-1);
590 for (k = 0; k < SQ[iNQ]/2+1; k++)
592 w_temp[k] *= (2.0*KPI)/((
double)(SQ[iNQ]));
593 w_temp[SQ[iNQ]-k] = w_temp[k];
595 fftw_destroy_plan(fplan);
601 if (gridtype == GRID_EQUIDISTRIBUTION)
607 w[d] = (4.0*KPI)/(m_total);
612 if (gridtype == GRID_EQUIDISTRIBUTION)
614 w[d] = w_temp[SQ[iNQ]];
618 w[d] = (4.0*KPI)/(m_total);
622 for (k = 1; k < SQ[iNQ]; k++)
624 theta_s = (double)k*KPI/(
double)SQ[iNQ];
625 M = (int)floor((2.0*KPI)/acos((cos(KPI/(
double)SQ[iNQ])-
626 cos(theta_s)*cos(theta_s))/(sin(theta_s)*sin(theta_s))));
628 for (n = 0; n < M; n++)
630 x_grid[2*d] = (n + 0.5)/M;
631 x_grid[2*d] -= (x_grid[2*d]>=0.5)?(1.0):(0.0);
632 x_grid[2*d+1] = theta_s/(2.0*KPI);
633 if (gridtype == GRID_EQUIDISTRIBUTION)
635 w[d] = w_temp[k]/((double)(M));
639 w[d] = (4.0*KPI)/(m_total);
645 if (gridtype == GRID_EQUIDISTRIBUTION)
656 f_grid = (
double _Complex*)
nfft_malloc(m_total*
sizeof(
double _Complex));
664 f_compare = (
double _Complex*)
nfft_malloc(m_compare*
sizeof(
double _Complex));
671 switch (testfunction)
673 case FUNCTION_RANDOM_BANDLIMITED:
685 plan_gen.
f_hat = f_hat_gen;
689 nfsft_precompute_x(&plan_gen);
691 for (k = 0; k < plan_gen.
N_total; k++)
696 for (k = 0; k <= N; k++)
698 for (n = -k; n <= k; n++)
701 (((double)rand())/RAND_MAX)-0.5 + _Complex_I*((((double)rand())/RAND_MAX)-0.5);
713 nfsft_trafo_direct(&plan_gen);
726 plan_gen.
f_hat = f_hat_gen;
727 plan_gen.
x = x_compare;
728 plan_gen.
f = f_compare;
730 nfsft_precompute_x(&plan_gen);
740 nfsft_trafo_direct(&plan_gen);
747 memcpy(f_compare,f_grid,m_total*
sizeof(
double _Complex));
755 for (d = 0; d < m_total; d++)
757 x1 = sin(x_grid[2*d+1]*2.0*KPI)*cos(x_grid[2*d]*2.0*KPI);
758 x2 = sin(x_grid[2*d+1]*2.0*KPI)*sin(x_grid[2*d]*2.0*KPI);
759 x3 = cos(x_grid[2*d+1]*2.0*KPI);
760 f_grid[d] = x1*x2*x3;
764 for (d = 0; d < m_compare; d++)
766 x1 = sin(x_compare[2*d+1]*2.0*KPI)*cos(x_compare[2*d]*2.0*KPI);
767 x2 = sin(x_compare[2*d+1]*2.0*KPI)*sin(x_compare[2*d]*2.0*KPI);
768 x3 = cos(x_compare[2*d+1]*2.0*KPI);
769 f_compare[d] = x1*x2*x3;
774 memcpy(f_compare,f_grid,m_total*
sizeof(
double _Complex));
778 for (d = 0; d < m_total; d++)
780 x1 = sin(x_grid[2*d+1]*2.0*KPI)*cos(x_grid[2*d]*2.0*KPI);
781 x2 = sin(x_grid[2*d+1]*2.0*KPI)*sin(x_grid[2*d]*2.0*KPI);
782 x3 = cos(x_grid[2*d+1]*2.0*KPI);
783 f_grid[d] = 0.1*exp(x1+x2+x3);
787 for (d = 0; d < m_compare; d++)
789 x1 = sin(x_compare[2*d+1]*2.0*KPI)*cos(x_compare[2*d]*2.0*KPI);
790 x2 = sin(x_compare[2*d+1]*2.0*KPI)*sin(x_compare[2*d]*2.0*KPI);
791 x3 = cos(x_compare[2*d+1]*2.0*KPI);
792 f_compare[d] = 0.1*exp(x1+x2+x3);
797 memcpy(f_compare,f_grid,m_total*
sizeof(
double _Complex));
801 for (d = 0; d < m_total; d++)
803 x1 = sin(x_grid[2*d+1]*2.0*KPI)*cos(x_grid[2*d]*2.0*KPI);
804 x2 = sin(x_grid[2*d+1]*2.0*KPI)*sin(x_grid[2*d]*2.0*KPI);
805 x3 = cos(x_grid[2*d+1]*2.0*KPI);
806 temp = sqrt(x1*x1)+sqrt(x2*x2)+sqrt(x3*x3);
807 f_grid[d] = 0.1*temp;
811 for (d = 0; d < m_compare; d++)
813 x1 = sin(x_compare[2*d+1]*2.0*KPI)*cos(x_compare[2*d]*2.0*KPI);
814 x2 = sin(x_compare[2*d+1]*2.0*KPI)*sin(x_compare[2*d]*2.0*KPI);
815 x3 = cos(x_compare[2*d+1]*2.0*KPI);
816 temp = sqrt(x1*x1)+sqrt(x2*x2)+sqrt(x3*x3);
817 f_compare[d] = 0.1*temp;
822 memcpy(f_compare,f_grid,m_total*
sizeof(
double _Complex));
826 for (d = 0; d < m_total; d++)
828 x1 = sin(x_grid[2*d+1]*2.0*KPI)*cos(x_grid[2*d]*2.0*KPI);
829 x2 = sin(x_grid[2*d+1]*2.0*KPI)*sin(x_grid[2*d]*2.0*KPI);
830 x3 = cos(x_grid[2*d+1]*2.0*KPI);
831 temp = sqrt(x1*x1)+sqrt(x2*x2)+sqrt(x3*x3);
832 f_grid[d] = 1.0/(temp);
836 for (d = 0; d < m_compare; d++)
838 x1 = sin(x_compare[2*d+1]*2.0*KPI)*cos(x_compare[2*d]*2.0*KPI);
839 x2 = sin(x_compare[2*d+1]*2.0*KPI)*sin(x_compare[2*d]*2.0*KPI);
840 x3 = cos(x_compare[2*d+1]*2.0*KPI);
841 temp = sqrt(x1*x1)+sqrt(x2*x2)+sqrt(x3*x3);
842 f_compare[d] = 1.0/(temp);
847 memcpy(f_compare,f_grid,m_total*
sizeof(
double _Complex));
851 for (d = 0; d < m_total; d++)
853 x1 = sin(x_grid[2*d+1]*2.0*KPI)*cos(x_grid[2*d]*2.0*KPI);
854 x2 = sin(x_grid[2*d+1]*2.0*KPI)*sin(x_grid[2*d]*2.0*KPI);
855 x3 = cos(x_grid[2*d+1]*2.0*KPI);
856 temp = sqrt(x1*x1)+sqrt(x2*x2)+sqrt(x3*x3);
857 f_grid[d] = 0.1*sin(1+temp)*sin(1+temp);
861 for (d = 0; d < m_compare; d++)
863 x1 = sin(x_compare[2*d+1]*2.0*KPI)*cos(x_compare[2*d]*2.0*KPI);
864 x2 = sin(x_compare[2*d+1]*2.0*KPI)*sin(x_compare[2*d]*2.0*KPI);
865 x3 = cos(x_compare[2*d+1]*2.0*KPI);
866 temp = sqrt(x1*x1)+sqrt(x2*x2)+sqrt(x3*x3);
867 f_compare[d] = 0.1*sin(1+temp)*sin(1+temp);
872 memcpy(f_compare,f_grid,m_total*
sizeof(
double _Complex));
876 for (d = 0; d < m_total; d++)
878 if (x_grid[2*d+1] <= 0.25)
884 f_grid[d] = 1.0/(sqrt(1+3*cos(2.0*KPI*x_grid[2*d+1])*cos(2.0*KPI*x_grid[2*d+1])));
889 for (d = 0; d < m_compare; d++)
891 if (x_compare[2*d+1] <= 0.25)
897 f_compare[d] = 1.0/(sqrt(1+3*cos(2.0*KPI*x_compare[2*d+1])*cos(2.0*KPI*x_compare[2*d+1])));
903 memcpy(f_compare,f_grid,m_total*
sizeof(
double _Complex));
909 for (d = 0; d < m_total; d++)
915 for (d = 0; d < m_compare; d++)
922 memcpy(f_compare,f_grid,m_total*
sizeof(
double _Complex));
936 plan_adjoint_ptr = &plan_adjoint;
949 plan_ptr = &plan_adjoint;
954 plan_adjoint_ptr->
f_hat = f_hat;
955 plan_adjoint_ptr->
x = x_grid;
956 plan_adjoint_ptr->
f = f_grid;
958 plan_ptr->
f_hat = f_hat;
959 plan_ptr->
x = x_compare;
964 nfsft_precompute_x(plan_adjoint_ptr);
965 if (plan_adjoint_ptr != plan_ptr)
967 nfsft_precompute_x(plan_ptr);
976 for (i = 0; i < 1; i++)
991 for (k = 0; k < m_theta; k++)
993 for (n = 0; n < m_phi; n++)
1021 if (use_nfsft != NO)
1029 nfsft_adjoint_direct(plan_adjoint_ptr);
1045 if (use_nfsft != NO)
1053 nfsft_trafo_direct(plan_ptr);
1063 if (plan_ptr != plan_adjoint_ptr)
1072 err_infty_avg +=
X(error_l_infty_complex)(f, f_compare, m_compare);
1073 err_2_avg +=
X(error_l_2_complex)(f, f_compare, m_compare);
1095 t_avg = t_avg/((double)repetitions);
1098 err_infty_avg = err_infty_avg/((double)repetitions);
1101 err_2_avg = err_2_avg/((double)repetitions);
1104 fprintf(stdout,
"%+le %+le %+le\n", t_avg, err_infty_avg, err_2_avg);
1105 fprintf(stderr,
"%d: %4d %4d %+le %+le %+le\n", tc, NQ[iNQ], SQ[iNQ],
1106 t_avg, err_infty_avg, err_2_avg);
1110 fprintf(stderr,
"\n");
1118 if (testmode == TIMING)
1130 if (testmode == TIMING)
1141 return EXIT_SUCCESS;
double * x
the nodes for ,
void nfsft_trafo(nfsft_plan *plan)
void nfsft_adjoint(nfsft_plan *plan)
fftw_complex * f_hat
Fourier coefficients.
R nfft_elapsed_seconds(ticks t1, ticks t0)
Return number of elapsed seconds between two time points.
void nfsft_precompute(int N, double kappa, unsigned int nfsft_flags, unsigned int fpt_flags)
data structure for an NFSFT (nonequispaced fast spherical Fourier transform) plan with double precisi...
#define NFSFT_NO_FAST_ALGORITHM
modes
TODO Add comment here.
testtype
Enumeration for test modes.
#define X(name)
Include header for C99 complex datatype.
functiontype
Enumeration for test functions.
void * nfft_malloc(size_t n)
NFFT_INT N_total
Total number of Fourier coefficients.
#define NFSFT_F_HAT_SIZE(N)
double threshold
The threshold /f$/f$.
void nfsft_finalize(nfsft_plan *plan)
Header file for the nfft3 library.
int main(int argc, char **argv)
The main program.
#define NFSFT_INDEX(k, n, plan)
gridtype
Enumeration for quadrature grid types.