1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  package org.apache.commons.math4.legacy.stat.inference;
19  
20  import java.lang.reflect.Method;
21  import java.util.Arrays;
22  
23  import org.apache.commons.math4.legacy.TestUtils;
24  import org.apache.commons.statistics.distribution.NormalDistribution;
25  import org.apache.commons.statistics.distribution.UniformContinuousDistribution;
26  import org.apache.commons.rng.simple.RandomSource;
27  import org.apache.commons.rng.UniformRandomProvider;
28  import org.apache.commons.numbers.combinatorics.BinomialCoefficient;
29  import org.apache.commons.math4.core.jdkmath.JdkMath;
30  import org.apache.commons.math4.legacy.core.MathArrays;
31  import org.apache.commons.math4.legacy.exception.NotANumberException;
32  import org.apache.commons.math4.legacy.exception.InsufficientDataException;
33  import org.junit.Assert;
34  import org.junit.Test;
35  import org.junit.Ignore;
36  
37  
38  
39  
40  
41  
42  public class KolmogorovSmirnovTestTest {
43      private static final double TOLERANCE = 1e-10;
44      private static final int MONTE_CARLO_ITERATIONS = 1000000;
45      private static final int LARGE_SAMPLE_PRODUCT = 10000;
46  
47      
48      protected static final double[] gaussian = {
49          0.26055895, -0.63665233, 1.51221323, 0.61246988, -0.03013003, -1.73025682, -0.51435805, 0.70494168, 0.18242945,
50          0.94734336, -0.04286604, -0.37931719, -1.07026403, -2.05861425, 0.11201862, 0.71400136, -0.52122185,
51          -0.02478725, -1.86811649, -1.79907688, 0.15046279, 1.32390193, 1.55889719, 1.83149171, -0.03948003,
52          -0.98579207, -0.76790540, 0.89080682, 0.19532153, 0.40692841, 0.15047336, -0.58546562, -0.39865469, 0.77604271,
53          -0.65188221, -1.80368554, 0.65273365, -0.75283102, -1.91022150, -0.07640869, -1.08681188, -0.89270600,
54          2.09017508, 0.43907981, 0.10744033, -0.70961218, 1.15707300, 0.44560525, -2.04593349, 0.53816843, -0.08366640,
55          0.24652218, 1.80549401, -0.99220707, -1.14589408, -0.27170290, -0.49696855, 0.00968353, -1.87113545,
56          -1.91116529, 0.97151891, -0.73576115, -0.59437029, 0.72148436, 0.01747695, -0.62601157, -1.00971538,
57          -1.42691397, 1.03250131, -0.30672627, -0.15353992, -1.19976069, -0.68364218, 0.37525652, -0.46592881,
58          -0.52116168, -0.17162202, 1.04679215, 0.25165971, -0.04125231, -0.23756244, -0.93389975, 0.75551407,
59          0.08347445, -0.27482228, -0.4717632, -0.1867746, -0.1166976, 0.5763333, 0.1307952, 0.7630584, -0.3616248,
60          2.1383790, -0.7946630, 0.0231885, 0.7919195, 1.6057144, -0.3802508, 0.1229078, 1.5252901, -0.8543149, 0.3025040
61      };
62  
63      
64      protected static final double[] gaussian2 = {
65          2.88041498038308, -0.632349445671017, 0.402121295225571, 0.692626364613243, 1.30693446815426,
66          -0.714176317131286, -0.233169206599583, 1.09113298322107, -1.53149079994305, 1.23259966205809,
67          1.01389927412503, 0.0143898711497477, -0.512813545447559, 2.79364360835469, 0.662008875538092,
68          1.04861546834788, -0.321280099931466, 0.250296656278743, 1.75820367603736, -2.31433523590905,
69          -0.462694696086403, 0.187725700950191, -2.24410950019152, 2.83473751105445, 0.252460174391016,
70          1.39051945380281, -1.56270144203134, 0.998522814471644, -1.50147469080896, 0.145307533554146,
71          0.469089457043406, -0.0914780723809334, -0.123446939266548, -0.610513388160565, -3.71548343891957,
72          -0.329577317349478, -0.312973794075871, 2.02051909758923, 2.85214308266271, 0.0193222002327237,
73          -0.0322422268266562, 0.514736012106768, 0.231484953375887, -2.22468798953629, 1.42197716075595,
74          2.69988043856357, 0.0443757119128293, 0.721536984407798, -0.0445688839903234, -0.294372724550705,
75          0.234041580912698, -0.868973119365727, 1.3524893453845, -0.931054600134503, -0.263514296006792,
76          0.540949457402918, -0.882544288773685, -0.34148675747989, 1.56664494810034, 2.19850536566584,
77          -0.667972122928022, -0.70889669526203, -0.00251758193079668, 2.39527162977682, -2.7559594317269,
78          -0.547393502656671, -2.62144031572617, 2.81504147017922, -1.02036850201042, -1.00713927602786,
79          -0.520197775122254, 1.00625480138649, 2.46756916531313, 1.64364743727799, 0.704545210648595,
80          -0.425885789416992, -1.78387854908546, -0.286783886710481, 0.404183648369076, -0.369324280845769,
81          -0.0391185138840443, 2.41257787857293, 2.49744281317859, -0.826964496939021, -0.792555379958975,
82          1.81097685787403, -0.475014580016638, 1.23387615291805, 0.646615294802053, 1.88496377454523, 1.20390698380814,
83          -0.27812153371728, 2.50149494533101, 0.406964323253817, -1.72253451309982, 1.98432494184332, 2.2223658560333,
84          0.393086362404685, -0.504073151377089, -0.0484610869883821
85      };
86  
87      
88      protected static final double[] uniform = {
89          0.7930305, 0.6424382, 0.8747699, 0.7156518, 0.1845909, 0.2022326, 0.4877206, 0.8928752, 0.2293062, 0.4222006,
90          0.1610459, 0.2830535, 0.9946345, 0.7329499, 0.26411126, 0.87958133, 0.29827437, 0.39185988, 0.38351185,
91          0.36359611, 0.48646472, 0.05577866, 0.56152250, 0.52672013, 0.13171783, 0.95864085, 0.03060207, 0.33514887,
92          0.72508148, 0.38901437, 0.9978665, 0.5981300, 0.1065388, 0.7036991, 0.1071584, 0.4423963, 0.1107071, 0.6437221,
93          0.58523872, 0.05044634, 0.65999539, 0.37367260, 0.73270024, 0.47473755, 0.74661163, 0.50765549, 0.05377347,
94          0.40998009, 0.55235182, 0.21361998, 0.63117971, 0.18109222, 0.89153510, 0.23203248, 0.6177106, 0.6856418,
95          0.2158557, 0.9870501, 0.2036914, 0.2100311, 0.9065020, 0.7459159, 0.56631790, 0.06753629, 0.39684629,
96          0.52504615, 0.14199103, 0.78551120, 0.90503321, 0.80452362, 0.9960115, 0.8172592, 0.5831134, 0.8794187,
97          0.2021501, 0.2923505, 0.9561824, 0.8792248, 0.85201008, 0.02945562, 0.26200374, 0.11382818, 0.17238856,
98          0.36449473, 0.69688273, 0.96216330, 0.4859432, 0.4503438, 0.1917656, 0.8357845, 0.9957812, 0.4633570,
99          0.8654599, 0.4597996, 0.68190289, 0.58887855, 0.09359396, 0.98081979, 0.73659533, 0.89344777, 0.18903099,
100         0.97660425
101     };
102 
103     
104     @Test
105     public void testOneSampleGaussianGaussian() {
106         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
107         final NormalDistribution unitNormal = NormalDistribution.of(0d, 1d);
108         
109         
110         
111         
112         Assert.assertEquals(0.3172069207622391, test.kolmogorovSmirnovTest(unitNormal, gaussian, false), TOLERANCE);
113         Assert.assertFalse(test.kolmogorovSmirnovTest(unitNormal, gaussian, 0.05));
114         Assert.assertEquals(0.0932947561266756, test.kolmogorovSmirnovStatistic(unitNormal, gaussian), TOLERANCE);
115     }
116 
117     
118     @Test
119     public void testOneSampleGaussianGaussianSmallSample() {
120         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
121         final NormalDistribution unitNormal = NormalDistribution.of(0d, 1d);
122         final double[] shortGaussian = new double[50];
123         System.arraycopy(gaussian, 0, shortGaussian, 0, 50);
124         Assert.assertEquals(0.683736463728347, test.kolmogorovSmirnovTest(unitNormal, shortGaussian, false), TOLERANCE);
125         Assert.assertFalse(test.kolmogorovSmirnovTest(unitNormal, gaussian, 0.05));
126         Assert.assertEquals(0.09820779969463278, test.kolmogorovSmirnovStatistic(unitNormal, shortGaussian), TOLERANCE);
127     }
128 
129     
130     @Test
131     public void testOneSampleGaussianUniform() {
132         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
133         final NormalDistribution unitNormal = NormalDistribution.of(0d, 1d);
134         
135         
136         
137         
138         Assert.assertEquals(8.881784197001252E-16, test.kolmogorovSmirnovTest(unitNormal, uniform, false), TOLERANCE);
139         Assert.assertFalse(test.kolmogorovSmirnovTest(unitNormal, gaussian, 0.05));
140         Assert.assertEquals(0.5117493931609258, test.kolmogorovSmirnovStatistic(unitNormal, uniform), TOLERANCE);
141     }
142 
143     
144     
145     public void testOneSampleUniformUniform() {
146         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
147         final UniformContinuousDistribution unif = UniformContinuousDistribution.of(-0.5, 0.5);
148         Assert.assertEquals(8.881784197001252E-16, test.kolmogorovSmirnovTest(unif, uniform, false), TOLERANCE);
149         Assert.assertTrue(test.kolmogorovSmirnovTest(unif, uniform, 0.05));
150         Assert.assertEquals(0.5400666982352942, test.kolmogorovSmirnovStatistic(unif, uniform), TOLERANCE);
151     }
152 
153     
154     @Test
155     public void testOneSampleUniformUniformSmallSample() {
156         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
157         final UniformContinuousDistribution unif = UniformContinuousDistribution.of(-0.5, 0.5);
158         final double[] shortUniform = new double[20];
159         System.arraycopy(uniform, 0, shortUniform, 0, 20);
160         Assert.assertEquals(4.117594598618268E-9, test.kolmogorovSmirnovTest(unif, shortUniform, false), TOLERANCE);
161         Assert.assertTrue(test.kolmogorovSmirnovTest(unif, shortUniform, 0.05));
162         Assert.assertEquals(0.6610459, test.kolmogorovSmirnovStatistic(unif, shortUniform), TOLERANCE);
163     }
164 
165     
166     @Test
167     public void testOneSampleUniformGaussian() {
168         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
169         final UniformContinuousDistribution unif = UniformContinuousDistribution.of(-0.5, 0.5);
170         
171         
172         Assert.assertEquals(4.9405812774239166E-11, test.kolmogorovSmirnovTest(unif, gaussian, false), TOLERANCE);
173         Assert.assertTrue(test.kolmogorovSmirnovTest(unif, gaussian, 0.05));
174         Assert.assertEquals(0.3401058049019608, test.kolmogorovSmirnovStatistic(unif, gaussian), TOLERANCE);
175     }
176 
177     
178     @Test
179     public void testTwoSampleSmallSampleExact() {
180         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
181         final double[] smallSample1 = {
182             6, 7, 9, 13, 19, 21, 22, 23, 24
183         };
184         final double[] smallSample2 = {
185             10, 11, 12, 16, 20, 27, 28, 32, 44, 54
186         };
187         
188         Assert
189             .assertEquals(0.105577085453247, test.kolmogorovSmirnovTest(smallSample1, smallSample2, false), TOLERANCE);
190         Assert.assertEquals(0.5, test.kolmogorovSmirnovStatistic(smallSample1, smallSample2), TOLERANCE);
191     }
192 
193     
194     @Test
195     public void testTwoSampleSmallSampleExact2() {
196         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
197         final double[] smallSample1 = {
198             6, 7, 9, 13, 19, 21, 22, 23, 24, 29, 30, 34, 36, 41, 45, 47, 51, 63, 33, 91
199         };
200         final double[] smallSample2 = {
201             10, 11, 12, 16, 20, 27, 28, 32, 44, 54, 56, 57, 64, 69, 71, 80, 81, 88, 90
202         };
203         
204         Assert
205             .assertEquals(0.0462986609, test.kolmogorovSmirnovTest(smallSample1, smallSample2, false), TOLERANCE);
206         Assert.assertEquals(0.4263157895, test.kolmogorovSmirnovStatistic(smallSample1, smallSample2), TOLERANCE);
207     }
208 
209     
210     @Test
211     public void testTwoSampleSmallSampleExact3() {
212         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
213         final double[] smallSample1 = {
214             -10, -5, 17, 21, 22, 23, 24, 30, 44, 50, 56, 57, 59, 67, 73, 75, 77, 78, 79, 80, 81, 83, 84, 85, 88, 90,
215             92, 93, 94, 95, 98, 100, 101, 103, 105, 110
216         };
217         final double[] smallSample2 = {
218             -2, -1, 0, 10, 14, 15, 16, 20, 25, 26, 27, 31, 32, 33, 34, 45, 47, 48, 51, 52, 53, 54, 60, 61, 62, 63,
219             74, 82, 106, 107, 109, 11, 112, 113, 114
220         };
221         
222         Assert
223             .assertEquals(0.00300743602, test.kolmogorovSmirnovTest(smallSample1, smallSample2, false), TOLERANCE);
224         Assert.assertEquals(0.4103174603, test.kolmogorovSmirnovStatistic(smallSample1, smallSample2), TOLERANCE);
225         Assert
226         .assertEquals(0.00300743602, test.kolmogorovSmirnovTest(smallSample2, smallSample1, false), TOLERANCE);
227     }
228 
229     
230 
231 
232 
233     @Test
234     public void testTwoSampleExactP() {
235         checkExactTable(4, 6, 5d / 6d, 0.01d);
236         checkExactTable(4, 7, 17d / 28d, 0.2d);
237         checkExactTable(6, 7, 29d / 42d, 0.05d);
238         checkExactTable(4, 10, 7d / 10d, 0.05d);
239         checkExactTable(5, 15, 11d / 15d, 0.02d);
240         checkExactTable(9, 10, 31d / 45d, 0.01d);
241         checkExactTable(7, 10, 43d / 70d, 0.05d);
242     }
243 
244     @Test
245     public void testTwoSampleApproximateCritialValues() {
246         final double tol = .01;
247         final double[] alpha = {
248             0.10, 0.05, 0.025, 0.01, 0.005, 0.001
249         };
250         
251         final double[] c = {
252             1.22, 1.36, 1.48, 1.63, 1.73, 1.95
253         };
254         final int k[] = {
255             60, 100, 500
256         };
257         double n;
258         double m;
259         for (int i = 0; i < k.length; i++) {
260             for (int j = 0; j < i; j++) {
261                 n = k[i];
262                 m = k[j];
263                 for (int l = 0; l < alpha.length; l++) {
264                     final double dCrit = c[l] * JdkMath.sqrt((n + m) / (n * m));
265                     checkApproximateTable(k[i], k[j], dCrit, alpha[l], tol);
266                 }
267             }
268         }
269     }
270 
271     @Test
272     public void testPelzGoodApproximation() {
273         KolmogorovSmirnovTest ksTest = new KolmogorovSmirnovTest();
274         final double d[] = {0.15, 0.20, 0.25, 0.3, 0.35, 0.4};
275         final int n[] = {141, 150, 180, 220, 1000};
276         
277         
278         final double ref[] = {
279             0.9968940168727819, 0.9979326624184857, 0.9994677598604506, 0.9999128354780209, 0.9999999999998661,
280             0.9999797514476236, 0.9999902122242081, 0.9999991327060908, 0.9999999657681911, 0.9999999999977929,
281             0.9999999706444976, 0.9999999906571532, 0.9999999997949596, 0.999999999998745, 0.9999999999993876,
282             0.9999999999916627, 0.9999999999984447, 0.9999999999999936, 0.999999999999341, 0.9999999999971508,
283             0.9999999999999877, 0.9999999999999191, 0.9999999999999254, 0.9999999999998178, 0.9999999999917788,
284             0.9999999999998556, 0.9999999999992014, 0.9999999999988859, 0.9999999999999325, 0.9999999999821726
285         };
286 
287         final double tol = 10e-15;
288         int k = 0;
289         for (int i = 0; i < 6; i++) {
290             for (int j = 0; j < 5; j++, k++) {
291                 Assert.assertEquals(ref[k], ksTest.pelzGood(d[i], n[j]), tol);
292             }
293         }
294     }
295 
296     
297     @Test
298     public void testTwoSampleApproximateP() {
299         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
300         
301         Assert.assertEquals(0.0319983962391632, test.kolmogorovSmirnovTest(gaussian, gaussian2), TOLERANCE);
302         Assert.assertEquals(0.202352941176471, test.kolmogorovSmirnovStatistic(gaussian, gaussian2), TOLERANCE);
303     }
304 
305     
306 
307 
308 
309 
310     @Test(timeout=5000)
311     public void testTwoSampleProductSizeOverflow() {
312         final int n = 50000;
313         Assert.assertTrue(n * n < 0);
314         double[] x = new double[n];
315         double[] y = new double[n];
316         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
317         Assert.assertFalse(Double.isNaN(test.kolmogorovSmirnovTest(x, y)));
318     }
319 
320     
321 
322 
323     @Test
324     public void testTwoSampleMonteCarlo() {
325         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
326         final UniformRandomProvider rng = RandomSource.WELL_19937_C.create(1000);
327         final int sampleSize = 14;
328         final double tol = .001;
329         final double[] shortUniform = new double[sampleSize];
330         System.arraycopy(uniform, 0, shortUniform, 0, sampleSize);
331         final double[] shortGaussian = new double[sampleSize];
332         final double[] shortGaussian2 = new double[sampleSize];
333         System.arraycopy(gaussian, 0, shortGaussian, 0, sampleSize);
334         System.arraycopy(gaussian, 10, shortGaussian2, 0, sampleSize);
335         final double[] d = {
336             test.kolmogorovSmirnovStatistic(shortGaussian, shortUniform),
337             test.kolmogorovSmirnovStatistic(shortGaussian2, shortGaussian)
338         };
339         for (double dv : d) {
340             double exactPStrict = test.exactP(dv, sampleSize, sampleSize, true);
341             double exactPNonStrict = test.exactP(dv, sampleSize, sampleSize, false);
342             double montePStrict = test.monteCarloP(dv, sampleSize, sampleSize, true,
343                                                    MONTE_CARLO_ITERATIONS, rng);
344             double montePNonStrict = test.monteCarloP(dv, sampleSize, sampleSize, false,
345                                                       MONTE_CARLO_ITERATIONS, rng);
346             Assert.assertEquals(exactPStrict, montePStrict, tol);
347             Assert.assertEquals(exactPNonStrict, montePNonStrict, tol);
348         }
349     }
350 
351     @Test
352     public void testTwoSampleMonteCarloDifferentSampleSizes() {
353         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
354         final UniformRandomProvider rng = RandomSource.WELL_19937_C.create(1000);
355         final int sampleSize1 = 14;
356         final int sampleSize2 = 7;
357         final double d = 0.3;
358         final boolean strict = false;
359         final double tol = 1e-2;
360         Assert.assertEquals(test.exactP(d, sampleSize1, sampleSize2, strict),
361                             test.monteCarloP(d, sampleSize1, sampleSize2, strict,
362                                              MONTE_CARLO_ITERATIONS, rng),
363                             tol);
364     }
365 
366     
367 
368 
369     
370     public void testTwoSampleMonteCarloPerformance() {
371         int numIterations = 100_000;
372         int N = (int)Math.sqrt(LARGE_SAMPLE_PRODUCT);
373         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
374         final UniformRandomProvider rng = RandomSource.WELL_19937_C.create(1000);
375         for (int n = 2; n <= N; ++n) {
376             long startMillis = System.currentTimeMillis();
377             int m = LARGE_SAMPLE_PRODUCT/n;
378             Assert.assertEquals(0d, test.monteCarloP(Double.POSITIVE_INFINITY, n, m, true, numIterations, rng), 0d);
379             long endMillis = System.currentTimeMillis();
380             System.out.println("n=" + n + ", m=" + m + ", time=" + (endMillis-startMillis)/1000d + "s");
381         }
382     }
383 
384     @Test
385     public void testTwoSampleWithManyTies() {
386         
387         final double[] x = {
388             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
389             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
390             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
391             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
392             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
393             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
394             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
395             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
396             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
397             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
398             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
399             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
400             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
401             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
402             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
403             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
404             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
405             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
406             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
407             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
408             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
409             0.000000, 2.202653, 2.202653, 2.202653, 2.202653, 2.202653,
410             2.202653, 2.202653, 2.202653, 2.202653, 2.202653, 2.202653,
411             2.202653, 2.202653, 2.202653, 2.202653, 2.202653, 2.202653,
412             2.202653, 2.202653, 2.202653, 2.202653, 2.202653, 2.202653,
413             2.202653, 2.202653, 2.202653, 2.202653, 2.202653, 2.202653,
414             2.202653, 2.202653, 2.202653, 2.202653, 2.202653, 2.202653,
415             3.181199, 3.181199, 3.181199, 3.181199, 3.181199, 3.181199,
416             3.723539, 3.723539, 3.723539, 3.723539, 4.383482, 4.383482,
417             4.383482, 4.383482, 5.320671, 5.320671, 5.320671, 5.717284,
418             6.964001, 7.352165, 8.710510, 8.710510, 8.710510, 8.710510,
419             8.710510, 8.710510, 9.539004, 9.539004, 10.720619, 17.726077,
420             17.726077, 17.726077, 17.726077, 22.053875, 23.799144, 27.355308,
421             30.584960, 30.584960, 30.584960, 30.584960, 30.751808
422         };
423 
424         final double[] y = {
425             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
426             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
427             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
428             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
429             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
430             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
431             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
432             0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000,
433             0.000000, 0.000000, 0.000000, 2.202653, 2.202653, 2.202653,
434             2.202653, 2.202653, 2.202653, 2.202653, 2.202653, 3.061758,
435             3.723539, 5.628420, 5.628420, 5.628420, 5.628420, 5.628420,
436             6.916982, 6.916982, 6.916982, 10.178538, 10.178538, 10.178538,
437             10.178538, 10.178538
438         };
439 
440         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
441 
442         Assert.assertEquals(0.0640394088, test.kolmogorovSmirnovStatistic(x, y), 1e-6);
443         Assert.assertEquals(0.9792777290, test.kolmogorovSmirnovTest(x, y), 1e-6);
444     }
445 
446     @Test
447     public void testTwoSampleWithManyTiesAndVerySmallDelta() {
448         
449 
450         final double[] x = {
451             0.0, 0.0,
452             1.0, 1.0,
453             1.5,
454             1.6,
455             1.7,
456             1.8,
457             1.9,
458             2.0,
459             2.000000000000001
460         };
461 
462         final double[] y = {
463             0.0, 0.0,
464             10.0, 10.0,
465             11.0, 11.0, 11.0,
466             15.0,
467             16.0,
468             17.0,
469             18.0,
470             19.0,
471             20.0,
472             20.000000000000001
473         };
474 
475         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
476         Assert.assertEquals(1.12173015e-5, test.kolmogorovSmirnovTest(x, y), 1e-6);
477     }
478 
479     @Ignore@Test
480     public void testTwoSampleWithManyTiesAndExtremeValues() {
481         
482 
483         final double[] largeX = {
484             Double.MAX_VALUE, Double.MAX_VALUE,
485             1e40, 1e40,
486             2e40, 2e40,
487             1e30,
488             2e30,
489             3e30,
490             4e30,
491             5e10,
492             6e10,
493             7e10,
494             8e10
495         };
496 
497         final double[] smallY = {
498             Double.MIN_VALUE,
499             2 * Double.MIN_VALUE,
500             1e-40, 1e-40,
501             2e-40, 2e-40,
502             1e-30,
503             2e-30,
504             3e-30,
505             4e-30,
506             5e-10,
507             6e-10,
508             7e-10,
509             8e-10
510         };
511 
512         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
513         Assert.assertEquals(0, test.kolmogorovSmirnovTest(largeX, smallY), 1e-10);
514     }
515 
516     @Ignore@Test
517     public void testTwoSamplesWithInfinitiesAndTies() {
518         final double[] x = {
519             1, 1,
520             Double.POSITIVE_INFINITY,
521             Double.POSITIVE_INFINITY,
522             Double.NEGATIVE_INFINITY,
523             Double.POSITIVE_INFINITY,
524             Double.NEGATIVE_INFINITY,
525             Double.POSITIVE_INFINITY,
526             Double.POSITIVE_INFINITY
527         };
528 
529         final double[] y = {
530             1, 1,
531             3, 3,
532             Double.NEGATIVE_INFINITY,
533             Double.POSITIVE_INFINITY,
534             Double.POSITIVE_INFINITY,
535             Double.POSITIVE_INFINITY,
536             Double.POSITIVE_INFINITY,
537             Double.POSITIVE_INFINITY,
538             Double.NEGATIVE_INFINITY
539         };
540 
541         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
542         Assert.assertEquals(0, test.kolmogorovSmirnovTest(x, y), 1e-10);
543     }
544 
545     @Test(expected=InsufficientDataException.class)
546     public void testTwoSamplesWithOnlyInfinities() {
547         final double[] x = {
548             Double.POSITIVE_INFINITY,
549             Double.POSITIVE_INFINITY,
550             Double.NEGATIVE_INFINITY,
551             Double.POSITIVE_INFINITY,
552             Double.NEGATIVE_INFINITY,
553             Double.POSITIVE_INFINITY,
554             Double.POSITIVE_INFINITY
555         };
556 
557         final double[] y = {
558             Double.NEGATIVE_INFINITY,
559             Double.POSITIVE_INFINITY,
560             Double.POSITIVE_INFINITY,
561             Double.POSITIVE_INFINITY,
562             Double.POSITIVE_INFINITY,
563             Double.POSITIVE_INFINITY,
564             Double.NEGATIVE_INFINITY
565         };
566 
567         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
568         Assert.assertEquals(0, test.kolmogorovSmirnovTest(x, y), 1e-10);
569     }
570 
571     @Test(expected=NotANumberException.class)
572     public void testTwoSampleWithTiesAndNaN1() {
573         
574 
575         final double[] x = { 1, Double.NaN, 3, 4 };
576         final double[] y = { 1, 2, 3, 4 };
577         new KolmogorovSmirnovTest().kolmogorovSmirnovTest(x, y);
578     }
579 
580     @Test(expected=NotANumberException.class)
581     public void testTwoSampleWithTiesAndNaN2() {
582         
583 
584         final double[] x = { 1, 2, 3, 4 };
585         final double[] y = { 1, 2, Double.NaN, 4 };
586 
587         new KolmogorovSmirnovTest().kolmogorovSmirnovTest(x, y);
588     }
589 
590     @Test
591     public void testTwoSamplesAllEqual() {
592         int iterations = 10_000;
593         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
594         final UniformRandomProvider rng = RandomSource.WELL_19937_C.create(1000);
595         for (int i = 2; i < 30; ++i) {
596             
597             double[] values = new double[i];
598             Arrays.fill(values, i);
599             
600             double[] ascendingValues = new double[i];
601             for (int j = 0; j < ascendingValues.length; j++) {
602                 ascendingValues[j] = j;
603             }
604 
605             Assert.assertEquals(0., test.kolmogorovSmirnovStatistic(values, values), 0.);
606             Assert.assertEquals(0., test.kolmogorovSmirnovStatistic(ascendingValues, ascendingValues), 0.);
607 
608             if (i < 10) {
609                 Assert.assertEquals(1.0, test.exactP(0, values.length, values.length, true), 0.);
610                 Assert.assertEquals(1.0, test.exactP(0, values.length, values.length, false), 0.);
611             }
612 
613             Assert.assertEquals(1.0, test.monteCarloP(0, values.length, values.length, true, iterations, rng), 0.);
614             Assert.assertEquals(1.0, test.monteCarloP(0, values.length, values.length, false, iterations, rng), 0.);
615 
616             Assert.assertEquals(1.0, test.approximateP(0, values.length, values.length), 0.);
617             Assert.assertEquals(1.0, test.approximateP(0, values.length, values.length), 0.);
618         }
619     }
620 
621     
622 
623 
624 
625 
626 
627     @Test
628     public void testDRounding() {
629         final double tol = 1e-12;
630         final double[] x = {0, 2, 3, 4, 5, 6, 7, 8, 9, 12};
631         final double[] y = {1, 10, 11, 13, 14, 15, 16, 17, 18};
632         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
633         Assert.assertEquals(0.0027495724090154106, test.kolmogorovSmirnovTest(x, y,false), tol);
634 
635         final double[] x1 = {2, 4, 6, 8, 9, 10, 11, 12, 13};
636         final double[] y1 = {0, 1, 3, 5, 7};
637         Assert.assertEquals(0.085914085914085896, test.kolmogorovSmirnovTest(x1, y1, false), tol);
638 
639         final double[] x2 = {4, 6, 7, 8, 9, 10, 11};
640         final double[] y2 = {0, 1, 2, 3, 5};
641         Assert.assertEquals(0.015151515151515027, test.kolmogorovSmirnovTest(x2, y2, false), tol);
642     }
643 
644     
645 
646 
647 
648 
649 
650     @Test
651     public void testDRoundingMonteCarlo() {
652         final double tol = 1e-2;
653         final int iterations = 1000000;
654         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
655         final UniformRandomProvider rng = RandomSource.WELL_19937_C.create(1000);
656 
657         final double[] x = {0, 2, 3, 4, 5, 6, 7, 8, 9, 12};
658         final double[] y = {1, 10, 11, 13, 14, 15, 16, 17, 18};
659         double d = test.kolmogorovSmirnovStatistic(x, y);
660         Assert.assertEquals(0.0027495724090154106, test.monteCarloP(d, x.length, y.length, false, iterations, rng), tol);
661 
662         final double[] x1 = {2, 4, 6, 8, 9, 10, 11, 12, 13};
663         final double[] y1 = {0, 1, 3, 5, 7};
664         d = test.kolmogorovSmirnovStatistic(x1, y1);
665         Assert.assertEquals(0.085914085914085896, test.monteCarloP(d, x1.length, y1.length, false, iterations, rng), tol);
666 
667         final double[] x2 = {4, 6, 7, 8, 9, 10, 11};
668         final double[] y2 = {0, 1, 2, 3, 5};
669         d = test.kolmogorovSmirnovStatistic(x2, y2);
670         Assert.assertEquals(0.015151515151515027, test.monteCarloP(d, x2.length, y2.length, false, iterations, rng), tol);
671     }
672 
673     @Test
674     public void testFillBooleanArrayRandomlyWithFixedNumberTrueValues() throws Exception {
675         Method method = KolmogorovSmirnovTest.class.getDeclaredMethod("fillBooleanArrayRandomlyWithFixedNumberTrueValues",
676                                                                       boolean[].class, Integer.TYPE, UniformRandomProvider.class);
677         method.setAccessible(true);
678 
679         final int[][] parameters = {{5, 1}, {5, 2}, {5, 3}, {5, 4}, {8, 1}, {8, 2}, {8, 3}, {8, 4}, {8, 5}, {8, 6}, {8, 7}};
680 
681         final double alpha = 0.001;
682         final int numIterations = 1000000;
683 
684         final UniformRandomProvider rng = RandomSource.WELL_19937_C.create(0);
685 
686         for (final int[] parameter : parameters) {
687 
688             final int arraySize = parameter[0];
689             final int numberOfTrueValues = parameter[1];
690 
691             final boolean[] b = new boolean[arraySize];
692             final long[] counts = new long[1 << arraySize];
693 
694             for (int i = 0; i < numIterations; ++i) {
695                 method.invoke(KolmogorovSmirnovTest.class, b, numberOfTrueValues, rng);
696                 int x = 0;
697                 for (int j = 0; j < arraySize; ++j) {
698                     x = (x << 1) | ((b[j])?1:0);
699                 }
700                 counts[x] += 1;
701             }
702 
703             final int numCombinations = (int) BinomialCoefficient.value(arraySize, numberOfTrueValues);
704 
705             final long[] observed = new long[numCombinations];
706             final double[] expected = new double[numCombinations];
707             Arrays.fill(expected, numIterations / (double) numCombinations);
708 
709             int observedIdx = 0;
710 
711             for (int i = 0; i < (1 << arraySize); ++i) {
712                 if (Integer.bitCount(i) == numberOfTrueValues) {
713                     observed[observedIdx] = counts[i];
714                     observedIdx += 1;
715                 } else {
716                     Assert.assertEquals(0, counts[i]);
717                 }
718             }
719 
720             Assert.assertEquals(numCombinations, observedIdx);
721             TestUtils.assertChiSquareAccept(expected, observed, alpha);
722         }
723     }
724 
725     
726 
727 
728 
729     @Test
730     public void testBootstrapSmallSamplesWithTies() {
731         final double[] x = {0, 2, 4, 6, 8, 8, 10, 15, 22, 30, 33, 36, 38};
732         final double[] y = {9, 17, 20, 33, 40, 51, 60, 60, 72, 90, 101};
733         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
734         final UniformRandomProvider rng = RandomSource.WELL_19937_C.create(2000);
735         Assert.assertEquals(0.0059, test.bootstrap(x, y, 10000, false, rng), 1E-3);
736     }
737 
738     
739 
740 
741 
742     @Test
743     public void testBootstrapLargeSamples() {
744         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
745         final UniformRandomProvider rng = RandomSource.WELL_19937_C.create(1000);
746         Assert.assertEquals(0.0237, test.bootstrap(gaussian, gaussian2, 10000, true, rng), 1E-2);
747     }
748 
749     
750 
751 
752 
753 
754     @Test
755     public void testBootstrapRounding() {
756         final double[] x = {2,4,6,8,9,10,11,12,13};
757         final double[] y = {0,1,3,5,7};
758         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
759         final UniformRandomProvider rng = RandomSource.WELL_19937_C.create(1000);
760         Assert.assertEquals(0.06303, test.bootstrap(x, y, 10000, false, rng), 1E-2);
761     }
762 
763     @Test
764     public void testFixTiesNoOp() throws Exception {
765         final double[] x = {0, 1, 2, 3, 4};
766         final double[] y = {5, 6, 7, 8};
767         final double[] origX = Arrays.copyOf(x, x.length);
768         final double[] origY = Arrays.copyOf(y, y.length);
769         fixTies(x,y);
770         Assert.assertArrayEquals(origX, x, 0);
771         Assert.assertArrayEquals(origY, y, 0);
772     }
773 
774     
775 
776 
777 
778     @Test
779     public void testFixTiesConsistency() throws Exception {
780         final double[] x = {0, 1, 2, 3, 4, 2};
781         final double[] y = {5, 6, 7, 8, 1, 2};
782         final double[] xP = Arrays.copyOf(x, x.length);
783         final double[] yP = Arrays.copyOf(y, y.length);
784         checkFixTies(x, y);
785         final double[] fixedX = Arrays.copyOf(x, x.length);
786         final double[] fixedY = Arrays.copyOf(y, y.length);
787         checkFixTies(xP, yP);
788         Assert.assertArrayEquals(fixedX, xP, 0);
789         Assert.assertArrayEquals(fixedY, yP, 0);
790     }
791 
792     @Test
793     public void testFixTies() throws Exception {
794         checkFixTies(new double[] {0, 1, 1, 4, 0}, new double[] {0, 5, 0.5, 0.55, 7});
795         checkFixTies(new double[] {1, 1, 1, 1, 1}, new double[] {1, 1});
796         checkFixTies(new double[] {1, 2, 3}, new double[] {1});
797         checkFixTies(new double[] {1, 1, 0, 1, 0}, new double[] {});
798     }
799 
800     @Test
801     public void testMath1475() throws Exception {
802         
803         double[] x = new double[] { 0.12350159883499146, -0.2601194679737091, -1.322849988937378, 0.379696249961853,
804                                     0.3987586498260498, -0.06924121081829071, -0.13951236009597778, 0.3213207423686981,
805                                     0.7949811816215515, -0.15811105072498322, 0.19912190735340118, -0.46363770961761475,
806                                     -0.20019817352294922, 0.3062838613986969, -0.3872813880443573, 0.10733723640441895,
807                                     0.10910066962242126, 0.625770092010498, 0.2824835777282715, 0.3107619881629944,
808                                     0.1432388722896576, -0.08056988567113876, -0.5816712379455566, -0.09488576650619507,
809                                     -0.2154506891965866, 0.2509046196937561, -0.06600788980722427, -0.01133995596319437,
810                                     -0.22642627358436584, -0.12150175869464874, -0.21109570562839508, -0.17732949554920197,
811                                     -0.2769380807876587, -0.3607368767261505, -0.07842907309532166, -0.2518743574619293,
812                                     0.035517483949661255, -0.6556509137153625, -0.360045850276947, -0.09371964633464813,
813                                     -0.7284095883369446, -0.22719840705394745, -1.5540679693222046, -0.008972732350230217,
814                                     -0.09106933325529099, -0.6465389132499695, 0.036245591938495636, 0.657580554485321,
815                                     0.32453101873397827, 0.6105462908744812, 0.25256943702697754, -0.194427490234375,
816                                     0.6238796710968018, 0.5203511118888855, -0.2708645761013031, 0.07761227339506149,
817                                     0.5315862894058228, 0.44320303201675415, 0.6283767819404602, 0.2618369162082672,
818                                     0.47253096103668213, 0.3889777660369873, 0.6856100559234619, 0.3007083833217621,
819                                     0.4963226914405823, 0.08229698985815048, 0.6170856952667236, 0.7501978874206543,
820                                     0.5744063258171082, 0.5233180522918701, 0.32654184103012085, 0.3014495372772217,
821                                     0.4082445800304413, -0.1075737327337265, -0.018864337354898453, 0.34642550349235535,
822                                     0.6414541602134705, 0.16678297519683838, 0.46028634905815125, 0.4151197075843811,
823                                     0.14407725632190704, 0.41751566529273987, -0.054958608001470566, 0.4995657801628113,
824                                     0.4485369324684143, 0.5600396990776062, 0.4098612368106842, 0.2748555839061737,
825                                     0.2562614381313324, 0.4324824810028076 };
826         double[] y = new double[] { 2.6881366763426717, 2.685469965655465, 2.261888917462379, -2.1933598759641226,
827                                     -2.4279488152810145, -3.159389495849609, -2.3150004548153444, 2.468029206047388,
828                                     2.9442494682288953, 2.653360013462529, -2.1189940659194835, -2.121635289903703,
829                                     -2.103092459792032, -2.737034221468073, -2.203389332350286, 2.1985949039005512,
830                                     -2.5021604073154737, 2.2732754920764533, -2.3867025598454346, 2.135919387338413,
831                                     2.338120776050672, 2.2579794509726874, 2.083329059799027, -2.209733724709957,
832                                     2.297192240399189, -2.201703830825843, -3.460208691996806, 2.428839296615834,
833                                     -3.2944259224581574, 2.0654875493620883, -2.743948930837782, -2.2240674680805212,
834                                     -3.646366778182357, -2.12513198437294, 2.979166188824589, -2.6275491570089033,
835                                     -2.3818176136461338, 2.882096356968376, -2.2147229261558334, -3.159389495849609,
836                                     2.312428759406432, 2.3313864098846477, -2.72802504046371, -2.4216068225364245,
837                                     3.0119599306499123, 2.5753099009496783, -2.9200121783556843, -2.519352725437922,
838                                     -4.133932580227538, -2.30496316762808, 2.5381353678521363, 2.4818233632136697,
839                                     2.5277451177925685, -2.166465445816232, -2.1193897819471563, -2.109654332722425,
840                                     3.260211545834851, -3.9527673876059013, -2.199885089466947, 2.152573429747697,
841                                     -3.1593894958496094, 2.5479522823226795, 3.342810742466116, -2.8197184957304007,
842                                     -2.3407900299253765, -2.3303967152728537, 2.1760131201015565, 2.143930552944634,
843                                     2.33336231754409, 2.9126278362420575, -2.121169134387265, -2.2980208408109095,
844                                     -2.285400411434817, -2.0742764640932903, 2.304178664095016, -2.2893825538911634,
845                                     -3.7714771984158806, -2.7153698816026886, 2.8995011276220226, -2.158787087333056,
846                                     -2.1045987952052547, 2.8478762016468147, -2.694578565956955, -2.696014432856399,
847                                     -2.3190122657403496, -2.48225194403028, 3.3393947563371764, 2.7775468034263517,
848                                     -3.396526561479875, -2.699967947404961};
849         KolmogorovSmirnovTest kst = new KolmogorovSmirnovTest();
850         kst.kolmogorovSmirnovTest(x, y);
851     }
852 
853     @Ignore@Test
854     public void testMath1535() {
855         
856         final double[] x = new double[] {0.8767630865438496, 0.9998809418147052, 0.9999999715463531, 0.9999985849345421,
857                                          0.973584315883326, 0.9999999875782982, 0.999999999999994, 0.9999999999908233,
858                                          1.0, 0.9999999890925574, 0.9999998345734327, 0.9999999350772448,
859                                          0.999999999999426, 0.9999147040688201, 0.9999999999999922, 1.0,
860                                          1.0, 0.9919050954798272, 0.8649014770687263, 0.9990869497973084,
861                                          0.9993222540990464, 0.999999999998189, 0.9999999999999365, 0.9790934801762917,
862                                          0.9999578695006303, 0.9999999999999998, 0.999999999996166, 0.9999999999995546,
863                                          0.9999999999908036, 0.99999999999744, 0.9999998802655555, 0.9079334221214075,
864                                          0.9794398308007372, 0.9999044231134367, 0.9999999999999813, 0.9999957841707683,
865                                          0.9277678892094009, 0.999948269893843, 0.9999999886132888, 0.9999998909699096,
866                                          0.9999099536620326, 0.9999999962217623, 0.9138936987350447, 0.9999999999779976,
867                                          0.999999999998822, 0.999979247207911, 0.9926904388316407, 1.0,
868                                          0.9999999999998814, 1.0, 0.9892505696426215, 0.9999996514123723,
869                                          0.9999999999999429, 0.9999999995399116, 0.999999999948221, 0.7358264887843119,
870                                          0.9999999994098534, 1.0, 0.9999986456748472, 1.0,
871                                          0.9999999999921501, 0.9999999999999996, 0.9999999999999944, 0.9473070068606853,
872                                          0.9993714060209042, 0.9999999409098718, 0.9999999592791519, 0.9999999999999805};
873         final double[] y = new double[x.length];
874         Arrays.fill(y, 1d);
875         final KolmogorovSmirnovTest kst = new KolmogorovSmirnovTest();
876         double p = kst.kolmogorovSmirnovTest(x, y);
877     }
878 
879     
880 
881 
882 
883     private void checkFixTies(double[] x, double[] y) throws Exception {
884         final double[] origCombined = MathArrays.concatenate(x, y);
885         fixTies(x, y);
886         Assert.assertFalse(hasTies(x, y));
887         final double[] combined = MathArrays.concatenate(x, y);
888         for (int i = 0; i < combined.length; i++) {
889             for (int j = 0; j < i; j++) {
890                 Assert.assertTrue(combined[i] != combined[j]);
891                 if (combined[i] < combined[j]) {
892                     Assert.assertTrue(origCombined[i] < origCombined[j]
893                                       || origCombined[i] == origCombined[j]);
894                 }
895             }
896         }
897     }
898 
899     
900 
901 
902 
903 
904 
905 
906 
907 
908 
909 
910 
911 
912 
913     private void checkExactTable(int n, int m, double criticalValue, double alpha) {
914         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
915         Assert.assertTrue(test.exactP(criticalValue, n, m, true) < alpha);
916         Assert.assertTrue(test.exactP(criticalValue, n, m, false) > alpha);
917     }
918 
919     
920 
921 
922 
923 
924 
925 
926 
927 
928     private void checkApproximateTable(int n, int m, double criticalValue, double alpha, double epsilon) {
929         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
930         Assert.assertEquals(alpha, test.approximateP(criticalValue, n, m), epsilon);
931     }
932 
933     
934 
935 
936     private static void fixTies(double[] x, double[] y) throws Exception {
937         Method method = KolmogorovSmirnovTest.class.getDeclaredMethod("fixTies",
938                                                                       double[].class, double[].class);
939         method.setAccessible(true);
940         method.invoke(KolmogorovSmirnovTest.class, x, y);
941     }
942 
943     
944 
945 
946     private static boolean hasTies(double[] x, double[] y) throws Exception {
947         Method method = KolmogorovSmirnovTest.class.getDeclaredMethod("hasTies",
948                                                                       double[].class, double[].class);
949         method.setAccessible(true);
950         return (boolean) method.invoke(KolmogorovSmirnovTest.class, x, y);
951     }
952 }