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  
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   * Test cases for {@link KolmogorovSmirnovTest}.
39   *
40   * @since 3.3
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      // Random N(0,1) values generated using R rnorm
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      // Random N(0, 1.6) values generated using R rnorm
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      // Random uniform (0, 1) generated using R runif
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     /** Unit normal distribution, unit normal data */
104     @Test
105     public void testOneSampleGaussianGaussian() {
106         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
107         final NormalDistribution unitNormal = NormalDistribution.of(0d, 1d);
108         // Uncomment to run exact test - takes about a minute. Same value is used in R tests and for
109         // approx.
110         // Assert.assertEquals(0.3172069207622391, test.kolmogorovSmirnovTest(unitNormal, gaussian,
111         // true), TOLERANCE);
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     /** Unit normal distribution, unit normal data, small dataset */
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     /** Unit normal distribution, uniform data */
130     @Test
131     public void testOneSampleGaussianUniform() {
132         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
133         final NormalDistribution unitNormal = NormalDistribution.of(0d, 1d);
134         // Uncomment to run exact test - takes a long time. Same value is used in R tests and for
135         // approx.
136         // Assert.assertEquals(0.3172069207622391, test.kolmogorovSmirnovTest(unitNormal, uniform,
137         // true), TOLERANCE);
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     /** Uniform distribution, uniform data */
144     // @Test - takes about 6 seconds, uncomment for
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     /** Uniform distribution, uniform data, small dataset */
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     /** Uniform distribution, unit normal dataset */
166     @Test
167     public void testOneSampleUniformGaussian() {
168         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
169         final UniformContinuousDistribution unif = UniformContinuousDistribution.of(-0.5, 0.5);
170         // Value was obtained via exact test, validated against R. Running exact test takes a long
171         // time.
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     /** Small samples - exact p-value, checked against R */
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         // Reference values from R, version 3.2.0 - R uses non-strict inequality in null hypothesis
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     /** Small samples - exact p-value, checked against R */
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         // Reference values from R, version 3.2.0 - R uses non-strict inequality in null hypothesis
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     /** Small samples - exact p-value, checked against R */
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         // Reference values from R, version 3.2.0 - R uses non-strict inequality in null hypothesis
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      * Checks exact p-value computations using critical values from Table 9 in V.K Rohatgi, An
231      * Introduction to Probability and Mathematical Statistics, Wiley, 1976, ISBN 0-471-73135-8.
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         // From Wikipedia KS article - TODO: get (and test) more precise values
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         // Reference values computed using the Pelz method from
277         // http://simul.iro.umontreal.ca/ksdir/KolmogorovSmirnovDist.java
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     /** Verifies large sample approximate p values against R */
297     @Test
298     public void testTwoSampleApproximateP() {
299         final KolmogorovSmirnovTest test = new KolmogorovSmirnovTest();
300         // Reference values from R, version 2.15.3
301         Assert.assertEquals(0.0319983962391632, test.kolmogorovSmirnovTest(gaussian, gaussian2), TOLERANCE);
302         Assert.assertEquals(0.202352941176471, test.kolmogorovSmirnovStatistic(gaussian, gaussian2), TOLERANCE);
303     }
304 
305     /**
306      * MATH-1181
307      * Verify that large sample method is selected for sample product > Integer.MAX_VALUE
308      * (integer overflow in sample product)
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      * Verifies that Monte Carlo simulation gives results close to exact p values.
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      * Performance test for monteCarlo method. Disabled by default.
368      */
369     // @Test
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         // MATH-1197
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         // Cf. MATH-1405
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         // Cf. MATH-1405
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         // Cf. MATH-1405
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         // Cf. MATH-1405
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             // testing values with ties
597             double[] values = new double[i];
598             Arrays.fill(values, i);
599             // testing values without ties
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      * JIRA: MATH-1245
623      *
624      * Verify that D-values are not viewed as distinct when they are mathematically equal
625      * when computing p-statistics for small sample tests. Reference values are from R 3.2.0.
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      * JIRA: MATH-1245
646      *
647      * Verify that D-values are not viewed as distinct when they are mathematically equal
648      * when computing p-statistics for small sample tests. Reference values are from R 3.2.0.
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      * Test an example with ties in the data.  Reference data is R 3.2.0,
727      * ks.boot implemented in Matching (Version 4.8-3.4, Build Date: 2013/10/28)
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      * Reference data is R 3.2.0, ks.boot implemented in
740      * Matching (Version 4.8-3.4, Build Date: 2013/10/28)
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      * Test an example where D-values are close (subject to rounding).
751      * Reference data is R 3.2.0, ks.boot implemented in
752      * Matching (Version 4.8-3.4, Build Date: 2013/10/28)
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      * Verify that fixTies is deterministic, i.e,
776      * x = x', y = y' => fixTies(x,y) = fixTies(x', y')
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         // MATH-1475
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         // MATH-1535
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      * Checks that fixTies eliminates ties in the data but does not otherwise
881      * perturb the ordering.
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      * Verifies the inequality exactP(criticalValue, n, m, true) < alpha < exactP(criticalValue, n,
901      * m, false).
902      *
903      * Note that the validity of this check depends on the fact that alpha lies strictly between two
904      * attained values of the distribution and that criticalValue is one of the attained values. The
905      * critical value table (reference below) uses attained values. This test therefore also
906      * verifies that criticalValue is attained.
907      *
908      * @param n first sample size
909      * @param m second sample size
910      * @param criticalValue critical value
911      * @param alpha significance level
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      * Verifies that approximateP(criticalValue, n, m) is within epsilon of alpha.
921      *
922      * @param n first sample size
923      * @param m second sample size
924      * @param criticalValue critical value (from table)
925      * @param alpha significance level
926      * @param epsilon tolerance
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      * Reflection hack to expose private fixTies method for testing.
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      * Reflection hack to expose private hasTies method.
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 }