NFFT Logo 3.0 API Reference
Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals

fastsumS2.c

00001 /* $Id: fastsumS2.c 1144 2006-10-26 13:08:56Z keiner $
00002  *
00003  * fastsumS2 - Fast summation of radial functions on the sphere
00004  *
00005  * Copyright (C) 2005 Jens Keiner
00006  *
00007  * This program is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2, or (at your option)
00010  * any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software Foundation,
00019  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00020  */
00021 
00028 /* Include standard C headers. */
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <math.h>
00032 
00033 /* Include NFFT3 library header. */
00034 #include "nfft3.h"
00035 
00036 /* Include NFFT 3 utilities headers. */
00037 #include "util.h"
00038 
00039 /* Include GSL header for spherical Bessel functions. */
00040 #include "../3rdparty/gsl/specfunc/gsl_sf_bessel.h"
00041 
00043 #define SYMBOL_ABEL_POISSON(k,h) (pow(h,k))
00044 
00046 #define SYMBOL_SINGULARITY(k,h) ((2.0/(2*k+1))*pow(h,k))
00047 
00048 /* Flags for the different kernel functions */
00049 
00051 #define KT_ABEL_POISSON (0)
00052 
00053 #define KT_SINGULARITY  (1)
00054 
00055 #define KT_LOC_SUPP     (2)
00056 
00057 #define KT_GAUSSIAN     (3)
00058 
00060 enum pvalue {NO = 0, YES = 1, BOTH = 2};
00061 
00076 double innerProduct(const double phi1, const double theta1, const double phi2,
00077   const double theta2)
00078 {
00079   return cos(theta1)*cos(theta2) + sin(theta1)*sin(theta2)*cos(phi1-phi2);
00080 }
00081 
00093 double poissonKernel(const double x, const double h)
00094 {
00095   return (1.0/(4*PI))*(1-h*h)/pow(sqrt(1-2*h*x+h*h),3);
00096 }
00097 
00109 double singularityKernel(const double x, const double h)
00110 {
00111   return (1.0/(2*PI))/sqrt(1-2*h*x+h*h);
00112 }
00113 
00127 double locallySupportedKernel(const double x, const double h,
00128   const double lambda)
00129 {
00130   return (x<=h)?(0.0):(pow((x-h),lambda));
00131 }
00132 
00145 double gaussianKernel(const double x, const double sigma)
00146 {
00147    return exp(2.0*sigma*(x-1));
00148 }
00149 
00160 int main (int argc, char **argv)
00161 {
00162   double **p;                  /* The array containing the parameter sets     *
00163                                 * for the kernel functions                    */
00164   int *m;                      /* The array containing the cut-off degrees M  */
00165   int **ld;                    /* The array containing the numbers of source  *
00166                                 * and target nodes, L and D                   */
00167   int ip;                      /* Index variable for p                        */
00168   int im;                      /* Index variable for m                        */
00169   int ild;                     /* Index variable for l                        */
00170   int ipp;                     /* Index for kernel parameters                 */
00171   int ip_max;                  /* The maximum index for p                     */
00172   int im_max;                  /* The maximum index for m                     */
00173   int ild_max;                 /* The maximum index for l                     */
00174   int ipp_max;                 /* The maximum index for ip                    */
00175   int tc_max;                  /* The number of testcases                     */
00176   int m_max;                   /* The maximum cut-off degree M for the        *
00177                                 * current dataset                             */
00178   int l_max;                   /* The maximum number of source nodes L for    *
00179                                 * the current dataset                         */
00180   int d_max;                   /* The maximum number of target nodes D for    *
00181                                 * the current dataset                         */
00182   long ld_max_prec;            /* The maximum number of source and target     *
00183                                 * nodes for precomputation multiplied         */
00184   long l_max_prec;             /* The maximum number of source nodes for      *
00185                                 * precomputation                              */
00186   int tc;                      /* Index variable for testcases                */
00187   int kt;                      /* The kernel function                         */
00188   int cutoff;                  /* The current NFFT cut-off parameter          */
00189   double threshold;            /* The current NFSFT threshold parameter       */
00190   double t_d;                  /* Time for direct algorithm in seconds        */
00191   double t_dp;                 /* Time for direct algorithm with              *
00192                                   precomputation in seconds                   */
00193   double t_fd;                 /* Time for fast direct algorithm in seconds   */
00194   double t_f;                  /* Time for fast algorithm in seconds          */
00195   double temp;                 /*                                             */
00196   double err_f;                /* Error E_infty for fast algorithm            */
00197   double err_fd;               /* Error E_\infty for fast direct algorithm    */
00198   double t;                    /*                                             */
00199   int precompute = NO;         /*                                             */
00200   complex double *ptr;         /*                                             */
00201   double* steed;               /*                                             */
00202   double* steed2;              /*                                             */
00203   complex double *b;           /* The weights (b_l)_{l=0}^{L-1}               */
00204   complex double *f_hat;       /* The spherical Fourier coefficients          */
00205   complex double *a;           /* The Fourier-Legendre coefficients           */
00206   double *xi;                  /* Target nodes                                */
00207   double *eta;                 /* Source nodes                                */
00208   complex double *f_m;         /* Approximate function values                 */
00209   complex double *f;           /* Exact function values                       */
00210   complex double *prec = NULL; /*                                             */
00211   nfsft_plan plan;             /* NFSFT plan                                  */
00212   nfsft_plan plan_adjoint;     /* adjoint NFSFT plan                          */
00213   int i;                       /*                                             */
00214   int k;                       /*                                             */
00215   int n;                       /*                                             */
00216   int d;                       /*                                             */
00217   int l;                       /*                                             */
00218   int use_nfsft;               /*                                             */
00219   int use_nfft;                /*                                             */
00220   int use_fpt;                 /*                                             */
00221   int rinc;                    /*                                             */
00222   double constant;             /*                                             */
00223 
00224   /* Read the number of testcases. */
00225   fscanf(stdin,"testcases=%d\n",&tc_max);
00226   fprintf(stdout,"%d\n",tc_max);
00227 
00228   /* Process each testcase. */
00229   for (tc = 0; tc < tc_max; tc++)
00230   {
00231     /* Check if the fast transform shall be used. */
00232     fscanf(stdin,"nfsft=%d\n",&use_nfsft);
00233     fprintf(stdout,"%d\n",use_nfsft);
00234     if (use_nfsft != NO)
00235     {
00236       /* Check if the NFFT shall be used. */
00237       fscanf(stdin,"nfft=%d\n",&use_nfft);
00238       fprintf(stdout,"%d\n",use_nfft);
00239       if (use_nfft != NO)
00240       {
00241         /* Read the cut-off parameter. */
00242         fscanf(stdin,"cutoff=%d\n",&cutoff);
00243         fprintf(stdout,"%d\n",cutoff);
00244       }
00245       else
00246       {
00247         /* TODO remove this */
00248         /* Initialize unused variable with dummy value. */
00249         cutoff = 1;
00250       }
00251       /* Check if the fast polynomial transform shall be used. */
00252       fscanf(stdin,"fpt=%d\n",&use_fpt);
00253       fprintf(stdout,"%d\n",use_fpt);
00254       /* Read the NFSFT threshold parameter. */
00255       fscanf(stdin,"threshold=%lf\n",&threshold);
00256       fprintf(stdout,"%lf\n",threshold);
00257     }
00258     else
00259     {
00260       /* TODO remove this */
00261       /* Set dummy values. */
00262       cutoff = 3;
00263       threshold = 1000000000000.0;
00264     }
00265 
00266     /* Initialize bandwidth bound. */
00267     m_max = 0;
00268     /* Initialize source nodes bound. */
00269     l_max = 0;
00270     /* Initialize target nodes bound. */
00271     d_max = 0;
00272     /* Initialize source nodes bound for precomputation. */
00273     l_max_prec = 0;
00274     /* Initialize source and target nodes bound for precomputation. */
00275     ld_max_prec = 0;
00276 
00277     /* Read the kernel type. This is one of KT_ABEL_POISSON, KT_SINGULARITY,
00278      * KT_LOC_SUPP and KT_GAUSSIAN. */
00279     fscanf(stdin,"kernel=%d\n",&kt);
00280     fprintf(stdout,"%d\n",kt);
00281 
00282     /* Read the number of parameter sets. */
00283     fscanf(stdin,"parameter_sets=%d\n",&ip_max);
00284     fprintf(stdout,"%d\n",ip_max);
00285 
00286     /* Allocate memory for pointers to parameter sets. */
00287     p = (double**) malloc(ip_max*sizeof(double*));
00288 
00289     /* We now read in the parameter sets. */
00290 
00291     /* Read number of parameters. */
00292     fscanf(stdin,"parameters=%d\n",&ipp_max);
00293     fprintf(stdout,"%d\n",ipp_max);
00294 
00295     for (ip = 0; ip < ip_max; ip++)
00296     {
00297       /* Allocate memory for the parameters. */
00298       p[ip] = (double*) malloc(ipp_max*sizeof(double));
00299 
00300       /* Read the parameters. */
00301       for (ipp = 0; ipp < ipp_max; ipp++)
00302       {
00303         /* Read the next parameter. */
00304         fscanf(stdin,"%lf\n",&p[ip][ipp]);
00305         fprintf(stdout,"%lf\n",p[ip][ipp]);
00306       }
00307     }
00308 
00309     /* Read the number of cut-off degrees. */
00310     fscanf(stdin,"bandwidths=%d\n",&im_max);
00311     fprintf(stdout,"%d\n",im_max);
00312     m = (int*) malloc(im_max*sizeof(int));
00313 
00314     /* Read the cut-off degrees. */
00315     for (im = 0; im < im_max; im++)
00316     {
00317       /* Read cut-off degree. */
00318       fscanf(stdin,"%d\n",&m[im]);
00319       fprintf(stdout,"%d\n",m[im]);
00320       m_max = NFFT_MAX(m_max,m[im]);
00321     }
00322 
00323     /* Read number of node specifications. */
00324     fscanf(stdin,"node_sets=%d\n",&ild_max);
00325     fprintf(stdout,"%d\n",ild_max);
00326     ld = (int**) malloc(ild_max*sizeof(int*));
00327 
00328     /* Read the run specification. */
00329     for (ild = 0; ild < ild_max; ild++)
00330     {
00331       /* Allocate memory for the run parameters. */
00332       ld[ild] = (int*) malloc(5*sizeof(int));
00333 
00334       /* Read number of source nodes. */
00335       fscanf(stdin,"L=%d ",&ld[ild][0]);
00336       fprintf(stdout,"%d\n",ld[ild][0]);
00337       l_max = NFFT_MAX(l_max,ld[ild][0]);
00338 
00339       /* Read number of target nodes. */
00340       fscanf(stdin,"D=%d ",&ld[ild][1]);
00341       fprintf(stdout,"%d\n",ld[ild][1]);
00342       d_max = NFFT_MAX(d_max,ld[ild][1]);
00343 
00344       /* Determine whether direct and fast algorithm shall be compared. */
00345       fscanf(stdin,"compare=%d ",&ld[ild][2]);
00346       fprintf(stdout,"%d\n",ld[ild][2]);
00347 
00348       /* Check if precomputation for the direct algorithm is used. */
00349       if (ld[ild][2] == YES)
00350       {
00351         /* Read whether the precomputed version shall also be used. */
00352         fscanf(stdin,"precomputed=%d\n",&ld[ild][3]);
00353         fprintf(stdout,"%d\n",ld[ild][3]);
00354 
00355         /* Read the number of repetitions over which measurements are
00356          * averaged. */
00357         fscanf(stdin,"repetitions=%d\n",&ld[ild][4]);
00358         fprintf(stdout,"%d\n",ld[ild][4]);
00359 
00360         /* Update ld_max_prec and l_max_prec. */
00361         if (ld[ild][3] == YES)
00362         {
00363           /* Update ld_max_prec. */
00364           ld_max_prec = NFFT_MAX(ld_max_prec,ld[ild][0]*ld[ild][1]);
00365           /* Update l_max_prec. */
00366           l_max_prec = NFFT_MAX(l_max_prec,ld[ild][0]);
00367           /* Turn on the precomputation for the direct algorithm. */
00368           precompute = YES;
00369         }
00370       }
00371       else
00372       {
00373         /* Set default value for the number of repetitions. */
00374         ld[ild][4] = 1;
00375       }
00376     }
00377 
00378     /* Allocate memory for data structures. */
00379     b = (complex double*) malloc(l_max*sizeof(complex double));
00380     eta = (double*) malloc(2*l_max*sizeof(double));
00381     f_hat = (complex double*) malloc(NFSFT_F_HAT_SIZE(m_max)*sizeof(complex double));
00382     a = (complex double*) malloc((m_max+1)*sizeof(complex double));
00383     xi = (double*) malloc(2*d_max*sizeof(double));
00384     f_m = (complex double*) malloc(d_max*sizeof(complex double));
00385     f = (complex double*) malloc(d_max*sizeof(complex double));
00386 
00387     /* Allocate memory for precomputed data. */
00388     if (precompute == YES)
00389     {
00390       prec = (complex double*) malloc(ld_max_prec*sizeof(complex double));
00391     }
00392 
00393     /* Generate random source nodes and weights. */
00394     for (l = 0; l < l_max; l++)
00395     {
00396       b[l] = (((double)rand())/RAND_MAX) - 0.5;
00397       eta[2*l] = (((double)rand())/RAND_MAX) - 0.5;
00398       eta[2*l+1] = acos(2.0*(((double)rand())/RAND_MAX) - 1.0)/(2.0*PI);
00399     }
00400 
00401     /* Generate random target nodes. */
00402     for (d = 0; d < d_max; d++)
00403     {
00404       xi[2*d] = (((double)rand())/RAND_MAX) - 0.5;
00405       xi[2*d+1] = acos(2.0*(((double)rand())/RAND_MAX) - 1.0)/(2.0*PI);
00406     }
00407 
00408     /* Do precomputation. */
00409     nfsft_precompute(m_max,threshold,
00410       ((use_nfsft==NO)?(NFSFT_NO_FAST_ALGORITHM):(0U/*NFSFT_NO_DIRECT_ALGORITHM*/)), 0U);
00411 
00412     /* Process all parameter sets. */
00413     for (ip = 0; ip < ip_max; ip++)
00414     {
00415       /* Compute kernel coeffcients up to the maximum cut-off degree m_max. */
00416       switch (kt)
00417       {
00418         case KT_ABEL_POISSON:
00419           /* Compute Fourier-Legendre coefficients for the Poisson kernel. */
00420           for (k = 0; k <= m_max; k++)
00421           {
00422             a[k] = SYMBOL_ABEL_POISSON(k,p[ip][0]);
00423           }
00424           break;
00425 
00426         case KT_SINGULARITY:
00427           /* Compute Fourier-Legendre coefficients for the singularity
00428            * kernel. */
00429           for (k = 0; k <= m_max; k++)
00430           {
00431             a[k] = SYMBOL_SINGULARITY(k,p[ip][0]);
00432           }
00433           break;
00434 
00435         case KT_LOC_SUPP:
00436           /* Compute Fourier-Legendre coefficients for the locally supported
00437            * kernel. */
00438           for (k = 0; k <= m_max; k++)
00439           {
00440             /* First case k = 0 for initialization of three-term recurrence. */
00441             if (k == 0)
00442             {
00443               a[k] = 1.0;
00444             }
00445             /* Second case k = 1 for initialization of three-term recurrence. */
00446             else if (k == 1)
00447             {
00448               a[k] = ((p[ip][1]+1+p[ip][0])/(p[ip][1]+2.0))*a[k-1];
00449             }
00450             /* Apply three-term recurrence. */
00451             else
00452             {
00453               a[k] = (1.0/(k+p[ip][1]+1))*((2*k-1)*p[ip][0]*a[k-1] -
00454                 (k-p[ip][1]-2)*a[k-2]);
00455             }
00456           }
00457           break;
00458 
00459           case KT_GAUSSIAN:
00460             /* Compute Fourier-Legendre coefficients for the locally supported
00461              * kernel. */
00462             steed = (double*) malloc((m_max+1)*sizeof(double));
00463             steed2 = (double*) malloc((m_max+1)*sizeof(double));
00464             gsl_sf_bessel_il_scaled_array(m_max,2.0*p[ip][0],steed);
00465             for (k = 0; k <= m_max; k++)
00466             {
00467               steed[k] = 4.0*PI;
00468               a[k] = steed[k];
00469             }
00470             for (k = 0; k <= m_max; k++)
00471             {
00472               steed[k] *= 4.0*PI;
00473               a[k] = steed[k];
00474             }
00475 
00476             free(steed);
00477             break;
00478       }
00479 
00480       /* Normalize Fourier-Legendre coefficients. */
00481       for (k = 0; k <= m_max; k++)
00482       {
00483         a[k] *= (2*k+1)/(4*PI);
00484       }
00485 
00486       /* Process all node sets. */
00487       for (ild = 0; ild < ild_max; ild++)
00488       {
00489         /* Check if the fast algorithm shall be used. */
00490         if (ld[ild][2] != NO)
00491         {
00492           /* Check if the direct algorithm with precomputation should be
00493            * tested. */
00494           if (ld[ild][3] != NO)
00495           {
00496             /* Get pointer to start of data. */
00497             ptr = prec;
00498             /* Calculate increment from one row to the next. */
00499             rinc = l_max_prec-ld[ild][0];
00500 
00501             /* Process al target nodes. */
00502             for (d = 0; d < ld[ild][1]; d++)
00503             {
00504               /* Process all source nodes. */
00505               for (l = 0; l < ld[ild][0]; l++)
00506               {
00507                 /* Compute inner product between current source and target
00508                  * node. */
00509                 temp = innerProduct(2*PI*eta[2*l],2*PI*eta[2*l+1],
00510                   2*PI*xi[2*d],2*PI*xi[2*d+1]);
00511 
00512                 /* Switch by the kernel type. */
00513                 switch (kt)
00514                 {
00515                   case KT_ABEL_POISSON:
00516                     /* Evaluate the Poisson kernel for the current value. */
00517                     *ptr++ = poissonKernel(temp,p[ip][0]);
00518                    break;
00519 
00520                   case KT_SINGULARITY:
00521                     /* Evaluate the singularity kernel for the current
00522                      * value. */
00523                     *ptr++ = singularityKernel(temp,p[ip][0]);
00524                     break;
00525 
00526                   case KT_LOC_SUPP:
00527                      /* Evaluate the localized kernel for the current
00528                       * value. */
00529                     *ptr++ = locallySupportedKernel(temp,p[ip][0],p[ip][1]);
00530                     break;
00531 
00532                     case KT_GAUSSIAN:
00533                        /* Evaluate the spherical Gaussian kernel for the current
00534                         * value. */
00535                       *ptr++ = gaussianKernel(temp,p[ip][0]);
00536                        break;
00537                 }
00538               }
00539               /* Increment pointer for next row. */
00540               ptr += rinc;
00541             }
00542 
00543             /* Initialize cumulative time variable. */
00544             t_dp = 0.0;
00545 
00546             /* Initialize time measurement. */
00547             t = nfft_second();
00548 
00549             /* Cycle through all runs. */
00550             for (i = 0; i < ld[ild][4]; i++)
00551             {
00552 
00553               /* Reset pointer to start of precomputed data. */
00554               ptr = prec;
00555               /* Calculate increment from one row to the next. */
00556               rinc = l_max_prec-ld[ild][0];
00557 
00558               /* Check if the localized kernel is used. */
00559               if (kt == KT_LOC_SUPP)
00560               {
00561                 /* Perform final summation */
00562 
00563                 /* Calculate the multiplicative constant. */
00564                 constant = ((p[ip][1]+1)/(2*PI*pow(1-p[ip][0],p[ip][1]+1)));
00565 
00566                 /* Process all target nodes. */
00567                 for (d = 0; d < ld[ild][1]; d++)
00568                 {
00569                   /* Initialize function value. */
00570                   f[d] = 0.0;
00571 
00572                   /* Process all source nodes. */
00573                   for (l = 0; l < ld[ild][0]; l++)
00574                   {
00575                     f[d] += b[l]*(*ptr++);
00576                   }
00577 
00578                   /* Multiply with the constant. */
00579                   f[d] *= constant;
00580 
00581                   /* Proceed to next row. */
00582                   ptr += rinc;
00583                 }
00584               }
00585               else
00586               {
00587                 /* Process all target nodes. */
00588                 for (d = 0; d < ld[ild][1]; d++)
00589                 {
00590                   /* Initialize function value. */
00591                   f[d] = 0.0;
00592 
00593                   /* Process all source nodes. */
00594                   for (l = 0; l < ld[ild][0]; l++)
00595                   {
00596                     f[d] += b[l]*(*ptr++);
00597                   }
00598 
00599                   /* Proceed to next row. */
00600                   ptr += rinc;
00601                 }
00602               }
00603             }
00604 
00605             /* Calculate the time needed. */
00606             t_dp = nfft_second() - t;
00607 
00608             /* Calculate average time needed. */
00609             t_dp = t_dp/((double)ld[ild][4]);
00610           }
00611           else
00612           {
00613             /* Initialize cumulative time variable with dummy value. */
00614             t_dp = -1.0;
00615           }
00616 
00617           /* Initialize cumulative time variable. */
00618           t_d = 0.0;
00619 
00620           /* Initialize time measurement. */
00621           t = nfft_second();
00622 
00623           /* Cycle through all runs. */
00624           for (i = 0; i < ld[ild][4]; i++)
00625           {
00626             /* Switch by the kernel type. */
00627             switch (kt)
00628             {
00629               case KT_ABEL_POISSON:
00630 
00631                 /* Process all target nodes. */
00632                 for (d = 0; d < ld[ild][1]; d++)
00633                 {
00634                   /* Initialize function value. */
00635                   f[d] = 0.0;
00636 
00637                   /* Process all source nodes. */
00638                   for (l = 0; l < ld[ild][0]; l++)
00639                   {
00640                     /* Compute the inner product for the current source and
00641                      * target nodes. */
00642                     temp = innerProduct(2*PI*eta[2*l],2*PI*eta[2*l+1],
00643                       2*PI*xi[2*d],2*PI*xi[2*d+1]);
00644 
00645                     /* Evaluate the Poisson kernel for the current value and add
00646                      * to the result. */
00647                     f[d] += b[l]*poissonKernel(temp,p[ip][0]);
00648                   }
00649                 }
00650                 break;
00651 
00652               case KT_SINGULARITY:
00653                 /* Process all target nodes. */
00654                 for (d = 0; d < ld[ild][1]; d++)
00655                 {
00656                   /* Initialize function value. */
00657                   f[d] = 0.0;
00658 
00659                   /* Process all source nodes. */
00660                   for (l = 0; l < ld[ild][0]; l++)
00661                   {
00662                     /* Compute the inner product for the current source and
00663                      * target nodes. */
00664                     temp = innerProduct(2*PI*eta[2*l],2*PI*eta[2*l+1],
00665                       2*PI*xi[2*d],2*PI*xi[2*d+1]);
00666 
00667                     /* Evaluate the Poisson kernel for the current value and add
00668                      * to the result. */
00669                     f[d] += b[l]*singularityKernel(temp,p[ip][0]);
00670                   }
00671                 }
00672                 break;
00673 
00674               case KT_LOC_SUPP:
00675                 /* Calculate the multiplicative constant. */
00676                 constant = ((p[ip][1]+1)/(2*PI*pow(1-p[ip][0],p[ip][1]+1)));
00677 
00678                 /* Process all target nodes. */
00679                 for (d = 0; d < ld[ild][1]; d++)
00680                 {
00681                   /* Initialize function value. */
00682                   f[d] = 0.0;
00683 
00684                   /* Process all source nodes. */
00685                   for (l = 0; l < ld[ild][0]; l++)
00686                   {
00687                     /* Compute the inner product for the current source and
00688                      * target nodes. */
00689                     temp = innerProduct(2*PI*eta[2*l],2*PI*eta[2*l+1],
00690                       2*PI*xi[2*d],2*PI*xi[2*d+1]);
00691 
00692                     /* Evaluate the Poisson kernel for the current value and add
00693                      * to the result. */
00694                     f[d] += b[l]*locallySupportedKernel(temp,p[ip][0],p[ip][1]);
00695                   }
00696 
00697                   /* Multiply result with constant. */
00698                   f[d] *= constant;
00699                 }
00700                 break;
00701 
00702                 case KT_GAUSSIAN:
00703                   /* Process all target nodes. */
00704                   for (d = 0; d < ld[ild][1]; d++)
00705                   {
00706                     /* Initialize function value. */
00707                     f[d] = 0.0;
00708 
00709                     /* Process all source nodes. */
00710                     for (l = 0; l < ld[ild][0]; l++)
00711                     {
00712                       /* Compute the inner product for the current source and
00713                        * target nodes. */
00714                       temp = innerProduct(2*PI*eta[2*l],2*PI*eta[2*l+1],
00715                         2*PI*xi[2*d],2*PI*xi[2*d+1]);
00716                       /* Evaluate the Poisson kernel for the current value and add
00717                        * to the result. */
00718                       f[d] += b[l]*gaussianKernel(temp,p[ip][0]);
00719                     }
00720                   }
00721                   break;
00722             }
00723           }
00724 
00725           /* Calculate and add the time needed. */
00726           t_d = nfft_second() - t;
00727           /* Calculate average time needed. */
00728           t_d = t_d/((double)ld[ild][4]);
00729         }
00730         else
00731         {
00732           /* Initialize cumulative time variable with dummy value. */
00733           t_d = -1.0;
00734           t_dp = -1.0;
00735         }
00736 
00737         /* Initialize error and cumulative time variables for the fast
00738          * algorithm. */
00739         err_fd = -1.0;
00740         err_f = -1.0;
00741         t_fd = -1.0;
00742         t_f = -1.0;
00743 
00744         /* Process all cut-off bandwidths. */
00745         for (im = 0; im < im_max; im++)
00746         {
00747           /* Init transform plans. */
00748           nfsft_init_guru(&plan_adjoint, m[im],ld[ild][0],
00749             ((use_nfft!=0)?(0U):(NFSFT_USE_NDFT)) |
00750             ((use_fpt!=0)?(0U):(NFSFT_USE_DPT)),
00751             PRE_PHI_HUT | PRE_PSI | FFTW_INIT |
00752             FFT_OUT_OF_PLACE, cutoff);
00753           nfsft_init_guru(&plan,m[im],ld[ild][1],
00754             ((use_nfft!=0)?(0U):(NFSFT_USE_NDFT)) |
00755             ((use_fpt!=0)?(0U):(NFSFT_USE_DPT)),
00756             PRE_PHI_HUT | PRE_PSI | FFTW_INIT |
00757             FFT_OUT_OF_PLACE,
00758              cutoff);
00759           plan_adjoint.f_hat = f_hat;
00760           plan_adjoint.x = eta;
00761           plan_adjoint.f = b;
00762           plan.f_hat = f_hat;
00763           plan.x = xi;
00764           plan.f = f_m;
00765           nfsft_precompute_x(&plan_adjoint);
00766           nfsft_precompute_x(&plan);
00767 
00768           /* Check if direct algorithm shall also be tested. */
00769           if (use_nfsft == BOTH)
00770           {
00771             /* Initialize cumulative time variable. */
00772             t_fd = 0.0;
00773 
00774             /* Initialize time measurement. */
00775             t = nfft_second();
00776 
00777             /* Cycle through all runs. */
00778             for (i = 0; i < ld[ild][4]; i++)
00779             {
00780 
00781               /* Execute adjoint direct NDSFT transformation. */
00782               ndsft_adjoint(&plan_adjoint);
00783 
00784               /* Multiplication with the Fourier-Legendre coefficients. */
00785               for (k = 0; k <= m[im]; k++)
00786               {
00787                 for (n = -k; n <= k; n++)
00788                 {
00789                   f_hat[NFSFT_INDEX(k,n,&plan_adjoint)] *= a[k];
00790                 }
00791               }
00792 
00793               /* Execute direct NDSFT transformation. */
00794               ndsft_trafo(&plan);
00795 
00796             }
00797 
00798             /* Calculate and add the time needed. */
00799             t_fd = nfft_second() - t;
00800 
00801             /* Calculate average time needed. */
00802             t_fd = t_fd/((double)ld[ild][4]);
00803 
00804             /* Check if error E_infty should be computed. */
00805             if (ld[ild][2] != NO)
00806             {
00807               /* Compute the error E_infinity. */
00808               err_fd = nfft_error_l_infty_1_complex(f, f_m, ld[ild][1], b,
00809                 ld[ild][0]);
00810             }
00811           }
00812 
00813           /* Check if the fast NFSFT algorithm shall also be tested. */
00814           if (use_nfsft != NO)
00815           {
00816             /* Initialize cumulative time variable for the NFSFT algorithm. */
00817             t_f = 0.0;
00818           }
00819           else
00820           {
00821             /* Initialize cumulative time variable for the direct NDSFT
00822              * algorithm. */
00823             t_fd = 0.0;
00824           }
00825 
00826           /* Initialize time measurement. */
00827           t = nfft_second();
00828 
00829           /* Cycle through all runs. */
00830           for (i = 0; i < ld[ild][4]; i++)
00831           {
00832             /* Check if the fast NFSFT algorithm shall also be tested. */
00833             if (use_nfsft != NO)
00834             {
00835               /* Execute the adjoint NFSFT transformation. */
00836               nfsft_adjoint(&plan_adjoint);
00837             }
00838             else
00839             {
00840               /* Execute the adjoint direct NDSFT transformation. */
00841               ndsft_adjoint(&plan_adjoint);
00842             }
00843 
00844             /* Multiplication with the Fourier-Legendre coefficients. */
00845             for (k = 0; k <= m[im]; k++)
00846             {
00847               for (n = -k; n <= k; n++)
00848               {
00849                 f_hat[NFSFT_INDEX(k,n,&plan_adjoint)] *= a[k];
00850                }
00851              }
00852 
00853             /* Check if the fast NFSFT algorithm shall also be tested. */
00854             if (use_nfsft != NO)
00855             {
00856               /* Execute the NFSFT transformation. */
00857               nfsft_trafo(&plan);
00858             }
00859             else
00860             {
00861               /* Execute the NDSFT transformation. */
00862               ndsft_trafo(&plan);
00863             }
00864 
00865             /*for (d = 0; d < ld[ild][1]; d++)
00866             {
00867               fprintf(stderr,"f_ref[%d] = %le + I*%le, f[%d] = %le + I*%le\n",
00868                 d,creal(f[d]),cimag(f[d]),d,creal(f_m[d]),cimag(f_m[d]));
00869             }*/
00870           }
00871 
00872           /* Check if the fast NFSFT algorithm has been used. */
00873           if (use_nfsft != NO)
00874           {
00875             /* Calculate and add the time needed. */
00876             t_f = nfft_second() - t;
00877           }
00878           else
00879           {
00880             /* Calculate and add the time needed. */
00881             t_fd = nfft_second() - t;
00882           }
00883 
00884           /* Check if the fast NFSFT algorithm has been used. */
00885           if (use_nfsft != NO)
00886           {
00887             /* Calculate average time needed. */
00888             t_f = t_f/((double)ld[ild][4]);
00889           }
00890           else
00891           {
00892             /* Calculate average time needed. */
00893             t_fd = t_fd/((double)ld[ild][4]);
00894           }
00895 
00896           /* Check if error E_infty should be computed. */
00897           if (ld[ild][2] != NO)
00898           {
00899             /* Check if the fast NFSFT algorithm has been used. */
00900             if (use_nfsft != NO)
00901             {
00902               /* Compute the error E_infinity. */
00903               err_f = nfft_error_l_infty_1_complex(f, f_m, ld[ild][1], b,
00904                 ld[ild][0]);
00905             }
00906             else
00907             {
00908               /* Compute the error E_infinity. */
00909               err_fd = nfft_error_l_infty_1_complex(f, f_m, ld[ild][1], b,
00910                 ld[ild][0]);
00911             }
00912           }
00913 
00914           /* Print out the error measurements. */
00915           fprintf(stdout,"%e\n%e\n%e\n%e\n%e\n%e\n\n",t_d,t_dp,t_fd,t_f,err_fd,
00916             err_f);
00917           /*fprintf(stderr,"%d: %e\t%e\t%e\t%e\t%e\t%e\n",m[im],t_d,t_dp,t_fd,t_f,
00918             err_fd,err_f);*/
00919 
00920           /* Finalize the NFSFT plans */
00921           nfsft_finalize(&plan_adjoint);
00922           nfsft_finalize(&plan);
00923         } /* for (im = 0; im < im_max; im++) - Process all cut-off
00924            * bandwidths.*/
00925       } /* for (ild = 0; ild < ild_max; ild++) - Process all node sets. */
00926     } /* for (ip = 0; ip < ip_max; ip++) - Process all parameter sets. */
00927 
00928     /* Delete precomputed data. */
00929     nfsft_forget();
00930 
00931     /* Check if memory for precomputed data of the matrix K has been
00932      * allocated. */
00933     if (precompute == YES)
00934     {
00935       /* Free memory for precomputed matrix K. */
00936       free(prec);
00937     }
00938     /* Free data arrays. */
00939     free(f);
00940     free(f_m);
00941     free(xi);
00942     free(eta);
00943     free(a);
00944     free(f_hat);
00945     free(b);
00946 
00947     /* Free memory for node sets. */
00948     for (ild = 0; ild < ild_max; ild++)
00949     {
00950       free(ld[ild]);
00951     }
00952     free(ld);
00953 
00954     /* Free memory for cut-off bandwidths. */
00955     free(m);
00956 
00957     /* Free memory for parameter sets. */
00958     for (ip = 0; ip < ip_max; ip++)
00959     {
00960       free(p[ip]);
00961     }
00962     free(p);
00963   } /* for (tc = 0; tc < tc_max; tc++) - Process each testcase. */
00964 
00965   /* Return exit code for successful run. */
00966   return EXIT_SUCCESS;
00967 }
00968 /* \} */

Generated on 1 Nov 2006 by Doxygen 1.4.4