View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.math4.legacy.stat.inference;
18  
19  import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
20  import org.apache.commons.math4.legacy.exception.NotPositiveException;
21  import org.apache.commons.math4.legacy.exception.NotStrictlyPositiveException;
22  import org.apache.commons.math4.legacy.exception.OutOfRangeException;
23  import org.apache.commons.math4.legacy.exception.ZeroException;
24  import org.junit.Assert;
25  import org.junit.Test;
26  import org.junit.jupiter.api.Assertions;
27  
28  
29  /**
30   * Test cases for the ChiSquareTestImpl class.
31   *
32   */
33  
34  public class ChiSquareTestTest {
35  
36      protected ChiSquareTest testStatistic = new ChiSquareTest();
37  
38      @Test
39      public void testChiSquare() {
40  
41          // Target values computed using R version 1.8.1
42          // Some assembly required ;-)
43          //      Use sum((obs - exp)^2/exp) for the chi-square statistic and
44          //      1 - pchisq(sum((obs - exp)^2/exp), length(obs) - 1) for the p-value
45  
46          long[] observed = {10, 9, 11};
47          double[] expected = {10, 10, 10};
48          Assert.assertEquals("chi-square statistic", 0.2,  testStatistic.chiSquare(expected, observed), 10E-12);
49          Assert.assertEquals("chi-square p-value", 0.904837418036, testStatistic.chiSquareTest(expected, observed), 1E-10);
50  
51          long[] observed1 = { 500, 623, 72, 70, 31 };
52          double[] expected1 = { 485, 541, 82, 61, 37 };
53          Assert.assertEquals( "chi-square test statistic", 9.023307936427388, testStatistic.chiSquare(expected1, observed1), 1E-10);
54          Assert.assertEquals("chi-square p-value", 0.06051952647453607, testStatistic.chiSquareTest(expected1, observed1), 1E-9);
55          Assert.assertTrue("chi-square test reject", testStatistic.chiSquareTest(expected1, observed1, 0.08));
56          Assert.assertFalse("chi-square test accept", testStatistic.chiSquareTest(expected1, observed1, 0.05));
57  
58          try {
59              testStatistic.chiSquareTest(expected1, observed1, 95);
60              Assert.fail("alpha out of range, OutOfRangeException expected");
61          } catch (OutOfRangeException ex) {
62              // expected
63          }
64  
65          long[] tooShortObs = { 0 };
66          double[] tooShortEx = { 1 };
67          try {
68              testStatistic.chiSquare(tooShortEx, tooShortObs);
69              Assert.fail("arguments too short, DimensionMismatchException expected");
70          } catch (DimensionMismatchException ex) {
71              // expected
72          }
73  
74          // unmatched arrays
75          long[] unMatchedObs = { 0, 1, 2, 3 };
76          double[] unMatchedEx = { 1, 1, 2 };
77          try {
78              testStatistic.chiSquare(unMatchedEx, unMatchedObs);
79              Assert.fail("arrays have different lengths, DimensionMismatchException expected");
80          } catch (DimensionMismatchException ex) {
81              // expected
82          }
83  
84          // 0 expected count
85          expected[0] = 0;
86          try {
87              testStatistic.chiSquareTest(expected, observed, .01);
88              Assert.fail("bad expected count, NotStrictlyPositiveException expected");
89          } catch (NotStrictlyPositiveException ex) {
90              // expected
91          }
92  
93          // negative observed count
94          expected[0] = 1;
95          observed[0] = -1;
96          try {
97              testStatistic.chiSquareTest(expected, observed, .01);
98              Assert.fail("bad expected count, NotPositiveException expected");
99          } catch (NotPositiveException ex) {
100             // expected
101         }
102     }
103 
104     @Test
105     public void testChiSquareIndependence() {
106 
107         // Target values computed using R version 1.8.1
108 
109         long[][] counts = { {40, 22, 43}, {91, 21, 28}, {60, 10, 22}};
110         Assert.assertEquals( "chi-square test statistic", 22.709027688, testStatistic.chiSquare(counts), 1E-9);
111         Assert.assertEquals("chi-square p-value", 0.000144751460134, testStatistic.chiSquareTest(counts), 1E-9);
112         Assert.assertTrue("chi-square test reject", testStatistic.chiSquareTest(counts, 0.0002));
113         Assert.assertFalse("chi-square test accept", testStatistic.chiSquareTest(counts, 0.0001));
114 
115         long[][] counts2 = {{10, 15}, {30, 40}, {60, 90} };
116         Assert.assertEquals( "chi-square test statistic", 0.168965517241, testStatistic.chiSquare(counts2), 1E-9);
117         Assert.assertEquals("chi-square p-value",0.918987499852, testStatistic.chiSquareTest(counts2), 1E-9);
118         Assert.assertFalse("chi-square test accept", testStatistic.chiSquareTest(counts2, 0.1));
119 
120         // ragged input array
121         long[][] counts3 = { {40, 22, 43}, {91, 21, 28}, {60, 10}};
122         try {
123             testStatistic.chiSquare(counts3);
124             Assert.fail("Expecting DimensionMismatchException");
125         } catch (DimensionMismatchException ex) {
126             // expected
127         }
128 
129         // insufficient data
130         long[][] counts4 = {{40, 22, 43}};
131         try {
132             testStatistic.chiSquare(counts4);
133             Assert.fail("Expecting DimensionMismatchException");
134         } catch (DimensionMismatchException ex) {
135             // expected
136         }
137         long[][] counts5 = {{40}, {40}, {30}, {10}};
138         try {
139             testStatistic.chiSquare(counts5);
140             Assert.fail("Expecting DimensionMismatchException");
141         } catch (DimensionMismatchException ex) {
142             // expected
143         }
144 
145         // negative counts
146         long[][] counts6 = {{10, -2}, {30, 40}, {60, 90} };
147         try {
148             testStatistic.chiSquare(counts6);
149             Assert.fail("Expecting NotPositiveException");
150         } catch (NotPositiveException ex) {
151             // expected
152         }
153 
154         // bad alpha
155         try {
156             testStatistic.chiSquareTest(counts, 0);
157             Assert.fail("Expecting OutOfRangeException");
158         } catch (OutOfRangeException ex) {
159             // expected
160         }
161     }
162 
163     @Test
164     public void testChiSquareLargeTestStatistic() {
165         double[] exp = new double[] {
166             3389119.5, 649136.6, 285745.4, 25357364.76, 11291189.78, 543628.0,
167             232921.0, 437665.75
168         };
169 
170         long[] obs = new long[] {
171             2372383, 584222, 257170, 17750155, 7903832, 489265, 209628, 393899
172         };
173         org.apache.commons.math4.legacy.stat.inference.ChiSquareTest csti =
174             new org.apache.commons.math4.legacy.stat.inference.ChiSquareTest();
175         double cst = csti.chiSquareTest(exp, obs);
176         Assert.assertEquals("chi-square p-value", 0.0, cst, 1E-3);
177         Assert.assertEquals( "chi-square test statistic",
178                 114875.90421929007, testStatistic.chiSquare(exp, obs), 1E-9);
179     }
180 
181     /** Contingency table containing zeros - PR # 32531 */
182     @Test
183     public void testChiSquareZeroCount() {
184         // Target values computed using R version 1.8.1
185         long[][] counts = { {40, 0, 4}, {91, 1, 2}, {60, 2, 0}};
186         Assert.assertEquals( "chi-square test statistic", 9.67444662263,
187                 testStatistic.chiSquare(counts), 1E-9);
188         Assert.assertEquals("chi-square p-value", 0.0462835770603,
189                 testStatistic.chiSquareTest(counts), 1E-9);
190     }
191 
192     /** Target values verified using DATAPLOT version 2006.3 */
193     @Test
194     public void testChiSquareDataSetsComparisonEqualCounts() {
195         long[] observed1 = {10, 12, 12, 10};
196         long[] observed2 = {5, 15, 14, 10};
197         Assert.assertEquals("chi-square p value", 0.541096,
198                 testStatistic.chiSquareTestDataSetsComparison(
199                 observed1, observed2), 1E-6);
200         Assert.assertEquals("chi-square test statistic", 2.153846,
201                 testStatistic.chiSquareDataSetsComparison(
202                 observed1, observed2), 1E-6);
203         Assert.assertFalse("chi-square test result",
204                 testStatistic.chiSquareTestDataSetsComparison(
205                 observed1, observed2, 0.4));
206     }
207 
208     /** Target values verified using DATAPLOT version 2006.3 */
209     @Test
210     public void testChiSquareDataSetsComparisonUnEqualCounts() {
211         long[] observed1 = {10, 12, 12, 10, 15};
212         long[] observed2 = {15, 10, 10, 15, 5};
213         Assert.assertEquals("chi-square p value", 0.124115,
214                 testStatistic.chiSquareTestDataSetsComparison(
215                 observed1, observed2), 1E-6);
216         Assert.assertEquals("chi-square test statistic", 7.232189,
217                 testStatistic.chiSquareDataSetsComparison(
218                 observed1, observed2), 1E-6);
219         Assert.assertTrue("chi-square test result",
220                 testStatistic.chiSquareTestDataSetsComparison(
221                 observed1, observed2, 0.13));
222         Assert.assertFalse("chi-square test result",
223                 testStatistic.chiSquareTestDataSetsComparison(
224                 observed1, observed2, 0.12));
225     }
226 
227     @Test
228     public void testChiSquareDataSetsComparisonBadCounts() {
229         long[] observed1 = {10, -1, 12, 10, 15};
230         long[] observed2 = {15, 10, 10, 15, 5};
231         try {
232             testStatistic.chiSquareTestDataSetsComparison(
233                     observed1, observed2);
234             Assert.fail("Expecting NotPositiveException - negative count");
235         } catch (NotPositiveException ex) {
236             // expected
237         }
238         long[] observed3 = {10, 0, 12, 10, 15};
239         long[] observed4 = {15, 0, 10, 15, 5};
240         try {
241             testStatistic.chiSquareTestDataSetsComparison(
242                     observed3, observed4);
243             Assert.fail("Expecting ZeroException - double 0's");
244         } catch (ZeroException ex) {
245             // expected
246         }
247         long[] observed5 = {10, 10, 12, 10, 15};
248         long[] observed6 = {0, 0, 0, 0, 0};
249         try {
250             testStatistic.chiSquareTestDataSetsComparison(
251                     observed5, observed6);
252             Assert.fail("Expecting ZeroException - vanishing counts");
253         } catch (ZeroException ex) {
254             // expected
255         }
256     }
257 
258     @Test
259     public void testChiSquareWithZeroObservations() {
260         // No counts
261         final long[][] counts = new long[2][2];
262         Assertions.assertThrows(ZeroException.class, () -> testStatistic.chiSquare(counts));
263         // Empty column
264         final long[][] counts2 = {{1, 2, 0}, {3, 4, 0}};
265         Assertions.assertThrows(ZeroException.class, () -> testStatistic.chiSquare(counts2));
266         // Empty row
267         final long[][] counts3 = {{1, 2}, {3, 4}, {0, 0}};
268         Assertions.assertThrows(ZeroException.class, () -> testStatistic.chiSquare(counts3));
269     }
270 }