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