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 }