    1   /*
    2    * Copyright 2005 The Apache Software Foundation.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  package org.apache.commons.math.stat.inference;
    17
    18  import junit.framework.Test;
    19  import junit.framework.TestCase;
    20  import junit.framework.TestSuite;
    21  import org.apache.commons.math.stat.descriptive.SummaryStatistics;
    22  /***
    23   * Test cases for the TestUtils class.
    24   *
    25   * @version $Revision: 209144 $ $Date: 2005-07-04 16:30:05 -0700 (Mon, 04 Jul 2005) $
    26   */
    27
    28  public class TestUtilsTest extends TestCase {
    29
    30      public TestUtilsTest(String name) {
    31          super(name);
    32      }
    33
    34      public void setUp() {
    35      }
    36
    37      public static Test suite() {
    38          TestSuite suite = new TestSuite(TestUtilsTest.class);
    39          suite.setName("TestUtils Tests");
    40          return suite;
    41      }
    42
    43      public void testChiSquare() throws Exception {
    44
    45          // Target values computed using R version 1.8.1
    46          // Some assembly required ;-)
    47          //      Use sum((obs - exp)^2/exp) for the chi-square statistic and
    48          //      1 - pchisq(sum((obs - exp)^2/exp), length(obs) - 1) for the p-value
    49
    50          long[] observed = {10, 9, 11};
    51          double[] expected = {10, 10, 10};
    52          assertEquals("chi-square statistic", 0.2,  TestUtils.chiSquare(expected, observed), 10E-12);
    53          assertEquals("chi-square p-value", 0.904837418036, TestUtils.chiSquareTest(expected, observed), 1E-10);
    54
    55          long[] observed1 = { 500, 623, 72, 70, 31 };
    56          double[] expected1 = { 485, 541, 82, 61, 37 };
    57          assertEquals( "chi-square test statistic", 16.4131070362, TestUtils.chiSquare(expected1, observed1), 1E-10);
    58          assertEquals("chi-square p-value", 0.002512096, TestUtils.chiSquareTest(expected1, observed1), 1E-9);
    59          assertTrue("chi-square test reject", TestUtils.chiSquareTest(expected1, observed1, 0.003));
    60          assertTrue("chi-square test accept", !TestUtils.chiSquareTest(expected1, observed1, 0.002));
    61
    62          try {
    63              TestUtils.chiSquareTest(expected1, observed1, 95);
    64              fail("alpha out of range, IllegalArgumentException expected");
    65          } catch (IllegalArgumentException ex) {
    66              // expected
    67          }
    68
    69          long[] tooShortObs = { 0 };
    70          double[] tooShortEx = { 1 };
    71          try {
    72              TestUtils.chiSquare(tooShortEx, tooShortObs);
    73              fail("arguments too short, IllegalArgumentException expected");
    74          } catch (IllegalArgumentException ex) {
    75              // expected
    76          }
    77
    78          // unmatched arrays
    79          long[] unMatchedObs = { 0, 1, 2, 3 };
    80          double[] unMatchedEx = { 1, 1, 2 };
    81          try {
    82              TestUtils.chiSquare(unMatchedEx, unMatchedObs);
    83              fail("arrays have different lengths, IllegalArgumentException expected");
    84          } catch (IllegalArgumentException ex) {
    85              // expected
    86          }
    87
    88          // 0 expected count
    89          expected[0] = 0;
    90          try {
    91              TestUtils.chiSquareTest(expected, observed, .01);
    92              fail("bad expected count, IllegalArgumentException expected");
    93          } catch (IllegalArgumentException ex) {
    94              // expected
    95          }
    96
    97          // negative observed count
    98          expected[0] = 1;
    99          observed[0] = -1;
    100         try {
    101             TestUtils.chiSquareTest(expected, observed, .01);
    102             fail("bad expected count, IllegalArgumentException expected");
    103         } catch (IllegalArgumentException ex) {
    104             // expected
    105         }
    106
    107     }
    108
    109     public void testChiSquareIndependence() throws Exception {
    110
    111         // Target values computed using R version 1.8.1
    112
    113         long[][] counts = { {40, 22, 43}, {91, 21, 28}, {60, 10, 22}};
    114         assertEquals( "chi-square test statistic", 22.709027688, TestUtils.chiSquare(counts), 1E-9);
    115         assertEquals("chi-square p-value", 0.000144751460134, TestUtils.chiSquareTest(counts), 1E-9);
    116         assertTrue("chi-square test reject", TestUtils.chiSquareTest(counts, 0.0002));
    117         assertTrue("chi-square test accept", !TestUtils.chiSquareTest(counts, 0.0001));
    118
    119         long[][] counts2 = {{10, 15}, {30, 40}, {60, 90} };
    120         assertEquals( "chi-square test statistic", 0.168965517241, TestUtils.chiSquare(counts2), 1E-9);
    121         assertEquals("chi-square p-value",0.918987499852, TestUtils.chiSquareTest(counts2), 1E-9);
    122         assertTrue("chi-square test accept", !TestUtils.chiSquareTest(counts2, 0.1));
    123
    124         // ragged input array
    125         long[][] counts3 = { {40, 22, 43}, {91, 21, 28}, {60, 10}};
    126         try {
    127             TestUtils.chiSquare(counts3);
    128             fail("Expecting IllegalArgumentException");
    129         } catch (IllegalArgumentException ex) {
    130             // expected
    131         }
    132
    133         // insufficient data
    134         long[][] counts4 = {{40, 22, 43}};
    135         try {
    136             TestUtils.chiSquare(counts4);
    137             fail("Expecting IllegalArgumentException");
    138         } catch (IllegalArgumentException ex) {
    139             // expected
    140         }
    141         long[][] counts5 = {{40}, {40}, {30}, {10}};
    142         try {
    143             TestUtils.chiSquare(counts5);
    144             fail("Expecting IllegalArgumentException");
    145         } catch (IllegalArgumentException ex) {
    146             // expected
    147         }
    148
    149         // negative counts
    150         long[][] counts6 = {{10, -2}, {30, 40}, {60, 90} };
    151         try {
    152             TestUtils.chiSquare(counts6);
    153             fail("Expecting IllegalArgumentException");
    154         } catch (IllegalArgumentException ex) {
    155             // expected
    156         }
    157
    158         // bad alpha
    159         try {
    160             TestUtils.chiSquareTest(counts, 0);
    161             fail("Expecting IllegalArgumentException");
    162         } catch (IllegalArgumentException ex) {
    163             // expected
    164         }
    165     }
    166
    167     public void testChiSquareLargeTestStatistic() throws Exception {
    168         double[] exp = new double[] {
    169                 3389119.5, 649136.6, 285745.4, 25357364.76, 11291189.78, 543628.0,
    170                 232921.0, 437665.75
    171         };
    172
    173         long[] obs = new long[] {
    174                 2372383, 584222, 257170, 17750155, 7903832, 489265, 209628, 393899
    175         };
    176         org.apache.commons.math.stat.inference.ChiSquareTestImpl csti =
    177             new org.apache.commons.math.stat.inference.ChiSquareTestImpl();
    178         double cst = csti.chiSquareTest(exp, obs);
    179         assertEquals("chi-square p-value", 0.0, cst, 1E-3);
    180         assertEquals( "chi-square test statistic",
    181                 3624883.342907764, TestUtils.chiSquare(exp, obs), 1E-9);
    182     }
    183
    184     /*** Contingency table containing zeros - PR # 32531 */
    185     public void testChiSquareZeroCount() throws Exception {
    186         // Target values computed using R version 1.8.1
    187         long[][] counts = { {40, 0, 4}, {91, 1, 2}, {60, 2, 0}};
    188         assertEquals( "chi-square test statistic", 9.67444662263,
    189                 TestUtils.chiSquare(counts), 1E-9);
    190         assertEquals("chi-square p-value", 0.0462835770603,
    191                 TestUtils.chiSquareTest(counts), 1E-9);
    192     }
    193
    194     private double[] tooShortObs = { 1.0 };
    195     private double[] nullObserved = null;
    196     private double[] emptyObs = {};
    197     private SummaryStatistics emptyStats = SummaryStatistics.newInstance();
    198     private SummaryStatistics nullStats = null;
    199     SummaryStatistics tooShortStats = null;
    200
    201     public void testOneSampleT() throws Exception {
    202         double[] observed =
    203             {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 };
    204         double mu = 100.0;
    205         SummaryStatistics sampleStats = null;
    206         sampleStats = SummaryStatistics.newInstance();
    207         for (int i = 0; i < observed.length; i++) {
    208             sampleStats.addValue(observed[i]);
    209         }
    210
    211         // Target comparison values computed using R version 1.8.1 (Linux version)
    212         assertEquals("t statistic",  -2.81976445346,
    213                 TestUtils.t(mu, observed), 10E-10);
    214         assertEquals("t statistic",  -2.81976445346,
    215                 TestUtils.t(mu, sampleStats), 10E-10);
    216         assertEquals("p value", 0.0136390585873,
    217                 TestUtils.tTest(mu, observed), 10E-10);
    218         assertEquals("p value", 0.0136390585873,
    219                 TestUtils.tTest(mu, sampleStats), 10E-10);
    220
    221         try {
    222             TestUtils.t(mu, nullObserved);
    223             fail("arguments too short, IllegalArgumentException expected");
    224         } catch (IllegalArgumentException ex) {
    225             // expected
    226         }
    227
    228         try {
    229             TestUtils.t(mu, nullStats);
    230             fail("arguments too short, IllegalArgumentException expected");
    231         } catch (IllegalArgumentException ex) {
    232             // expected
    233         }
    234
    235         try {
    236             TestUtils.t(mu, emptyObs);
    237             fail("arguments too short, IllegalArgumentException expected");
    238         } catch (IllegalArgumentException ex) {
    239             // expected
    240         }
    241
    242         try {
    243             TestUtils.t(mu, emptyStats);
    244             fail("arguments too short, IllegalArgumentException expected");
    245         } catch (IllegalArgumentException ex) {
    246             // expected
    247         }
    248
    249         try {
    250             TestUtils.t(mu, tooShortObs);
    251             fail("insufficient data to compute t statistic, IllegalArgumentException expected");
    252         } catch (IllegalArgumentException ex) {
    253             // exptected
    254         }
    255         try {
    256             TestUtils.tTest(mu, tooShortObs);
    257             fail("insufficient data to perform t test, IllegalArgumentException expected");
    258         } catch (IllegalArgumentException ex) {
    259             // expected
    260         }
    261
    262         try {
    263             TestUtils.t(mu, tooShortStats);
    264             fail("insufficient data to compute t statistic, IllegalArgumentException expected");
    265         } catch (IllegalArgumentException ex) {
    266             // exptected
    267         }
    268         try {
    269             TestUtils.tTest(mu, tooShortStats);
    270             fail("insufficient data to perform t test, IllegalArgumentException expected");
    271         } catch (IllegalArgumentException ex) {
    272             // exptected
    273         }
    274     }
    275
    276     public void testOneSampleTTest() throws Exception {
    277         double[] oneSidedP =
    278             {2d, 0d, 6d, 6d, 3d, 3d, 2d, 3d, -6d, 6d, 6d, 6d, 3d, 0d, 1d, 1d, 0d, 2d, 3d, 3d };
    279         SummaryStatistics oneSidedPStats = SummaryStatistics.newInstance();
    280         for (int i = 0; i < oneSidedP.length; i++) {
    281             oneSidedPStats.addValue(oneSidedP[i]);
    282         }
    283         // Target comparison values computed using R version 1.8.1 (Linux version)
    284         assertEquals("one sample t stat", 3.86485535541,
    285                 TestUtils.t(0d, oneSidedP), 10E-10);
    286         assertEquals("one sample t stat", 3.86485535541,
    287                 TestUtils.t(0d, oneSidedPStats),1E-10);
    288         assertEquals("one sample p value", 0.000521637019637,
    289                 TestUtils.tTest(0d, oneSidedP) / 2d, 10E-10);
    290         assertEquals("one sample p value", 0.000521637019637,
    291                 TestUtils.tTest(0d, oneSidedPStats) / 2d, 10E-5);
    292         assertTrue("one sample t-test reject", TestUtils.tTest(0d, oneSidedP, 0.01));
    293         assertTrue("one sample t-test reject", TestUtils.tTest(0d, oneSidedPStats, 0.01));
    294         assertTrue("one sample t-test accept", !TestUtils.tTest(0d, oneSidedP, 0.0001));
    295         assertTrue("one sample t-test accept", !TestUtils.tTest(0d, oneSidedPStats, 0.0001));
    296
    297         try {
    298             TestUtils.tTest(0d, oneSidedP, 95);
    299             fail("alpha out of range, IllegalArgumentException expected");
    300         } catch (IllegalArgumentException ex) {
    301             // exptected
    302         }
    303
    304         try {
    305             TestUtils.tTest(0d, oneSidedPStats, 95);
    306             fail("alpha out of range, IllegalArgumentException expected");
    307         } catch (IllegalArgumentException ex) {
    308             // expected
    309         }
    310
    311     }
    312
    313     public void testTwoSampleTHeterscedastic() throws Exception {
    314         double[] sample1 = { 7d, -4d, 18d, 17d, -3d, -5d, 1d, 10d, 11d, -2d };
    315         double[] sample2 = { -1d, 12d, -1d, -3d, 3d, -5d, 5d, 2d, -11d, -1d, -3d };
    316         SummaryStatistics sampleStats1 = SummaryStatistics.newInstance();
    317         for (int i = 0; i < sample1.length; i++) {
    318             sampleStats1.addValue(sample1[i]);
    319         }
    320         SummaryStatistics sampleStats2 = SummaryStatistics.newInstance();
    321         for (int i = 0; i < sample2.length; i++) {
    322             sampleStats2.addValue(sample2[i]);
    323         }
    324
    325         // Target comparison values computed using R version 1.8.1 (Linux version)
    326         assertEquals("two sample heteroscedastic t stat", 1.60371728768,
    327                 TestUtils.t(sample1, sample2), 1E-10);
    328         assertEquals("two sample heteroscedastic t stat", 1.60371728768,
    329                 TestUtils.t(sampleStats1, sampleStats2), 1E-10);
    330         assertEquals("two sample heteroscedastic p value", 0.128839369622,
    331                 TestUtils.tTest(sample1, sample2), 1E-10);
    332         assertEquals("two sample heteroscedastic p value", 0.128839369622,
    333                 TestUtils.tTest(sampleStats1, sampleStats2), 1E-10);
    334         assertTrue("two sample heteroscedastic t-test reject",
    335                 TestUtils.tTest(sample1, sample2, 0.2));
    336         assertTrue("two sample heteroscedastic t-test reject",
    337                 TestUtils.tTest(sampleStats1, sampleStats2, 0.2));
    338         assertTrue("two sample heteroscedastic t-test accept",
    339                 !TestUtils.tTest(sample1, sample2, 0.1));
    340         assertTrue("two sample heteroscedastic t-test accept",
    341                 !TestUtils.tTest(sampleStats1, sampleStats2, 0.1));
    342
    343         try {
    344             TestUtils.tTest(sample1, sample2, .95);
    345             fail("alpha out of range, IllegalArgumentException expected");
    346         } catch (IllegalArgumentException ex) {
    347             // expected
    348         }
    349
    350         try {
    351             TestUtils.tTest(sampleStats1, sampleStats2, .95);
    352             fail("alpha out of range, IllegalArgumentException expected");
    353         } catch (IllegalArgumentException ex) {
    354             // expected
    355         }
    356
    357         try {
    358             TestUtils.tTest(sample1, tooShortObs, .01);
    359             fail("insufficient data, IllegalArgumentException expected");
    360         } catch (IllegalArgumentException ex) {
    361             // expected
    362         }
    363
    364         try {
    365             TestUtils.tTest(sampleStats1, tooShortStats, .01);
    366             fail("insufficient data, IllegalArgumentException expected");
    367         } catch (IllegalArgumentException ex) {
    368             // expected
    369         }
    370
    371         try {
    372             TestUtils.tTest(sample1, tooShortObs);
    373             fail("insufficient data, IllegalArgumentException expected");
    374         } catch (IllegalArgumentException ex) {
    375             // expected
    376         }
    377
    378         try {
    379             TestUtils.tTest(sampleStats1, tooShortStats);
    380             fail("insufficient data, IllegalArgumentException expected");
    381         } catch (IllegalArgumentException ex) {
    382             // expected
    383         }
    384
    385         try {
    386             TestUtils.t(sample1, tooShortObs);
    387             fail("insufficient data, IllegalArgumentException expected");
    388         } catch (IllegalArgumentException ex) {
    389             // expected
    390         }
    391
    392         try {
    393             TestUtils.t(sampleStats1, tooShortStats);
    394             fail("insufficient data, IllegalArgumentException expected");
    395         } catch (IllegalArgumentException ex) {
    396             // expected
    397         }
    398     }
    399     public void testTwoSampleTHomoscedastic() throws Exception {
    400         double[] sample1 ={2, 4, 6, 8, 10, 97};
    401         double[] sample2 = {4, 6, 8, 10, 16};
    402         SummaryStatistics sampleStats1 = SummaryStatistics.newInstance();
    403         for (int i = 0; i < sample1.length; i++) {
    404             sampleStats1.addValue(sample1[i]);
    405         }
    406         SummaryStatistics sampleStats2 = SummaryStatistics.newInstance();
    407         for (int i = 0; i < sample2.length; i++) {
    408             sampleStats2.addValue(sample2[i]);
    409         }
    410
    411         // Target comparison values computed using R version 1.8.1 (Linux version)
    412         assertEquals("two sample homoscedastic t stat", 0.73096310086,
    413                 TestUtils.homoscedasticT(sample1, sample2), 10E-11);
    414         assertEquals("two sample homoscedastic p value", 0.4833963785,
    415                 TestUtils.homoscedasticTTest(sampleStats1, sampleStats2), 1E-10);
    416         assertTrue("two sample homoscedastic t-test reject",
    417                 TestUtils.homoscedasticTTest(sample1, sample2, 0.49));
    418         assertTrue("two sample homoscedastic t-test accept",
    419                 !TestUtils.homoscedasticTTest(sample1, sample2, 0.48));
    420     }
    421
    422     public void testSmallSamples() throws Exception {
    423         double[] sample1 = {1d, 3d};
    424         double[] sample2 = {4d, 5d};
    425
    426         // Target values computed using R, version 1.8.1 (linux version)
    427         assertEquals(-2.2360679775, TestUtils.t(sample1, sample2),
    428                 1E-10);
    429         assertEquals(0.198727388935, TestUtils.tTest(sample1, sample2),
    430                 1E-10);
    431     }
    432
    433     public void testPaired() throws Exception {
    434         double[] sample1 = {1d, 3d, 5d, 7d};
    435         double[] sample2 = {0d, 6d, 11d, 2d};
    436         double[] sample3 = {5d, 7d, 8d, 10d};
    437         double[] sample4 = {0d, 2d};
    438
    439         // Target values computed using R, version 1.8.1 (linux version)
    440         assertEquals(-0.3133, TestUtils.pairedT(sample1, sample2), 1E-4);
    441         assertEquals(0.774544295819, TestUtils.pairedTTest(sample1, sample2), 1E-10);
    442         assertEquals(0.001208, TestUtils.pairedTTest(sample1, sample3), 1E-6);
    443         assertFalse(TestUtils.pairedTTest(sample1, sample3, .001));
    444         assertTrue(TestUtils.pairedTTest(sample1, sample3, .002));
    445     }
    446 }