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 junit.framework.Test;
020    import junit.framework.TestCase;
021    import junit.framework.TestSuite;
022    
023    /**
024     * Test cases for the ChiSquareTestImpl class.
025     *
026     * @version $Revision: 762087 $ $Date: 2009-04-05 10:20:18 -0400 (Sun, 05 Apr 2009) $
027     */
028    
029    public class ChiSquareTestTest extends TestCase {
030    
031        protected UnknownDistributionChiSquareTest testStatistic = new ChiSquareTestImpl();
032    
033        public ChiSquareTestTest(String name) {
034            super(name);
035        }
036    
037        public static Test suite() {
038            TestSuite suite = new TestSuite(ChiSquareTestTest.class);
039            suite.setName("TestStatistic Tests");
040            return suite;
041        }
042    
043        public void testChiSquare() throws Exception {
044     
045            // Target values computed using R version 1.8.1 
046            // Some assembly required ;-)  
047            //      Use sum((obs - exp)^2/exp) for the chi-square statistic and
048            //      1 - pchisq(sum((obs - exp)^2/exp), length(obs) - 1) for the p-value
049            
050            long[] observed = {10, 9, 11};
051            double[] expected = {10, 10, 10};
052            assertEquals("chi-square statistic", 0.2,  testStatistic.chiSquare(expected, observed), 10E-12);
053            assertEquals("chi-square p-value", 0.904837418036, testStatistic.chiSquareTest(expected, observed), 1E-10);
054            
055            long[] observed1 = { 500, 623, 72, 70, 31 };
056            double[] expected1 = { 485, 541, 82, 61, 37 };
057            assertEquals( "chi-square test statistic", 9.023307936427388, testStatistic.chiSquare(expected1, observed1), 1E-10);
058            assertEquals("chi-square p-value", 0.06051952647453607, testStatistic.chiSquareTest(expected1, observed1), 1E-9);
059            assertTrue("chi-square test reject", testStatistic.chiSquareTest(expected1, observed1, 0.08));
060            assertTrue("chi-square test accept", !testStatistic.chiSquareTest(expected1, observed1, 0.05));
061    
062            try {
063                testStatistic.chiSquareTest(expected1, observed1, 95);
064                fail("alpha out of range, IllegalArgumentException expected");
065            } catch (IllegalArgumentException ex) {
066                // expected
067            }  
068            
069            long[] tooShortObs = { 0 };
070            double[] tooShortEx = { 1 };
071            try {
072                testStatistic.chiSquare(tooShortEx, tooShortObs);
073                fail("arguments too short, IllegalArgumentException expected");
074            } catch (IllegalArgumentException ex) {
075                // expected
076            }
077    
078            // unmatched arrays
079            long[] unMatchedObs = { 0, 1, 2, 3 };
080            double[] unMatchedEx = { 1, 1, 2 };
081            try {
082                testStatistic.chiSquare(unMatchedEx, unMatchedObs);
083                fail("arrays have different lengths, IllegalArgumentException expected");
084            } catch (IllegalArgumentException ex) {
085                // expected
086            }
087            
088            // 0 expected count
089            expected[0] = 0;
090            try {
091                testStatistic.chiSquareTest(expected, observed, .01);
092                fail("bad expected count, IllegalArgumentException expected");
093            } catch (IllegalArgumentException ex) {
094                // expected
095            } 
096            
097            // negative observed count
098            expected[0] = 1;
099            observed[0] = -1;
100            try {
101                testStatistic.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, testStatistic.chiSquare(counts), 1E-9);
115            assertEquals("chi-square p-value", 0.000144751460134, testStatistic.chiSquareTest(counts), 1E-9);
116            assertTrue("chi-square test reject", testStatistic.chiSquareTest(counts, 0.0002));
117            assertTrue("chi-square test accept", !testStatistic.chiSquareTest(counts, 0.0001));    
118            
119            long[][] counts2 = {{10, 15}, {30, 40}, {60, 90} };
120            assertEquals( "chi-square test statistic", 0.168965517241, testStatistic.chiSquare(counts2), 1E-9);
121            assertEquals("chi-square p-value",0.918987499852, testStatistic.chiSquareTest(counts2), 1E-9);
122            assertTrue("chi-square test accept", !testStatistic.chiSquareTest(counts2, 0.1)); 
123            
124            // ragged input array
125            long[][] counts3 = { {40, 22, 43}, {91, 21, 28}, {60, 10}};
126            try {
127                testStatistic.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                testStatistic.chiSquare(counts4);
137                fail("Expecting IllegalArgumentException");
138            } catch (IllegalArgumentException ex) {
139                // expected
140            } 
141            long[][] counts5 = {{40}, {40}, {30}, {10}};
142            try {
143                testStatistic.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                testStatistic.chiSquare(counts6);
153                fail("Expecting IllegalArgumentException");
154            } catch (IllegalArgumentException ex) {
155                // expected
156            } 
157            
158            // bad alpha
159            try {
160                testStatistic.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                    114875.90421929007, testStatistic.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                    testStatistic.chiSquare(counts), 1E-9);
190            assertEquals("chi-square p-value", 0.0462835770603,
191                    testStatistic.chiSquareTest(counts), 1E-9);       
192        }
193        
194        /** Target values verified using DATAPLOT version 2006.3 */
195        public void testChiSquareDataSetsComparisonEqualCounts()
196        throws Exception {
197            long[] observed1 = {10, 12, 12, 10};
198            long[] observed2 = {5, 15, 14, 10};    
199            assertEquals("chi-square p value", 0.541096, 
200                    testStatistic.chiSquareTestDataSetsComparison(
201                    observed1, observed2), 1E-6);
202            assertEquals("chi-square test statistic", 2.153846,
203                    testStatistic.chiSquareDataSetsComparison(
204                    observed1, observed2), 1E-6);
205            assertFalse("chi-square test result", 
206                    testStatistic.chiSquareTestDataSetsComparison(
207                    observed1, observed2, 0.4));
208        }
209        
210        /** Target values verified using DATAPLOT version 2006.3 */
211        public void testChiSquareDataSetsComparisonUnEqualCounts()
212        throws Exception {
213            long[] observed1 = {10, 12, 12, 10, 15};
214            long[] observed2 = {15, 10, 10, 15, 5};    
215            assertEquals("chi-square p value", 0.124115, 
216                    testStatistic.chiSquareTestDataSetsComparison(
217                    observed1, observed2), 1E-6);
218            assertEquals("chi-square test statistic", 7.232189,
219                    testStatistic.chiSquareDataSetsComparison(
220                    observed1, observed2), 1E-6);
221            assertTrue("chi-square test result", 
222                    testStatistic.chiSquareTestDataSetsComparison(
223                    observed1, observed2, 0.13));
224            assertFalse("chi-square test result", 
225                    testStatistic.chiSquareTestDataSetsComparison(
226                    observed1, observed2, 0.12));
227        }
228        
229        public void testChiSquareDataSetsComparisonBadCounts()
230        throws Exception {
231            long[] observed1 = {10, -1, 12, 10, 15};
232            long[] observed2 = {15, 10, 10, 15, 5};
233            try {
234                testStatistic.chiSquareTestDataSetsComparison(
235                        observed1, observed2);
236                fail("Expecting IllegalArgumentException - negative count");
237            } catch (IllegalArgumentException ex) {
238                // expected
239            }
240            long[] observed3 = {10, 0, 12, 10, 15};
241            long[] observed4 = {15, 0, 10, 15, 5};
242            try {
243                testStatistic.chiSquareTestDataSetsComparison(
244                        observed3, observed4);
245                fail("Expecting IllegalArgumentException - double 0's");
246            } catch (IllegalArgumentException ex) {
247                // expected
248            }
249            long[] observed5 = {10, 10, 12, 10, 15};
250            long[] observed6 = {0, 0, 0, 0, 0};
251            try {
252                testStatistic.chiSquareTestDataSetsComparison(
253                        observed5, observed6);
254                fail("Expecting IllegalArgumentException - vanishing counts");
255            } catch (IllegalArgumentException ex) {
256                // expected
257            }
258        }
259    }