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

legendre.c

00001 #include "legendre.h"
00002 #include "api.h"
00003 #include <math.h>
00004 
00009 inline double alpha_al(int k, int n)
00010 { 
00011   if (k == -1)
00012   {
00013     return (0.0); 
00014   }
00015   else if (k == 0)
00016   {
00017     if (n == 0)
00018     {
00019       return 1;
00020     }
00021     else
00022     {
00023       return n%2==0?-1.0:0.0;
00024     }
00025   }
00026   else if (k < n) 
00027   {
00028     return k%2==0?-1.0:1.0;
00029   }  
00030   else 
00031   {
00032     return (2.0*k+1.0) / sqrt ((k-n+1.0) * (k+n+1.0));        
00033   }
00034 }
00035 
00036 inline double beta_al(int k, int n)
00037 {
00038   if (0 <= k && k < n)
00039   {
00040     return (1.0);
00041   }
00042   else
00043   {
00044     return (0.0);
00045   }
00046 }
00047 
00048 inline double gamma_al(int k, int n)
00049 { 
00050   static int i;
00051   static double result;
00052   
00053   if (k == -1) 
00054   {
00055     /* Constant is ((2n)!)^(1/2) / (2^n n!). */
00056     result = 1.0;
00057     for (i = 1; i <= n; i++)
00058     {  
00059       result *= (n+i)/(4.0*i);                                      
00060     }  
00061     return (sqrt(result));
00062   }
00063   else if (k <= n) 
00064   {
00065     return (0.0);
00066   }
00067   else 
00068   {
00069     return (-sqrt(((double)(k-n)*(k+n))/(((k-n+1.0)*(k+n+1.0))))); 
00070   }
00071 }             
00072 
00073 inline void alpha_al_row(double *alpha, int N, int n)
00074 {
00075   int j;
00076   double *alpha_act = alpha;
00077   for (j = -1; j <= N; j++)
00078   {
00079     *alpha_act = alpha_al(j,n); 
00080     alpha_act++;
00081   }  
00082 }
00083 
00084 inline void beta_al_row(double *beta, int N, int n)
00085 {
00086   int j;
00087   double *beta_act = beta;
00088   for (j = -1; j <= N; j++)
00089   {
00090     *beta_act = beta_al(j,n); 
00091     beta_act++;
00092   }  
00093 }
00094 
00095 inline void gamma_al_row(double *gamma, int N, int n)
00096 {
00097   int j;
00098   double *gamma_act = gamma;
00099   for (j = -1; j <= N; j++)
00100   {
00101     *gamma_act = gamma_al(j,n); 
00102     gamma_act++;
00103   }  
00104 }
00105 
00106 inline void alpha_al_all(double *alpha, int N)
00107 {
00108   int i,j;
00109   double *alpha_act = alpha;
00110   for (i = 0; i <= N; i++)
00111   {
00112     for (j = -1; j <= N; j++)
00113     {
00114       *alpha_act = alpha_al(j,i); 
00115       alpha_act++;
00116     }  
00117   }  
00118 }
00119 
00120 inline void beta_al_all(double *alpha, int N)
00121 {
00122   int i,j;
00123   double *alpha_act = alpha;
00124   for (i = 0; i <= N; i++)
00125   {
00126     for (j = -1; j <= N; j++)
00127     {
00128       *alpha_act = beta_al(j,i); 
00129       alpha_act++;
00130     }  
00131   }  
00132 }
00133 
00134 inline void gamma_al_all(double *alpha, int N)
00135 {
00136   int i,j;
00137   double *alpha_act = alpha;
00138   for (i = 0; i <= N; i++)
00139   {
00140     for (j = -1; j <= N; j++)
00141     {
00142       *alpha_act = gamma_al(j,i); 
00143       alpha_act++;
00144     }  
00145   }  
00146 }
00147 
00148 inline void eval_al(double *x, double *y, int size, int k, double *alpha, 
00149   double *beta, double *gamma)
00150 {
00151   /* Evaluate the associated Legendre polynomial P_{k,nleg} (l,x) for the vector 
00152    * of knots  x[0], ..., x[size-1] by the Clenshaw algorithm
00153    */
00154   int i,j;
00155   double a,b,x_val_act,a_old;
00156   double *x_act, *y_act;  
00157   double *alpha_act, *beta_act, *gamma_act;
00158   
00159   /* Traverse all nodes. */
00160   x_act = x;
00161   y_act = y;
00162   for (i = 0; i < size; i++)
00163   {
00164     a = 1.0;
00165     b = 0.0;
00166     x_val_act = *x_act;
00167     
00168     if (k == 0)
00169     {  
00170       *y_act = 1.0;
00171     }
00172     else
00173     {
00174       alpha_act = &(alpha[k]);
00175       beta_act = &(beta[k]);
00176       gamma_act = &(gamma[k]);
00177       for (j = k; j > 1; j--)
00178       {
00179         a_old = a;
00180         a = b + a_old*((*alpha_act)*x_val_act+(*beta_act));           
00181          b = a_old*(*gamma_act);
00182         alpha_act--;
00183         beta_act--;
00184         gamma_act--;
00185       }
00186       *y_act = (a*((*alpha_act)*x_val_act+(*beta_act))+b);                  
00187     }
00188     x_act++;
00189     y_act++;
00190   }
00191 }
00192 
00193 inline int eval_al_thresh(double *x, double *y, int size, int k, double *alpha, 
00194   double *beta, double *gamma, double threshold)
00195 {
00196   /* Evaluate the associated Legendre polynomial P_{k,nleg} (l,x) for the vector 
00197    * of knots  x[0], ..., x[size-1] by the Clenshaw algorithm
00198    */
00199   int i,j;
00200   double a,b,x_val_act,a_old;
00201   double *x_act, *y_act;
00202   double *alpha_act, *beta_act, *gamma_act;
00203   
00204   /* Traverse all nodes. */
00205   x_act = x;
00206   y_act = y;
00207   for (i = 0; i < size; i++)
00208   {
00209     a = 1.0;
00210     b = 0.0;
00211     x_val_act = *x_act;
00212     
00213     if (k == 0)
00214     {  
00215      *y_act = 1.0;
00216     }
00217     else
00218     {
00219       alpha_act = &(alpha[k]);
00220       beta_act = &(beta[k]);
00221       gamma_act = &(gamma[k]);
00222       for (j = k; j > 1; j--)
00223       {
00224         a_old = a;
00225         a = b + a_old*((*alpha_act)*x_val_act+(*beta_act));           
00226          b = a_old*(*gamma_act);
00227         alpha_act--;
00228         beta_act--;
00229         gamma_act--;
00230       }
00231       *y_act = (a*((*alpha_act)*x_val_act+(*beta_act))+b);                  
00232       if (fabs(*y_act) > threshold)
00233       {
00234         return 1;
00235       }
00236     }
00237     x_act++;
00238     y_act++;
00239   }
00240   return 0;
00241 }
00242 /* \} */

Generated on 1 Nov 2006 by Doxygen 1.4.4