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

nfst.c

00001 
00007 #include <stdio.h>
00008 #include <math.h>
00009 #include <string.h>
00010 #include <stdlib.h>
00011 
00012 #include "util.h"
00013 #include "options.h"
00014 #include "window_defines.h"
00015 
00016 #include "nfft3.h"
00017 
00018 
00022 #define NFST_DEFAULT_FLAGS   PRE_PHI_HUT|\
00023                              PRE_PSI|\
00024                              MALLOC_X|\
00025                              MALLOC_F_HAT|\
00026                              MALLOC_F|\
00027                              FFTW_INIT|\
00028                              FFT_OUT_OF_PLACE
00029 
00030 #define FFTW_DEFAULT_FLAGS   FFTW_ESTIMATE|\
00031                              FFTW_DESTROY_INPUT
00032 
00033 #define NFST_SUMMANDS ( 2 * ths->m + 2)
00034 #define NODE(p,r) ( ths->x[(p) * ths->d + (r)])
00035 
00036 #define MACRO_ndst_init_result_trafo      \
00037   memset( f, 0, ths->M_total * sizeof( double));
00038 #define MACRO_ndst_init_result_adjoint \
00039   memset( f_hat, 0, ths->N_total * sizeof( double));
00040 
00041 
00042 #define MACRO_nfst_D_init_result_A        \
00043   memset(g_hat, 0, nfst_prod_minus_a_int( ths->n, 0, ths->d) * sizeof( double));  
00044 #define MACRO_nfst_D_init_result_T        \
00045   memset(f_hat, 0, ths->N_total * sizeof( double));  
00046 
00047 #define MACRO_nfst_B_init_result_A        \
00048   memset(f, 0,     ths->M_total * sizeof( double));  
00049 #define MACRO_nfst_B_init_result_T        \
00050   memset(g, 0, nfst_prod_minus_a_int( ths->n, 0, ths->d) * sizeof( double));  
00051 
00052  
00053 #define NFST_PRE_WINFUN( d)  ths->N[d] = 2 * ths->N[d];         \
00054                              ths->n[d] = nfst_fftw_2N( ths->n[d]);
00055 
00056 #define NFST_POST_WINFUN( d) ths->N[d] = ((int)(0.5 * ths->N[d]));   \
00057                              ths->n[d] = nfst_fftw_2N_rev( ths->n[d]);
00058 
00059 
00060 #define NFST_WINDOW_HELP_INIT  WINDOW_HELP_INIT
00061 
00062 
00063 double nfst_phi_hut( nfst_plan *ths, int k, int d)
00064 {
00065   NFST_PRE_WINFUN( d);
00066   double phi_hut_tmp = PHI_HUT( k, d);
00067   NFST_POST_WINFUN( d);
00068 
00069   return phi_hut_tmp;
00070 }
00071 
00072 double nfst_phi( nfst_plan *ths, double x, int d)
00073 {
00074   NFST_PRE_WINFUN( d); 
00075   double phi_tmp = PHI( x, d); 
00076   NFST_POST_WINFUN( d); 
00077  
00078   return phi_tmp; 
00079 } 
00080 
00081 int nfst_fftw_2N( int n)
00082 {
00083   return 2 * ( n + 1);
00084 }
00085 
00086 int nfst_fftw_2N_rev( int n)
00087 {
00088   div_t n_div;
00089   
00090   n_div = div(n, 2);
00091   return n_div.quot - 1;
00092 }
00093 
00094 #define MACRO_with_sin_vec     sin_vec[t][ka[t]] 
00095 #define MACRO_without_sin_vec  sin( 2.0 * PI * (ka[t]+1) * NODE(j,t)) 
00096  
00097  
00098 #define MACRO_with_PRE_PHI_HUT     ths->c_phi_inv[t][kg[t]]; 
00099 #define MACRO_compute_PHI_HUT_INV  (1.0 / (nfst_phi_hut( ths, kg[t]+1, t)))
00100 
00101 #define MACRO_with_PRE_PSI     ths->psi[(j * ths->d + t) * NFST_SUMMANDS + lc[t]];  
00102 #define MACRO_compute_PSI      \
00103   nfst_phi( ths, NODE(j,t) - (( double)(lc[t] + lb[t])) / nfst_fftw_2N( ths->n[t]), t)  
00104 
00105 
00106 
00122 #define MACRO_ndst_malloc__sin_vec                                              \
00123                                                                                 \
00124   double **sin_vec;                                                             \
00125   sin_vec = (double**)malloc( ths->d * sizeof( double*));                       \
00126   for( t = 0; t < ths->d; t++)                                                  \
00127     sin_vec[t] = (double*)malloc( ( ths->N[t] - 1) * sizeof( double));          \
00128 
00129 
00130 
00131 
00132 #define MACRO_ndst_free__sin_vec                                                \
00133 {                                                                               \
00134   /* free allocated memory */                                                   \
00135   for( t = 0; t < ths->d; t++)                                                  \
00136     free( sin_vec[t]);                                                          \
00137   free( sin_vec);                                                               \
00138 }
00139 
00140 
00141 
00142 #define MACRO_ndst_init__sin_vec                                                \
00143 {                                                                               \
00144   for( t = 0; t < ths->d; t++)                                                  \
00145   {                                                                             \
00146     cos_x[t] = cos( 2.0 * PI * NODE(j,t));                                      \
00147     sin_vec[t][0] = sin( 2.0 * PI * NODE(j,t));                                 \
00148     sin_vec[t][1] = sin( 4.0 * PI * NODE(j,t));                                 \
00149     for( k = 2; k < ths->N[t] - 1; k++)                                         \
00150       sin_vec[t][k] = 2.0 * cos_x[t] * sin_vec[t][k-1]                          \
00151                       - sin_vec[t][k-2];                                        \
00152   }                                                                             \
00153 }
00154 
00155 
00156 #define MACRO_ndst_init__k__sin_k( which_one)                                   \
00157 {                                                                               \
00158   sin_k[0] = 1.0;                                                               \
00159   for( t = 0; t < ths->d; t++)                                                  \
00160     ka[t] = 0;                                                                  \
00161                                                                                 \
00162   for( t = 0; t < ths->d; t++)                                                  \
00163   {                                                                             \
00164     sin_k[t+1] = sin_k[t] * MACRO_ ##which_one;                                 \
00165   }                                                                             \
00166 }
00167 
00168 
00169 #define MACRO_ndst_count__k__sin_k( which_one)                                  \
00170 {                                                                               \
00171   ka[ths->d-1]++;                                                               \
00172   i = ths->d - 1;                                                               \
00173   while( ( ka[i] == ths->N[i] - 1) && ( i > 0))                                 \
00174   {                                                                             \
00175     ka[i - 1]++;                                                                \
00176     ka[i] = 0;                                                                  \
00177                                                                                 \
00178     i--;                                                                        \
00179   }                                                                             \
00180   for( t = i; t < ths->d; t++)                                                  \
00181     sin_k[t+1] = sin_k[t] * MACRO_ ##which_one;                                 \
00182 }
00183 
00184 
00185 #define MACRO_ndst_compute__trafo                                               \
00186 {                                                                               \
00187   f[j] += f_hat[k] * sin_k[ths->d];                                             \
00188 }
00189 
00190 #define MACRO_ndst_compute__adjoint                                             \
00191 {                                                                               \
00192   f_hat[k] += f[j] * sin_k[ths->d];                                             \
00193 }
00194 
00195 
00196 /* slow (trafo) transform */
00197 #define MACRO_ndst( which_one)                                                  \
00198   void ndst_ ## which_one ( nfst_plan *ths)                                     \
00199   {                                                                             \
00200     int j, k, t, i;                                                             \
00201     int ka[ths->d];                                                             \
00202     double sin_k[ths->d+1];                                                     \
00203     double cos_x[ths->d];                                                       \
00204                                                                                 \
00205     double *f     = ths->f;                                                     \
00206     double *f_hat = ths->f_hat;                                                 \
00207                                                                                 \
00208     MACRO_ndst_init_result_ ## which_one;                                       \
00209                                                                                 \
00210     if( ths->d == 1)                                                            \
00211       for( j = 0; j < ths->M_total; j++)                                        \
00212         for( k = 0; k < ths->N_total; k++)                                      \
00213         {                                                                       \
00214           sin_k[ths->d] = sin( 2.0 * PI * (k+1) * NODE(j,0));                   \
00215           MACRO_ndst_compute__ ## which_one;                                    \
00216         }                                                                       \
00217     else                                                                        \
00218       if( 1 == 0) /*FIXME: remove slow slow ... */                              \
00219         /* slow ndst */                                                         \
00220         for( j = 0; j < ths->M_total; j++)                                      \
00221         {                                                                       \
00222           MACRO_ndst_init__k__sin_k(without_sin_vec);                           \
00223                                                                                 \
00224           for( k = 0; k < ths->N_total; k++)                                    \
00225           {                                                                     \
00226             MACRO_ndst_compute__ ## which_one;                                  \
00227                                                                                 \
00228             MACRO_ndst_count__k__sin_k(without_sin_vec);                        \
00229           }                                                                     \
00230         }                                                                       \
00231       else                                                                      \
00232       {                                                                         \
00233         /* fast ndst_trafo */                                                   \
00234         MACRO_ndst_malloc__sin_vec;                                             \
00235                                                                                 \
00236         for( j = 0; j < ths->M_total; j++)                                      \
00237         {                                                                       \
00238           MACRO_ndst_init__sin_vec;                                             \
00239                                                                                 \
00240           MACRO_ndst_init__k__sin_k(with_sin_vec);                              \
00241                                                                                 \
00242           for( k = 0; k < ths->N_total; k++)                                    \
00243           {                                                                     \
00244             MACRO_ndst_compute__ ## which_one;                                  \
00245                                                                                 \
00246             MACRO_ndst_count__k__sin_k(with_sin_vec);                           \
00247           }                                                                     \
00248         }                                                                       \
00249         MACRO_ndst_free__sin_vec;                                               \
00250       }                                                                         \
00251   } /* ndst_{trafo, adjoint} */
00252 
00253  
00254 MACRO_ndst(trafo)
00255 MACRO_ndst(adjoint)
00256 
00257 
00258 
00259 
00274 #define MACRO_nfst__lower_boundary( j,act_dim)                                  \
00275 {                                                                               \
00276   lb[(act_dim)] =                                                               \
00277     ((int)(NODE((j),(act_dim)) * nfst_fftw_2N( ths->n[(act_dim)]))) - ths->m;   \
00278 }
00279 
00280 #define MACRO_nfst_D_compute_A                                                  \
00281 {                                                                               \
00282   g_hat[kg_plain[ths->d]] = f_hat[k_L] * c_phi_inv_k[ths->d];                   \
00283 }
00284 
00285 #define MACRO_nfst_D_compute_T                                                  \
00286 {                                                                               \
00287   f_hat[k_L] = g_hat[kg_plain[ths->d]] * c_phi_inv_k[ths->d];                   \
00288 }
00289 
00290 
00291 #define MACRO_init__kg                                                          \
00292 {                                                                               \
00293   for( t = 0; t < ths->d; t++)                                                  \
00294     kg[t] = 0;                                                                  \
00295                                                                                 \
00296   i = 0;                                                                        \
00297 }
00298 
00299 
00300 #define MACRO_count__kg                                                         \
00301 {                                                                               \
00302   kg[ths->d - 1]++;                                                             \
00303   i = ths->d - 1;                                                               \
00304   while( ( kg[i] == ths->N[i] - 1) && ( i > 0))                                 \
00305   {                                                                             \
00306     kg[i - 1]++;                                                                \
00307     kg[i] = 0;                                                                  \
00308                                                                                 \
00309     i--;                                                                        \
00310   }                                                                             \
00311 }
00312 
00313   
00314 #define MACRO_update__c_phi_inv_k__lg_plain( which_one, which_phi)              \
00315 {                                                                               \
00316   for( t = i; t < ths->d; t++) {                                                \
00317     MACRO__c_phi_inv_k( which_phi);                                             \
00318     kg_plain[t+1] = kg_plain[t] * ths->n[t] + kg[t];                            \
00319   }                                                                             \
00320 }
00321 
00322 
00323 #define MACRO__c_phi_inv_k( which_phi)                                          \
00324 {                                                                               \
00325   c_phi_inv_k[t+1] = 0.5 * c_phi_inv_k[t] * MACRO_ ## which_phi;                \
00326 }
00327 
00328 
00329 #define MACRO_nfst_D(which_one)                                                 \
00330 inline void nfst_D_ ## which_one (nfst_plan *ths)                               \
00331 {                                                                               \
00332   int k_L;                                    \
00333                                                                                 \
00334   int i, t;                                                                     \
00335   int kg[ths->d];                             \
00336   double c_phi_inv_k[ths->d+1];               \
00337   int kg_plain[ths->d+1];                     \
00338                                                                                 \
00339   double *g_hat, *f_hat;                      \
00340                                                                                 \
00341   g_hat = ths->g_hat;                                                           \
00342   f_hat = ths->f_hat;                                                           \
00343                                                                                 \
00344   MACRO_nfst_D_init_result_ ## which_one                                        \
00345                                                                                 \
00346   c_phi_inv_k[0] = 1;                                                           \
00347   kg_plain[0]    = 0;                                                           \
00348                                                                                 \
00349   MACRO_init__kg;                                                               \
00350                                                                                 \
00351   if( ths->nfst_flags & PRE_PHI_HUT)                                            \
00352                                                                                 \
00353     for( k_L = 0; k_L < ths->N_total; k_L++)                                    \
00354     {                                                                           \
00355       MACRO_update__c_phi_inv_k__lg_plain( which_one, with_PRE_PHI_HUT);        \
00356                                                                                 \
00357       MACRO_nfst_D_compute_ ## which_one;                                       \
00358                                                                                 \
00359       MACRO_count__kg;                                                          \
00360                                                                                 \
00361     } /* for(k_L) */                                                            \
00362                                                                                 \
00363   else                                                                          \
00364                                                                                 \
00365     for( k_L = 0; k_L < ths->N_total; k_L++)                                    \
00366     {                                                                           \
00367       MACRO_update__c_phi_inv_k__lg_plain( which_one, compute_PHI_HUT_INV);     \
00368                                                                                 \
00369       MACRO_nfst_D_compute_ ## which_one;                                       \
00370                                                                                 \
00371       MACRO_count__kg                                                           \
00372                                                                                 \
00373     } /* for(k_L) */                                                            \
00374 } /* nfst_D */
00375   
00376 MACRO_nfst_D(A)
00377 MACRO_nfst_D(T)
00378 
00379 
00380 
00381 
00382 
00383 
00384 
00388 #define MACRO_nfst_B_PRE_FULL_PSI_compute_A                                     \
00389 {                                                                               \
00390   (*fj) += ths->psi[ix] * g[ths->psi_index_g[ix]];                              \
00391 }
00392 
00393 #define MACRO_nfst_B_PRE_FULL_PSI_compute_T                                     \
00394 {                                                                               \
00395   g[ths->psi_index_g[ix]] += ths->psi[ix] * (*fj);                              \
00396 }
00397 
00398 
00399 
00400 #define MACRO_nfst_B_compute_A                                                  \
00401 {                                                                               \
00402   (*fj) += phi_tilde[ths->d] * g[lg_plain[ths->d]];                             \
00403 }
00404 
00405 #define MACRO_nfst_B_compute_T                                                  \
00406 {                                                                               \
00407   g[lg_plain[ths->d]] += phi_tilde[ths->d] * (*fj);                             \
00408 }
00409 
00410 
00411 
00412 #define MACRO_compute_lg_offset__count_lg( i0)                                  \
00413 {                                                                               \
00414   /* determine index in g-array corresponding to lb[(i0)] */                    \
00415   if( lb[(i0)] < 0)                                                             \
00416   {                                                                             \
00417     lg_offset[(i0)] =                                                           \
00418       (lb[(i0)] % nfst_fftw_2N( ths->n[(i0)])) + nfst_fftw_2N( ths->n[(i0)]);   \
00419   }                                                                             \
00420   else                                                                          \
00421   {                                                                             \
00422     lg_offset[(i0)] = lb[(i0)] % nfst_fftw_2N( ths->n[(i0)]);                   \
00423   }                                                                             \
00424                                                                                 \
00425   if( lg_offset[(i0)] > ths->n[(i0)]+1)                                         \
00426       lg_offset[(i0)] = -( nfst_fftw_2N( ths->n[(i0)]) - lg_offset[(i0)]);      \
00427 }
00428 
00429 
00430 
00431 #define MACRO_set__lg__to__lg_offset                                            \
00432 {                                                                               \
00433   if( lg_offset[i] <= 0)                                                        \
00434   {                                                                             \
00435     lg[i] = -lg_offset[i];                                                      \
00436     count_lg[i] = -1;                                                           \
00437   }                                                                             \
00438   else                                                                          \
00439   {                                                                             \
00440     lg[i] = +lg_offset[i];                                                      \
00441     count_lg[i] = +1;                                                           \
00442   }                                                                             \
00443 }
00444 
00445 
00446 
00447 #define MACRO_count__lg(dim)                                                    \
00448 {                                                                               \
00449   /* turn around when we hit one of the boundaries */                           \
00450   if( ((lg[(dim)] == 0) || (lg[(dim)] == (ths->n[(dim)] + 1))) )                \
00451     count_lg[(dim)] *= -1;                                                      \
00452                                                                                 \
00453   lg[(dim)] += count_lg[(dim)];                                                 \
00454 }
00455 
00456 
00457 
00458 #define MACRO_init_lb_lg_lc_phi_tilde_lg_plain( which_psi)                      \
00459 {                                                                               \
00460   for( i = 0; i < ths->d; i++)                                                  \
00461   {                                                                             \
00462     MACRO_nfst__lower_boundary( j, i);                                          \
00463                                                                                 \
00464     MACRO_compute_lg_offset__count_lg( i);                                      \
00465     MACRO_set__lg__to__lg_offset;                                               \
00466                                                                                 \
00467     /* counter for lg */                                                        \
00468     lc[i] = 0;                                                                  \
00469   }                                                                             \
00470                                                                                 \
00471   for( t = 0; t < ths->d; t++)                                                  \
00472   {                                                                             \
00473     if( lg[t] == 0)                                                             \
00474     {                                                                           \
00475       lg_plain[t+1]  = lg_plain[t] * ths->n[t];                                 \
00476       phi_tilde[t+1] = 0.0;                                                     \
00477     }                                                                           \
00478     else                                                                        \
00479       if( lg[t] == ths->n[t]+1)                                                 \
00480       {                                                                         \
00481         lg_plain[t+1]  = lg_plain[t] * ths->n[t] + ths->n[t]-1;                 \
00482         phi_tilde[t+1] = 0.0;                                                   \
00483       }                                                                         \
00484       else                                                                      \
00485       {                                                                         \
00486         MACRO__phi_tilde( which_psi);                                           \
00487         lg_plain[t+1]  = lg_plain[t] * ths->n[t] + lg[t]-1;                     \
00488       }                                                                         \
00489   }                                                                             \
00490                                                                                 \
00491   i = 0;                                                                        \
00492 }
00493 
00494 
00495 
00496 #define MACRO_count__lg_lc                                                      \
00497 {                                                                               \
00498   MACRO_count__lg( ths->d-1);                                                   \
00499                                                                                 \
00500   lc[ths->d - 1]++;                                                             \
00501   i = ths->d - 1;                                                               \
00502                                                                                 \
00503   while( (lc[i] == NFST_SUMMANDS) && (i > 0))                                   \
00504   {                                                                             \
00505     lc[i - 1]++;                                                                \
00506     lc[i] = 0;                                                                  \
00507                                                                                 \
00508     /* ansonsten lg[i-1] verschieben */                                         \
00509     MACRO_count__lg( i - 1);                                                    \
00510     /* lg[i] = anfangswert */                                                   \
00511     MACRO_set__lg__to__lg_offset;                                               \
00512                                                                                 \
00513     i--;                                                                        \
00514   }                                                                             \
00515 }
00516 
00517 
00518 #define MACRO_update__phi_tilde__lg_plain( which_psi)                           \
00519 {                                                                               \
00520   for( t = i; t < ths->d; t++)                                                  \
00521   {                                                                             \
00522     if( (lg[t] != 0) && (lg[t] != ths->n[t]+1))                                 \
00523     {                                                                           \
00524       MACRO__phi_tilde( which_psi);                                             \
00525       lg_plain[t+1] = lg_plain[t] * ths->n[t] + lg[t]-1;                        \
00526     }                                                                           \
00527     else                                                                        \
00528       phi_tilde[t+1] = 0.0;                                                     \
00529   }                                                                             \
00530 }
00531 
00532 
00533 
00534 #define MACRO__phi_tilde( which_psi)                                            \
00535 {                                                                               \
00536   phi_tilde[t+1] = (double)count_lg[t] * phi_tilde[t] * MACRO_ ## which_psi;    \
00537 }
00538 
00539 
00540 
00541 
00542 #define MACRO_nfst_B( which_one)                                                \
00543   inline void nfst_B_ ## which_one ( nfst_plan *ths)                            \
00544   { /* MACRO_nfst_B */                                                          \
00545     int lb[ths->d];                       \
00546     int j, t, i;                          \
00547     int lprod, l_L, ix;                   \
00548     int lc[ths->d];                       \
00549     int lg[ths->d];                       \
00550     int lg_offset[ths->d];                \
00551     int count_lg[ths->d];                 \
00552     int lg_plain[ths->d+1];               \
00553     double *f, *g;                        \
00554     double phi_tilde[ths->d+1];           \
00555     double *fj;                           \
00556                                                                                 \
00557     f = ths->f; g = ths->g;                                                     \
00558                                                                                 \
00559     MACRO_nfst_B_init_result_ ## which_one                                      \
00560                                                                                 \
00561     /* both flags are set */                                                    \
00562     if( (ths->nfst_flags & PRE_PSI) && (ths->nfst_flags & PRE_FULL_PSI))        \
00563     {                                                                           \
00564       for( ix = 0, j = 0, fj = &f[0]; j < ths->M_total; j++, fj += 1)           \
00565         for( l_L = 0; l_L < ths->psi_index_f[j]; l_L++, ix++)                   \
00566         {                                                                       \
00567           MACRO_nfst_B_PRE_FULL_PSI_compute_ ## which_one;                      \
00568         }                                                                       \
00569     }                                                                           \
00570     else                                                                        \
00571     {                                                                           \
00572       phi_tilde[0] = 1;                                                         \
00573       lg_plain[0]  = 0;                                                         \
00574                                                                                 \
00575       for( t = 0, lprod = 1; t < ths->d; t++)                                   \
00576         lprod *= NFST_SUMMANDS;                                                 \
00577                                                                                 \
00578       /* PRE_PSI flag is set */                                                 \
00579       if( ths->nfst_flags & PRE_PSI)                                            \
00580       {                                                                         \
00581         for( j = 0, fj = &f[0]; j < ths->M_total; j++, fj += 1)                 \
00582         {                                                                       \
00583           MACRO_init_lb_lg_lc_phi_tilde_lg_plain( with_PRE_PSI);                \
00584                                                                                 \
00585           for( l_L = 0; l_L < lprod; l_L++)                                     \
00586           {                                                                     \
00587             MACRO_update__phi_tilde__lg_plain( with_PRE_PSI);                   \
00588                                                                                 \
00589             MACRO_nfst_B_compute_ ## which_one;                                 \
00590                                                                                 \
00591             MACRO_count__lg_lc;                                                 \
00592                                                                                 \
00593           } /* for( l_L) */                                                     \
00594         } /* for( j) */                                                         \
00595       } /* if( PRE_PSI) */                                                      \
00596                                                                                 \
00597       /* no PSI flag is set */                                                  \
00598       else                                                                      \
00599       {                                                                         \
00600         for( j = 0, fj = &f[0]; j < ths->M_total; j++, fj += 1)                 \
00601         {                                                                       \
00602           MACRO_init_lb_lg_lc_phi_tilde_lg_plain( compute_PSI);                 \
00603                                                                                 \
00604           for( l_L = 0; l_L < lprod; l_L++)                                     \
00605           {                                                                     \
00606             MACRO_update__phi_tilde__lg_plain( compute_PSI);                    \
00607                                                                                 \
00608             MACRO_nfst_B_compute_ ## which_one;                                 \
00609                                                                                 \
00610             MACRO_count__lg_lc;                                                 \
00611                                                                                 \
00612           } /* for(l_L) */                                                      \
00613         } /* for(j) */                                                          \
00614       } /* else(PRE_PSI) */                                                     \
00615     }/* else( PRE_PRE && FULL_PRE_PSI) */                                       \
00616 } /* nfst_B */
00617   
00618 MACRO_nfst_B(A)
00619 MACRO_nfst_B(T)
00620 
00621 
00622 
00623 
00624 
00625 
00630 void nfst_trafo( nfst_plan *ths)
00631 {
00636   ths->g_hat = ths->g1;
00637   ths->g     = ths->g2;
00638 
00639  
00645   TIC(0)
00646   nfst_D_A( ths);
00647   TOC(0)
00648 
00649 
00650   
00656   TIC(1)
00657   fftw_execute( ths->my_fftw_r2r_plan);
00658   TOC(1)
00659 
00660 
00661   
00666   TIC(2)
00667   nfst_B_A( ths);
00668   TOC(2)
00669 
00670 } /* nfst_trafo */
00671 
00672 
00673 
00674 
00675 void nfst_adjoint( nfst_plan *ths)
00676 {
00681   ths->g_hat = ths->g2;
00682   ths->g     = ths->g1;
00683 
00684 
00690   TIC(2)
00691   nfst_B_T( ths);
00692   TOC(2)
00693       
00694 
00695   
00701   TIC(1)
00702   fftw_execute( ths->my_fftw_r2r_plan);
00703   TOC(1)
00704 
00705   
00706   
00711   TIC(0)
00712   nfst_D_T( ths);
00713   TOC(0)
00714 
00715 } /* nfst_adjoint */
00716 
00717 
00718 
00723 void nfst_precompute_phi_hut( nfst_plan *ths)
00724 {
00725   int kg[ths->d];                      
00726   int t;                               
00728   ths->c_phi_inv = (double**)fftw_malloc( ths->d * sizeof( double*));
00729 
00730   for( t = 0; t < ths->d; t++)
00731   {
00732     ths->c_phi_inv[t] = (double*)fftw_malloc( ( ths->N[t] - 1) * sizeof( double));
00733     
00734     for( kg[t] = 0; kg[t] < ths->N[t] - 1; kg[t]++)
00735     {
00736       ths->c_phi_inv[t][kg[t]] = MACRO_compute_PHI_HUT_INV;
00737     }
00738   }
00739 } /* nfst_phi_hut */
00740 
00741 
00742 
00743 void nfst_precompute_psi( nfst_plan *ths)
00744 {
00745   int t;                                
00746   int j;                                
00747   int lc[ths->d];                       
00748   int lb[ths->d];                       
00750   for (t = 0; t < ths->d; t++)
00751   {
00752     for(j = 0; j < ths->M_total; j++)
00753     {
00754       MACRO_nfst__lower_boundary( j, t);
00755 
00756       for( lc[t] = 0; lc[t] < NFST_SUMMANDS; lc[t]++)
00757         ths->psi[(j * ths->d + t) * NFST_SUMMANDS + lc[t]] = MACRO_compute_PSI;
00758 
00759     } /* for(j) */
00760   }  /* for(t) */
00761 
00762   /* full precomputation of psi */
00763   if ( ths->nfst_flags & PRE_FULL_PSI)
00764     nfst_full_psi( ths, ths->nfst_full_psi_eps);
00765 
00766 } /* nfst_precompute_psi */
00767 
00768 
00769 
00771 void nfst_full_psi(nfst_plan *ths, double eps)
00772 {
00773   int t, i;                             
00774   int j;                                
00775   int l_L;                              
00776   int lc[ths->d];                       
00777   int lg_plain[ths->d+1];               
00778   int count_lg[ths->d];
00779   int lg_offset[ths->d];
00780   int lg[ths->d];
00781   int lprod;                            
00782   int lb[ths->d];                       
00784   double phi_tilde[ths->d+1];
00785 
00786   int *index_g, *index_f;
00787   double *new_psi;
00788   int ix, ix_old, size_psi;
00789 
00790   phi_tilde[0] = 1.0;
00791   lg_plain[0]  =   0;
00792 
00793   if(ths->nfst_flags & PRE_PSI)
00794   {
00795     size_psi = ths->M_total;
00796     index_f  =    (int*)malloc( ths->M_total  * sizeof( int));
00797     index_g  =    (int*)malloc( size_psi * sizeof( int));
00798     new_psi  = (double*)malloc( size_psi * sizeof( double));
00799     
00800     for( t = 0,lprod = 1; t < ths->d; t++)
00801     {
00802       lprod *= NFST_SUMMANDS;
00803       eps *= PHI( 0, t);
00804     }
00805     
00806     for( ix = 0, ix_old = 0, j = 0; j < ths->M_total; j++)
00807     {
00808       MACRO_init_lb_lg_lc_phi_tilde_lg_plain( with_PRE_PSI);
00809           
00810       for( l_L = 0; l_L < lprod; l_L++)
00811       {
00812         MACRO_update__phi_tilde__lg_plain( with_PRE_PSI);
00813 
00814         if( fabs(phi_tilde[ths->d]) > eps)
00815         {
00816           index_g[ix] =  lg_plain[ths->d];
00817           new_psi[ix] = phi_tilde[ths->d];
00818   
00819           ix++;
00820           if( ix == size_psi)
00821           {
00822             size_psi += ths->M_total;
00823             index_g   =    (int*)realloc( index_g, size_psi * sizeof( int));
00824             new_psi   = (double*)realloc( new_psi, size_psi * sizeof( double));
00825           }
00826         }
00827         MACRO_count__lg_lc;
00828 
00829       } /* for(l_L) */
00830       
00831       index_f[j] = ix - ix_old;
00832       ix_old     = ix;
00833       
00834     } /* for(j) */
00835     
00836     free( ths->psi);
00837 
00838     size_psi      = ix;
00839     ths->size_psi = size_psi;
00840     index_g       = (int*)realloc( index_g, size_psi * sizeof( int));
00841     new_psi       = (double*)realloc( new_psi, size_psi * sizeof( double));
00842     
00843     ths->psi         = new_psi;
00844     ths->psi_index_g = index_g; 
00845     ths->psi_index_f = index_f;
00846     
00847   } /* if(PRE_PSI) */
00848 } /* nfst_full_psi */
00849 
00850 
00851 
00852 
00853 void nfst_init_help( nfst_plan *ths)
00854 {
00855   int t;                                
00857   ths->N_total = nfst_prod_minus_a_int( ths->N, 1, ths->d);
00858 
00859   ths->sigma   = (double*)fftw_malloc( ths->d * sizeof( double));
00860 
00861   for( t = 0; t < ths->d; t++) 
00862     /* FIXME: n/N or (n+1)/N */
00863     ths->sigma[t] = ((double)ths->n[t] + 1) / ths->N[t];
00864 
00865   /* assign r2r transform kinds for each dimension */
00866   ths->r2r_kind = (fftw_r2r_kind*) fftw_malloc ( ths->d * sizeof( fftw_r2r_kind));
00867   for (t = 0; t < ths->d; t++)
00868     ths->r2r_kind[t] = FFTW_RODFT00;
00869 
00870 
00871   WINDOW_HELP_INIT;
00872 
00873   if(ths->nfst_flags & MALLOC_X)
00874     ths->x = (double*)fftw_malloc( ths->d * ths->M_total * sizeof( double));
00875 
00876   if(ths->nfst_flags & MALLOC_F_HAT)
00877     ths->f_hat = (double*)fftw_malloc( ths->N_total * sizeof( double));
00878 
00879   if(ths->nfst_flags & MALLOC_F)
00880     ths->f = (double*)fftw_malloc( ths->M_total * sizeof( double));
00881 
00882   if(ths->nfst_flags & PRE_PHI_HUT)
00883     nfst_precompute_phi_hut( ths);
00884 
00885   /* NO FFTW_MALLOC HERE */
00886   if(ths->nfst_flags & PRE_PSI)
00887   {
00888     ths->psi =
00889       (double*)malloc( ths->M_total * ths->d * NFST_SUMMANDS * sizeof( double));
00890 
00894     ths->nfst_full_psi_eps = pow(10, -10);
00895   }
00896   
00897   if(ths->nfst_flags & FFTW_INIT)
00898   {
00899       ths->g1 =
00900         (double*)fftw_malloc( nfst_prod_minus_a_int( ths->n, 0, ths->d) * sizeof( double));
00901 
00902       if(ths->nfst_flags & FFT_OUT_OF_PLACE)
00903         ths->g2 =
00904           (double*)fftw_malloc( nfst_prod_minus_a_int( ths->n, 0, ths->d) * sizeof( double));
00905       else
00906         ths->g2 = ths->g1;
00907 
00908       ths->my_fftw_r2r_plan = 
00909         fftw_plan_r2r( ths->d, ths->n, ths->g1, ths->g2, ths->r2r_kind, ths->fftw_flags);
00910   }
00911 }
00912 
00913 void nfst_init( nfst_plan *ths, int d, int *N, int M_total)
00914 {
00915   int t;                                
00917   ths->d = d;
00918 
00919   ths->N      = (int*)fftw_malloc( ths->d * sizeof( int));
00920 
00921   for(t = 0;t < d; t++)
00922     ths->N[t] = N[t];
00923 
00924   ths->n      = (int*)fftw_malloc( ths->d * sizeof( int));
00925 
00926   for( t = 0; t < d; t++)
00927     ths->n[t] = 2 * nfft_next_power_of_2( ths->N[t]) - 1;
00928 
00929   ths->M_total = M_total;
00930 
00931   WINDOW_HELP_ESTIMATE_m;
00932 
00933   ths->nfst_flags = NFST_DEFAULT_FLAGS;
00934   ths->fftw_flags = FFTW_DEFAULT_FLAGS;
00935 
00936   nfst_init_help( ths);    
00937 }
00938 
00939 
00940 void nfst_init_m( nfst_plan *ths, int d, int *N, int M_total, int m)
00941 {
00942   int t, n[d];
00943 
00944   for( t = 0; t < d; t++) 
00945     n[t] = nfst_fftw_2N( nfft_next_power_of_2( N[t])); 
00946 
00947   nfst_init_guru( ths, d, N, M_total, n, m, NFST_DEFAULT_FLAGS, FFTW_DEFAULT_FLAGS);
00948 }
00949 
00950 
00951 void nfst_init_guru( nfst_plan *ths, int d, int *N,
00952      int M_total, int *n, int m,
00953      unsigned nfst_flags, unsigned fftw_flags)
00954 {
00955   int t;             
00957   ths->d = d;
00958   ths->M_total = M_total;
00959 
00960   ths->N      = (int*)fftw_malloc( ths->d * sizeof( int));
00961 
00962   for( t = 0; t < d; t++)
00963     ths->N[t]      = N[t];
00964 
00965   ths->n      = (int*)fftw_malloc( ths->d * sizeof( int));
00966 
00967   for( t = 0; t < d; t++)
00968     ths->n[t]      = n[t];
00969 
00970   ths->m = m;
00971 
00972   ths->nfst_flags = nfst_flags;
00973   ths->fftw_flags = fftw_flags;
00974 
00975   nfst_init_help( ths);  
00976 }
00977 
00978 
00979 void nfst_init_1d( nfst_plan *ths, int N0, int M_total)
00980 {
00981   int N[1];
00982 
00983   N[0] = N0;
00984   nfst_init( ths, 1, N, M_total);
00985 }
00986 
00987 void nfst_init_2d( nfst_plan *ths, int N0, int N1, int M_total)
00988 {
00989   int N[2];
00990 
00991   N[0] = N0;
00992   N[1] = N1;
00993   nfst_init( ths, 2, N, M_total);
00994 }
00995 
00996 void nfst_init_3d( nfst_plan *ths, int N0, int N1, int N2, int M_total)
00997 {
00998   int N[3];
00999 
01000   N[0] = N0;
01001   N[1] = N1;
01002   N[2] = N2;
01003   nfst_init( ths, 3, N, M_total);
01004 }
01005 
01006 void nfst_finalize( nfst_plan *ths)
01007 {
01008   int t; /* index over dimensions */
01009 
01010   if( ths->nfst_flags & FFTW_INIT)
01011   {
01012     fftw_destroy_plan( ths->my_fftw_r2r_plan);
01013       
01014     if( ths->nfst_flags & FFT_OUT_OF_PLACE)
01015       fftw_free( ths->g2);
01016       
01017     fftw_free( ths->g1);
01018   }
01019 
01020   /* NO FFTW_FREE HERE */
01021   if( ths->nfst_flags & PRE_PSI)
01022   {
01023     if( ths->nfst_flags & PRE_FULL_PSI)
01024     {
01025       free( ths->psi_index_g);
01026       free( ths->psi_index_f);
01027     }
01028     
01029     free( ths->psi);
01030   }
01031 
01032   if( ths->nfst_flags & PRE_PHI_HUT) {
01033     for( t = 0; t < ths->d; t++)
01034       fftw_free( ths->c_phi_inv[t]);
01035     fftw_free( ths->c_phi_inv);
01036   }
01037 
01038   if( ths->nfst_flags & MALLOC_F)
01039     fftw_free( ths->f);
01040 
01041   if( ths->nfst_flags & MALLOC_F_HAT)
01042     fftw_free( ths->f_hat);
01043   
01044   if( ths->nfst_flags & MALLOC_X)
01045     fftw_free( ths->x);
01046  
01047   WINDOW_HELP_FINALIZE;
01048 
01049   fftw_free( ths->N);
01050   fftw_free( ths->n);
01051   fftw_free( ths->sigma);
01052 
01053 } /* nfst_finalize */
01054 

Generated on 1 Nov 2006 by Doxygen 1.4.4