63 lines
2.2 KiB
D
63 lines
2.2 KiB
D
import std.stdio, std.math, std.mathspecial;
|
|
|
|
real taylorGamma(in real x) pure nothrow @safe @nogc {
|
|
static immutable real[30] table = [
|
|
0x1p+0, 0x1.2788cfc6fb618f4cp-1,
|
|
-0x1.4fcf4026afa2dcecp-1, -0x1.5815e8fa27047c8cp-5,
|
|
0x1.5512320b43fbe5dep-3, -0x1.59af103c340927bep-5,
|
|
-0x1.3b4af28483e214e4p-7, 0x1.d919c527f60b195ap-8,
|
|
-0x1.317112ce3a2a7bd2p-10, -0x1.c364fe6f1563ce9cp-13,
|
|
0x1.0c8a78cd9f9d1a78p-13, -0x1.51ce8af47eabdfdcp-16,
|
|
-0x1.4fad41fc34fbb2p-20, 0x1.302509dbc0de2c82p-20,
|
|
-0x1.b9986666c225d1d4p-23, 0x1.a44b7ba22d628acap-28,
|
|
0x1.57bc3fc384333fb2p-28, -0x1.44b4cedca388f7c6p-30,
|
|
0x1.cae7675c18606c6p-34, 0x1.11d065bfaf06745ap-37,
|
|
-0x1.0423bac8ca3faaa4p-38, 0x1.1f20151323cd0392p-41,
|
|
-0x1.72cb88ea5ae6e778p-46, -0x1.815f72a05f16f348p-48,
|
|
0x1.6198491a83bccbep-50, -0x1.10613dde57a88bd6p-53,
|
|
0x1.5e3fee81de0e9c84p-60, 0x1.a0dc770fb8a499b6p-60,
|
|
-0x1.0f635344a29e9f8ep-62, 0x1.43d79a4b90ce8044p-66];
|
|
|
|
immutable real y = x - 1.0L;
|
|
real sm = table[$ - 1];
|
|
foreach_reverse (immutable an; table[0 .. $ - 1])
|
|
sm = sm * y + an;
|
|
return 1.0L / sm;
|
|
}
|
|
|
|
real lanczosGamma(real z) pure nothrow @safe @nogc {
|
|
// Coefficients used by the GNU Scientific Library.
|
|
// http://en.wikipedia.org/wiki/Lanczos_approximation
|
|
enum g = 7;
|
|
static immutable real[9] table =
|
|
[ 0.99999_99999_99809_93,
|
|
676.52036_81218_851,
|
|
-1259.13921_67224_028,
|
|
771.32342_87776_5313,
|
|
-176.61502_91621_4059,
|
|
12.50734_32786_86905,
|
|
-0.13857_10952_65720_12,
|
|
9.98436_95780_19571_6e-6,
|
|
1.50563_27351_49311_6e-7];
|
|
|
|
// Reflection formula.
|
|
if (z < 0.5L) {
|
|
return PI / (sin(PI * z) * lanczosGamma(1 - z));
|
|
} else {
|
|
z -= 1;
|
|
real x = table[0];
|
|
foreach (immutable i; 1 .. g + 2)
|
|
x += table[i] / (z + i);
|
|
immutable real t = z + g + 0.5L;
|
|
return sqrt(2 * PI) * t ^^ (z + 0.5L) * exp(-t) * x;
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
foreach (immutable i; 1 .. 11) {
|
|
immutable real x = i / 3.0L;
|
|
writefln("%f: %20.19e %20.19e %20.19e", x,
|
|
x.taylorGamma, x.lanczosGamma, x.gamma);
|
|
}
|
|
}
|