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.stat.inference; 018 019 import java.util.ArrayList; 020 import java.util.List; 021 022 import junit.framework.Test; 023 import junit.framework.TestCase; 024 import junit.framework.TestSuite; 025 import org.apache.commons.math.stat.descriptive.SummaryStatistics; 026 /** 027 * Test cases for the TestUtils class. 028 * 029 * @version $Revision: 762087 $ $Date: 2009-04-05 10:20:18 -0400 (Sun, 05 Apr 2009) $ 030 */ 031 032 public class TestUtilsTest extends TestCase { 033 034 public TestUtilsTest(String name) { 035 super(name); 036 } 037 038 public static Test suite() { 039 TestSuite suite = new TestSuite(TestUtilsTest.class); 040 suite.setName("TestUtils Tests"); 041 return suite; 042 } 043 044 public void testChiSquare() throws Exception { 045 046 // Target values computed using R version 1.8.1 047 // Some assembly required ;-) 048 // Use sum((obs - exp)^2/exp) for the chi-square statistic and 049 // 1 - pchisq(sum((obs - exp)^2/exp), length(obs) - 1) for the p-value 050 051 long[] observed = {10, 9, 11}; 052 double[] expected = {10, 10, 10}; 053 assertEquals("chi-square statistic", 0.2, TestUtils.chiSquare(expected, observed), 10E-12); 054 assertEquals("chi-square p-value", 0.904837418036, TestUtils.chiSquareTest(expected, observed), 1E-10); 055 056 long[] observed1 = { 500, 623, 72, 70, 31 }; 057 double[] expected1 = { 485, 541, 82, 61, 37 }; 058 assertEquals( "chi-square test statistic", 9.023307936427388, TestUtils.chiSquare(expected1, observed1), 1E-10); 059 assertEquals("chi-square p-value", 0.06051952647453607, TestUtils.chiSquareTest(expected1, observed1), 1E-9); 060 assertTrue("chi-square test reject", TestUtils.chiSquareTest(expected1, observed1, 0.07)); 061 assertTrue("chi-square test accept", !TestUtils.chiSquareTest(expected1, observed1, 0.05)); 062 063 try { 064 TestUtils.chiSquareTest(expected1, observed1, 95); 065 fail("alpha out of range, IllegalArgumentException expected"); 066 } catch (IllegalArgumentException ex) { 067 // expected 068 } 069 070 long[] tooShortObs = { 0 }; 071 double[] tooShortEx = { 1 }; 072 try { 073 TestUtils.chiSquare(tooShortEx, tooShortObs); 074 fail("arguments too short, IllegalArgumentException expected"); 075 } catch (IllegalArgumentException ex) { 076 // expected 077 } 078 079 // unmatched arrays 080 long[] unMatchedObs = { 0, 1, 2, 3 }; 081 double[] unMatchedEx = { 1, 1, 2 }; 082 try { 083 TestUtils.chiSquare(unMatchedEx, unMatchedObs); 084 fail("arrays have different lengths, IllegalArgumentException expected"); 085 } catch (IllegalArgumentException ex) { 086 // expected 087 } 088 089 // 0 expected count 090 expected[0] = 0; 091 try { 092 TestUtils.chiSquareTest(expected, observed, .01); 093 fail("bad expected count, IllegalArgumentException expected"); 094 } catch (IllegalArgumentException ex) { 095 // expected 096 } 097 098 // negative observed count 099 expected[0] = 1; 100 observed[0] = -1; 101 try { 102 TestUtils.chiSquareTest(expected, observed, .01); 103 fail("bad expected count, IllegalArgumentException expected"); 104 } catch (IllegalArgumentException ex) { 105 // expected 106 } 107 108 } 109 110 public void testChiSquareIndependence() throws Exception { 111 112 // Target values computed using R version 1.8.1 113 114 long[][] counts = { {40, 22, 43}, {91, 21, 28}, {60, 10, 22}}; 115 assertEquals( "chi-square test statistic", 22.709027688, TestUtils.chiSquare(counts), 1E-9); 116 assertEquals("chi-square p-value", 0.000144751460134, TestUtils.chiSquareTest(counts), 1E-9); 117 assertTrue("chi-square test reject", TestUtils.chiSquareTest(counts, 0.0002)); 118 assertTrue("chi-square test accept", !TestUtils.chiSquareTest(counts, 0.0001)); 119 120 long[][] counts2 = {{10, 15}, {30, 40}, {60, 90} }; 121 assertEquals( "chi-square test statistic", 0.168965517241, TestUtils.chiSquare(counts2), 1E-9); 122 assertEquals("chi-square p-value",0.918987499852, TestUtils.chiSquareTest(counts2), 1E-9); 123 assertTrue("chi-square test accept", !TestUtils.chiSquareTest(counts2, 0.1)); 124 125 // ragged input array 126 long[][] counts3 = { {40, 22, 43}, {91, 21, 28}, {60, 10}}; 127 try { 128 TestUtils.chiSquare(counts3); 129 fail("Expecting IllegalArgumentException"); 130 } catch (IllegalArgumentException ex) { 131 // expected 132 } 133 134 // insufficient data 135 long[][] counts4 = {{40, 22, 43}}; 136 try { 137 TestUtils.chiSquare(counts4); 138 fail("Expecting IllegalArgumentException"); 139 } catch (IllegalArgumentException ex) { 140 // expected 141 } 142 long[][] counts5 = {{40}, {40}, {30}, {10}}; 143 try { 144 TestUtils.chiSquare(counts5); 145 fail("Expecting IllegalArgumentException"); 146 } catch (IllegalArgumentException ex) { 147 // expected 148 } 149 150 // negative counts 151 long[][] counts6 = {{10, -2}, {30, 40}, {60, 90} }; 152 try { 153 TestUtils.chiSquare(counts6); 154 fail("Expecting IllegalArgumentException"); 155 } catch (IllegalArgumentException ex) { 156 // expected 157 } 158 159 // bad alpha 160 try { 161 TestUtils.chiSquareTest(counts, 0); 162 fail("Expecting IllegalArgumentException"); 163 } catch (IllegalArgumentException ex) { 164 // expected 165 } 166 } 167 168 public void testChiSquareLargeTestStatistic() throws Exception { 169 double[] exp = new double[] { 170 3389119.5, 649136.6, 285745.4, 25357364.76, 11291189.78, 543628.0, 171 232921.0, 437665.75 172 }; 173 174 long[] obs = new long[] { 175 2372383, 584222, 257170, 17750155, 7903832, 489265, 209628, 393899 176 }; 177 org.apache.commons.math.stat.inference.ChiSquareTestImpl csti = 178 new org.apache.commons.math.stat.inference.ChiSquareTestImpl(); 179 double cst = csti.chiSquareTest(exp, obs); 180 assertEquals("chi-square p-value", 0.0, cst, 1E-3); 181 assertEquals( "chi-square test statistic", 182 114875.90421929007, TestUtils.chiSquare(exp, obs), 1E-9); 183 } 184 185 /** Contingency table containing zeros - PR # 32531 */ 186 public void testChiSquareZeroCount() throws Exception { 187 // Target values computed using R version 1.8.1 188 long[][] counts = { {40, 0, 4}, {91, 1, 2}, {60, 2, 0}}; 189 assertEquals( "chi-square test statistic", 9.67444662263, 190 TestUtils.chiSquare(counts), 1E-9); 191 assertEquals("chi-square p-value", 0.0462835770603, 192 TestUtils.chiSquareTest(counts), 1E-9); 193 } 194 195 private double[] tooShortObs = { 1.0 }; 196 private double[] emptyObs = {}; 197 private SummaryStatistics emptyStats = new SummaryStatistics(); 198 199 public void testOneSampleT() throws Exception { 200 double[] observed = 201 {93.0, 103.0, 95.0, 101.0, 91.0, 105.0, 96.0, 94.0, 101.0, 88.0, 98.0, 94.0, 101.0, 92.0, 95.0 }; 202 double mu = 100.0; 203 SummaryStatistics sampleStats = null; 204 sampleStats = new SummaryStatistics(); 205 for (int i = 0; i < observed.length; i++) { 206 sampleStats.addValue(observed[i]); 207 } 208 209 // Target comparison values computed using R version 1.8.1 (Linux version) 210 assertEquals("t statistic", -2.81976445346, 211 TestUtils.t(mu, observed), 10E-10); 212 assertEquals("t statistic", -2.81976445346, 213 TestUtils.t(mu, sampleStats), 10E-10); 214 assertEquals("p value", 0.0136390585873, 215 TestUtils.tTest(mu, observed), 10E-10); 216 assertEquals("p value", 0.0136390585873, 217 TestUtils.tTest(mu, sampleStats), 10E-10); 218 219 try { 220 TestUtils.t(mu, (double[]) null); 221 fail("arguments too short, IllegalArgumentException expected"); 222 } catch (IllegalArgumentException ex) { 223 // expected 224 } 225 226 try { 227 TestUtils.t(mu, (SummaryStatistics) null); 228 fail("arguments too short, IllegalArgumentException expected"); 229 } catch (IllegalArgumentException ex) { 230 // expected 231 } 232 233 try { 234 TestUtils.t(mu, emptyObs); 235 fail("arguments too short, IllegalArgumentException expected"); 236 } catch (IllegalArgumentException ex) { 237 // expected 238 } 239 240 try { 241 TestUtils.t(mu, emptyStats); 242 fail("arguments too short, IllegalArgumentException expected"); 243 } catch (IllegalArgumentException ex) { 244 // expected 245 } 246 247 try { 248 TestUtils.t(mu, tooShortObs); 249 fail("insufficient data to compute t statistic, IllegalArgumentException expected"); 250 } catch (IllegalArgumentException ex) { 251 // expected 252 } 253 try { 254 TestUtils.tTest(mu, tooShortObs); 255 fail("insufficient data to perform t test, IllegalArgumentException expected"); 256 } catch (IllegalArgumentException ex) { 257 // expected 258 } 259 260 try { 261 TestUtils.t(mu, (SummaryStatistics) null); 262 fail("insufficient data to compute t statistic, IllegalArgumentException expected"); 263 } catch (IllegalArgumentException ex) { 264 // expected 265 } 266 try { 267 TestUtils.tTest(mu, (SummaryStatistics) null); 268 fail("insufficient data to perform t test, IllegalArgumentException expected"); 269 } catch (IllegalArgumentException ex) { 270 // expected 271 } 272 } 273 274 public void testOneSampleTTest() throws Exception { 275 double[] oneSidedP = 276 {2d, 0d, 6d, 6d, 3d, 3d, 2d, 3d, -6d, 6d, 6d, 6d, 3d, 0d, 1d, 1d, 0d, 2d, 3d, 3d }; 277 SummaryStatistics oneSidedPStats = new SummaryStatistics(); 278 for (int i = 0; i < oneSidedP.length; i++) { 279 oneSidedPStats.addValue(oneSidedP[i]); 280 } 281 // Target comparison values computed using R version 1.8.1 (Linux version) 282 assertEquals("one sample t stat", 3.86485535541, 283 TestUtils.t(0d, oneSidedP), 10E-10); 284 assertEquals("one sample t stat", 3.86485535541, 285 TestUtils.t(0d, oneSidedPStats),1E-10); 286 assertEquals("one sample p value", 0.000521637019637, 287 TestUtils.tTest(0d, oneSidedP) / 2d, 10E-10); 288 assertEquals("one sample p value", 0.000521637019637, 289 TestUtils.tTest(0d, oneSidedPStats) / 2d, 10E-5); 290 assertTrue("one sample t-test reject", TestUtils.tTest(0d, oneSidedP, 0.01)); 291 assertTrue("one sample t-test reject", TestUtils.tTest(0d, oneSidedPStats, 0.01)); 292 assertTrue("one sample t-test accept", !TestUtils.tTest(0d, oneSidedP, 0.0001)); 293 assertTrue("one sample t-test accept", !TestUtils.tTest(0d, oneSidedPStats, 0.0001)); 294 295 try { 296 TestUtils.tTest(0d, oneSidedP, 95); 297 fail("alpha out of range, IllegalArgumentException expected"); 298 } catch (IllegalArgumentException ex) { 299 // expected 300 } 301 302 try { 303 TestUtils.tTest(0d, oneSidedPStats, 95); 304 fail("alpha out of range, IllegalArgumentException expected"); 305 } catch (IllegalArgumentException ex) { 306 // expected 307 } 308 309 } 310 311 public void testTwoSampleTHeterscedastic() throws Exception { 312 double[] sample1 = { 7d, -4d, 18d, 17d, -3d, -5d, 1d, 10d, 11d, -2d }; 313 double[] sample2 = { -1d, 12d, -1d, -3d, 3d, -5d, 5d, 2d, -11d, -1d, -3d }; 314 SummaryStatistics sampleStats1 = new SummaryStatistics(); 315 for (int i = 0; i < sample1.length; i++) { 316 sampleStats1.addValue(sample1[i]); 317 } 318 SummaryStatistics sampleStats2 = new SummaryStatistics(); 319 for (int i = 0; i < sample2.length; i++) { 320 sampleStats2.addValue(sample2[i]); 321 } 322 323 // Target comparison values computed using R version 1.8.1 (Linux version) 324 assertEquals("two sample heteroscedastic t stat", 1.60371728768, 325 TestUtils.t(sample1, sample2), 1E-10); 326 assertEquals("two sample heteroscedastic t stat", 1.60371728768, 327 TestUtils.t(sampleStats1, sampleStats2), 1E-10); 328 assertEquals("two sample heteroscedastic p value", 0.128839369622, 329 TestUtils.tTest(sample1, sample2), 1E-10); 330 assertEquals("two sample heteroscedastic p value", 0.128839369622, 331 TestUtils.tTest(sampleStats1, sampleStats2), 1E-10); 332 assertTrue("two sample heteroscedastic t-test reject", 333 TestUtils.tTest(sample1, sample2, 0.2)); 334 assertTrue("two sample heteroscedastic t-test reject", 335 TestUtils.tTest(sampleStats1, sampleStats2, 0.2)); 336 assertTrue("two sample heteroscedastic t-test accept", 337 !TestUtils.tTest(sample1, sample2, 0.1)); 338 assertTrue("two sample heteroscedastic t-test accept", 339 !TestUtils.tTest(sampleStats1, sampleStats2, 0.1)); 340 341 try { 342 TestUtils.tTest(sample1, sample2, .95); 343 fail("alpha out of range, IllegalArgumentException expected"); 344 } catch (IllegalArgumentException ex) { 345 // expected 346 } 347 348 try { 349 TestUtils.tTest(sampleStats1, sampleStats2, .95); 350 fail("alpha out of range, IllegalArgumentException expected"); 351 } catch (IllegalArgumentException ex) { 352 // expected 353 } 354 355 try { 356 TestUtils.tTest(sample1, tooShortObs, .01); 357 fail("insufficient data, IllegalArgumentException expected"); 358 } catch (IllegalArgumentException ex) { 359 // expected 360 } 361 362 try { 363 TestUtils.tTest(sampleStats1, (SummaryStatistics) null, .01); 364 fail("insufficient data, IllegalArgumentException expected"); 365 } catch (IllegalArgumentException ex) { 366 // expected 367 } 368 369 try { 370 TestUtils.tTest(sample1, tooShortObs); 371 fail("insufficient data, IllegalArgumentException expected"); 372 } catch (IllegalArgumentException ex) { 373 // expected 374 } 375 376 try { 377 TestUtils.tTest(sampleStats1, (SummaryStatistics) null); 378 fail("insufficient data, IllegalArgumentException expected"); 379 } catch (IllegalArgumentException ex) { 380 // expected 381 } 382 383 try { 384 TestUtils.t(sample1, tooShortObs); 385 fail("insufficient data, IllegalArgumentException expected"); 386 } catch (IllegalArgumentException ex) { 387 // expected 388 } 389 390 try { 391 TestUtils.t(sampleStats1, (SummaryStatistics) null); 392 fail("insufficient data, IllegalArgumentException expected"); 393 } catch (IllegalArgumentException ex) { 394 // expected 395 } 396 } 397 public void testTwoSampleTHomoscedastic() throws Exception { 398 double[] sample1 ={2, 4, 6, 8, 10, 97}; 399 double[] sample2 = {4, 6, 8, 10, 16}; 400 SummaryStatistics sampleStats1 = new SummaryStatistics(); 401 for (int i = 0; i < sample1.length; i++) { 402 sampleStats1.addValue(sample1[i]); 403 } 404 SummaryStatistics sampleStats2 = new SummaryStatistics(); 405 for (int i = 0; i < sample2.length; i++) { 406 sampleStats2.addValue(sample2[i]); 407 } 408 409 // Target comparison values computed using R version 1.8.1 (Linux version) 410 assertEquals("two sample homoscedastic t stat", 0.73096310086, 411 TestUtils.homoscedasticT(sample1, sample2), 10E-11); 412 assertEquals("two sample homoscedastic p value", 0.4833963785, 413 TestUtils.homoscedasticTTest(sampleStats1, sampleStats2), 1E-10); 414 assertTrue("two sample homoscedastic t-test reject", 415 TestUtils.homoscedasticTTest(sample1, sample2, 0.49)); 416 assertTrue("two sample homoscedastic t-test accept", 417 !TestUtils.homoscedasticTTest(sample1, sample2, 0.48)); 418 } 419 420 public void testSmallSamples() throws Exception { 421 double[] sample1 = {1d, 3d}; 422 double[] sample2 = {4d, 5d}; 423 424 // Target values computed using R, version 1.8.1 (linux version) 425 assertEquals(-2.2360679775, TestUtils.t(sample1, sample2), 426 1E-10); 427 assertEquals(0.198727388935, TestUtils.tTest(sample1, sample2), 428 1E-10); 429 } 430 431 public void testPaired() throws Exception { 432 double[] sample1 = {1d, 3d, 5d, 7d}; 433 double[] sample2 = {0d, 6d, 11d, 2d}; 434 double[] sample3 = {5d, 7d, 8d, 10d}; 435 436 // Target values computed using R, version 1.8.1 (linux version) 437 assertEquals(-0.3133, TestUtils.pairedT(sample1, sample2), 1E-4); 438 assertEquals(0.774544295819, TestUtils.pairedTTest(sample1, sample2), 1E-10); 439 assertEquals(0.001208, TestUtils.pairedTTest(sample1, sample3), 1E-6); 440 assertFalse(TestUtils.pairedTTest(sample1, sample3, .001)); 441 assertTrue(TestUtils.pairedTTest(sample1, sample3, .002)); 442 } 443 444 private double[] classA = 445 {93.0, 103.0, 95.0, 101.0}; 446 private double[] classB = 447 {99.0, 92.0, 102.0, 100.0, 102.0}; 448 private double[] classC = 449 {110.0, 115.0, 111.0, 117.0, 128.0}; 450 451 private List<double[]> classes = new ArrayList<double[]>(); 452 private OneWayAnova oneWayAnova = new OneWayAnovaImpl(); 453 454 public void testOneWayAnovaUtils() throws Exception { 455 classes.add(classA); 456 classes.add(classB); 457 classes.add(classC); 458 assertEquals(oneWayAnova.anovaFValue(classes), 459 TestUtils.oneWayAnovaFValue(classes), 10E-12); 460 assertEquals(oneWayAnova.anovaPValue(classes), 461 TestUtils.oneWayAnovaPValue(classes), 10E-12); 462 assertEquals(oneWayAnova.anovaTest(classes, 0.01), 463 TestUtils.oneWayAnovaTest(classes, 0.01)); 464 } 465 }