00001
00008 #include <stdlib.h>
00009 #include <stdio.h>
00010 #include <string.h>
00011 #include <math.h>
00012 #include <time.h>
00013
00014 #include "fields_fastsum.h"
00015
00016 int main(int argc, char **argv)
00017 {
00018 int j,k,t;
00019 int N;
00020 int n;
00021 int m;
00022 int p;
00023 fields_fastsum_plan my_plan;
00024 double *direct;
00025 double *simple;
00026 double time_diff;
00027 double error=0.0;
00028 double error_simple_fast=0.0;
00029 double norm_direct;
00030 double norm_diff;
00031 double norm_simple;
00032 double norm_diff_simple;
00033 double sum_error_direct;
00034 double sum_error_diff;
00035 double eps_I;
00036 double eps_B = 0.0625;
00038 if (argc < 5)
00039 {
00040 printf("\nfastsum_test N n m p [eps_I]\n\n");
00041 printf(" N number of nodes \n");
00042 printf(" n expansion degree \n");
00043 printf(" m cut-off parameter \n");
00044 printf(" p degree of smoothness \n");
00045 printf(" eps_I inner boundary \n");
00046 exit(-1);
00047 }
00048 else
00049 {
00050 N=atoi(argv[1]);
00051 n=atoi(argv[2]);
00052 m=atoi(argv[3]);
00053 p=atoi(argv[4]);
00054 if (argc > 5)
00055 eps_I=atof(argv[5]);
00056 else
00057 eps_I=(double)p/n;
00058 }
00059 printf("N=%d, n=%d, m=%d, p=%d, eps_I=%g, eps_B=%g \n",N,n,m,p,eps_I,eps_B);
00060
00061
00062 fields_fastsum_init(&my_plan, N, 0, n, m, p, eps_I, eps_B);
00063
00064
00065 srand(time(NULL));
00066
00068 double r_2 = 0.0;
00069 for (k=0; k<N; k++)
00070 {
00071 do {
00072 my_plan.r[3*k] = (double)rand()/(double)RAND_MAX*2.0 - 1.0;
00073 my_plan.r[3*k+1] = (double)rand()/(double)RAND_MAX*2.0 - 1.0;
00074 my_plan.r[3*k+2] = (double)rand()/(double)RAND_MAX*2.0 - 1.0;
00075 r_2 = my_plan.r[3*k] * my_plan.r[3*k] + my_plan.r[3*k+1] * my_plan.r[3*k+1] + my_plan.r[3*k+2] * my_plan.r[3*k+2];
00076 } while(r_2 > 1.0);
00077 my_plan.r[3*k] *= (0.25-eps_B/2.0);
00078 my_plan.r[3*k+1] *= (0.25-eps_B/2.0);
00079 my_plan.r[3*k+2] *= (0.25-eps_B/2.0);
00080
00081 my_plan.q[k] = (double)rand()/(double)RAND_MAX;
00082 }
00083
00085 printf("direct computation: "); fflush(NULL);
00086 time_diff=nfft_second();
00087 fields_fastsum_exact(&my_plan);
00088 time_diff=nfft_second()-time_diff;
00089 printf("%fsec\n",time_diff);
00090
00092 direct = (double *)malloc(3*my_plan.N_total*(sizeof(double)));
00093 for (j=0; j<3*my_plan.N_total; j++)
00094 direct[j]=my_plan.E[j];
00095
00097 printf("fast computation, simple: "); fflush(NULL);
00098 time_diff=nfft_second();
00099 fields_fastsum_simple(&my_plan);
00100 time_diff=nfft_second()-time_diff;
00101 printf("%fsec\n",time_diff);
00102
00104 simple = (double *)malloc(3*my_plan.N_total*(sizeof(double)));
00105 for (j=0; j<3*my_plan.N_total; j++)
00106 simple[j]=my_plan.E[j];
00107
00109 printf("fast computation: "); fflush(NULL);
00110 time_diff=nfft_second();
00111 fields_fastsum_precompute(&my_plan);
00112 fields_fastsum_trafo(&my_plan);
00113 time_diff=nfft_second()-time_diff;
00114 printf("%fsec\n",time_diff);
00115
00117 if (my_plan.N_total < 11) {
00118 for (j=0; j < my_plan.N_total; j++) {
00119 printf("% .16e; ", my_plan.q[j]);
00120 printf("% .16e, ", my_plan.r[j*3]);
00121 printf("% .16e, ", my_plan.r[j*3+1]);
00122 printf("% .16e\n", my_plan.r[j*3+2]);
00123 }
00124 }
00125
00127 error=0.0;
00128 error_simple_fast = 0.0;
00129 sum_error_direct = 0.0;
00130 sum_error_diff = 0.0;
00131 for (j=0; j<my_plan.N_total; j++)
00132 {
00133 norm_direct = 0.0;
00134 norm_diff = 0.0;
00135 norm_diff_simple = 0.0;
00136 norm_simple = 0.0;
00137 for (t=0; t < 3; t++) {
00138 if (my_plan.N_total < 11) {
00139 printf(" % .16e | ", direct[j*3+t]);
00140 printf(" % .16e\n", my_plan.E[j*3+t]);
00141 }
00142 norm_direct += direct[j*3+t] * direct[j*3+t];
00143 norm_simple += simple[j*3+t] * simple[j*3+t];
00144 norm_diff += (my_plan.E[j*3+t] - direct[j*3+t]) * (my_plan.E[j*3+t] - direct[j*3+t]);
00145 norm_diff_simple += (my_plan.E[j*3+t] - simple[j*3+t]) * (my_plan.E[j*3+t] - simple[j*3+t]);
00146 }
00147 sum_error_direct += norm_direct;
00148 sum_error_diff += norm_diff;
00149 norm_direct = sqrt(norm_direct);
00150 norm_simple = sqrt(norm_simple);
00151 norm_diff = sqrt(norm_diff);
00152 norm_diff_simple = sqrt(norm_diff_simple);
00153 if (fabs(norm_diff)/fabs(norm_direct)>error)
00154 error=fabs(norm_diff)/fabs(norm_direct);
00155
00156 if (fabs(norm_diff_simple)/fabs(norm_simple)>error_simple_fast)
00157 error_simple_fast = fabs(norm_diff_simple)/fabs(norm_simple);
00158 }
00159 printf("max relative error(slow,fast): %e\n",error);
00160 printf("max relative error(simple,fast): %e\n",error_simple_fast);
00161 printf("error epsilon_2(slow,fast) (p.7): %e\n", sqrt(sum_error_diff)/sqrt(sum_error_direct));
00162
00164 fields_fastsum_finalize(&my_plan);
00165
00166 return 0;
00167 }