NFFT Logo 3.2.3
lambda.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: util.c 3483 2010-04-23 19:02:34Z keiner $ */
20 
21 #include "infft.h"
22 
23 /* Coefficients for Lanzcos's approximation to the Gamma function. Can be
24  * regenerated with Mathematica from file lambda.nb. */
25 
26 #if defined(NFFT_LDOUBLE)
27  #if LDBL_MANT_DIG > 64
28  /* long double 128 bit wide */
29  #define N 24
30  static const R num[24] =
31  {
32  K(3.035162425359883494754028782232869726547E21),
33  K(3.4967568944064301036001605717507506346E21),
34  K(1.9266526566893208886540195401514595829E21),
35  K(6.755170664882727663160830237424406199E20),
36  K(1.691728531049187527800862627495648317E20),
37  K(3.21979351672256057856444116302160246E19),
38  K(4.8378495427140832493758744745481812E18),
39  K(5.8843103809049324230843820398664955E17),
40  K(5.893958514163405862064178891925630E16),
41  K(4.919561837722192829918665308020810E15),
42  K(3.449165802442404074427531228315120E14),
43  K(2.041330296068782505988459692384726E13),
44  K(1.022234822943784007524609706893119E12),
45  K(4.33137871919821354846952908076307E10),
46  K(1.54921950559667418528481770869280E9),
47  K(4.6544421199876191938054157935810E7),
48  K(1.16527806807504975090675074910053E6),
49  K(24024.759267256769471083727721827),
50  K(400.96500811342195582435806376976),
51  K(5.2829901565447826961703902917085),
52  K(0.05289990244125101024092566765994),
53  K(0.0003783467106547406854542665695934),
54  K(1.7219414217921113919596660801124E-6),
55  K(3.747999317071488557713812635427084359354E-9)
56  };
57 /* static const R denom[24] =
58  {
59  K(0.0),
60  K(1124000727777607680000.0),
61  K(4148476779335454720000.0),
62  K(6756146673770930688000.0),
63  K(6548684852703068697600.0),
64  K(4280722865357147142912.0),
65  K(2021687376910682741568.0),
66  K(720308216440924653696.0),
67  K(199321978221066137360.0),
68  K(43714229649594412832.0),
69  K(7707401101297361068.0),
70  K(1103230881185949736.0),
71  K(129006659818331295.0),
72  K(12363045847086207.0),
73  K(971250460939913.0),
74  K(62382416421941.0),
75  K(3256091103430.0),
76  K(136717357942.0),
77  K(4546047198.0),
78  K(116896626.0),
79  K(2240315.0),
80  K(30107.0),
81  K(253.0),
82  K(1.0L)
83  };*/
84  static const R g = K(20.32098218798637390136718750000000000000);
85  #elif LDBL_MANT_DIG == 64
86  /* long double 96 bit wide */
87  #define N 17
88  static const R num[17] =
89  {
90  K(2.715894658327717377557655133124376674911E12),
91  K(3.59017952609791210503852552872112955043E12),
92  K(2.22396659973781496931212735323581871017E12),
93  K(8.5694083451895624818099258668254858834E11),
94  K(2.2988587166874907293359744645339939547E11),
95  K(4.552617168754610815813502794395753410E10),
96  K(6.884887713165178784550917647709216425E9),
97  K(8.11048596140753186476028245385237278E8),
98  K(7.52139159654082231449961362311950170E7),
99  K(5.50924541722426515169752795795495283E6),
100  K(317673.536843541912671493184218236957),
101  K(14268.2798984503552014701437332033752),
102  K(489.361872040326367021390908360178781),
103  K(12.3894133003845444929588321786545861),
104  K(0.218362738950461496394157450728168315),
105  K(0.00239374952205844918669062799606398310),
106  K(0.00001229541408909435212800785616808830746135)
107  };
108 /* static const R denom[17] =
109  {
110  K(0.0),
111  K(1307674368000.0),
112  K(4339163001600.0),
113  K(6165817614720.0),
114  K(5056995703824.0),
115  K(2706813345600.0),
116  K(1009672107080.0),
117  K(272803210680.0),
118  K(54631129553.0),
119  K(8207628000.0),
120  K(928095740.0),
121  K(78558480.0),
122  K(4899622.0),
123  K(218400.0),
124  K(6580.0),
125  K(120.0),
126  K(1.0L)
127  };*/
128  static const R g = K(12.22522273659706115722656250000000000000);
129  #else
130  #error Unsupported size of long double
131  #endif
132 #elif defined(NFFT_SINGLE)
133  /* float */
134  #define N 6
135  static const R num[6] =
136  {
137  K(14.02614328749964766195705772850038393570),
138  K(43.74732405540314316089531289293124360129),
139  K(50.59547402616588964511581430025589038612),
140  K(26.90456680562548195593733429204228910299),
141  K(6.595765571169314946316366571954421695196),
142  K(0.6007854010515290065101128585795542383721)
143  };
144 /* static const R denom[6] =
145  {
146  K(0.0),
147  K(24.0),
148  K(50.0),
149  K(35.0),
150  K(10.0),
151  K(1.0)
152  };*/
153  static const R g = K(1.428456135094165802001953125000000000000);
154 #else
155  /* double */
156  #define N 13
157  static const R num[13] =
158  {
159  K(5.690652191347156388090791033559122686859E7),
160  K(1.037940431163445451906271053616070238554E8),
161  K(8.63631312881385914554692728897786842234E7),
162  K(4.33388893246761383477372374059053331609E7),
163  K(1.46055780876850680841416998279135921857E7),
164  K(3.48171215498064590882071018964774556468E6),
165  K(601859.61716810987866702265336993523025),
166  K(75999.293040145426498753034435989091371),
167  K(6955.9996025153761403563101155151989875),
168  K(449.944556906316811944685860765098840962),
169  K(19.5199278824761748284786096623565213621),
170  K(0.509841665565667618812517864480469450999),
171  K(0.006061842346248906525783753964555936883222)
172  };
173 /* static const R denom[13] =
174  {
175  K(0.0),
176  K(39916800.0),
177  K(120543840.0),
178  K(150917976.0),
179  K(105258076.0),
180  K(45995730.0),
181  K(13339535.0),
182  K(2637558.0),
183  K(357423.0),
184  K(32670.0),
185  K(1925.0),
186  K(66.0),
187  K(1.0)
188  };*/
189  static const R g = K(6.024680040776729583740234375000000000000);
190 #endif
191 
192 static inline R evaluate_rational(const R z_)
193 {
194  R z = z_, s1, s2;
195  int i;
196 
197  if (z <= K(1.0))
198  {
199  s1 = num[N - 1];
200  s2 = K(1.0);
201  for (i = N - 2; i >= 0; --i)
202  {
203  s1 *= z;
204  s2 *= (z + i);
205  s1 += num[i];
206  }
207  }
208  else
209  {
210  z = K(1.0)/z;
211  s1 = num[0];
212  s2 = K(1.0);
213  for (i = 1; i < N; ++i)
214  {
215  s1 *= z;
216  s2 *= K(1.0) + (i-1)*z;
217  s1 += num[i];
218  }
219  }
220  return s1 / s2;
221 }
222 
223 R X(lambda)(const R z, const R eps)
224 {
225  const R d = K(1.0) - eps, zpg = z + g, emh = eps - K(0.5);
226  return EXP(-LOG1P(d / (zpg + emh)) * (z + emh)) *
227  POW(KE / (zpg + K(0.5)),d) *
228  (evaluate_rational(z + eps) / evaluate_rational(z + K(1.0)));
229 }
230 
231 R X(lambda2)(const R mu, const R nu)
232 {
233  if (mu == K(0.0))
234  return K(1.0);
235  else if (nu == K(0.0))
236  return K(1.0);
237  else
238  return
239  SQRT(
240  POW((mu + nu + g + K(0.5)) / (K(1.0) * (mu + g + K(0.5))), mu) *
241  POW((mu + nu + g + K(0.5)) / (K(1.0) * (nu + g + K(0.5))), nu) *
242  SQRT(KE * (mu + nu + g + K(0.5)) /
243  ((mu + g + K(0.5)) * (nu + g + K(0.5)))) *
244  (evaluate_rational(mu + nu + K(1.0)) /
245  (evaluate_rational(mu + K(1.0)) * evaluate_rational(nu + K(1.0))))
246  );
247 }

Generated on Tue Apr 30 2013 by Doxygen 1.8.1