View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.math4.legacy.distribution;
18  
19  import org.apache.commons.statistics.distribution.DiscreteDistribution;
20  import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
21  import org.apache.commons.math4.legacy.exception.MathArithmeticException;
22  import org.apache.commons.math4.legacy.exception.NotANumberException;
23  import org.apache.commons.math4.legacy.exception.NotFiniteNumberException;
24  import org.apache.commons.math4.legacy.exception.NotPositiveException;
25  import org.apache.commons.math4.core.jdkmath.JdkMath;
26  import org.apache.commons.rng.simple.RandomSource;
27  import org.junit.Assert;
28  import org.junit.Test;
29  
30  /**
31   * Test class for {@link EnumeratedIntegerDistribution}.
32   *
33   */
34  public class EnumeratedIntegerDistributionTest {
35  
36      /**
37       * The distribution object used for testing.
38       */
39      private final EnumeratedIntegerDistribution testDistribution;
40  
41      /**
42       * Creates the default distribution object used for testing.
43       */
44      public EnumeratedIntegerDistributionTest() {
45          // Non-sorted singleton array with duplicates should be allowed.
46          // Values with zero-probability do not extend the support.
47          testDistribution = new EnumeratedIntegerDistribution(
48                  new int[]{3, -1, 3, 7, -2, 8},
49                  new double[]{0.2, 0.2, 0.3, 0.3, 0.0, 0.0});
50      }
51  
52      /**
53       * Tests if the EnumeratedIntegerDistribution constructor throws
54       * exceptions for invalid data.
55       */
56      @Test
57      public void testExceptions() {
58          EnumeratedIntegerDistribution invalid = null;
59          try {
60              new EnumeratedIntegerDistribution(new int[]{1, 2}, new double[]{0.0});
61              Assert.fail("Expected DimensionMismatchException");
62          } catch (DimensionMismatchException e) {
63          }
64          try {
65              new EnumeratedIntegerDistribution(new int[]{1, 2}, new double[]{0.0, -1.0});
66              Assert.fail("Expected NotPositiveException");
67          } catch (NotPositiveException e) {
68          }
69          try {
70              new EnumeratedIntegerDistribution(new int[]{1, 2}, new double[]{0.0, 0.0});
71              Assert.fail("Expected MathArithmeticException");
72          } catch (MathArithmeticException e) {
73          }
74          try {
75            new EnumeratedIntegerDistribution(new int[]{1, 2}, new double[]{0.0, Double.NaN});
76              Assert.fail("Expected NotANumberException");
77          } catch (NotANumberException e) {
78          }
79          try {
80          new EnumeratedIntegerDistribution(new int[]{1, 2}, new double[]{0.0, Double.POSITIVE_INFINITY});
81              Assert.fail("Expected NotFiniteNumberException");
82          } catch (NotFiniteNumberException e) {
83          }
84          Assert.assertNull("Expected non-initialized DiscreteRealDistribution", invalid);
85      }
86  
87      /**
88       * Tests if the distribution returns proper probability values.
89       */
90      @Test
91      public void testProbability() {
92          int[] points = new int[]{-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8};
93          double[] results = new double[]{0, 0.2, 0, 0, 0, 0.5, 0, 0, 0, 0.3, 0};
94          for (int p = 0; p < points.length; p++) {
95              double probability = testDistribution.probability(points[p]);
96              Assert.assertEquals(results[p], probability, 0.0);
97          }
98      }
99  
100     /**
101      * Tests if the distribution returns proper cumulative probability values.
102      */
103     @Test
104     public void testCumulativeProbability() {
105         int[] points = new int[]{-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8};
106         double[] results = new double[]{0, 0.2, 0.2, 0.2, 0.2, 0.7, 0.7, 0.7, 0.7, 1.0, 1.0};
107         for (int p = 0; p < points.length; p++) {
108             double probability = testDistribution.cumulativeProbability(points[p]);
109             Assert.assertEquals(results[p], probability, 1e-10);
110         }
111     }
112 
113     /**
114      * Tests if the distribution returns proper mean value.
115      */
116     @Test
117     public void testGetNumericalMean() {
118         Assert.assertEquals(3.4, testDistribution.getMean(), 1e-10);
119     }
120 
121     /**
122      * Tests if the distribution returns proper variance.
123      */
124     @Test
125     public void testGetNumericalVariance() {
126         Assert.assertEquals(7.84, testDistribution.getVariance(), 1e-10);
127     }
128 
129     /**
130      * Tests if the distribution returns proper lower bound.
131      */
132     @Test
133     public void testGetSupportLowerBound() {
134         Assert.assertEquals(-1, testDistribution.getSupportLowerBound());
135     }
136 
137     /**
138      * Tests if the distribution returns proper upper bound.
139      */
140     @Test
141     public void testGetSupportUpperBound() {
142         Assert.assertEquals(7, testDistribution.getSupportUpperBound());
143     }
144 
145     /**
146      * Tests sampling.
147      */
148     @Test
149     public void testSample() {
150         final int n = 1000000;
151         final DiscreteDistribution.Sampler sampler =
152             testDistribution.createSampler(RandomSource.XO_RO_SHI_RO_128_PP.create());
153         final int[] samples = AbstractIntegerDistribution.sample(n, sampler);
154         Assert.assertEquals(n, samples.length);
155         double sum = 0;
156         double sumOfSquares = 0;
157         for (int i = 0; i < samples.length; i++) {
158             sum += samples[i];
159             sumOfSquares += samples[i] * samples[i];
160         }
161         final double mean = testDistribution.getMean();
162         Assert.assertEquals("Mean", mean, sum / n, mean * 1e-2);
163         final double var = testDistribution.getVariance();
164         Assert.assertEquals("Variance", var, sumOfSquares / n - JdkMath.pow(sum / n, 2), var * 1e-2);
165     }
166 
167     @Test
168     public void testCreateFromIntegers() {
169         final int[] data = new int[] {0, 1, 1, 2, 2, 2};
170         EnumeratedIntegerDistribution distribution = new EnumeratedIntegerDistribution(data);
171         Assert.assertEquals(0.5, distribution.probability(2), 0);
172         Assert.assertEquals(0.5, distribution.cumulativeProbability(1), 0);
173     }
174 }