Gamma { public static double logGamma(double x) { double ret; if (Double.isNaN(x) || (x <= 0.0)) { ret = Double.NaN; } else if (x < 0.5) { return logGamma1p(x) - FastMath.log(x); } else if (x <= 2.5) { return logGamma1p((x - 0.5) - 0.5); } else if (x <= 8.0) { final int n = (int) FastMath.floor(x - 1.5); double prod = 1.0; for (int i = 1; i <= n; i++) { prod *= x - i; } return logGamma1p(x - (n + 1)) + FastMath.log(prod); } else { double sum = lanczos(x); double tmp = x + LANCZOS_G + .5; ret = ((x + .5) * FastMath.log(tmp)) - tmp + HALF_LOG_2_PI + FastMath.log(sum / x); } return ret; } private  Gamma(); static double logGamma(double x); static double regularizedGammaP(double a, double x); static double regularizedGammaP(double a,
                                           double x,
                                           double epsilon,
                                           int maxIterations); static double regularizedGammaQ(double a, double x); static double regularizedGammaQ(final double a,
                                           double x,
                                           double epsilon,
                                           int maxIterations); static double digamma(double x); static double trigamma(double x); static double lanczos(final double x); static double invGamma1pm1(final double x); static double logGamma1p(final double x); static double gamma(final double x); static final double GAMMA; static final double LANCZOS_G; }
@Test public void testLogGamma() { final int ulps = 3; for (int i = 0; i < LOG_GAMMA_REF.length; i++) { final double[] data = LOG_GAMMA_REF[i]; final double x = data[0]; final double expected = data[1]; final double actual = Gamma.logGamma(x); final double tol; if (expected == 0.0) { tol = 1E-15; } else { tol = ulps * FastMath.ulp(expected); } Assert.assertEquals(Double.toString(x), expected, actual, tol); } }
@Test public void testLogGammaPrecondition1() { Assert.assertTrue(Double.isNaN(Gamma.logGamma(0.0))); }
@Test public void testLogGammaPrecondition2() { Assert.assertTrue(Double.isNaN(Gamma.logGamma(-1.0))); }