47 enum boolean {NO = 0, YES = 1};
53 enum gridtype {GRID_GAUSS_LEGENDRE = 0, GRID_CLENSHAW_CURTIS = 1,
54 GRID_HEALPIX = 2, GRID_EQUIDISTRIBUTION = 3, GRID_EQUIDISTRIBUTION_UNIFORM = 4};
57 enum functiontype {FUNCTION_RANDOM_BANDLIMITED = 0, FUNCTION_F1 = 1,
58 FUNCTION_F2 = 2, FUNCTION_F3 = 3, FUNCTION_F4 = 4, FUNCTION_F5 = 5,
62 enum modes {USE_GRID = 0, RANDOM = 1};
72 int main (
int argc,
char **argv)
104 double _Complex *f_grid;
105 double _Complex *f_compare;
107 double _Complex *f_hat_gen;
109 double _Complex *f_hat;
116 double err_infty_avg;
139 double x1,x2,x3,temp;
148 fscanf(stdin,
"testcases=%d\n",&tc_max);
149 fprintf(stdout,
"%d\n",tc_max);
152 for (tc = 0; tc < tc_max; tc++)
155 fscanf(stdin,
"nfsft=%d\n",&use_nfsft);
156 fprintf(stdout,
"%d\n",use_nfsft);
160 fscanf(stdin,
"nfft=%d\n",&use_nfft);
161 fprintf(stdout,
"%d\n",use_nfsft);
165 fscanf(stdin,
"cutoff=%d\n",&cutoff);
166 fprintf(stdout,
"%d\n",cutoff);
175 fscanf(stdin,
"fpt=%d\n",&use_fpt);
176 fprintf(stdout,
"%d\n",use_fpt);
180 fscanf(stdin,
"threshold=%lf\n",&threshold);
181 fprintf(stdout,
"%lf\n",threshold);
201 fscanf(stdin,
"testmode=%d\n",&testmode);
202 fprintf(stdout,
"%d\n",testmode);
204 if (testmode == ERROR)
207 fscanf(stdin,
"gridtype=%d\n",&gridtype);
208 fprintf(stdout,
"%d\n",gridtype);
211 fscanf(stdin,
"testfunction=%d\n",&testfunction);
212 fprintf(stdout,
"%d\n",testfunction);
215 if (testfunction == FUNCTION_RANDOM_BANDLIMITED)
218 fscanf(stdin,
"bandlimit=%d\n",&N);
219 fprintf(stdout,
"%d\n",N);
227 fscanf(stdin,
"repetitions=%d\n",&repetitions);
228 fprintf(stdout,
"%d\n",repetitions);
230 fscanf(stdin,
"mode=%d\n",&mode);
231 fprintf(stdout,
"%d\n",mode);
236 fscanf(stdin,
"points=%d\n",&m_compare);
237 fprintf(stdout,
"%d\n",m_compare);
238 x_compare = (
double*)
nfft_malloc(2*m_compare*
sizeof(
double));
240 while (d < m_compare)
242 x1 = 2.0*(((double)rand())/RAND_MAX) - 1.0;
243 x2 = 2.0*(((double)rand())/RAND_MAX) - 1.0;
244 x3 = 2.0*(((double)rand())/RAND_MAX) - 1.0;
245 temp = sqrt(x1*x1+x2*x2+x3*x3);
248 x_compare[2*d+1] = acos(x3);
249 if (x_compare[2*d+1] == 0 || x_compare[2*d+1] ==
PI)
251 x_compare[2*d] = 0.0;
255 x_compare[2*d] = atan2(x2/sin(x_compare[2*d+1]),x1/sin(x_compare[2*d+1]));
257 x_compare[2*d] *= 1.0/(2.0*
PI);
258 x_compare[2*d+1] *= 1.0/(2.0*
PI);
262 f_compare = (
double _Complex*)
nfft_malloc(m_compare*
sizeof(
double _Complex));
263 f = (
double _Complex*)
nfft_malloc(m_compare*
sizeof(
double _Complex));
272 fscanf(stdin,
"bandwidths=%d\n",&iNQ_max);
273 fprintf(stdout,
"%d\n",iNQ_max);
278 if (testmode == TIMING)
284 for (iNQ = 0; iNQ < iNQ_max; iNQ++)
286 if (testmode == TIMING)
289 fscanf(stdin,
"%d %d %d\n",&NQ[iNQ],&SQ[iNQ],&RQ[iNQ]);
290 fprintf(stdout,
"%d %d %d\n",NQ[iNQ],SQ[iNQ],RQ[iNQ]);
297 fscanf(stdin,
"%d %d\n",&NQ[iNQ],&SQ[iNQ]);
298 fprintf(stdout,
"%d %d\n",NQ[iNQ],SQ[iNQ]);
307 nfsft_precompute(NQ_max, threshold,
308 ((use_nfsft==NO)?(NFSFT_NO_FAST_ALGORITHM):(0U)), 0U);
310 if (testmode == TIMING)
313 f_hat = (
double _Complex*)
nfft_malloc(NFSFT_F_HAT_SIZE(NQ_max)*
sizeof(
double _Complex));
314 f = (
double _Complex*)
nfft_malloc(SQ_max*
sizeof(
double _Complex));
315 x_grid = (
double*)
nfft_malloc(2*SQ_max*
sizeof(
double));
316 for (d = 0; d < SQ_max; d++)
318 f[d] = (((double)rand())/RAND_MAX)-0.5 + _Complex_I*((((double)rand())/RAND_MAX)-0.5);
319 x_grid[2*d] = (((double)rand())/RAND_MAX) - 0.5;
320 x_grid[2*d+1] = (((double)rand())/RAND_MAX) * 0.5;
327 for (iNQ = 0; iNQ < iNQ_max; iNQ++)
329 if (testmode == TIMING)
331 nfsft_init_guru(&plan,NQ[iNQ],SQ[iNQ], NFSFT_NORMALIZED |
332 ((use_nfft!=NO)?(0U):(NFSFT_USE_NDFT)) |
333 ((use_fpt!=NO)?(0U):(NFSFT_USE_DPT)),
334 PRE_PHI_HUT | PRE_PSI | FFTW_INIT | FFTW_MEASURE | FFT_OUT_OF_PLACE,
341 nfsft_precompute_x(&plan);
345 for (i = 0; i < RQ[iNQ]; i++)
352 nfsft_adjoint(&plan);
357 nfsft_adjoint_direct(&plan);
361 t_avg += nfft_elapsed_seconds(t1,t0);
364 t_avg = t_avg/((double)RQ[iNQ]);
366 nfsft_finalize(&plan);
368 fprintf(stdout,
"%+le\n", t_avg);
369 fprintf(stderr,
"%d: %4d %4d %+le\n", tc, NQ[iNQ], SQ[iNQ], t_avg);
376 case GRID_GAUSS_LEGENDRE:
378 m_theta = SQ[iNQ] + 1;
379 m_phi = 2*SQ[iNQ] + 2;
380 m_total = m_theta*m_phi;
382 case GRID_CLENSHAW_CURTIS:
384 m_theta = 2*SQ[iNQ] + 1;
385 m_phi = 2*SQ[iNQ] + 2;
386 m_total = m_theta*m_phi;
390 m_phi = 12*SQ[iNQ]*SQ[iNQ];
391 m_total = m_theta * m_phi;
394 case GRID_EQUIDISTRIBUTION:
395 case GRID_EQUIDISTRIBUTION_UNIFORM:
398 for (k = 1; k < SQ[iNQ]; k++)
400 m_theta += (int)floor((2*
PI)/acos((cos(
PI/(
double)SQ[iNQ])-
401 cos(k*
PI/(
double)SQ[iNQ])*cos(k*
PI/(
double)SQ[iNQ]))/
402 (sin(k*
PI/(
double)SQ[iNQ])*sin(k*
PI/(
double)SQ[iNQ]))));
407 m_total = m_theta * m_phi;
413 x_grid = (
double*)
nfft_malloc(2*m_total*
sizeof(
double));
419 case GRID_GAUSS_LEGENDRE:
424 for (k = 0; k < m_theta; k++)
426 fscanf(stdin,
"%le\n",&w[k]);
427 w[k] *= (2.0*
PI)/((
double)m_phi);
433 theta = (
double*)
nfft_malloc(m_theta*
sizeof(
double));
444 for (k = 0; k < m_theta; k++)
446 fscanf(stdin,
"%le\n",&theta[k]);
450 for (n = 0; n < m_phi; n++)
452 phi[n] = n/((double)m_phi);
453 phi[n] -= ((phi[n]>=0.5)?(1.0):(0.0));
461 for (k = 0; k < m_theta; k++)
463 for (n = 0; n < m_phi; n++)
465 x_grid[2*d] = phi[n];
466 x_grid[2*d+1] = theta[k];
479 case GRID_CLENSHAW_CURTIS:
482 theta = (
double*)
nfft_malloc(m_theta*
sizeof(
double));
486 for (k = 0; k < m_theta; k++)
488 theta[k] = k/((double)2*(m_theta-1));
492 for (n = 0; n < m_phi; n++)
494 phi[n] = n/((double)m_phi);
495 phi[n] -= ((phi[n]>=0.5)?(1.0):(0.0));
499 fplan = fftw_plan_r2r_1d(SQ[iNQ]+1, w, w, FFTW_REDFT00, 0U);
500 for (k = 0; k < SQ[iNQ]+1; k++)
502 w[k] = -2.0/(4*k*k-1);
507 for (k = 0; k < SQ[iNQ]+1; k++)
509 w[k] *= (2.0*
PI)/((
double)(m_theta-1)*m_phi);
510 w[m_theta-1-k] = w[k];
512 fftw_destroy_plan(fplan);
516 for (k = 0; k < m_theta; k++)
518 for (n = 0; n < m_phi; n++)
520 x_grid[2*d] = phi[n];
521 x_grid[2*d+1] = theta[k];
535 for (k = 1; k <= SQ[iNQ]-1; k++)
537 for (n = 0; n <= 4*k-1; n++)
539 x_grid[2*d+1] = 1 - (k*k)/((
double)(3.0*SQ[iNQ]*SQ[iNQ]));
540 x_grid[2*d] = ((n+0.5)/(4*k));
541 x_grid[2*d] -= (x_grid[2*d]>=0.5)?(1.0):(0.0);
548 for (k = SQ[iNQ]; k <= 3*SQ[iNQ]; k++)
550 for (n = 0; n <= 4*SQ[iNQ]-1; n++)
552 x_grid[2*d+1] = 2.0/(3*SQ[iNQ])*(2*SQ[iNQ]-k);
553 x_grid[2*d] = (n+((k%2==0)?(0.5):(0.0)))/(4*SQ[iNQ]);
554 x_grid[2*d] -= (x_grid[2*d]>=0.5)?(1.0):(0.0);
559 for (k = 1; k <= SQ[iNQ]-1; k++)
561 for (n = 0; n <= 4*k-1; n++)
563 x_grid[2*d+1] = -x_grid[2*d2+1];
564 x_grid[2*d] = x_grid[2*d2];
570 for (d = 0; d < m_total; d++)
572 x_grid[2*d+1] = acos(x_grid[2*d+1])/(2.0*
PI);
575 w[0] = (4.0*
PI)/(m_total);
578 case GRID_EQUIDISTRIBUTION:
579 case GRID_EQUIDISTRIBUTION_UNIFORM:
582 if (gridtype == GRID_EQUIDISTRIBUTION)
584 w_temp = (
double*)
nfft_malloc((SQ[iNQ]+1)*
sizeof(double));
585 fplan = fftw_plan_r2r_1d(SQ[iNQ]/2+1, w_temp, w_temp, FFTW_REDFT00, 0U);
586 for (k = 0; k < SQ[iNQ]/2+1; k++)
588 w_temp[k] = -2.0/(4*k*k-1);
593 for (k = 0; k < SQ[iNQ]/2+1; k++)
595 w_temp[k] *= (2.0*
PI)/((
double)(SQ[iNQ]));
596 w_temp[SQ[iNQ]-k] = w_temp[k];
598 fftw_destroy_plan(fplan);
604 if (gridtype == GRID_EQUIDISTRIBUTION)
610 w[d] = (4.0*
PI)/(m_total);
615 if (gridtype == GRID_EQUIDISTRIBUTION)
617 w[d] = w_temp[SQ[iNQ]];
621 w[d] = (4.0*
PI)/(m_total);
625 for (k = 1; k < SQ[iNQ]; k++)
627 theta_s = (double)k*
PI/(
double)SQ[iNQ];
628 M = (int)floor((2.0*
PI)/acos((cos(
PI/(
double)SQ[iNQ])-
629 cos(theta_s)*cos(theta_s))/(sin(theta_s)*sin(theta_s))));
631 for (n = 0; n < M; n++)
633 x_grid[2*d] = (n + 0.5)/M;
634 x_grid[2*d] -= (x_grid[2*d]>=0.5)?(1.0):(0.0);
635 x_grid[2*d+1] = theta_s/(2.0*
PI);
636 if (gridtype == GRID_EQUIDISTRIBUTION)
638 w[d] = w_temp[k]/((double)(M));
642 w[d] = (4.0*
PI)/(m_total);
648 if (gridtype == GRID_EQUIDISTRIBUTION)
659 f_grid = (
double _Complex*)
nfft_malloc(m_total*
sizeof(
double _Complex));
667 f_compare = (
double _Complex*)
nfft_malloc(m_compare*
sizeof(
double _Complex));
674 switch (testfunction)
676 case FUNCTION_RANDOM_BANDLIMITED:
677 f_hat_gen = (
double _Complex*)
nfft_malloc(NFSFT_F_HAT_SIZE(N)*
sizeof(
double _Complex));
682 nfsft_init_guru(&plan_gen,N,m_total, NFSFT_NORMALIZED |
683 ((use_nfft!=NO)?(0U):(NFSFT_USE_NDFT)) |
684 ((use_fpt!=NO)?(0U):(NFSFT_USE_DPT)),
685 ((N>512)?(0U):(PRE_PHI_HUT | PRE_PSI)) | FFTW_INIT |
686 FFT_OUT_OF_PLACE, cutoff);
688 plan_gen.
f_hat = f_hat_gen;
692 nfsft_precompute_x(&plan_gen);
694 for (k = 0; k < plan_gen.
N_total; k++)
699 for (k = 0; k <= N; k++)
701 for (n = -k; n <= k; n++)
703 f_hat_gen[NFSFT_INDEX(k,n,&plan_gen)] =
704 (((double)rand())/RAND_MAX)-0.5 + _Complex_I*((((double)rand())/RAND_MAX)-0.5);
711 nfsft_trafo(&plan_gen);
716 nfsft_trafo_direct(&plan_gen);
719 nfsft_finalize(&plan_gen);
723 nfsft_init_guru(&plan_gen,N,m_compare, NFSFT_NORMALIZED |
724 ((use_nfft!=NO)?(0U):(NFSFT_USE_NDFT)) |
725 ((use_fpt!=NO)?(0U):(NFSFT_USE_DPT)),
726 ((N>512)?(0U):(PRE_PHI_HUT | PRE_PSI)) | FFTW_INIT |
727 FFT_OUT_OF_PLACE, cutoff);
729 plan_gen.
f_hat = f_hat_gen;
730 plan_gen.
x = x_compare;
731 plan_gen.
f = f_compare;
733 nfsft_precompute_x(&plan_gen);
738 nfsft_trafo(&plan_gen);
743 nfsft_trafo_direct(&plan_gen);
746 nfsft_finalize(&plan_gen);
750 memcpy(f_compare,f_grid,m_total*
sizeof(
double _Complex));
758 for (d = 0; d < m_total; d++)
760 x1 = sin(x_grid[2*d+1]*2.0*
PI)*cos(x_grid[2*d]*2.0*
PI);
761 x2 = sin(x_grid[2*d+1]*2.0*PI)*sin(x_grid[2*d]*2.0*PI);
762 x3 = cos(x_grid[2*d+1]*2.0*PI);
763 f_grid[d] = x1*x2*x3;
767 for (d = 0; d < m_compare; d++)
769 x1 = sin(x_compare[2*d+1]*2.0*
PI)*cos(x_compare[2*d]*2.0*
PI);
770 x2 = sin(x_compare[2*d+1]*2.0*PI)*sin(x_compare[2*d]*2.0*PI);
771 x3 = cos(x_compare[2*d+1]*2.0*PI);
772 f_compare[d] = x1*x2*x3;
777 memcpy(f_compare,f_grid,m_total*
sizeof(
double _Complex));
781 for (d = 0; d < m_total; d++)
783 x1 = sin(x_grid[2*d+1]*2.0*
PI)*cos(x_grid[2*d]*2.0*
PI);
784 x2 = sin(x_grid[2*d+1]*2.0*PI)*sin(x_grid[2*d]*2.0*PI);
785 x3 = cos(x_grid[2*d+1]*2.0*PI);
786 f_grid[d] = 0.1*exp(x1+x2+x3);
790 for (d = 0; d < m_compare; d++)
792 x1 = sin(x_compare[2*d+1]*2.0*
PI)*cos(x_compare[2*d]*2.0*
PI);
793 x2 = sin(x_compare[2*d+1]*2.0*PI)*sin(x_compare[2*d]*2.0*PI);
794 x3 = cos(x_compare[2*d+1]*2.0*PI);
795 f_compare[d] = 0.1*exp(x1+x2+x3);
800 memcpy(f_compare,f_grid,m_total*
sizeof(
double _Complex));
804 for (d = 0; d < m_total; d++)
806 x1 = sin(x_grid[2*d+1]*2.0*
PI)*cos(x_grid[2*d]*2.0*
PI);
807 x2 = sin(x_grid[2*d+1]*2.0*PI)*sin(x_grid[2*d]*2.0*PI);
808 x3 = cos(x_grid[2*d+1]*2.0*PI);
809 temp = sqrt(x1*x1)+sqrt(x2*x2)+sqrt(x3*x3);
810 f_grid[d] = 0.1*temp;
814 for (d = 0; d < m_compare; d++)
816 x1 = sin(x_compare[2*d+1]*2.0*
PI)*cos(x_compare[2*d]*2.0*
PI);
817 x2 = sin(x_compare[2*d+1]*2.0*PI)*sin(x_compare[2*d]*2.0*PI);
818 x3 = cos(x_compare[2*d+1]*2.0*PI);
819 temp = sqrt(x1*x1)+sqrt(x2*x2)+sqrt(x3*x3);
820 f_compare[d] = 0.1*temp;
825 memcpy(f_compare,f_grid,m_total*
sizeof(
double _Complex));
829 for (d = 0; d < m_total; d++)
831 x1 = sin(x_grid[2*d+1]*2.0*
PI)*cos(x_grid[2*d]*2.0*
PI);
832 x2 = sin(x_grid[2*d+1]*2.0*PI)*sin(x_grid[2*d]*2.0*PI);
833 x3 = cos(x_grid[2*d+1]*2.0*PI);
834 temp = sqrt(x1*x1)+sqrt(x2*x2)+sqrt(x3*x3);
835 f_grid[d] = 1.0/(temp);
839 for (d = 0; d < m_compare; d++)
841 x1 = sin(x_compare[2*d+1]*2.0*
PI)*cos(x_compare[2*d]*2.0*
PI);
842 x2 = sin(x_compare[2*d+1]*2.0*PI)*sin(x_compare[2*d]*2.0*PI);
843 x3 = cos(x_compare[2*d+1]*2.0*PI);
844 temp = sqrt(x1*x1)+sqrt(x2*x2)+sqrt(x3*x3);
845 f_compare[d] = 1.0/(temp);
850 memcpy(f_compare,f_grid,m_total*
sizeof(
double _Complex));
854 for (d = 0; d < m_total; d++)
856 x1 = sin(x_grid[2*d+1]*2.0*
PI)*cos(x_grid[2*d]*2.0*
PI);
857 x2 = sin(x_grid[2*d+1]*2.0*PI)*sin(x_grid[2*d]*2.0*PI);
858 x3 = cos(x_grid[2*d+1]*2.0*PI);
859 temp = sqrt(x1*x1)+sqrt(x2*x2)+sqrt(x3*x3);
860 f_grid[d] = 0.1*sin(1+temp)*sin(1+temp);
864 for (d = 0; d < m_compare; d++)
866 x1 = sin(x_compare[2*d+1]*2.0*
PI)*cos(x_compare[2*d]*2.0*
PI);
867 x2 = sin(x_compare[2*d+1]*2.0*PI)*sin(x_compare[2*d]*2.0*PI);
868 x3 = cos(x_compare[2*d+1]*2.0*PI);
869 temp = sqrt(x1*x1)+sqrt(x2*x2)+sqrt(x3*x3);
870 f_compare[d] = 0.1*sin(1+temp)*sin(1+temp);
875 memcpy(f_compare,f_grid,m_total*
sizeof(
double _Complex));
879 for (d = 0; d < m_total; d++)
881 if (x_grid[2*d+1] <= 0.25)
887 f_grid[d] = 1.0/(sqrt(1+3*cos(2.0*
PI*x_grid[2*d+1])*cos(2.0*
PI*x_grid[2*d+1])));
892 for (d = 0; d < m_compare; d++)
894 if (x_compare[2*d+1] <= 0.25)
900 f_compare[d] = 1.0/(sqrt(1+3*cos(2.0*
PI*x_compare[2*d+1])*cos(2.0*
PI*x_compare[2*d+1])));
906 memcpy(f_compare,f_grid,m_total*
sizeof(
double _Complex));
912 for (d = 0; d < m_total; d++)
918 for (d = 0; d < m_compare; d++)
925 memcpy(f_compare,f_grid,m_total*
sizeof(
double _Complex));
933 nfsft_init_guru(&plan_adjoint,NQ[iNQ],m_total, NFSFT_NORMALIZED |
934 ((use_nfft!=NO)?(0U):(NFSFT_USE_NDFT)) |
935 ((use_fpt!=NO)?(0U):(NFSFT_USE_DPT)),
936 ((NQ[iNQ]>512)?(0U):(PRE_PHI_HUT | PRE_PSI)) | FFTW_INIT |
937 FFT_OUT_OF_PLACE, cutoff);
939 plan_adjoint_ptr = &plan_adjoint;
943 nfsft_init_guru(&plan,NQ[iNQ],m_compare, NFSFT_NORMALIZED |
944 ((use_nfft!=NO)?(0U):(NFSFT_USE_NDFT)) |
945 ((use_fpt!=NO)?(0U):(NFSFT_USE_DPT)),
946 ((NQ[iNQ]>512)?(0U):(PRE_PHI_HUT | PRE_PSI)) | FFTW_INIT |
947 FFT_OUT_OF_PLACE, cutoff);
952 plan_ptr = &plan_adjoint;
955 f_hat = (
double _Complex*)
nfft_malloc(NFSFT_F_HAT_SIZE(NQ[iNQ])*
sizeof(
double _Complex));
957 plan_adjoint_ptr->
f_hat = f_hat;
958 plan_adjoint_ptr->
x = x_grid;
959 plan_adjoint_ptr->
f = f_grid;
961 plan_ptr->
f_hat = f_hat;
962 plan_ptr->
x = x_compare;
967 nfsft_precompute_x(plan_adjoint_ptr);
968 if (plan_adjoint_ptr != plan_ptr)
970 nfsft_precompute_x(plan_ptr);
979 for (i = 0; i < 1; i++)
994 for (k = 0; k < m_theta; k++)
996 for (n = 0; n < m_phi; n++)
1007 t_avg += nfft_elapsed_seconds(t1,t0);
1024 if (use_nfsft != NO)
1027 nfsft_adjoint(plan_adjoint_ptr);
1032 nfsft_adjoint_direct(plan_adjoint_ptr);
1048 if (use_nfsft != NO)
1051 nfsft_trafo(plan_ptr);
1056 nfsft_trafo_direct(plan_ptr);
1060 t_avg += nfft_elapsed_seconds(t1,t0);
1065 nfsft_finalize(plan_adjoint_ptr);
1066 if (plan_ptr != plan_adjoint_ptr)
1068 nfsft_finalize(plan_ptr);
1075 err_infty_avg += X(error_l_infty_complex)(f, f_compare, m_compare);
1076 err_2_avg += X(error_l_2_complex)(f, f_compare, m_compare);
1098 t_avg = t_avg/((double)repetitions);
1101 err_infty_avg = err_infty_avg/((double)repetitions);
1104 err_2_avg = err_2_avg/((double)repetitions);
1107 fprintf(stdout,
"%+le %+le %+le\n", t_avg, err_infty_avg, err_2_avg);
1108 fprintf(stderr,
"%d: %4d %4d %+le %+le %+le\n", tc, NQ[iNQ], SQ[iNQ],
1109 t_avg, err_infty_avg, err_2_avg);
1113 fprintf(stderr,
"\n");
1121 if (testmode == TIMING)
1133 if (testmode == TIMING)
1144 return EXIT_SUCCESS;