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    *      https://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  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.distribution.continuous;
23  
24  import static org.junit.Assert.assertEquals;
25  import static org.junit.Assert.assertNull;
26  import static org.junit.Assert.assertTrue;
27  import static org.junit.Assert.fail;
28  
29  import java.util.HashMap;
30  import java.util.List;
31  import java.util.Map;
32  
33  import org.hipparchus.exception.MathIllegalArgumentException;
34  import org.hipparchus.exception.MathRuntimeException;
35  import org.hipparchus.util.Pair;
36  import org.junit.Test;
37  
38  /**
39   * Test class for {@link EnumeratedRealDistribution}.
40   */
41  public class EnumeratedRealDistributionTest {
42  
43      /**
44       * The distribution object used for testing.
45       */
46      private final EnumeratedRealDistribution testDistribution;
47  
48      /**
49       * Creates the default distribution object used for testing.
50       */
51      public EnumeratedRealDistributionTest() {
52          // Non-sorted singleton array with duplicates should be allowed.
53          // Values with zero-probability do not extend the support.
54          testDistribution = new EnumeratedRealDistribution(
55                  new double[]{3.0, -1.0, 3.0, 7.0, -2.0, 8.0},
56                  new double[]{0.2, 0.2, 0.3, 0.3, 0.0, 0.0});
57      }
58  
59      /**
60       * Tests if the {@link EnumeratedRealDistribution} constructor throws
61       * exceptions for invalid data.
62       */
63      @Test
64      public void testExceptions() {
65          EnumeratedRealDistribution invalid = null;
66          try {
67              invalid = new EnumeratedRealDistribution(new double[]{1.0, 2.0}, new double[]{0.0});
68              fail("Expected MathIllegalArgumentException");
69          } catch (MathIllegalArgumentException e) {
70          }
71          try{
72          invalid = new EnumeratedRealDistribution(new double[]{1.0, 2.0}, new double[]{0.0, -1.0});
73              fail("Expected MathIllegalArgumentException");
74          } catch (MathIllegalArgumentException e) {
75          }
76          try {
77              invalid = new EnumeratedRealDistribution(new double[]{1.0, 2.0}, new double[]{0.0, 0.0});
78              fail("Expected MathRuntimeException");
79          } catch (MathRuntimeException e) {
80          }
81          try {
82              invalid = new EnumeratedRealDistribution(new double[]{1.0, 2.0}, new double[]{0.0, Double.NaN});
83              fail("Expected MathIllegalArgumentException");
84          } catch (MathIllegalArgumentException e) {
85          }
86          try {
87              invalid = new EnumeratedRealDistribution(new double[]{1.0, 2.0}, new double[]{0.0, Double.POSITIVE_INFINITY});
88              fail("Expected MathIllegalArgumentException");
89          } catch (MathIllegalArgumentException e) {
90          }
91          assertNull("Expected non-initialized DiscreteRealDistribution", invalid);
92      }
93  
94      /**
95       * Tests if the distribution returns proper probability values.
96       */
97      @Test
98      public void testProbability() {
99          double[] points = new double[]{-2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0};
100         double[] results = new double[]{0, 0.2, 0, 0, 0, 0.5, 0, 0, 0, 0.3, 0};
101         for (int p = 0; p < points.length; p++) {
102             double density = testDistribution.probability(points[p]);
103             assertEquals(results[p], density, 0.0);
104         }
105     }
106 
107     /**
108      * Tests if the distribution returns proper density values.
109      */
110     @Test
111     public void testDensity() {
112         double[] points = new double[]{-2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0};
113         double[] results = new double[]{0, 0.2, 0, 0, 0, 0.5, 0, 0, 0, 0.3, 0};
114         for (int p = 0; p < points.length; p++) {
115             double density = testDistribution.density(points[p]);
116             assertEquals(results[p], density, 0.0);
117         }
118     }
119 
120     /**
121      * Tests if the distribution returns proper cumulative probability values.
122      */
123     @Test
124     public void testCumulativeProbability() {
125         double[] points = new double[]{-2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0};
126         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};
127         for (int p = 0; p < points.length; p++) {
128             double probability = testDistribution.cumulativeProbability(points[p]);
129             assertEquals(results[p], probability, 1e-10);
130         }
131     }
132 
133     /**
134      * Tests if the distribution returns proper mean value.
135      */
136     @Test
137     public void testGetNumericalMean() {
138         assertEquals(3.4, testDistribution.getNumericalMean(), 1e-10);
139     }
140 
141     /**
142      * Tests if the distribution returns proper variance.
143      */
144     @Test
145     public void testGetNumericalVariance() {
146         assertEquals(7.84, testDistribution.getNumericalVariance(), 1e-10);
147     }
148 
149     /**
150      * Tests if the distribution returns proper lower bound.
151      */
152     @Test
153     public void testGetSupportLowerBound() {
154         assertEquals(-1, testDistribution.getSupportLowerBound(), 0);
155     }
156 
157     /**
158      * Tests if the distribution returns proper upper bound.
159      */
160     @Test
161     public void testGetSupportUpperBound() {
162         assertEquals(7, testDistribution.getSupportUpperBound(), 0);
163     }
164 
165     /**
166      * Tests if the distribution returns properly that the support is connected.
167      */
168     @Test
169     public void testIsSupportConnected() {
170         assertTrue(testDistribution.isSupportConnected());
171     }
172 
173 
174     @Test
175     public void testIssue1065() {
176         // Test Distribution for inverseCumulativeProbability
177         //
178         //         ^
179         //         |
180         // 1.000   +--------------------------------o===============
181         //         |                               3|
182         //         |                                |
183         //         |                             1o=
184         // 0.750   +-------------------------> o==  .
185         //         |                          3|  . .
186         //         |                   0       |  . .
187         // 0.5625  +---------------> o==o======   . .
188         //         |                 |  .      .  . .
189         //         |                 |  .      .  . .
190         //         |                5|  .      .  . .
191         //         |                 |  .      .  . .
192         //         |             o===   .      .  . .
193         //         |             |   .  .      .  . .
194         //         |            4|   .  .      .  . .
195         //         |             |   .  .      .  . .
196         // 0.000   +=============----+--+------+--+-+--------------->
197         //                      14  18 21     28 31 33
198         //
199         // sum  = 4+5+0+3+1+3 = 16
200 
201         EnumeratedRealDistribution distribution = new EnumeratedRealDistribution(
202                 new double[] { 14.0, 18.0, 21.0, 28.0, 31.0, 33.0 },
203                 new double[] { 4.0 / 16.0, 5.0 / 16.0, 0.0 / 16.0, 3.0 / 16.0, 1.0 / 16.0, 3.0 / 16.0 });
204 
205         assertEquals(14.0, distribution.inverseCumulativeProbability(0.0000), 0.0);
206         assertEquals(14.0, distribution.inverseCumulativeProbability(0.2500), 0.0);
207         assertEquals(33.0, distribution.inverseCumulativeProbability(1.0000), 0.0);
208 
209         assertEquals(18.0, distribution.inverseCumulativeProbability(0.5000), 0.0);
210         assertEquals(18.0, distribution.inverseCumulativeProbability(0.5624), 0.0);
211         assertEquals(28.0, distribution.inverseCumulativeProbability(0.5626), 0.0);
212         assertEquals(31.0, distribution.inverseCumulativeProbability(0.7600), 0.0);
213         assertEquals(18.0, distribution.inverseCumulativeProbability(0.5625), 0.0);
214         assertEquals(28.0, distribution.inverseCumulativeProbability(0.7500), 0.0);
215     }
216 
217     @Test
218     public void testCreateFromDoubles() {
219         final double[] data = new double[] {0, 1, 1, 2, 2, 2};
220         EnumeratedRealDistribution distribution = new EnumeratedRealDistribution(data);
221         assertEquals(0.5, distribution.probability(2), 0);
222         assertEquals(0.5, distribution.cumulativeProbability(1), 0);
223     }
224 
225     @Test
226     public void testGetPmf() {
227         final double[] data = new double[] {0,0,1,1,2,2,2,2,3,4};
228         final EnumeratedRealDistribution distribution = new EnumeratedRealDistribution(data);
229         final List<Pair<Double, Double>> pmf = distribution.getPmf();
230         assertEquals(5, pmf.size());
231         final Map<Double, Double> pmfMap = new HashMap<Double, Double>();
232         pmfMap.put(0d, 0.2);
233         pmfMap.put(1d, 0.2);
234         pmfMap.put(2d, 0.4);
235         pmfMap.put(3d, 0.1);
236         pmfMap.put(4d, 0.1);
237         for (int i = 0; i < 5; i++) {
238             assertEquals(pmf.get(i).getSecond(), pmfMap.get(pmf.get(i).getFirst()), 0);
239         }
240     }
241 }