blob: be1635d9af5ef20967991bb76b3bce9a14e23398 [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.statistics.distribution;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Test cases for TDistribution.
* Extends ContinuousDistributionAbstractTest. See class javadoc for
* ContinuousDistributionAbstractTest for details.
*/
class TDistributionTest extends ContinuousDistributionAbstractTest {
//---------------------- Override tolerance --------------------------------
@BeforeEach
void customSetUp() {
setTolerance(1e-9);
}
//-------------- Implementations for abstract methods ----------------------
@Override
public TDistribution makeDistribution() {
return new TDistribution(5.0);
}
@Override
public double[] makeCumulativeTestPoints() {
// quantiles computed using R version 2.9.2
return new double[] {-5.89342953136, -3.36492999891, -2.57058183564, -2.01504837333, -1.47588404882,
5.89342953136, 3.36492999891, 2.57058183564, 2.01504837333, 1.47588404882};
}
@Override
public double[] makeCumulativeTestValues() {
return new double[] {0.001, 0.01, 0.025, 0.05, 0.1, 0.999,
0.990, 0.975, 0.950, 0.900};
}
@Override
public double[] makeDensityTestValues() {
return new double[] {0.000756494565517, 0.0109109752919, 0.0303377878006, 0.0637967988952, 0.128289492005,
0.000756494565517, 0.0109109752919, 0.0303377878006, 0.0637967988952, 0.128289492005};
}
@Override
public double[] makeCumulativePrecisionTestPoints() {
return new double[] {-4200, -6400};
}
@Override
public double[] makeCumulativePrecisionTestValues() {
// These were created using WolframAlpha
return new double[] {7.261513520181652e-18, 8.838404680725267e-19};
}
@Override
public double[] makeSurvivalPrecisionTestPoints() {
return new double[] {4200, 6400};
}
@Override
public double[] makeSurvivalPrecisionTestValues() {
// These were created using WolframAlpha
return new double[] {7.261513520181652e-18, 8.838404680725267e-19};
}
//-------------------- Additional test cases -------------------------------
/**
* @see <a href="https://issues.apache.orgg/bugzilla/show_bug.cgi?id=27243">
* Bug report that prompted this unit test.</a>
*/
@Test
void testCumulativeProbabilityAgainstStackOverflow() {
Assertions.assertDoesNotThrow(() -> {
final TDistribution td = new TDistribution(5.);
td.cumulativeProbability(.1);
td.cumulativeProbability(.01);
});
}
@Test
void testSmallDf() {
setDistribution(new TDistribution(1d));
// quantiles computed using R version 2.9.2
setCumulativeTestPoints(new double[] {-318.308838986, -31.8205159538, -12.7062047362,
-6.31375151468, -3.07768353718, 318.308838986,
31.8205159538, 12.7062047362, 6.31375151468,
3.07768353718});
setDensityTestValues(new double[] {3.14158231817e-06, 0.000314055924703, 0.00195946145194,
0.00778959736375, 0.0303958893917, 3.14158231817e-06,
0.000314055924703, 0.00195946145194, 0.00778959736375,
0.0303958893917});
setInverseCumulativeTestValues(getCumulativeTestPoints());
verifyCumulativeProbabilities();
verifyInverseCumulativeProbabilities();
verifyDensities();
}
@Test
void testInverseCumulativeProbabilityExtremes() {
setInverseCumulativeTestPoints(new double[] {0, 1});
setInverseCumulativeTestValues(new double[] {Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY});
verifyInverseCumulativeProbabilities();
}
@Test
void testCumulativeProbablilityExtremes() {
TDistribution dist;
for (int i = 1; i < 11; i++) {
dist = new TDistribution(i * 5);
Assertions.assertEquals(1,
dist.cumulativeProbability(Double.POSITIVE_INFINITY), Double.MIN_VALUE);
Assertions.assertEquals(0,
dist.cumulativeProbability(Double.NEGATIVE_INFINITY), Double.MIN_VALUE);
}
}
@Test
void testParameterAccessors() {
final TDistribution dist = makeDistribution();
Assertions.assertEquals(5d, dist.getDegreesOfFreedom());
}
@Test
void testConstructorPrecondition1() {
Assertions.assertThrows(DistributionException.class, () -> new TDistribution(0));
}
@Test
void testMoments() {
final double tol = 1e-9;
TDistribution dist;
dist = new TDistribution(1);
Assertions.assertTrue(Double.isNaN(dist.getMean()));
Assertions.assertTrue(Double.isNaN(dist.getVariance()));
dist = new TDistribution(1.5);
Assertions.assertEquals(0, dist.getMean(), tol);
Assertions.assertEquals(Double.POSITIVE_INFINITY, dist.getVariance());
dist = new TDistribution(5);
Assertions.assertEquals(0, dist.getMean(), tol);
Assertions.assertEquals(5d / (5d - 2d), dist.getVariance(), tol);
}
/*
* Adding this test to benchmark against tables published by NIST
* http://itl.nist.gov/div898/handbook/eda/section3/eda3672.htm
* Have chosen tabulated results for degrees of freedom 2,10,30,100
* Have chosen problevels from 0.10 to 0.001
*/
@Test
void nistData() {
final double[] prob = new double[]{0.10, 0.05, 0.025, 0.01, 0.005, 0.001};
final double[] args2 = new double[]{1.886, 2.920, 4.303, 6.965, 9.925, 22.327};
final double[] args10 = new double[]{1.372, 1.812, 2.228, 2.764, 3.169, 4.143};
final double[] args30 = new double[]{1.310, 1.697, 2.042, 2.457, 2.750, 3.385};
final double[] args100 = new double[]{1.290, 1.660, 1.984, 2.364, 2.626, 3.174};
TestUtils.assertEquals(prob, makeNistResults(args2, 2), 1.0e-4);
TestUtils.assertEquals(prob, makeNistResults(args10, 10), 1.0e-4);
TestUtils.assertEquals(prob, makeNistResults(args30, 30), 1.0e-4);
TestUtils.assertEquals(prob, makeNistResults(args100, 100), 1.0e-4);
}
// See https://issues.apache.org/jira/browse/STATISTICS-25
@Test
void testStatistics25() {
final double[] df = {1, 10, 1e2, 1e3, 1e4, 1e5,
1e6, 2e6, 2.98e6, 2.99e6, 3e6, 4e6,
1e7, 1e8, 1e9, 1e10};
// Generated from Python.
final double[] expected = {0.507956089912,
0.509726595102,
0.509947608093,
0.509970024339,
0.509972268782,
0.509972493254,
0.509972515701,
0.509972516948,
0.509972517358,
0.509972517361,
0.509972517364,
0.509972517572,
0.509972517946,
0.50997251817,
0.509972518193,
0.509972518195};
final double c = 0.025;
final double tol = 1e-9;
for (int i = 0; i < df.length; i++) {
final TDistribution dist = new TDistribution(df[i]);
final double x = dist.cumulativeProbability(c);
Assertions.assertEquals(expected[i], x, tol);
}
}
private double[] makeNistResults(double[] args, int df) {
final TDistribution td = new TDistribution(df);
final double[] res = new double[args.length];
for (int i = 0; i < res.length; i++) {
res[i] = 1.0 - td.cumulativeProbability(args[i]);
}
return res;
}
}