NFFT Logo 3.2.3
legendre.c
1 /*
2  * Copyright (c) 2002, 2012 Jens Keiner, Stefan Kunis, Daniel Potts
3  *
4  * This program is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU General Public License as published by the Free Software
6  * Foundation; either version 2 of the License, or (at your option) any later
7  * version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc., 51
16  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 /* $Id: legendre.c 3896 2012-10-10 12:19:26Z tovo $ */
20 
21 #include <math.h>
22 #include <stdio.h>
23 #include "infft.h"
24 #include "nfft3util.h"
25 #include "legendre.h"
26 
27 /* One over sqrt(pi) */
28 DK(KSQRTPII,0.56418958354775628694807945156077258584405062932900);
29 
30 static inline R alpha_al(const int k, const int n)
31 {
32  if (k > 0)
33  {
34  if (k < n)
35  return IF(k%2,K(1.0),K(-1.0));
36  else
37  return SQRT(((R)(2*k+1))/((R)(k-n+1)))*SQRT((((R)(2*k+1))/((R)(k+n+1))));
38  }
39  else if (k == 0)
40  {
41  if (n == 0)
42  return K(1.0);
43  else
44  return IF(n%2,K(0.0),K(-1.0));
45  }
46  return K(0.0);
47 }
48 
49 static inline R beta_al(const int k, const int n)
50 {
51  if (0 <= k && k < n)
52  return K(1.0);
53  else
54  return K(0.0);
55 }
56 
57 static inline R gamma_al(const int k, const int n)
58 {
59  if (k == -1)
60  return SQRT(KSQRTPII*nfft_lambda((R)(n),K(0.5)));
61  else if (k <= n)
62  return K(0.0);
63  else
64  return -SQRT(((R)(k-n))/((R)(k-n+1))*((R)(k+n))/((R)(k+n+1)));
65 }
66 
67 void alpha_al_row(R *alpha, const int N, const int n)
68 {
69  int j;
70  R *p = alpha;
71  for (j = -1; j <= N; j++)
72  *p++ = alpha_al(j,n);
73 }
74 
75 void beta_al_row(R *beta, const int N, const int n)
76 {
77  int j;
78  R *p = beta;
79  for (j = -1; j <= N; j++)
80  *p++ = beta_al(j,n);
81 }
82 
83 void gamma_al_row(R *gamma, const int N, const int n)
84 {
85  int j;
86  R *p = gamma;
87  for (j = -1; j <= N; j++)
88  *p++ = gamma_al(j,n);
89 }
90 
91 inline void alpha_al_all(R *alpha, const int N)
92 {
93  int i,j;
94  R *p = alpha;
95  for (i = 0; i <= N; i++)
96  for (j = -1; j <= N; j++)
97  *p++ = alpha_al(j,i);
98 }
99 
100 inline void beta_al_all(R *alpha, const int N)
101 {
102  int i,j;
103  R *p = alpha;
104  for (i = 0; i <= N; i++)
105  for (j = -1; j <= N; j++)
106  *p++ = beta_al(j,i);
107 }
108 
109 inline void gamma_al_all(R *alpha, const int N)
110 {
111  int i,j;
112  R *p = alpha;
113  for (i = 0; i <= N; i++)
114  for (j = -1; j <= N; j++)
115  *p++ = gamma_al(j,i);
116 }
117 
118 void eval_al(R *x, R *y, const int size, const int k, R *alpha,
119  R *beta, R *gamma)
120 {
121  /* Evaluate the associated Legendre polynomial P_{k,nleg} (l,x) for the vector
122  * of knots x[0], ..., x[size-1] by the Clenshaw algorithm
123  */
124  int i,j;
125  R a,b,x_val_act,a_old;
126  R *x_act, *y_act;
127  R *alpha_act, *beta_act, *gamma_act;
128 
129  /* Traverse all nodes. */
130  x_act = x;
131  y_act = y;
132  for (i = 0; i < size; i++)
133  {
134  a = 1.0;
135  b = 0.0;
136  x_val_act = *x_act;
137 
138  if (k == 0)
139  {
140  *y_act = 1.0;
141  }
142  else
143  {
144  alpha_act = &(alpha[k]);
145  beta_act = &(beta[k]);
146  gamma_act = &(gamma[k]);
147  for (j = k; j > 1; j--)
148  {
149  a_old = a;
150  a = b + a_old*((*alpha_act)*x_val_act+(*beta_act));
151  b = a_old*(*gamma_act);
152  alpha_act--;
153  beta_act--;
154  gamma_act--;
155  }
156  *y_act = (a*((*alpha_act)*x_val_act+(*beta_act))+b);
157  }
158  x_act++;
159  y_act++;
160  }
161 }
162 
163 int eval_al_thresh(R *x, R *y, const int size, const int k, R *alpha,
164  R *beta, R *gamma, R threshold)
165 {
166  /* Evaluate the associated Legendre polynomial P_{k,nleg} (l,x) for the vector
167  * of knots x[0], ..., x[size-1] by the Clenshaw algorithm
168  */
169  int i,j;
170  R a,b,x_val_act,a_old;
171  R *x_act, *y_act;
172  R *alpha_act, *beta_act, *gamma_act;
173 
174  /* Traverse all nodes. */
175  x_act = x;
176  y_act = y;
177  for (i = 0; i < size; i++)
178  {
179  a = 1.0;
180  b = 0.0;
181  x_val_act = *x_act;
182 
183  if (k == 0)
184  {
185  *y_act = 1.0;
186  }
187  else
188  {
189  alpha_act = &(alpha[k]);
190  beta_act = &(beta[k]);
191  gamma_act = &(gamma[k]);
192  for (j = k; j > 1; j--)
193  {
194  a_old = a;
195  a = b + a_old*((*alpha_act)*x_val_act+(*beta_act));
196  b = a_old*(*gamma_act);
197  alpha_act--;
198  beta_act--;
199  gamma_act--;
200  }
201  *y_act = (a*((*alpha_act)*x_val_act+(*beta_act))+b);
202  if (fabs(*y_act) > threshold)
203  {
204  return 1;
205  }
206  }
207  x_act++;
208  y_act++;
209  }
210  return 0;
211 }

Generated on Tue Apr 30 2013 by Doxygen 1.8.1