NFFT 3.6.0
lambda.c
1/*
2 * Copyright (c) 2002, 2017 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#include "infft.h"
20
21/* Coefficients for Lanzcos's approximation to the Gamma function. Can be
22 * regenerated with Mathematica from file lambda.nb. */
23
24 #if MANT_DIG == 113
25 // IEEE 754 quadruple precision, 128 bits.
26 #define N 24
27 static const R num[24] =
28 {
29 K(3.035162425359883494754028782232869726547E21),
30 K(3.4967568944064301036001605717507506346E21),
31 K(1.9266526566893208886540195401514595829E21),
32 K(6.755170664882727663160830237424406199E20),
33 K(1.691728531049187527800862627495648317E20),
34 K(3.21979351672256057856444116302160246E19),
35 K(4.8378495427140832493758744745481812E18),
36 K(5.8843103809049324230843820398664955E17),
37 K(5.893958514163405862064178891925630E16),
38 K(4.919561837722192829918665308020810E15),
39 K(3.449165802442404074427531228315120E14),
40 K(2.041330296068782505988459692384726E13),
41 K(1.022234822943784007524609706893119E12),
42 K(4.33137871919821354846952908076307E10),
43 K(1.54921950559667418528481770869280E9),
44 K(4.6544421199876191938054157935810E7),
45 K(1.16527806807504975090675074910053E6),
46 K(24024.759267256769471083727721827),
47 K(400.96500811342195582435806376976),
48 K(5.2829901565447826961703902917085),
49 K(0.05289990244125101024092566765994),
50 K(0.0003783467106547406854542665695934),
51 K(1.7219414217921113919596660801124E-6),
52 K(3.747999317071488557713812635427084359354E-9)
53 };
54 static const R g = K(20.32098218798637390136718750000000000000);
55#elif MANT_DIG == 64
56// Intel double extended, 80 bits.
57 #define N 17
58 static const R num[17] =
59 {
60 K(2.715894658327717377557655133124376674911E12),
61 K(3.59017952609791210503852552872112955043E12),
62 K(2.22396659973781496931212735323581871017E12),
63 K(8.5694083451895624818099258668254858834E11),
64 K(2.2988587166874907293359744645339939547E11),
65 K(4.552617168754610815813502794395753410E10),
66 K(6.884887713165178784550917647709216425E9),
67 K(8.11048596140753186476028245385237278E8),
68 K(7.52139159654082231449961362311950170E7),
69 K(5.50924541722426515169752795795495283E6),
70 K(317673.536843541912671493184218236957),
71 K(14268.2798984503552014701437332033752),
72 K(489.361872040326367021390908360178781),
73 K(12.3894133003845444929588321786545861),
74 K(0.218362738950461496394157450728168315),
75 K(0.00239374952205844918669062799606398310),
76 K(0.00001229541408909435212800785616808830746135)
77 };
78 static const R g = K(12.22522273659706115722656250000000000000);
79#elif MANT_DIG == 53
80 // IEEE 754 double precision, 64 bits.
81 #define N 13
82 static const R num[13] =
83 {
84 K(5.690652191347156388090791033559122686859E7),
85 K(1.037940431163445451906271053616070238554E8),
86 K(8.63631312881385914554692728897786842234E7),
87 K(4.33388893246761383477372374059053331609E7),
88 K(1.46055780876850680841416998279135921857E7),
89 K(3.48171215498064590882071018964774556468E6),
90 K(601859.61716810987866702265336993523025),
91 K(75999.293040145426498753034435989091371),
92 K(6955.9996025153761403563101155151989875),
93 K(449.944556906316811944685860765098840962),
94 K(19.5199278824761748284786096623565213621),
95 K(0.509841665565667618812517864480469450999),
96 K(0.006061842346248906525783753964555936883222)
97 };
98 static const R g = K(6.024680040776729583740234375000000000000);
99#elif MANT_DIG == 24
100 // IEEE 754 single precision, 32 bits.
101 #define N 6
102 static const R num[6] =
103 {
104 K(14.02614328749964766195705772850038393570),
105 K(43.74732405540314316089531289293124360129),
106 K(50.59547402616588964511581430025589038612),
107 K(26.90456680562548195593733429204228910299),
108 K(6.595765571169314946316366571954421695196),
109 K(0.6007854010515290065101128585795542383721)
110 };
111 static const R g = K(1.428456135094165802001953125000000000000);
112#else
113 // Unknown floating-point type.
114 // Assume IEEE 754 double precision, 64 bits.
115 #define N 13
116 static const R num[13] =
117 {
118 K(5.690652191347156388090791033559122686859E7),
119 K(1.037940431163445451906271053616070238554E8),
120 K(8.63631312881385914554692728897786842234E7),
121 K(4.33388893246761383477372374059053331609E7),
122 K(1.46055780876850680841416998279135921857E7),
123 K(3.48171215498064590882071018964774556468E6),
124 K(601859.61716810987866702265336993523025),
125 K(75999.293040145426498753034435989091371),
126 K(6955.9996025153761403563101155151989875),
127 K(449.944556906316811944685860765098840962),
128 K(19.5199278824761748284786096623565213621),
129 K(0.509841665565667618812517864480469450999),
130 K(0.006061842346248906525783753964555936883222)
131 };
132 static const R g = K(6.024680040776729583740234375000000000000);
133#endif
134
135static inline R evaluate_rational(const R z_)
136{
137 R z = z_, s1, s2;
138 INT i;
139
140 if (z <= K(1.0))
141 {
142 s1 = num[N - 1];
143 s2 = K(1.0);
144 for (i = N - 2; i >= 0; --i)
145 {
146 s1 *= z;
147 s2 *= z + (R)(i);
148 s1 += num[i];
149 }
150 }
151 else
152 {
153 z = K(1.0)/z;
154 s1 = num[0];
155 s2 = K(1.0);
156 for (i = 1; i < N; ++i)
157 {
158 s1 *= z;
159 s2 *= K(1.0) + (R)(i-1) * z;
160 s1 += num[i];
161 }
162 }
163 return s1 / s2;
164}
165
166R Y(lambda)(const R z, const R eps)
167{
168 const R d = K(1.0) - eps, zpg = z + g, emh = eps - K(0.5);
169 return EXP(-LOG1P(d / (zpg + emh)) * (z + emh)) *
170 POW(KE / (zpg + K(0.5)),d) *
171 (evaluate_rational(z + eps) / evaluate_rational(z + K(1.0)));
172}
173
174R Y(lambda2)(const R mu, const R nu)
175{
176 if (mu == K(0.0))
177 return K(1.0);
178 else if (nu == K(0.0))
179 return K(1.0);
180 else
181 return
182 SQRT(
183 POW((mu + nu + g + K(0.5)) / (K(1.0) * (mu + g + K(0.5))), mu) *
184 POW((mu + nu + g + K(0.5)) / (K(1.0) * (nu + g + K(0.5))), nu) *
185 SQRT(KE * (mu + nu + g + K(0.5)) /
186 ((mu + g + K(0.5)) * (nu + g + K(0.5)))) *
187 (evaluate_rational(mu + nu + K(1.0)) /
188 (evaluate_rational(mu + K(1.0)) * evaluate_rational(nu + K(1.0))))
189 );
190}
Internal header file for auxiliary definitions and functions.