blob: 3f18410218e6d6500a4790d48539b94e2b292bd5 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.numbers.gamma;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
/**
* Tests for {@link LogGamma}.
*/
class LogGammaTest {
/**
* Reference data for the {@link Gamma#logGamma(double)} function. This data
* was generated with the following <a
* href="http://maxima.sourceforge.net/">Maxima</a> script.
*
* <pre>
* kill(all);
*
* fpprec : 64;
* gamln(x) := log(gamma(x));
* x : append(makelist(bfloat(i / 8), i, 1, 80),
* [0.8b0, 1b2, 1b3, 1b4, 1b5, 1b6, 1b7, 1b8, 1b9, 1b10]);
*
* for i : 1 while i <= length(x) do
* print("{", float(x[i]), ",", float(gamln(x[i])), "},");
* </pre>
*/
private static final double[][] LOG_GAMMA_REF = {
{0.125, 2.019418357553796},
{0.25, 1.288022524698077},
{0.375, .8630739822706475},
{0.5, .5723649429247001},
{0.625, .3608294954889402},
{0.75, .2032809514312954},
{0.875, .08585870722533433},
{0.890625, .07353860936979656},
{0.90625, .06169536624059108},
{0.921875, .05031670080005688},
{0.9375, 0.0393909017345823},
{0.953125, .02890678734595923},
{0.96875, .01885367233441289},
{0.984375, .009221337197578781},
{1.0, 0.0},
{1.015625, -0.00881970970573307},
{1.03125, -.01724677500176807},
{1.046875, -.02528981394675729},
{1.0625, -.03295710029357782},
{1.078125, -.04025658272400143},
{1.09375, -.04719590272716985},
{1.109375, -.05378241123619192},
{1.125, -.06002318412603958},
{1.25, -.09827183642181316},
{1.375, -.1177552707410788},
{1.5, -.1207822376352452},
{1.625, -.1091741337567954},
{1.75, -.08440112102048555},
{1.875, -0.0476726853991883},
{1.890625, -.04229320615532515},
{1.90625, -.03674470657266143},
{1.921875, -.03102893865389552},
{1.9375, -.02514761940298887},
{1.953125, -.01910243184040138},
{1.96875, -.01289502598016741},
{1.984375, -.006527019770560387},
{2.0, 0.0},
{2.015625, .006684476830232185},
{2.03125, .01352488366498562},
{2.046875, .02051972208453692},
{2.0625, .02766752152285702},
{2.078125, 0.0349668385135861},
{2.09375, .04241625596251728},
{2.109375, .05001438244545164},
{2.125, .05775985153034387},
{2.25, .1248717148923966},
{2.375, .2006984603774558},
{2.5, .2846828704729192},
{2.625, .3763336820249054},
{2.75, .4752146669149371},
{2.875, .5809359740231859},
{2.890625, .5946142560817441},
{2.90625, .6083932548009232},
{2.921875, .6222723333588501},
{2.9375, .6362508628423761},
{2.953125, .6503282221022278},
{2.96875, .6645037976116387},
{2.984375, 0.678776983328359},
{3.0, .6931471805599453},
{3.015625, .7076137978322324},
{3.03125, .7221762507608962},
{3.046875, .7368339619260166},
{3.0625, 0.751586360749556},
{3.078125, .7664328833756681},
{3.09375, .7813729725537568},
{3.109375, .7964060775242092},
{3.125, 0.811531653906724},
{3.25, .9358019311087253},
{3.375, 1.06569589786406},
{3.5, 1.200973602347074},
{3.625, 1.341414578068493},
{3.75, 1.486815578593417},
{3.875, 1.6369886482725},
{4.0, 1.791759469228055},
{4.125, 1.950965937095089},
{4.25, 2.114456927450371},
{4.375, 2.282091222188554},
{4.5, 2.453736570842442},
{4.625, 2.62926886637513},
{4.75, 2.808571418575736},
{4.875, 2.99153431107781},
{5.0, 3.178053830347946},
{5.125, 3.368031956881733},
{5.25, 3.561375910386697},
{5.375, 3.757997741998131},
{5.5, 3.957813967618717},
{5.625, 4.160745237339519},
{5.75, 4.366716036622286},
{5.875, 4.57565441552762},
{6.0, 4.787491742782046},
{6.125, 5.002162481906205},
{6.25, 5.219603986990229},
{6.375, 5.439756316011858},
{6.5, 5.662562059857142},
{6.625, 5.887966185430003},
{6.75, 6.115915891431546},
{6.875, 6.346360475557843},
{7.0, 6.579251212010101},
{7.125, 6.814541238336996},
{7.25, 7.05218545073854},
{7.375, 7.292140407056348},
{7.5, 7.534364236758733},
{7.625, 7.778816557302289},
{7.75, 8.025458396315983},
{7.875, 8.274252119110479},
{8.0, 8.525161361065415},
{8.125, 8.77815096449171},
{8.25, 9.033186919605123},
{8.375, 9.290236309282232},
{8.5, 9.549267257300997},
{8.625, 9.810248879795765},
{8.75, 10.07315123968124},
{8.875, 10.33794530382217},
{9.0, 10.60460290274525},
{9.125, 10.87309669270751},
{9.25, 11.14340011995171},
{9.375, 11.41548738699336},
{9.5, 11.68933342079727},
{9.625, 11.96491384271319},
{9.75, 12.24220494005076},
{9.875, 12.52118363918365},
{10.0, 12.80182748008147},
{0.8, .1520596783998376},
{100.0, 359.1342053695754},
{1000.0, 5905.220423209181},
{10000.0, 82099.71749644238},
{100000.0, 1051287.708973657},
{1000000.0, 1.2815504569147612e+7},
{10000000.0, 1.511809493694739e+8},
{1.e+8, 1.7420680661038346e+9},
{1.e+9, 1.972326582750371e+10},
{1.e+10, 2.202585092888106e+11},
};
@Test
void testLogGammaNan() {
testLogGamma(Double.NaN, Double.NaN);
}
@Test
void testLogGammaNegative() {
testLogGamma(Double.NaN, -1.0);
}
@Test
void testLogGammaZero() {
testLogGamma(Double.NaN, 0.0);
}
@Test
void testLogGammaPositive() {
testLogGamma(0.6931471805599457, 3.0);
}
@Test
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 = LogGamma.value(x);
final double tol;
if (expected == 0.0) {
tol = 1E-15;
} else {
tol = ulps * Math.ulp(expected);
}
Assertions.assertEquals(expected, actual, tol, Double.toString(x));
}
}
@Test
void testLogGammaPrecondition1() {
Assertions.assertTrue(Double.isNaN(LogGamma.value(0.0)));
}
@Test
void testLogGammaPrecondition2() {
Assertions.assertTrue(Double.isNaN(LogGamma.value(-1.0)));
}
private void testLogGamma(double expected, double x) {
double actual = LogGamma.value(x);
Assertions.assertEquals(expected, actual, 1e-15);
}
}