001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.math.random;
018
019 import java.io.BufferedReader;
020 import java.io.File;
021 import java.io.IOException;
022 import java.io.InputStreamReader;
023 import java.net.URL;
024 import java.util.ArrayList;
025
026 import junit.framework.Test;
027 import junit.framework.TestSuite;
028
029 import org.apache.commons.math.MathRuntimeException;
030 import org.apache.commons.math.RetryTestCase;
031 import org.apache.commons.math.TestUtils;
032 import org.apache.commons.math.stat.descriptive.SummaryStatistics;
033
034 /**
035 * Test cases for the EmpiricalDistribution class
036 *
037 * @version $Revision: 762087 $ $Date: 2009-04-05 10:20:18 -0400 (Sun, 05 Apr 2009) $
038 */
039
040 public final class EmpiricalDistributionTest extends RetryTestCase {
041
042 protected EmpiricalDistribution empiricalDistribution = null;
043 protected EmpiricalDistribution empiricalDistribution2 = null;
044 protected File file = null;
045 protected URL url = null;
046 protected double[] dataArray = null;
047
048 public EmpiricalDistributionTest(String name) {
049 super(name);
050 }
051
052 @Override
053 public void setUp() throws IOException {
054 empiricalDistribution = new EmpiricalDistributionImpl(100);
055 url = getClass().getResource("testData.txt");
056
057 empiricalDistribution2 = new EmpiricalDistributionImpl(100);
058 BufferedReader in =
059 new BufferedReader(new InputStreamReader(
060 url.openStream()));
061 String str = null;
062 ArrayList<Double> list = new ArrayList<Double>();
063 while ((str = in.readLine()) != null) {
064 list.add(Double.valueOf(str));
065 }
066 in.close();
067 in = null;
068
069 dataArray = new double[list.size()];
070 int i = 0;
071 for (Double data : list) {
072 dataArray[i] = data.doubleValue();
073 i++;
074 }
075 }
076
077 public static Test suite() {
078 TestSuite suite = new TestSuite(EmpiricalDistributionTest.class);
079 suite.setName("EmpiricalDistribution Tests");
080 return suite;
081 }
082
083 /**
084 * Test EmpiricalDistrbution.load() using sample data file.<br>
085 * Check that the sampleCount, mu and sigma match data in
086 * the sample data file.
087 */
088 public void testLoad() throws Exception {
089 empiricalDistribution.load(url);
090 // testData File has 10000 values, with mean ~ 5.0, std dev ~ 1
091 // Make sure that loaded distribution matches this
092 assertEquals(empiricalDistribution.getSampleStats().getN(),1000,10E-7);
093 //TODO: replace with statistical tests
094 assertEquals
095 (empiricalDistribution.getSampleStats().getMean(),
096 5.069831575018909,10E-7);
097 assertEquals
098 (empiricalDistribution.getSampleStats().getStandardDeviation(),
099 1.0173699343977738,10E-7);
100 }
101
102 /**
103 * Test EmpiricalDistrbution.load(double[]) using data taken from
104 * sample data file.<br>
105 * Check that the sampleCount, mu and sigma match data in
106 * the sample data file.
107 */
108 public void testDoubleLoad() throws Exception {
109 empiricalDistribution2.load(dataArray);
110 // testData File has 10000 values, with mean ~ 5.0, std dev ~ 1
111 // Make sure that loaded distribution matches this
112 assertEquals(empiricalDistribution2.getSampleStats().getN(),1000,10E-7);
113 //TODO: replace with statistical tests
114 assertEquals
115 (empiricalDistribution2.getSampleStats().getMean(),
116 5.069831575018909,10E-7);
117 assertEquals
118 (empiricalDistribution2.getSampleStats().getStandardDeviation(),
119 1.0173699343977738,10E-7);
120
121 double[] bounds = empiricalDistribution2.getUpperBounds();
122 assertEquals(bounds.length, 100);
123 assertEquals(bounds[99], 1.0, 10e-12);
124
125 }
126
127 /**
128 * Generate 1000 random values and make sure they look OK.<br>
129 * Note that there is a non-zero (but very small) probability that
130 * these tests will fail even if the code is working as designed.
131 */
132 public void testNext() throws Exception {
133 tstGen(0.1);
134 tstDoubleGen(0.1);
135 }
136
137 /**
138 * Make sure exception thrown if digest getNext is attempted
139 * before loading empiricalDistribution.
140 */
141 public void testNexFail() {
142 try {
143 empiricalDistribution.getNextValue();
144 empiricalDistribution2.getNextValue();
145 fail("Expecting IllegalStateException");
146 } catch (IllegalStateException ex) {
147 // expected
148 } catch (Exception e) {
149 fail("wrong exception caught");
150 }
151 }
152
153 /**
154 * Make sure we can handle a grid size that is too fine
155 */
156 public void testGridTooFine() throws Exception {
157 empiricalDistribution = new EmpiricalDistributionImpl(1001);
158 tstGen(0.1);
159 empiricalDistribution2 = new EmpiricalDistributionImpl(1001);
160 tstDoubleGen(0.1);
161 }
162
163 /**
164 * How about too fat?
165 */
166 public void testGridTooFat() throws Exception {
167 empiricalDistribution = new EmpiricalDistributionImpl(1);
168 tstGen(5); // ridiculous tolerance; but ridiculous grid size
169 // really just checking to make sure we do not bomb
170 empiricalDistribution2 = new EmpiricalDistributionImpl(1);
171 tstDoubleGen(5);
172 }
173
174 /**
175 * Test bin index overflow problem (BZ 36450)
176 */
177 public void testBinIndexOverflow() throws Exception {
178 double[] x = new double[] {9474.94326071674, 2080107.8865462579};
179 new EmpiricalDistributionImpl().load(x);
180 }
181
182 public void testSerialization() {
183 // Empty
184 EmpiricalDistribution dist = new EmpiricalDistributionImpl();
185 EmpiricalDistribution dist2 = (EmpiricalDistribution) TestUtils.serializeAndRecover(dist);
186 verifySame(dist, dist2);
187
188 // Loaded
189 empiricalDistribution2.load(dataArray);
190 dist2 = (EmpiricalDistribution) TestUtils.serializeAndRecover(empiricalDistribution2);
191 verifySame(empiricalDistribution2, dist2);
192 }
193
194 public void testLoadNullDoubleArray() {
195 EmpiricalDistribution dist = new EmpiricalDistributionImpl();
196 try {
197 dist.load((double[]) null);
198 fail("load((double[]) null) expected RuntimeException");
199 } catch (MathRuntimeException e) {
200 // expected
201 } catch (Exception e) {
202 fail("wrong exception caught");
203 }
204 }
205
206 public void testLoadNullURL() throws Exception {
207 EmpiricalDistribution dist = new EmpiricalDistributionImpl();
208 try {
209 dist.load((URL) null);
210 fail("load((URL) null) expected NullPointerException");
211 } catch (NullPointerException e) {
212 // expected
213 } catch (Exception e) {
214 fail("wrong exception caught");
215 }
216 }
217
218 public void testLoadNullFile() throws Exception {
219 EmpiricalDistribution dist = new EmpiricalDistributionImpl();
220 try {
221 dist.load((File) null);
222 fail("load((File) null) expected NullPointerException");
223 } catch (NullPointerException e) {
224 // expected
225 } catch (Exception e) {
226 fail("wrong exception caught");
227 }
228 }
229
230 private void verifySame(EmpiricalDistribution d1, EmpiricalDistribution d2) {
231 assertEquals(d1.isLoaded(), d2.isLoaded());
232 assertEquals(d1.getBinCount(), d2.getBinCount());
233 assertEquals(d1.getSampleStats(), d2.getSampleStats());
234 if (d1.isLoaded()) {
235 for (int i = 0; i < d1.getUpperBounds().length; i++) {
236 assertEquals(d1.getUpperBounds()[i], d2.getUpperBounds()[i], 0);
237 }
238 assertEquals(d1.getBinStats(), d2.getBinStats());
239 }
240 }
241
242 private void tstGen(double tolerance)throws Exception {
243 empiricalDistribution.load(url);
244 SummaryStatistics stats = new SummaryStatistics();
245 for (int i = 1; i < 1000; i++) {
246 stats.addValue(empiricalDistribution.getNextValue());
247 }
248 assertEquals("mean", stats.getMean(),5.069831575018909,tolerance);
249 assertEquals
250 ("std dev", stats.getStandardDeviation(),1.0173699343977738,tolerance);
251 }
252
253 private void tstDoubleGen(double tolerance)throws Exception {
254 empiricalDistribution2.load(dataArray);
255 SummaryStatistics stats = new SummaryStatistics();
256 for (int i = 1; i < 1000; i++) {
257 stats.addValue(empiricalDistribution2.getNextValue());
258 }
259 assertEquals("mean", stats.getMean(),5.069831575018909,tolerance);
260 assertEquals
261 ("std dev", stats.getStandardDeviation(),1.0173699343977738,tolerance);
262 }
263 }