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