-
Notifications
You must be signed in to change notification settings - Fork 0
/
FastGamma.java
66 lines (61 loc) · 2.45 KB
/
FastGamma.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/**
* Copyright Johannes Kloimböck 2021 - 2022.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE or copy at
* https://www.boost.org/LICENSE_1_0.txt)
*/
public class FastGamma {
// Some useful private constants that shouldn't have to be recalculated every time.
private static final double TWOPID = Math.PI + Math.PI;
private static final float TWOPIF = (float)(TWOPID);
private static final double LOG_2D = Math.log(2.0);
private static final float LOG_2F = (float)(LOG_2D);
private static final double RECED = 1.0 / Math.E;
private static final float RECEF = (float)(RECED);
/*
* Approximates the gamma function for the double-precision input variable x.
* The greater the argument is the more precision the result is going to have.
* The function DOES NOT perform any argument checks! This is done on purpose.
*/
public static double gamma (double x) {
x = x - 1.0;
// standard Stirling formula
return Math.sqrt(TWOPID * x) * Math.pow(x * RECED, x);
}
/*
* Approximates the gamma function for the single-precision input variable x.
* The greater the argument is the more precision the result is going to have.
* The function DOES NOT perform any argument checks! This is done on purpose.
*/
public static float gamma (float x) {
x = x - 1.0f;
// standard Stirling formula
return (float)(Math.sqrt(TWOPIF * x)) * (float)(Math.pow(x * RECEF, x));
}
/*
* Approximates the natural logarithm of the gamma function for the double-precision input
* variable x. The greater the argument is the more precision the result is going to have.
* The function DOES NOT perform any argument checks! This is done on purpose.
*/
public static double logGamma (double x) {
long bits = Double.doubleToRawLongBits(x);
bits &= 0x3fffffffffffffffL;
bits >>= 52;
double log = bits;
log *= LOG_2D; // a rough estimate of the natural log of x - 1
return x * log;
}
/*
* Approximates the natural logarithm of the gamma function for the single-precision input
* variable x. The greater the argument is the more precision the result is going to have.
* The function DOES NOT perform any argument checks! This is done on purpose.
*/
public static float logGamma (float x) {
int bits = Float.floatToRawIntBits(x);
bits &= 0x3fffffff;
bits >>= 23;
float log = bits;
log *= LOG_2F; // a rough estimate of the natural log of x - 1
return x * log;
}
}