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 }