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 }