You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2018/01/21 14:05:43 UTC
[08/16] commons-statistics git commit: STATISTICS-2: Migrate
"o.a.c.math4.distribution" from Commons Math.
http://git-wip-us.apache.org/repos/asf/commons-statistics/blob/9c794a15/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/NormalDistributionTest.java
----------------------------------------------------------------------
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/NormalDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/NormalDistributionTest.java
new file mode 100644
index 0000000..3b2889e
--- /dev/null
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/NormalDistributionTest.java
@@ -0,0 +1,213 @@
+/*
+ * 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.Assert;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link NormalDistribution}. Extends
+ * {@link ContinuousDistributionAbstractTest}. See class javadoc of that class
+ * for details.
+ *
+ */
+public class NormalDistributionTest extends ContinuousDistributionAbstractTest {
+
+ //-------------- Implementations for abstract methods -----------------------
+
+ /** Creates the default real distribution instance to use in tests. */
+ @Override
+ public NormalDistribution makeDistribution() {
+ return new NormalDistribution(2.1, 1.4);
+ }
+
+ /** Creates the default cumulative probability distribution test input values */
+ @Override
+ public double[] makeCumulativeTestPoints() {
+ // quantiles computed using R
+ return new double[] {-2.226325228634938d, -1.156887023657177d, -0.643949578356075d, -0.2027950777320613d, 0.305827808237559d,
+ 6.42632522863494d, 5.35688702365718d, 4.843949578356074d, 4.40279507773206d, 3.89417219176244d};
+ }
+
+ /** Creates the default cumulative probability density test expected values */
+ @Override
+ public double[] makeCumulativeTestValues() {
+ return new double[] {0.001d, 0.01d, 0.025d, 0.05d, 0.1d, 0.999d,
+ 0.990d, 0.975d, 0.950d, 0.900d};
+ }
+
+ /** Creates the default probability density test expected values */
+ @Override
+ public double[] makeDensityTestValues() {
+ return new double[] {0.00240506434076, 0.0190372444310, 0.0417464784322, 0.0736683145538, 0.125355951380,
+ 0.00240506434076, 0.0190372444310, 0.0417464784322, 0.0736683145538, 0.125355951380};
+ }
+
+ // --------------------- Override tolerance --------------
+ private double defaultTolerance = 1e-7;
+ @Override
+ public void setUp() {
+ super.setUp();
+ setTolerance(defaultTolerance);
+ }
+
+ //---------------------------- Additional test cases -------------------------
+
+ private void verifyQuantiles() {
+ NormalDistribution distribution = (NormalDistribution) getDistribution();
+ double mu = distribution.getMean();
+ double sigma = distribution.getStandardDeviation();
+ setCumulativeTestPoints( new double[] {mu - 2 *sigma, mu - sigma,
+ mu, mu + sigma, mu + 2 * sigma, mu + 3 * sigma, mu + 4 * sigma,
+ mu + 5 * sigma});
+ // Quantiles computed using R (same as Mathematica)
+ setCumulativeTestValues(new double[] {0.02275013194817921, 0.158655253931457, 0.5, 0.841344746068543,
+ 0.977249868051821, 0.99865010196837, 0.999968328758167, 0.999999713348428});
+ verifyCumulativeProbabilities();
+ }
+
+ @Test
+ public void testQuantiles() {
+ setDensityTestValues(new double[] {0.0385649760808, 0.172836231799, 0.284958771715, 0.172836231799, 0.0385649760808,
+ 0.00316560600853, 9.55930184035e-05, 1.06194251052e-06});
+ verifyQuantiles();
+ verifyDensities();
+
+ setDistribution(new NormalDistribution(0, 1));
+ setDensityTestValues(new double[] {0.0539909665132, 0.241970724519, 0.398942280401, 0.241970724519, 0.0539909665132,
+ 0.00443184841194, 0.000133830225765, 1.48671951473e-06});
+ verifyQuantiles();
+ verifyDensities();
+
+ setDistribution(new NormalDistribution(0, 0.1));
+ setDensityTestValues(new double[] {0.539909665132, 2.41970724519, 3.98942280401, 2.41970724519,
+ 0.539909665132, 0.0443184841194, 0.00133830225765, 1.48671951473e-05});
+ verifyQuantiles();
+ verifyDensities();
+ }
+
+ @Test
+ public void testInverseCumulativeProbabilityExtremes() {
+ setInverseCumulativeTestPoints(new double[] {0, 1});
+ setInverseCumulativeTestValues(new double[] {Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY});
+ verifyInverseCumulativeProbabilities();
+ }
+
+ // MATH-1257
+ @Test
+ public void testCumulativeProbability() {
+ final ContinuousDistribution dist = new NormalDistribution(0, 1);
+ double x = -10;
+ double expected = 7.61985e-24;
+ double v = dist.cumulativeProbability(x);
+ double tol = 1e-5;
+ Assert.assertEquals(1, v / expected, 1e-5);
+ }
+
+ @Test
+ public void testGetMean() {
+ NormalDistribution distribution = (NormalDistribution) getDistribution();
+ Assert.assertEquals(2.1, distribution.getMean(), 0);
+ }
+
+ @Test
+ public void testGetStandardDeviation() {
+ NormalDistribution distribution = (NormalDistribution) getDistribution();
+ Assert.assertEquals(1.4, distribution.getStandardDeviation(), 0);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testPrecondition1() {
+ new NormalDistribution(1, 0);
+ }
+
+ @Test
+ public void testDensity() {
+ double [] x = new double[]{-2, -1, 0, 1, 2};
+ // R 2.5: print(dnorm(c(-2,-1,0,1,2)), digits=10)
+ checkDensity(0, 1, x, new double[]{0.05399096651, 0.24197072452, 0.39894228040, 0.24197072452, 0.05399096651});
+ // R 2.5: print(dnorm(c(-2,-1,0,1,2), mean=1.1), digits=10)
+ checkDensity(1.1, 1, x, new double[]{0.003266819056,0.043983595980,0.217852177033,0.396952547477,0.266085249899});
+ }
+
+ private void checkDensity(double mean, double sd, double[] x, double[] expected) {
+ NormalDistribution d = new NormalDistribution(mean, sd);
+ for (int i = 0; i < x.length; i++) {
+ Assert.assertEquals(expected[i], d.density(x[i]), 1e-9);
+ }
+ }
+
+ /**
+ * Check to make sure top-coding of extreme values works correctly.
+ * Verifies fixes for JIRA MATH-167, MATH-414
+ */
+ @Test
+ public void testExtremeValues() {
+ NormalDistribution distribution = new NormalDistribution(0, 1);
+ for (int i = 0; i < 100; i++) { // make sure no convergence exception
+ double lowerTail = distribution.cumulativeProbability(-i);
+ double upperTail = distribution.cumulativeProbability(i);
+ if (i < 9) { // make sure not top-coded
+ // For i = 10, due to bad tail precision in erf (MATH-364), 1 is returned
+ // TODO: once MATH-364 is resolved, replace 9 with 30
+ Assert.assertTrue(lowerTail > 0.0d);
+ Assert.assertTrue(upperTail < 1.0d);
+ }
+ else { // make sure top coding not reversed
+ Assert.assertTrue(lowerTail < 0.00001);
+ Assert.assertTrue(upperTail > 0.99999);
+ }
+ }
+
+ Assert.assertEquals(distribution.cumulativeProbability(Double.MAX_VALUE), 1, 0);
+ Assert.assertEquals(distribution.cumulativeProbability(-Double.MAX_VALUE), 0, 0);
+ Assert.assertEquals(distribution.cumulativeProbability(Double.POSITIVE_INFINITY), 1, 0);
+ Assert.assertEquals(distribution.cumulativeProbability(Double.NEGATIVE_INFINITY), 0, 0);
+ }
+
+ @Test
+ public void testMath280() {
+ NormalDistribution normal = new NormalDistribution(0,1);
+ double result = normal.inverseCumulativeProbability(0.9986501019683698);
+ Assert.assertEquals(3.0, result, defaultTolerance);
+ result = normal.inverseCumulativeProbability(0.841344746068543);
+ Assert.assertEquals(1.0, result, defaultTolerance);
+ result = normal.inverseCumulativeProbability(0.9999683287581673);
+ Assert.assertEquals(4.0, result, defaultTolerance);
+ result = normal.inverseCumulativeProbability(0.9772498680518209);
+ Assert.assertEquals(2.0, result, defaultTolerance);
+ }
+
+ @Test
+ public void testMoments() {
+ final double tol = 1e-9;
+ NormalDistribution dist;
+
+ dist = new NormalDistribution(0, 1);
+ Assert.assertEquals(dist.getNumericalMean(), 0, tol);
+ Assert.assertEquals(dist.getNumericalVariance(), 1, tol);
+
+ dist = new NormalDistribution(2.2, 1.4);
+ Assert.assertEquals(dist.getNumericalMean(), 2.2, tol);
+ Assert.assertEquals(dist.getNumericalVariance(), 1.4 * 1.4, tol);
+
+ dist = new NormalDistribution(-2000.9, 10.4);
+ Assert.assertEquals(dist.getNumericalMean(), -2000.9, tol);
+ Assert.assertEquals(dist.getNumericalVariance(), 10.4 * 10.4, tol);
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-statistics/blob/9c794a15/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ParetoDistributionTest.java
----------------------------------------------------------------------
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ParetoDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ParetoDistributionTest.java
new file mode 100644
index 0000000..6223dbc
--- /dev/null
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ParetoDistributionTest.java
@@ -0,0 +1,201 @@
+/*
+ * 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.Assert;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link ParetoDistribution}.
+ * Extends {@link ContinuousDistributionAbstractTest}. See class javadoc of that class for details.
+ */
+public class ParetoDistributionTest extends ContinuousDistributionAbstractTest {
+
+ //-------------- Implementations for abstract methods -----------------------
+
+ /** Creates the default real distribution instance to use in tests. */
+ @Override
+ public ParetoDistribution makeDistribution() {
+ return new ParetoDistribution(2.1, 1.4);
+ }
+
+ /** Creates the default cumulative probability distribution test input values */
+ @Override
+ public double[] makeCumulativeTestPoints() {
+ // quantiles computed using R
+ return new double[] { -2.226325228634938, -1.156887023657177, -0.643949578356075, -0.2027950777320613, 0.305827808237559,
+ +6.42632522863494, 5.35688702365718, 4.843949578356074, 4.40279507773206, 3.89417219176244 };
+ }
+
+ /** Creates the default cumulative probability density test expected values */
+ @Override
+ public double[] makeCumulativeTestValues() {
+ return new double[] { 0, 0, 0, 0, 0, 0.791089998892, 0.730456085931, 0.689667290488, 0.645278794701, 0.578763688757 };
+ }
+
+ /** Creates the default probability density test expected values */
+ @Override
+ public double[] makeDensityTestValues() {
+ return new double[] { 0, 0, 0, 0, 0, 0.0455118580441, 0.070444173646, 0.0896924681582, 0.112794186114, 0.151439332084 };
+ }
+
+ /**
+ * Creates the default inverse cumulative probability distribution test input values.
+ */
+ @Override
+ public double[] makeInverseCumulativeTestPoints() {
+ // Exclude the test points less than zero, as they have cumulative
+ // probability of zero, meaning the inverse returns zero, and not the
+ // points less than zero.
+ double[] points = makeCumulativeTestValues();
+ double[] points2 = new double[points.length - 5];
+ System.arraycopy(points, 5, points2, 0, points.length - 5);
+ return points2;
+ }
+
+ /**
+ * Creates the default inverse cumulative probability test expected values.
+ */
+ @Override
+ public double[] makeInverseCumulativeTestValues() {
+ // Exclude the test points less than zero, as they have cumulative
+ // probability of zero, meaning the inverse returns zero, and not the
+ // points less than zero.
+ double[] points = makeCumulativeTestPoints();
+ double[] points2 = new double[points.length - 5];
+ System.arraycopy(points, 5, points2, 0, points.length - 5);
+ return points2;
+ }
+
+ // --------------------- Override tolerance --------------
+ @Override
+ public void setUp() {
+ super.setUp();
+ setTolerance(1e-7);
+ }
+
+ //---------------------------- Additional test cases -------------------------
+
+ private void verifyQuantiles() {
+ ParetoDistribution distribution = (ParetoDistribution)getDistribution();
+ double mu = distribution.getScale();
+ double sigma = distribution.getShape();
+ setCumulativeTestPoints( new double[] { mu - 2 *sigma, mu - sigma,
+ mu, mu + sigma,
+ mu + 2 * sigma, mu + 3 * sigma,
+ mu + 4 * sigma, mu + 5 * sigma });
+ verifyCumulativeProbabilities();
+ }
+
+ @Test
+ public void testQuantiles() {
+ setCumulativeTestValues(new double[] {0, 0, 0, 0.510884134236, 0.694625688662, 0.785201995008, 0.837811522357, 0.871634279326});
+ setDensityTestValues(new double[] {0, 0, 0.666666666, 0.195646346305, 0.0872498032394, 0.0477328899983, 0.0294888141169, 0.0197485724114});
+ verifyQuantiles();
+ verifyDensities();
+
+ setDistribution(new ParetoDistribution(1, 1));
+ setCumulativeTestValues(new double[] {0, 0, 0, 0.5, 0.666666666667, 0.75, 0.8, 0.833333333333});
+ setDensityTestValues(new double[] {0, 0, 1.0, 0.25, 0.111111111111, 0.0625, 0.04, 0.0277777777778});
+ verifyQuantiles();
+ verifyDensities();
+
+ setDistribution(new ParetoDistribution(0.1, 0.1));
+ setCumulativeTestValues(new double[] {0, 0, 0, 0.0669670084632, 0.104041540159, 0.129449436704, 0.148660077479, 0.164041197922});
+ setDensityTestValues(new double[] {0, 0, 1.0, 0.466516495768, 0.298652819947, 0.217637640824, 0.170267984504, 0.139326467013});
+ verifyQuantiles();
+ verifyDensities();
+ }
+
+ @Test
+ public void testInverseCumulativeProbabilityExtremes() {
+ setInverseCumulativeTestPoints(new double[] {0, 1});
+ setInverseCumulativeTestValues(new double[] {2.1, Double.POSITIVE_INFINITY});
+ verifyInverseCumulativeProbabilities();
+ }
+
+ @Test
+ public void testGetScale() {
+ ParetoDistribution distribution = (ParetoDistribution)getDistribution();
+ Assert.assertEquals(2.1, distribution.getScale(), 0);
+ }
+
+ @Test
+ public void testGetShape() {
+ ParetoDistribution distribution = (ParetoDistribution)getDistribution();
+ Assert.assertEquals(1.4, distribution.getShape(), 0);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testPrecondition1() {
+ new ParetoDistribution(1, 0);
+ }
+
+ @Test
+ public void testDensity() {
+ double [] x = new double[]{-2, -1, 0, 1, 2};
+ // R 2.14: print(dpareto(c(-2,-1,0,1,2), scale=1, shape=1), digits=10)
+ checkDensity(1, 1, x, new double[] { 0.00, 0.00, 0.00, 1.00, 0.25 });
+ // R 2.14: print(dpareto(c(-2,-1,0,1,2), scale=1.1, shape=1), digits=10)
+ checkDensity(1.1, 1, x, new double[] { 0.000, 0.000, 0.000, 0.000, 0.275 });
+ }
+
+ private void checkDensity(double scale, double shape, double[] x,
+ double[] expected) {
+ ParetoDistribution d = new ParetoDistribution(scale, shape);
+ for (int i = 0; i < x.length; i++) {
+ Assert.assertEquals(expected[i], d.density(x[i]), 1e-9);
+ }
+ }
+
+ /**
+ * Check to make sure top-coding of extreme values works correctly.
+ */
+ @Test
+ public void testExtremeValues() {
+ ParetoDistribution d = new ParetoDistribution(1, 1);
+ for (int i = 0; i < 1e5; i++) { // make sure no convergence exception
+ double upperTail = d.cumulativeProbability(i);
+ if (i <= 1000) { // make sure not top-coded
+ Assert.assertTrue(upperTail < 1.0d);
+ }
+ else { // make sure top coding not reversed
+ Assert.assertTrue(upperTail > 0.999);
+ }
+ }
+
+ Assert.assertEquals(d.cumulativeProbability(Double.MAX_VALUE), 1, 0);
+ Assert.assertEquals(d.cumulativeProbability(-Double.MAX_VALUE), 0, 0);
+ Assert.assertEquals(d.cumulativeProbability(Double.POSITIVE_INFINITY), 1, 0);
+ Assert.assertEquals(d.cumulativeProbability(Double.NEGATIVE_INFINITY), 0, 0);
+ }
+
+ @Test
+ public void testMeanVariance() {
+ final double tol = 1e-9;
+ ParetoDistribution dist;
+
+ dist = new ParetoDistribution(1, 1);
+ Assert.assertEquals(dist.getNumericalMean(), Double.POSITIVE_INFINITY, tol);
+ Assert.assertEquals(dist.getNumericalVariance(), Double.POSITIVE_INFINITY, tol);
+
+ dist = new ParetoDistribution(2.2, 2.4);
+ Assert.assertEquals(dist.getNumericalMean(), 3.771428571428, tol);
+ Assert.assertEquals(dist.getNumericalVariance(), 14.816326530, tol);
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-statistics/blob/9c794a15/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/PascalDistributionTest.java
----------------------------------------------------------------------
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/PascalDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/PascalDistributionTest.java
new file mode 100644
index 0000000..b0d7ac1
--- /dev/null
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/PascalDistributionTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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.Assert;
+import org.junit.Test;
+
+/**
+ * Test cases for PascalDistribution.
+ * Extends DiscreteDistributionAbstractTest. See class javadoc for
+ * DiscreteDistributionAbstractTest for details.
+ *
+ */
+public class PascalDistributionTest extends DiscreteDistributionAbstractTest {
+
+ // --------------------- Override tolerance --------------
+ protected double defaultTolerance = 1e-7;
+ @Override
+ public void setUp() {
+ super.setUp();
+ setTolerance(defaultTolerance);
+ }
+
+ //-------------- Implementations for abstract methods -----------------------
+
+ /** Creates the default discrete distribution instance to use in tests. */
+ @Override
+ public DiscreteDistribution makeDistribution() {
+ return new PascalDistribution(10,0.70);
+ }
+
+ /** Creates the default probability density test input values */
+ @Override
+ public int[] makeDensityTestPoints() {
+ return new int[] {-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+ }
+
+ /** Creates the default probability density test expected values */
+ @Override
+ public double[] makeDensityTestValues() {
+ return new double[] {0, 0.0282475249, 0.0847425747, 0.139825248255, 0.167790297906, 0.163595540458,
+ 0.137420253985, 0.103065190489, 0.070673273478, 0.0450542118422, 0.0270325271053,
+ 0.0154085404500, 0.0084046584273};
+ }
+
+ /** Creates the default cumulative probability density test input values */
+ @Override
+ public int[] makeCumulativeTestPoints() {
+ return makeDensityTestPoints();
+ }
+
+ /** Creates the default cumulative probability density test expected values */
+ @Override
+ public double[] makeCumulativeTestValues() {
+ return new double[] {0, 0.0282475249, 0.1129900996, 0.252815347855, 0.420605645761, 0.584201186219,
+ 0.721621440204, 0.824686630693, 0.895359904171, 0.940414116013, 0.967446643119,
+ 0.982855183569, 0.991259841996};
+ }
+
+ /** Creates the default inverse cumulative probability test input values */
+ @Override
+ public double[] makeInverseCumulativeTestPoints() {
+ return new double[] {0.0, 0.001, 0.010, 0.025, 0.050, 0.100, 0.999,
+ 0.990, 0.975, 0.950, 0.900, 1.0};
+ }
+
+ /** Creates the default inverse cumulative probability density test expected values */
+ @Override
+ public int[] makeInverseCumulativeTestValues() {
+ return new int[] {0, 0, 0, 0, 1, 1, 14, 11, 10, 9, 8, Integer.MAX_VALUE};
+ }
+
+ //----------------- Additional test cases ---------------------------------
+
+ /** Test degenerate case p = 0 */
+ @Test
+ public void testDegenerate0() {
+ setDistribution(new PascalDistribution(5, 0.0d));
+ setCumulativeTestPoints(new int[] {-1, 0, 1, 5, 10 });
+ setCumulativeTestValues(new double[] {0d, 0d, 0d, 0d, 0d});
+ setDensityTestPoints(new int[] {-1, 0, 1, 10, 11});
+ setDensityTestValues(new double[] {0d, 0d, 0d, 0d, 0d});
+ setInverseCumulativeTestPoints(new double[] {0.1d, 0.5d});
+ setInverseCumulativeTestValues(new int[] {Integer.MAX_VALUE, Integer.MAX_VALUE});
+ verifyDensities();
+ verifyCumulativeProbabilities();
+ verifyInverseCumulativeProbabilities();
+ }
+
+ /** Test degenerate case p = 1 */
+ @Test
+ public void testDegenerate1() {
+ setDistribution(new PascalDistribution(5, 1.0d));
+ setCumulativeTestPoints(new int[] {-1, 0, 1, 2, 5, 10 });
+ setCumulativeTestValues(new double[] {0d, 1d, 1d, 1d, 1d, 1d});
+ setDensityTestPoints(new int[] {-1, 0, 1, 2, 5, 10});
+ setDensityTestValues(new double[] {0d, 1d, 0d, 0d, 0d, 0d});
+ setInverseCumulativeTestPoints(new double[] {0.1d, 0.5d});
+ setInverseCumulativeTestValues(new int[] {0, 0});
+ verifyDensities();
+ verifyCumulativeProbabilities();
+ verifyInverseCumulativeProbabilities();
+ }
+
+ @Test
+ public void testMoments() {
+ final double tol = 1e-9;
+ PascalDistribution dist;
+
+ dist = new PascalDistribution(10, 0.5);
+ Assert.assertEquals(dist.getNumericalMean(), ( 10d * 0.5d ) / 0.5d, tol);
+ Assert.assertEquals(dist.getNumericalVariance(), ( 10d * 0.5d ) / (0.5d * 0.5d), tol);
+
+ dist = new PascalDistribution(25, 0.7);
+ Assert.assertEquals(dist.getNumericalMean(), ( 25d * 0.3d ) / 0.7d, tol);
+ Assert.assertEquals(dist.getNumericalVariance(), ( 25d * 0.3d ) / (0.7d * 0.7d), tol);
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-statistics/blob/9c794a15/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/PoissonDistributionTest.java
----------------------------------------------------------------------
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/PoissonDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/PoissonDistributionTest.java
new file mode 100644
index 0000000..150e120
--- /dev/null
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/PoissonDistributionTest.java
@@ -0,0 +1,244 @@
+/*
+ * 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.Assert;
+import org.junit.Test;
+
+/**
+ * <code>PoissonDistributionTest</code>
+ *
+ */
+public class PoissonDistributionTest extends DiscreteDistributionAbstractTest {
+
+ /**
+ * Poisson parameter value for the test distribution.
+ */
+ private static final double DEFAULT_TEST_POISSON_PARAMETER = 4.0;
+
+ /**
+ * Constructor.
+ */
+ public PoissonDistributionTest() {
+ setTolerance(1e-12);
+ }
+
+ /**
+ * Creates the default discrete distribution instance to use in tests.
+ */
+ @Override
+ public DiscreteDistribution makeDistribution() {
+ return new PoissonDistribution(DEFAULT_TEST_POISSON_PARAMETER);
+ }
+
+ /**
+ * Creates the default probability density test input values.
+ */
+ @Override
+ public int[] makeDensityTestPoints() {
+ return new int[] { -1, 0, 1, 2, 3, 4, 5, 10, 20};
+ }
+
+ /**
+ * Creates the default probability density test expected values.
+ * These and all other test values are generated by R, version 1.8.1
+ */
+ @Override
+ public double[] makeDensityTestValues() {
+ return new double[] { 0d, 0.0183156388887d, 0.073262555555d,
+ 0.14652511111d, 0.195366814813d, 0.195366814813,
+ 0.156293451851d, 0.00529247667642d, 8.27746364655e-09};
+ }
+
+ /**
+ * Creates the default logarithmic probability density test expected values.
+ * Reference values are from R, version 2.14.1.
+ */
+ @Override
+ public double[] makeLogDensityTestValues() {
+ return new double[] { Double.NEGATIVE_INFINITY, -4.000000000000d,
+ -2.613705638880d, -1.920558458320d, -1.632876385868d,
+ -1.632876385868d, -1.856019937183d, -5.241468961877d,
+ -18.609729238356d};
+ }
+
+ /**
+ * Creates the default cumulative probability density test input values.
+ */
+ @Override
+ public int[] makeCumulativeTestPoints() {
+ return new int[] { -1, 0, 1, 2, 3, 4, 5, 10, 20 };
+ }
+
+ /**
+ * Creates the default cumulative probability density test expected values.
+ */
+ @Override
+ public double[] makeCumulativeTestValues() {
+ return new double[] { 0d, 0.0183156388887d, 0.0915781944437d,
+ 0.238103305554d, 0.433470120367d, 0.62883693518,
+ 0.78513038703d, 0.99716023388d, 0.999999998077 };
+ }
+
+ /**
+ * Creates the default inverse cumulative probability test input values.
+ */
+ @Override
+ public double[] makeInverseCumulativeTestPoints() {
+ DiscreteDistribution dist = getDistribution();
+ return new double[] { 0d, 0.018315638886d, 0.018315638890d,
+ 0.091578194441d, 0.091578194445d, 0.238103305552d,
+ 0.238103305556d, dist.cumulativeProbability(3),
+ dist.cumulativeProbability(4), dist.cumulativeProbability(5),
+ dist.cumulativeProbability(10), dist.cumulativeProbability(20)};
+ }
+
+ /**
+ * Creates the default inverse cumulative probability density test expected values.
+ */
+ @Override
+ public int[] makeInverseCumulativeTestValues() {
+ return new int[] { 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 10, 20};
+ }
+
+ /**
+ * Test the normal approximation of the Poisson distribution by
+ * calculating P(90 ≤ X ≤ 110) for X = Po(100) and
+ * P(9900 ≤ X ≤ 10200) for X = Po(10000)
+ */
+ @Test
+ public void testNormalApproximateProbability() {
+ PoissonDistribution dist = new PoissonDistribution(100);
+ double result = dist.normalApproximateProbability(110)
+ - dist.normalApproximateProbability(89);
+ Assert.assertEquals(0.706281887248, result, 1e-10);
+
+ dist = new PoissonDistribution(10000);
+ result = dist.normalApproximateProbability(10200)
+ - dist.normalApproximateProbability(9899);
+ Assert.assertEquals(0.820070051552, result, 1E-10);
+ }
+
+ /**
+ * Test the degenerate cases of a 0.0 and 1.0 inverse cumulative probability.
+ */
+ @Test
+ public void testDegenerateInverseCumulativeProbability() {
+ PoissonDistribution dist = new PoissonDistribution(DEFAULT_TEST_POISSON_PARAMETER);
+ Assert.assertEquals(Integer.MAX_VALUE, dist.inverseCumulativeProbability(1.0d));
+ Assert.assertEquals(0, dist.inverseCumulativeProbability(0d));
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testNegativeMean() {
+ new PoissonDistribution(-1);
+ }
+
+ @Test
+ public void testMean() {
+ PoissonDistribution dist = new PoissonDistribution(10.0);
+ Assert.assertEquals(10.0, dist.getMean(), 0.0);
+ }
+
+ @Test
+ public void testLargeMeanCumulativeProbability() {
+ double mean = 1.0;
+ while (mean <= 10000000.0) {
+ PoissonDistribution dist = new PoissonDistribution(mean);
+
+ double x = mean * 2.0;
+ double dx = x / 10.0;
+ double p = Double.NaN;
+ double sigma = Math.sqrt(mean);
+ while (x >= 0) {
+ try {
+ p = dist.cumulativeProbability((int) x);
+ Assert.assertFalse("NaN cumulative probability returned for mean = " +
+ mean + " x = " + x,Double.isNaN(p));
+ if (x > mean - 2 * sigma) {
+ Assert.assertTrue("Zero cum probaility returned for mean = " +
+ mean + " x = " + x, p > 0);
+ }
+ } catch (Exception ex) {
+ Assert.fail("mean of " + mean + " and x of " + x + " caused " + ex.getMessage());
+ }
+ x -= dx;
+ }
+
+ mean *= 10.0;
+ }
+ }
+
+ /**
+ * JIRA: MATH-282
+ */
+ @Test
+ public void testCumulativeProbabilitySpecial() {
+ PoissonDistribution dist;
+ dist = new PoissonDistribution(9120);
+ checkProbability(dist, 9075);
+ checkProbability(dist, 9102);
+ dist = new PoissonDistribution(5058);
+ checkProbability(dist, 5044);
+ dist = new PoissonDistribution(6986);
+ checkProbability(dist, 6950);
+ }
+
+ private void checkProbability(PoissonDistribution dist, int x) {
+ double p = dist.cumulativeProbability(x);
+ Assert.assertFalse("NaN cumulative probability returned for mean = " +
+ dist.getMean() + " x = " + x, Double.isNaN(p));
+ Assert.assertTrue("Zero cum probability returned for mean = " +
+ dist.getMean() + " x = " + x, p > 0);
+ }
+
+ @Test
+ public void testLargeMeanInverseCumulativeProbability() {
+ double mean = 1.0;
+ while (mean <= 100000.0) { // Extended test value: 1E7. Reduced to limit run time.
+ PoissonDistribution dist = new PoissonDistribution(mean);
+ double p = 0.1;
+ double dp = p;
+ while (p < .99) {
+ try {
+ int ret = dist.inverseCumulativeProbability(p);
+ // Verify that returned value satisties definition
+ Assert.assertTrue(p <= dist.cumulativeProbability(ret));
+ Assert.assertTrue(p > dist.cumulativeProbability(ret - 1));
+ } catch (Exception ex) {
+ Assert.fail("mean of " + mean + " and p of " + p + " caused " + ex.getMessage());
+ }
+ p += dp;
+ }
+ mean *= 10.0;
+ }
+ }
+
+ @Test
+ public void testMoments() {
+ final double tol = 1e-9;
+ PoissonDistribution dist;
+
+ dist = new PoissonDistribution(1);
+ Assert.assertEquals(dist.getNumericalMean(), 1, tol);
+ Assert.assertEquals(dist.getNumericalVariance(), 1, tol);
+
+ dist = new PoissonDistribution(11.23);
+ Assert.assertEquals(dist.getNumericalMean(), 11.23, tol);
+ Assert.assertEquals(dist.getNumericalVariance(), 11.23, tol);
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-statistics/blob/9c794a15/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TDistributionTest.java
----------------------------------------------------------------------
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TDistributionTest.java
new file mode 100644
index 0000000..46e2a08
--- /dev/null
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TDistributionTest.java
@@ -0,0 +1,169 @@
+/*
+ * 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.Assert;
+import org.junit.Test;
+/**
+ * Test cases for TDistribution.
+ * Extends ContinuousDistributionAbstractTest. See class javadoc for
+ * ContinuousDistributionAbstractTest for details.
+ *
+ */
+public class TDistributionTest extends ContinuousDistributionAbstractTest {
+
+ //-------------- Implementations for abstract methods -----------------------
+
+ /** Creates the default continuous distribution instance to use in tests. */
+ @Override
+ public TDistribution makeDistribution() {
+ return new TDistribution(5.0);
+ }
+
+ /** Creates the default cumulative probability distribution test input values */
+ @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};
+ }
+
+ /** Creates the default cumulative probability density test expected values */
+ @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};
+ }
+
+ /** Creates the default probability density test expected values */
+ @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 tolerance --------------
+ @Override
+ public void setUp() {
+ super.setUp();
+ setTolerance(1e-9);
+ }
+
+ //---------------------------- Additional test cases -------------------------
+ /**
+ * @see <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=27243">
+ * Bug report that prompted this unit test.</a>
+ */
+ @Test
+ public void testCumulativeProbabilityAgainstStackOverflow() {
+ TDistribution td = new TDistribution(5.);
+ td.cumulativeProbability(.1);
+ td.cumulativeProbability(.01);
+ }
+
+ @Test
+ public 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
+ public void testInverseCumulativeProbabilityExtremes() {
+ setInverseCumulativeTestPoints(new double[] {0, 1});
+ setInverseCumulativeTestValues(new double[] {Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY});
+ verifyInverseCumulativeProbabilities();
+ }
+
+ @Test
+ public void testCumulativeProbablilityExtremes() {
+ TDistribution dist;
+ for (int i = 1; i < 11; i++) {
+ dist = new TDistribution(i * 5);
+ Assert.assertEquals(1,
+ dist.cumulativeProbability(Double.POSITIVE_INFINITY), Double.MIN_VALUE);
+ Assert.assertEquals(0,
+ dist.cumulativeProbability(Double.NEGATIVE_INFINITY), Double.MIN_VALUE);
+ }
+ }
+
+ @Test
+ public void testDfAccessors() {
+ TDistribution dist = (TDistribution) getDistribution();
+ Assert.assertEquals(5d, dist.getDegreesOfFreedom(), Double.MIN_VALUE);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testPreconditions() {
+ new TDistribution(0);
+ }
+
+ @Test
+ public void testMoments() {
+ final double tol = 1e-9;
+ TDistribution dist;
+
+ dist = new TDistribution(1);
+ Assert.assertTrue(Double.isNaN(dist.getNumericalMean()));
+ Assert.assertTrue(Double.isNaN(dist.getNumericalVariance()));
+
+ dist = new TDistribution(1.5);
+ Assert.assertEquals(dist.getNumericalMean(), 0, tol);
+ Assert.assertTrue(Double.isInfinite(dist.getNumericalVariance()));
+
+ dist = new TDistribution(5);
+ Assert.assertEquals(dist.getNumericalMean(), 0, tol);
+ Assert.assertEquals(dist.getNumericalVariance(), 5d / (5d - 2d), 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
+ public void nistData(){
+ double[] prob = new double[]{ 0.10,0.05,0.025,0.01,0.005,0.001};
+ double[] args2 = new double[]{1.886,2.920,4.303,6.965,9.925,22.327};
+ double[] args10 = new double[]{1.372,1.812,2.228,2.764,3.169,4.143};
+ double[] args30 = new double[]{1.310,1.697,2.042,2.457,2.750,3.385};
+ 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);
+ return;
+ }
+ private double[] makeNistResults(double[] args, int df){
+ TDistribution td = new TDistribution(df);
+ double[] res = new double[ args.length ];
+ for( int i = 0 ; i < res.length ; i++){
+ res[i] = 1.0 - td.cumulativeProbability(args[i]);
+ }
+ return res;
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-statistics/blob/9c794a15/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TestUtils.java
----------------------------------------------------------------------
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TestUtils.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TestUtils.java
new file mode 100644
index 0000000..8a074d0
--- /dev/null
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TestUtils.java
@@ -0,0 +1,281 @@
+/*
+ * 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 java.text.DecimalFormat;
+import org.apache.commons.math3.stat.inference.ChiSquareTest;
+import org.apache.commons.numbers.core.Precision;
+import org.junit.Assert;
+
+/**
+ *
+ */
+public class TestUtils {
+ /**
+ * Collection of static methods used in math unit tests.
+ */
+ private TestUtils() {}
+
+ /**
+ * Verifies that expected and actual are within delta, or are both NaN or
+ * infinities of the same sign.
+ */
+ public static void assertEquals(double expected,
+ double actual,
+ double delta) {
+ Assert.assertEquals(null, expected, actual, delta);
+ }
+
+ /**
+ * Verifies that expected and actual are within delta, or are both NaN or
+ * infinities of the same sign.
+ */
+ public static void assertEquals(String msg,
+ double expected,
+ double actual,
+ double delta) {
+ // check for NaN
+ if(Double.isNaN(expected)){
+ Assert.assertTrue("" + actual + " is not NaN.",
+ Double.isNaN(actual));
+ } else {
+ Assert.assertEquals(msg, expected, actual, delta);
+ }
+ }
+
+ /**
+ * Verifies that two double arrays have equal entries, up to tolerance
+ */
+ public static void assertEquals(double expected[],
+ double observed[],
+ double tolerance) {
+ assertEquals("Array comparison failure", expected, observed, tolerance);
+ }
+
+ /**
+ * Verifies that the relative error in actual vs. expected is less than or
+ * equal to relativeError. If expected is infinite or NaN, actual must be
+ * the same (NaN or infinity of the same sign).
+ *
+ * @param expected expected value
+ * @param actual observed value
+ * @param relativeError maximum allowable relative error
+ */
+ public static void assertRelativelyEquals(double expected,
+ double actual,
+ double relativeError) {
+ assertRelativelyEquals(null, expected, actual, relativeError);
+ }
+
+ /**
+ * Verifies that the relative error in actual vs. expected is less than or
+ * equal to relativeError. If expected is infinite or NaN, actual must be
+ * the same (NaN or infinity of the same sign).
+ *
+ * @param msg message to return with failure
+ * @param expected expected value
+ * @param actual observed value
+ * @param relativeError maximum allowable relative error
+ */
+ public static void assertRelativelyEquals(String msg,
+ double expected,
+ double actual,
+ double relativeError) {
+ if (Double.isNaN(expected)) {
+ Assert.assertTrue(msg, Double.isNaN(actual));
+ } else if (Double.isNaN(actual)) {
+ Assert.assertTrue(msg, Double.isNaN(expected));
+ } else if (Double.isInfinite(actual) || Double.isInfinite(expected)) {
+ Assert.assertEquals(expected, actual, relativeError);
+ } else if (expected == 0.0) {
+ Assert.assertEquals(msg, actual, expected, relativeError);
+ } else {
+ double absError = Math.abs(expected) * relativeError;
+ Assert.assertEquals(msg, expected, actual, absError);
+ }
+ }
+
+ /** verifies that two arrays are close (sup norm) */
+ public static void assertEquals(String msg,
+ double[] expected,
+ double[] observed,
+ double tolerance) {
+ StringBuilder out = new StringBuilder(msg);
+ if (expected.length != observed.length) {
+ out.append("\n Arrays not same length. \n");
+ out.append("expected has length ");
+ out.append(expected.length);
+ out.append(" observed length = ");
+ out.append(observed.length);
+ Assert.fail(out.toString());
+ }
+ boolean failure = false;
+ for (int i=0; i < expected.length; i++) {
+ if (!Precision.equalsIncludingNaN(expected[i], observed[i], tolerance)) {
+ failure = true;
+ out.append("\n Elements at index ");
+ out.append(i);
+ out.append(" differ. ");
+ out.append(" expected = ");
+ out.append(expected[i]);
+ out.append(" observed = ");
+ out.append(observed[i]);
+ }
+ }
+ if (failure) {
+ Assert.fail(out.toString());
+ }
+ }
+
+ /**
+ * Asserts the null hypothesis for a ChiSquare test. Fails and dumps arguments and test
+ * statistics if the null hypothesis can be rejected with confidence 100 * (1 - alpha)%
+ *
+ * @param valueLabels labels for the values of the discrete distribution under test
+ * @param expected expected counts
+ * @param observed observed counts
+ * @param alpha significance level of the test
+ */
+ public static void assertChiSquareAccept(String[] valueLabels,
+ double[] expected,
+ long[] observed,
+ double alpha) {
+ ChiSquareTest chiSquareTest = new ChiSquareTest();
+
+ // Fail if we can reject null hypothesis that distributions are the same
+ if (chiSquareTest.chiSquareTest(expected, observed, alpha)) {
+ StringBuilder msgBuffer = new StringBuilder();
+ DecimalFormat df = new DecimalFormat("#.##");
+ msgBuffer.append("Chisquare test failed");
+ msgBuffer.append(" p-value = ");
+ msgBuffer.append(chiSquareTest.chiSquareTest(expected, observed));
+ msgBuffer.append(" chisquare statistic = ");
+ msgBuffer.append(chiSquareTest.chiSquare(expected, observed));
+ msgBuffer.append(". \n");
+ msgBuffer.append("value\texpected\tobserved\n");
+ for (int i = 0; i < expected.length; i++) {
+ msgBuffer.append(valueLabels[i]);
+ msgBuffer.append("\t");
+ msgBuffer.append(df.format(expected[i]));
+ msgBuffer.append("\t\t");
+ msgBuffer.append(observed[i]);
+ msgBuffer.append("\n");
+ }
+ msgBuffer.append("This test can fail randomly due to sampling error with probability ");
+ msgBuffer.append(alpha);
+ msgBuffer.append(".");
+ Assert.fail(msgBuffer.toString());
+ }
+ }
+
+ /**
+ * Asserts the null hypothesis for a ChiSquare test. Fails and dumps arguments and test
+ * statistics if the null hypothesis can be rejected with confidence 100 * (1 - alpha)%
+ *
+ * @param values integer values whose observed and expected counts are being compared
+ * @param expected expected counts
+ * @param observed observed counts
+ * @param alpha significance level of the test
+ */
+ public static void assertChiSquareAccept(int[] values,
+ double[] expected,
+ long[] observed,
+ double alpha) {
+ String[] labels = new String[values.length];
+ for (int i = 0; i < values.length; i++) {
+ labels[i] = Integer.toString(values[i]);
+ }
+ assertChiSquareAccept(labels, expected, observed, alpha);
+ }
+
+ /**
+ * Asserts the null hypothesis for a ChiSquare test. Fails and dumps arguments and test
+ * statistics if the null hypothesis can be rejected with confidence 100 * (1 - alpha)%
+ *
+ * @param expected expected counts
+ * @param observed observed counts
+ * @param alpha significance level of the test
+ */
+ public static void assertChiSquareAccept(double[] expected,
+ long[] observed,
+ double alpha) {
+ String[] labels = new String[expected.length];
+ for (int i = 0; i < labels.length; i++) {
+ labels[i] = Integer.toString(i + 1);
+ }
+ assertChiSquareAccept(labels, expected, observed, alpha);
+ }
+
+ /**
+ * Computes the 25th, 50th and 75th percentiles of the given distribution and returns
+ * these values in an array.
+ */
+ public static double[] getDistributionQuartiles(ContinuousDistribution distribution) {
+ double[] quantiles = new double[3];
+ quantiles[0] = distribution.inverseCumulativeProbability(0.25d);
+ quantiles[1] = distribution.inverseCumulativeProbability(0.5d);
+ quantiles[2] = distribution.inverseCumulativeProbability(0.75d);
+ return quantiles;
+ }
+
+ /**
+ * Updates observed counts of values in quartiles.
+ * counts[0] <-> 1st quartile ... counts[3] <-> top quartile
+ */
+ public static void updateCounts(double value, long[] counts, double[] quartiles) {
+ if (value < quartiles[0]) {
+ counts[0]++;
+ } else if (value > quartiles[2]) {
+ counts[3]++;
+ } else if (value > quartiles[1]) {
+ counts[2]++;
+ } else {
+ counts[1]++;
+ }
+ }
+
+ /**
+ * Eliminates points with zero mass from densityPoints and densityValues parallel
+ * arrays. Returns the number of positive mass points and collapses the arrays so
+ * that the first <returned value> elements of the input arrays represent the positive
+ * mass points.
+ */
+ public static int eliminateZeroMassPoints(int[] densityPoints, double[] densityValues) {
+ int positiveMassCount = 0;
+ for (int i = 0; i < densityValues.length; i++) {
+ if (densityValues[i] > 0) {
+ positiveMassCount++;
+ }
+ }
+ if (positiveMassCount < densityValues.length) {
+ int[] newPoints = new int[positiveMassCount];
+ double[] newValues = new double[positiveMassCount];
+ int j = 0;
+ for (int i = 0; i < densityValues.length; i++) {
+ if (densityValues[i] > 0) {
+ newPoints[j] = densityPoints[i];
+ newValues[j] = densityValues[i];
+ j++;
+ }
+ }
+ System.arraycopy(newPoints,0,densityPoints,0,positiveMassCount);
+ System.arraycopy(newValues,0,densityValues,0,positiveMassCount);
+ }
+ return positiveMassCount;
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-statistics/blob/9c794a15/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TriangularDistributionTest.java
----------------------------------------------------------------------
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TriangularDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TriangularDistributionTest.java
new file mode 100644
index 0000000..cddb70d
--- /dev/null
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TriangularDistributionTest.java
@@ -0,0 +1,192 @@
+/*
+ * 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.Assert;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link TriangularDistribution}. See class javadoc for
+ * {@link ContinuousDistributionAbstractTest} for further details.
+ */
+public class TriangularDistributionTest extends ContinuousDistributionAbstractTest {
+
+ // --- Override tolerance -------------------------------------------------
+
+ @Override
+ public void setUp() {
+ super.setUp();
+ setTolerance(1e-4);
+ }
+
+ //--- Implementations for abstract methods --------------------------------
+
+ /**
+ * Creates the default triangular distribution instance to use in tests.
+ */
+ @Override
+ public TriangularDistribution makeDistribution() {
+ // Left side 5 wide, right side 10 wide.
+ return new TriangularDistribution(-3, 2, 12);
+ }
+
+ /**
+ * Creates the default cumulative probability distribution test input
+ * values.
+ */
+ @Override
+ public double[] makeCumulativeTestPoints() {
+ return new double[] {
+ -3.0001, // below lower limit
+ -3.0, // at lower limit
+ -2.0, -1.0, 0.0, 1.0, // on lower side
+ 2.0, // at mode
+ 3.0, 4.0, 10.0, 11.0, // on upper side
+ 12.0, // at upper limit
+ 12.0001 // above upper limit
+ };
+ }
+
+ /**
+ * Creates the default cumulative probability density test expected values.
+ */
+ @Override
+ public double[] makeCumulativeTestValues() {
+ // Top at 2 / (b - a) = 2 / (12 - -3) = 2 / 15 = 7.5
+ // Area left = 7.5 * 5 * 0.5 = 18.75 (1/3 of the total area)
+ // Area right = 7.5 * 10 * 0.5 = 37.5 (2/3 of the total area)
+ // Area total = 18.75 + 37.5 = 56.25
+ // Derivative left side = 7.5 / 5 = 1.5
+ // Derivative right side = -7.5 / 10 = -0.75
+ double third = 1 / 3.0;
+ double left = 18.75;
+ double area = 56.25;
+ return new double[] { 0.0,
+ 0.0,
+ 0.75 / area, 3 / area, 6.75 / area, 12 / area,
+ third,
+ (left + 7.125) / area, (left + 13.5) / area,
+ (left + 36) / area, (left + 37.125) / area,
+ 1.0,
+ 1.0
+ };
+ }
+
+ /**
+ * Creates the default inverse cumulative probability distribution test
+ * input values.
+ */
+ @Override
+ public double[] makeInverseCumulativeTestPoints() {
+ // Exclude the points outside the limits, as they have cumulative
+ // probability of zero and one, meaning the inverse returns the
+ // limits and not the points outside the limits.
+ double[] points = makeCumulativeTestValues();
+ double[] points2 = new double[points.length-2];
+ System.arraycopy(points, 1, points2, 0, points2.length);
+ return points2;
+ //return Arrays.copyOfRange(points, 1, points.length - 1);
+ }
+
+ /**
+ * Creates the default inverse cumulative probability density test expected
+ * values.
+ */
+ @Override
+ public double[] makeInverseCumulativeTestValues() {
+ // Exclude the points outside the limits, as they have cumulative
+ // probability of zero and one, meaning the inverse returns the
+ // limits and not the points outside the limits.
+ double[] points = makeCumulativeTestPoints();
+ double[] points2 = new double[points.length-2];
+ System.arraycopy(points, 1, points2, 0, points2.length);
+ return points2;
+ //return Arrays.copyOfRange(points, 1, points.length - 1);
+ }
+
+ /** Creates the default probability density test expected values. */
+ @Override
+ public double[] makeDensityTestValues() {
+ return new double[] { 0,
+ 0,
+ 2 / 75.0, 4 / 75.0, 6 / 75.0, 8 / 75.0,
+ 10 / 75.0,
+ 9 / 75.0, 8 / 75.0, 2 / 75.0, 1 / 75.0,
+ 0,
+ 0
+ };
+ }
+
+ //--- Additional test cases -----------------------------------------------
+
+ /** Test lower bound getter. */
+ @Test
+ public void testGetLowerBound() {
+ TriangularDistribution distribution = makeDistribution();
+ Assert.assertEquals(-3.0, distribution.getSupportLowerBound(), 0);
+ }
+
+ /** Test upper bound getter. */
+ @Test
+ public void testGetUpperBound() {
+ TriangularDistribution distribution = makeDistribution();
+ Assert.assertEquals(12.0, distribution.getSupportUpperBound(), 0);
+ }
+
+ /** Test pre-condition for equal lower/upper limit. */
+ @Test(expected=IllegalArgumentException.class)
+ public void testPreconditions1() {
+ new TriangularDistribution(0, 0, 0);
+ }
+
+ /** Test pre-condition for lower limit larger than upper limit. */
+ @Test(expected=IllegalArgumentException.class)
+ public void testPreconditions2() {
+ new TriangularDistribution(1, 1, 0);
+ }
+
+ /** Test pre-condition for mode larger than upper limit. */
+ @Test(expected=IllegalArgumentException.class)
+ public void testPreconditions3() {
+ new TriangularDistribution(0, 2, 1);
+ }
+
+ /** Test pre-condition for mode smaller than lower limit. */
+ @Test(expected=IllegalArgumentException.class)
+ public void testPreconditions4() {
+ new TriangularDistribution(2, 1, 3);
+ }
+
+ /** Test mean/variance. */
+ @Test
+ public void testMeanVariance() {
+ TriangularDistribution dist;
+
+ dist = new TriangularDistribution(0, 0.5, 1.0);
+ Assert.assertEquals(dist.getNumericalMean(), 0.5, 0);
+ Assert.assertEquals(dist.getNumericalVariance(), 1 / 24.0, 0);
+
+ dist = new TriangularDistribution(0, 1, 1);
+ Assert.assertEquals(dist.getNumericalMean(), 2 / 3.0, 0);
+ Assert.assertEquals(dist.getNumericalVariance(), 1 / 18.0, 0);
+
+ dist = new TriangularDistribution(-3, 2, 12);
+ Assert.assertEquals(dist.getNumericalMean(), 3 + (2 / 3.0), 0);
+ Assert.assertEquals(dist.getNumericalVariance(), 175 / 18.0, 0);
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-statistics/blob/9c794a15/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformContinuousDistributionTest.java
----------------------------------------------------------------------
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformContinuousDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformContinuousDistributionTest.java
new file mode 100644
index 0000000..7f76f08
--- /dev/null
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformContinuousDistributionTest.java
@@ -0,0 +1,123 @@
+/*
+ * 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.Assert;
+import org.junit.Test;
+
+/**
+ * Test cases for UniformContinuousDistribution. See class javadoc for
+ * {@link ContinuousDistributionAbstractTest} for further details.
+ */
+public class UniformContinuousDistributionTest extends ContinuousDistributionAbstractTest {
+
+ // --- Override tolerance -------------------------------------------------
+
+ @Override
+ public void setUp() {
+ super.setUp();
+ setTolerance(1e-4);
+ }
+
+ //--- Implementations for abstract methods --------------------------------
+
+ /** Creates the default uniform real distribution instance to use in tests. */
+ @Override
+ public UniformContinuousDistribution makeDistribution() {
+ return new UniformContinuousDistribution(-0.5, 1.25);
+ }
+
+ /** Creates the default cumulative probability distribution test input values */
+ @Override
+ public double[] makeCumulativeTestPoints() {
+ return new double[] {-0.5001, -0.5, -0.4999, -0.25, -0.0001, 0.0,
+ 0.0001, 0.25, 1.0, 1.2499, 1.25, 1.2501};
+ }
+
+ /** Creates the default cumulative probability density test expected values */
+ @Override
+ public double[] makeCumulativeTestValues() {
+ return new double[] {0.0, 0.0, 0.0001, 0.25/1.75, 0.4999/1.75,
+ 0.5/1.75, 0.5001/1.75, 0.75/1.75, 1.5/1.75,
+ 1.7499/1.75, 1.0, 1.0};
+ }
+
+ /** Creates the default probability density test expected values */
+ @Override
+ public double[] makeDensityTestValues() {
+ double d = 1 / 1.75;
+ return new double[] {0, d, d, d, d, d, d, d, d, d, d, 0};
+ }
+
+ //--- Additional test cases -----------------------------------------------
+
+ /** Test lower bound getter. */
+ @Test
+ public void testGetLowerBound() {
+ UniformContinuousDistribution distribution = makeDistribution();
+ Assert.assertEquals(-0.5, distribution.getSupportLowerBound(), 0);
+ }
+
+ /** Test upper bound getter. */
+ @Test
+ public void testGetUpperBound() {
+ UniformContinuousDistribution distribution = makeDistribution();
+ Assert.assertEquals(1.25, distribution.getSupportUpperBound(), 0);
+ }
+
+ /** Test pre-condition for equal lower/upper bound. */
+ @Test(expected=IllegalArgumentException.class)
+ public void testPreconditions1() {
+ new UniformContinuousDistribution(0, 0);
+ }
+
+ /** Test pre-condition for lower bound larger than upper bound. */
+ @Test(expected=IllegalArgumentException.class)
+ public void testPreconditions2() {
+ new UniformContinuousDistribution(1, 0);
+ }
+
+ /** Test mean/variance. */
+ @Test
+ public void testMeanVariance() {
+ UniformContinuousDistribution dist;
+
+ dist = new UniformContinuousDistribution(0, 1);
+ Assert.assertEquals(dist.getNumericalMean(), 0.5, 0);
+ Assert.assertEquals(dist.getNumericalVariance(), 1/12.0, 0);
+
+ dist = new UniformContinuousDistribution(-1.5, 0.6);
+ Assert.assertEquals(dist.getNumericalMean(), -0.45, 0);
+ Assert.assertEquals(dist.getNumericalVariance(), 0.3675, 0);
+
+ dist = new UniformContinuousDistribution(-0.5, 1.25);
+ Assert.assertEquals(dist.getNumericalMean(), 0.375, 0);
+ Assert.assertEquals(dist.getNumericalVariance(), 0.2552083333333333, 0);
+ }
+
+ /**
+ * Check accuracy of analytical inverse CDF. Fails if a solver is used
+ * with the default accuracy.
+ */
+ @Test
+ public void testInverseCumulativeDistribution() {
+ UniformContinuousDistribution dist = new UniformContinuousDistribution(0, 1e-9);
+
+ Assert.assertEquals(2.5e-10, dist.inverseCumulativeProbability(0.25), 0);
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-statistics/blob/9c794a15/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformDiscreteDistributionTest.java
----------------------------------------------------------------------
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformDiscreteDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformDiscreteDistributionTest.java
new file mode 100644
index 0000000..98305db
--- /dev/null
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformDiscreteDistributionTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.Assert;
+import org.junit.Test;
+import org.apache.commons.numbers.core.Precision;
+
+/**
+ * Test cases for UniformDiscreteDistribution. See class javadoc for
+ * {@link DiscreteDistributionAbstractTest} for further details.
+ */
+public class UniformDiscreteDistributionTest extends DiscreteDistributionAbstractTest {
+
+ // --- Override tolerance -------------------------------------------------
+
+ @Override
+ public void setUp() {
+ super.setUp();
+ setTolerance(1e-9);
+ }
+
+ //--- Implementations for abstract methods --------------------------------
+
+ /** Creates the default discrete distribution instance to use in tests. */
+ @Override
+ public DiscreteDistribution makeDistribution() {
+ return new UniformDiscreteDistribution(-3, 5);
+ }
+
+ /** Creates the default probability density test input values. */
+ @Override
+ public int[] makeDensityTestPoints() {
+ return new int[] {-4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6};
+ }
+
+ /** Creates the default probability density test expected values. */
+ @Override
+ public double[] makeDensityTestValues() {
+ double d = 1.0 / (5 - -3 + 1);
+ return new double[] {0, d, d, d, d, d, d, d, d, d, 0};
+ }
+
+ /** Creates the default cumulative probability density test input values. */
+ @Override
+ public int[] makeCumulativeTestPoints() {
+ return makeDensityTestPoints();
+ }
+
+ /** Creates the default cumulative probability density test expected values. */
+ @Override
+ public double[] makeCumulativeTestValues() {
+ return new double[] {0, 1 / 9.0, 2 / 9.0, 3 / 9.0, 4 / 9.0, 5 / 9.0,
+ 6 / 9.0, 7 / 9.0, 8 / 9.0, 1, 1};
+ }
+
+ /** Creates the default inverse cumulative probability test input values */
+ @Override
+ public double[] makeInverseCumulativeTestPoints() {
+ return new double[] {0, 0.001, 0.010, 0.025, 0.050, 0.100, 0.200,
+ 0.5, 0.999, 0.990, 0.975, 0.950, 0.900, 1};
+ }
+
+ /** Creates the default inverse cumulative probability density test expected values */
+ @Override
+ public int[] makeInverseCumulativeTestValues() {
+ return new int[] {-3, -3, -3, -3, -3, -3, -2, 1, 5, 5, 5, 5, 5, 5};
+ }
+
+ //--- Additional test cases -----------------------------------------------
+
+ /** Test mean/variance. */
+ @Test
+ public void testMoments() {
+ UniformDiscreteDistribution dist;
+
+ dist = new UniformDiscreteDistribution(0, 5);
+ Assert.assertEquals(dist.getNumericalMean(), 2.5, 0);
+ Assert.assertEquals(dist.getNumericalVariance(), 35 / 12.0, 0);
+
+ dist = new UniformDiscreteDistribution(0, 1);
+ Assert.assertEquals(dist.getNumericalMean(), 0.5, 0);
+ Assert.assertEquals(dist.getNumericalVariance(), 3 / 12.0, 0);
+ }
+
+ // MATH-1141
+ @Test(expected=IllegalArgumentException.class)
+ public void testPreconditionUpperBoundInclusive1() {
+ new UniformDiscreteDistribution(1, 0);
+ }
+
+ // MATH-1141
+ @Test
+ public void testPreconditionUpperBoundInclusive2() {
+ // Degenerate case is allowed.
+ new UniformDiscreteDistribution(0, 0);
+ }
+
+ // MATH-1396
+ @Test
+ public void testLargeRangeSubtractionOverflow() {
+ final int hi = Integer.MAX_VALUE / 2 + 10;
+ UniformDiscreteDistribution dist = new UniformDiscreteDistribution(-hi, hi - 1);
+
+ final double tol = Math.ulp(1d);
+ Assert.assertEquals(0.5 / hi, dist.probability(123456), tol);
+ Assert.assertEquals(0.5, dist.cumulativeProbability(-1), tol);
+
+ Assert.assertTrue(Precision.equals((Math.pow(2d * hi, 2) - 1) / 12, dist.getNumericalVariance(), 1));
+ }
+
+ // MATH-1396
+ @Test
+ public void testLargeRangeAdditionOverflow() {
+ final int hi = Integer.MAX_VALUE / 2 + 10;
+ UniformDiscreteDistribution dist = new UniformDiscreteDistribution(hi - 1, hi + 1);
+
+ final double tol = Math.ulp(1d);
+ Assert.assertEquals(1d / 3d, dist.probability(hi), tol);
+ Assert.assertEquals(2d / 3d, dist.cumulativeProbability(hi), tol);
+
+ Assert.assertTrue(Precision.equals(hi, dist.getNumericalMean(), 1));
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-statistics/blob/9c794a15/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/WeibullDistributionTest.java
----------------------------------------------------------------------
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/WeibullDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/WeibullDistributionTest.java
new file mode 100644
index 0000000..c993fba
--- /dev/null
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/WeibullDistributionTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.apache.commons.numbers.gamma.LogGamma;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test cases for WeibullDistribution.
+ * Extends ContinuousDistributionAbstractTest. See class javadoc for
+ * ContinuousDistributionAbstractTest for details.
+ *
+ */
+public class WeibullDistributionTest extends ContinuousDistributionAbstractTest {
+
+ //-------------- Implementations for abstract methods -----------------------
+
+ /** Creates the default continuous distribution instance to use in tests. */
+ @Override
+ public WeibullDistribution makeDistribution() {
+ return new WeibullDistribution(1.2, 2.1);
+ }
+
+ /** Creates the default cumulative probability distribution test input values */
+ @Override
+ public double[] makeCumulativeTestPoints() {
+ // quantiles computed using R version 2.9.2
+ return new double[] {0.00664355180993, 0.0454328283309, 0.0981162737374, 0.176713524579, 0.321946865392,
+ 10.5115496887, 7.4976304671, 6.23205600701, 5.23968436955, 4.2079028257};
+ }
+
+ /** Creates the default cumulative probability density test expected values */
+ @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};
+ }
+
+ /** Creates the default probability density test expected values */
+ @Override
+ public double[] makeDensityTestValues() {
+ return new double[] {0.180535929306, 0.262801138133, 0.301905425199, 0.330899152971,
+ 0.353441418887, 0.000788590320203, 0.00737060094841, 0.0177576041516, 0.0343043442574, 0.065664589369};
+ }
+
+ //---------------------------- Additional test cases -------------------------
+
+ @Test
+ public void testInverseCumulativeProbabilitySmallPAccuracy() {
+ WeibullDistribution dist = new WeibullDistribution(2, 3);
+ double t = dist.inverseCumulativeProbability(1e-17);
+ // Analytically, answer is solution to 1e-17 = 1-exp(-(x/3)^2)
+ // x = sqrt(-9*log(1-1e-17))
+ // If we're not careful, answer will be 0. Answer below is computed with care in Octave:
+ Assert.assertEquals(9.48683298050514e-9, t, 1e-17);
+ }
+
+ @Test
+ public void testInverseCumulativeProbabilityExtremes() {
+ setInverseCumulativeTestPoints(new double[] {0.0, 1.0});
+ setInverseCumulativeTestValues(new double[] {0.0, Double.POSITIVE_INFINITY});
+ verifyInverseCumulativeProbabilities();
+ }
+
+ @Test
+ public void testAlpha() {
+ WeibullDistribution dist = new WeibullDistribution(1, 2);
+ Assert.assertEquals(1, dist.getShape(), 0);
+ }
+ @Test(expected=IllegalArgumentException.class)
+ public void testPrecondition1() {
+ new WeibullDistribution(0, 2);
+ }
+
+ @Test
+ public void testBeta() {
+ WeibullDistribution dist = new WeibullDistribution(1, 2);
+ Assert.assertEquals(2, dist.getScale(), 0);
+ }
+ @Test(expected=IllegalArgumentException.class)
+ public void testPrecondition2() {
+ new WeibullDistribution(1, 0);
+ }
+
+ @Test
+ public void testMoments() {
+ final double tol = 1e-9;
+ WeibullDistribution dist;
+
+ dist = new WeibullDistribution(2.5, 3.5);
+ // In R: 3.5*gamma(1+(1/2.5)) (or emperically: mean(rweibull(10000, 2.5, 3.5)))
+ Assert.assertEquals(dist.getNumericalMean(), 3.5 * Math.exp(LogGamma.value(1 + (1 / 2.5))), tol);
+ Assert.assertEquals(dist.getNumericalVariance(), (3.5 * 3.5) *
+ Math.exp(LogGamma.value(1 + (2 / 2.5))) -
+ (dist.getNumericalMean() * dist.getNumericalMean()), tol);
+
+ dist = new WeibullDistribution(10.4, 2.222);
+ Assert.assertEquals(dist.getNumericalMean(), 2.222 * Math.exp(LogGamma.value(1 + (1 / 10.4))), tol);
+ Assert.assertEquals(dist.getNumericalVariance(), (2.222 * 2.222) *
+ Math.exp(LogGamma.value(1 + (2 / 10.4))) -
+ (dist.getNumericalMean() * dist.getNumericalMean()), tol);
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-statistics/blob/9c794a15/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ZipfDistributionTest.java
----------------------------------------------------------------------
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ZipfDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ZipfDistributionTest.java
new file mode 100644
index 0000000..489a4bb
--- /dev/null
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ZipfDistributionTest.java
@@ -0,0 +1,166 @@
+/*
+ * 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.apache.commons.rng.simple.RandomSource;
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * Test cases for {@link ZipfDistribution}.
+ * Extends DiscreteDistributionAbstractTest.
+ * See class javadoc for DiscreteDistributionAbstractTest for details.
+ */
+public class ZipfDistributionTest extends DiscreteDistributionAbstractTest {
+
+ /**
+ * Constructor to override default tolerance.
+ */
+ public ZipfDistributionTest() {
+ setTolerance(1e-12);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testPreconditions1() {
+ new ZipfDistribution(0, 1);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testPreconditions2() {
+ new ZipfDistribution(1, 0);
+ }
+
+ //-------------- Implementations for abstract methods -----------------------
+
+ /** Creates the default discrete distribution instance to use in tests. */
+ @Override
+ public DiscreteDistribution makeDistribution() {
+ return new ZipfDistribution(10, 1);
+ }
+
+ /** Creates the default probability density test input values */
+ @Override
+ public int[] makeDensityTestPoints() {
+ return new int[] {-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+ }
+
+ /**
+ * Creates the default probability density test expected values.
+ * Reference values are from R, version 2.15.3 (VGAM package 0.9-0).
+ */
+ @Override
+ public double[] makeDensityTestValues() {
+ return new double[] {0d, 0d, 0.341417152147, 0.170708576074, 0.113805717382, 0.0853542880369, 0.0682834304295,
+ 0.0569028586912, 0.0487738788782, 0.0426771440184, 0.0379352391275, 0.0341417152147, 0};
+ }
+
+ /**
+ * Creates the default logarithmic probability density test expected values.
+ * Reference values are from R, version 2.14.1.
+ */
+ @Override
+ public double[] makeLogDensityTestValues() {
+ return new double[] {Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY,
+ -1.07465022926458, -1.76779740982453, -2.17326251793269, -2.46094459038447,
+ -2.68408814169868, -2.86640969849264, -3.0205603783199, -3.15409177094442,
+ -3.2718748066008, -3.37723532225863, Double.NEGATIVE_INFINITY};
+ }
+
+ /** Creates the default cumulative probability density test input values */
+ @Override
+ public int[] makeCumulativeTestPoints() {
+ return makeDensityTestPoints();
+ }
+
+ /** Creates the default cumulative probability density test expected values */
+ @Override
+ public double[] makeCumulativeTestValues() {
+ return new double[] {0, 0, 0.341417152147, 0.512125728221, 0.625931445604, 0.71128573364,
+ 0.77956916407, 0.836472022761, 0.885245901639, 0.927923045658, 0.965858284785, 1d, 1d};
+ }
+
+ /** Creates the default inverse cumulative probability test input values */
+ @Override
+ public double[] makeInverseCumulativeTestPoints() {
+ return new double[] {0d, 0.001d, 0.010d, 0.025d, 0.050d, 0.3413d, 0.3415d, 0.999d,
+ 0.990d, 0.975d, 0.950d, 0.900d, 1d};
+ }
+
+ /** Creates the default inverse cumulative probability density test expected values */
+ @Override
+ public int[] makeInverseCumulativeTestValues() {
+ return new int[] {1, 1, 1, 1, 1, 1, 2, 10, 10, 10, 9, 8, 10};
+ }
+
+ @Test
+ public void testMoments() {
+ final double tol = 1e-9;
+ ZipfDistribution dist;
+
+ dist = new ZipfDistribution(2, 0.5);
+ Assert.assertEquals(dist.getNumericalMean(), Math.sqrt(2), tol);
+ Assert.assertEquals(dist.getNumericalVariance(), 0.24264068711928521, tol);
+ }
+
+
+ /**
+ * Test sampling for various number of points and exponents.
+ */
+ @Test
+ public void testSamplingExtended() {
+ int sampleSize = 1000;
+
+ int[] numPointsValues = {
+ 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100
+ };
+ double[] exponentValues = {
+ 1e-10, 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 2e-1, 5e-1,
+ 1. - 1e-9, 1.0, 1. + 1e-9, 1.1, 1.2, 1.3, 1.5, 1.6, 1.7, 1.8, 2.0,
+ 2.5, 3.0, 4., 5., 6., 7., 8., 9., 10., 20., 30., 100., 150.
+ };
+
+ for (int numPoints : numPointsValues) {
+ for (double exponent : exponentValues) {
+ double weightSum = 0.;
+ double[] weights = new double[numPoints];
+ for (int i = numPoints; i>=1; i-=1) {
+ weights[i-1] = Math.pow(i, -exponent);
+ weightSum += weights[i-1];
+ }
+
+ // Use fixed seed, the test is expected to fail for more than 50% of all
+ // seeds because each test case can fail with probability 0.001, the chance
+ // that all test cases do not fail is 0.999^(32*22) = 0.49442874426
+ DiscreteDistribution.Sampler distribution =
+ new ZipfDistribution(numPoints, exponent).createSampler(RandomSource.create(RandomSource.WELL_19937_C, 6));
+
+ double[] expectedCounts = new double[numPoints];
+ long[] observedCounts = new long[numPoints];
+ for (int i = 0; i < numPoints; i++) {
+ expectedCounts[i] = sampleSize * (weights[i]/weightSum);
+ }
+ int[] sample = AbstractDiscreteDistribution.sample(sampleSize, distribution);
+ for (int s : sample) {
+ observedCounts[s-1]++;
+ }
+ TestUtils.assertChiSquareAccept(expectedCounts, observedCounts, 0.001);
+ }
+ }
+ }
+}