1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.stat.descriptive.rank;
23
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertFalse;
26 import static org.junit.Assert.assertTrue;
27 import static org.junit.Assert.fail;
28
29 import java.util.Arrays;
30
31 import org.hipparchus.distribution.continuous.NormalDistribution;
32 import org.hipparchus.exception.MathIllegalArgumentException;
33 import org.hipparchus.exception.NullArgumentException;
34 import org.hipparchus.random.RandomDataGenerator;
35 import org.hipparchus.stat.descriptive.UnivariateStatistic;
36 import org.hipparchus.stat.descriptive.UnivariateStatisticAbstractTest;
37 import org.hipparchus.stat.descriptive.rank.Percentile.EstimationType;
38 import org.hipparchus.stat.ranking.NaNStrategy;
39 import org.hipparchus.util.KthSelector;
40 import org.hipparchus.util.PivotingStrategy;
41 import org.junit.Before;
42 import org.junit.Test;
43
44
45
46
47 public class PercentileTest extends UnivariateStatisticAbstractTest{
48
49 private double quantile;
50
51
52
53
54
55 private Percentile.EstimationType type;
56
57
58
59
60
61 private NaNStrategy nanStrategy;
62
63
64
65
66 private KthSelector kthSelector;
67
68
69
70
71 protected final double DEFAULT_PERCENTILE = 95d;
72
73
74
75
76 @Before
77 public void setup() {
78 quantile = 95.0;
79 type = Percentile.EstimationType.LEGACY;
80 nanStrategy = NaNStrategy.REMOVED;
81 kthSelector = new KthSelector(PivotingStrategy.MEDIAN_OF_3);
82 }
83
84 private void reset(final double p, final Percentile.EstimationType type) {
85 this.quantile = p;
86 this.type = type;
87 nanStrategy = (type == Percentile.EstimationType.LEGACY) ? NaNStrategy.FIXED : NaNStrategy.REMOVED;
88 }
89
90 @Override
91 public Percentile getUnivariateStatistic() {
92 return new Percentile(quantile)
93 .withEstimationType(type)
94 .withNaNStrategy(nanStrategy)
95 .withKthSelector(kthSelector);
96 }
97
98 @Override
99 public double expectedValue() {
100 return this.percentile95;
101 }
102
103 @Test
104 public void testHighPercentile(){
105 final double[] d = new double[]{1, 2, 3};
106 final Percentile p = new Percentile(75);
107 assertEquals(3.0, p.evaluate(d), 1.0e-5);
108 }
109
110 @Test
111 public void testLowPercentile() {
112 final double[] d = new double[] {0, 1};
113 final Percentile p = new Percentile(25);
114 assertEquals(0d, p.evaluate(d), Double.MIN_VALUE);
115 }
116
117 @Test
118 public void testPercentile() {
119 final double[] d = new double[] {1, 3, 2, 4};
120 final Percentile p = new Percentile(30);
121 assertEquals(1.5, p.evaluate(d), 1.0e-5);
122 p.setQuantile(25);
123 assertEquals(1.25, p.evaluate(d), 1.0e-5);
124 p.setQuantile(75);
125 assertEquals(3.75, p.evaluate(d), 1.0e-5);
126 p.setQuantile(50);
127 assertEquals(2.5, p.evaluate(d), 1.0e-5);
128
129
130 try {
131 p.evaluate(d, 0, d.length, -1.0);
132 fail();
133 } catch (final MathIllegalArgumentException ex) {
134
135 }
136 try {
137 p.evaluate(d, 0, d.length, 101.0);
138 fail();
139 } catch (final MathIllegalArgumentException ex) {
140
141 }
142 }
143
144 @Test
145 public void testNISTExample() {
146 final double[] d = new double[] {95.1772, 95.1567, 95.1937, 95.1959,
147 95.1442, 95.0610, 95.1591, 95.1195, 95.1772, 95.0925, 95.1990, 95.1682
148 };
149 final Percentile p = new Percentile(90);
150 assertEquals(95.1981, p.evaluate(d), 1.0e-4);
151 assertEquals(95.1990, p.evaluate(d,0,d.length, 100d), 0);
152 }
153
154 @Test
155 public void test5() {
156 final Percentile percentile = new Percentile(5);
157 assertEquals(this.percentile5, percentile.evaluate(testArray), getTolerance());
158 }
159
160 @Test
161 public void testNullEmpty() {
162 final Percentile percentile = new Percentile(50);
163 final double[] nullArray = null;
164 final double[] emptyArray = new double[] {};
165 try {
166 percentile.evaluate(nullArray);
167 fail("Expecting NullArgumentException for null array");
168 } catch (final NullArgumentException ex) {
169
170 }
171 assertTrue(Double.isNaN(percentile.evaluate(emptyArray)));
172 }
173
174 @Test
175 public void testSingleton() {
176 final Percentile percentile = new Percentile(50);
177 final double[] singletonArray = new double[] {1d};
178 assertEquals(1d, percentile.evaluate(singletonArray), 0);
179 assertEquals(1d, percentile.evaluate(singletonArray, 0, 1), 0);
180 assertEquals(1d, percentile.evaluate(singletonArray, 0, 1, 5), 0);
181 assertEquals(1d, percentile.evaluate(singletonArray, 0, 1, 100), 0);
182 assertTrue(Double.isNaN(percentile.evaluate(singletonArray, 0, 0)));
183 }
184
185 @Test
186 public void testSpecialValues() {
187 final Percentile percentile = new Percentile(50);
188 double[] specialValues = new double[] {0d, 1d, 2d, 3d, 4d, Double.NaN};
189 assertEquals(2d, percentile.evaluate(specialValues), 0);
190 specialValues = new double[] { Double.NEGATIVE_INFINITY, 1d, 2d, 3d, Double.NaN, Double.POSITIVE_INFINITY };
191 assertEquals(2d, percentile.evaluate(specialValues), 0);
192 specialValues = new double[] {1d, 1d, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY};
193 assertTrue(Double.isInfinite(percentile.evaluate(specialValues)));
194 specialValues = new double[] {1d, 1d, Double.NaN, Double.NaN};
195 assertTrue(!Double.isNaN(percentile.evaluate(specialValues)));
196 assertTrue(1d==percentile.evaluate(specialValues));
197 specialValues = new double[] {1d, 1d, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY};
198
199 assertTrue(Double.isNaN(percentile.evaluate(specialValues)));
200 }
201
202 @Test
203 public void testSetQuantile() {
204 final Percentile percentile = new Percentile(10);
205 percentile.setQuantile(100);
206 assertEquals(100, percentile.getQuantile(), 0);
207 try {
208 percentile.setQuantile(0);
209 fail("Expecting MathIllegalArgumentException");
210 } catch (final MathIllegalArgumentException ex) {
211
212 }
213 try {
214 new Percentile(0);
215 fail("Expecting MathIllegalArgumentException");
216 } catch (final MathIllegalArgumentException ex) {
217
218 }
219 }
220
221
222
223
224
225
226 @Test
227 public void testAllTechniquesHighPercentile() {
228 final double[] d = new double[] { 1, 2, 3 };
229 testAssertMappedValues(d, new Object[][] { { Percentile.EstimationType.LEGACY, 3d }, { Percentile.EstimationType.R_1, 3d },
230 { Percentile.EstimationType.R_2, 3d }, { Percentile.EstimationType.R_3, 2d }, { Percentile.EstimationType.R_4, 2.25 }, { Percentile.EstimationType.R_5, 2.75 },
231 { Percentile.EstimationType.R_6, 3d }, { Percentile.EstimationType.R_7, 2.5 },{ Percentile.EstimationType.R_8, 2.83333 }, {Percentile.EstimationType.R_9,2.81250} },
232 75d, 1.0e-5);
233 }
234
235 @Test
236 public void testAllTechniquesLowPercentile() {
237 final double[] d = new double[] { 0, 1 };
238 testAssertMappedValues(d, new Object[][] { { Percentile.EstimationType.LEGACY, 0d }, { Percentile.EstimationType.R_1, 0d },
239 { Percentile.EstimationType.R_2, 0d }, { Percentile.EstimationType.R_3, 0d }, { Percentile.EstimationType.R_4, 0d }, {Percentile.EstimationType.R_5, 0d}, {Percentile.EstimationType.R_6, 0d},
240 { Percentile.EstimationType.R_7, 0.25 }, { Percentile.EstimationType.R_8, 0d }, {Percentile.EstimationType.R_9, 0d} },
241 25d, Double.MIN_VALUE);
242 }
243
244 public void checkAllTechniquesPercentile() {
245 final double[] d = new double[] { 1, 3, 2, 4 };
246
247 testAssertMappedValues(d, new Object[][] { { Percentile.EstimationType.LEGACY, 1.5d },
248 { Percentile.EstimationType.R_1, 2d }, { Percentile.EstimationType.R_2, 2d }, { Percentile.EstimationType.R_3, 1d }, { Percentile.EstimationType.R_4, 1.2 }, {Percentile.EstimationType.R_5, 1.7},
249 { Percentile.EstimationType.R_6, 1.5 },{ Percentile.EstimationType.R_7, 1.9 }, { Percentile.EstimationType.R_8, 1.63333 },{ Percentile.EstimationType.R_9, 1.65 } },
250 30d, 1.0e-05);
251
252 testAssertMappedValues(d, new Object[][] { { Percentile.EstimationType.LEGACY, 1.25d },
253 { Percentile.EstimationType.R_1, 1d }, { Percentile.EstimationType.R_2, 1.5d }, { Percentile.EstimationType.R_3, 1d }, { Percentile.EstimationType.R_4, 1d }, {Percentile.EstimationType.R_5, 1.5},
254 { Percentile.EstimationType.R_6, 1.25 },{ Percentile.EstimationType.R_7, 1.75 },
255 { Percentile.EstimationType.R_8, 1.41667 }, { Percentile.EstimationType.R_9, 1.43750 } }, 25d, 1.0e-05);
256
257 testAssertMappedValues(d, new Object[][] { { Percentile.EstimationType.LEGACY, 3.75d },
258 { Percentile.EstimationType.R_1, 3d }, { Percentile.EstimationType.R_2, 3.5d }, { Percentile.EstimationType.R_3, 3d }, { Percentile.EstimationType.R_4, 3d },
259 { Percentile.EstimationType.R_5, 3.5d },{ Percentile.EstimationType.R_6, 3.75d }, { Percentile.EstimationType.R_7, 3.25 },
260 { Percentile.EstimationType.R_8, 3.58333 },{ Percentile.EstimationType.R_9, 3.56250} }, 75d, 1.0e-05);
261
262 testAssertMappedValues(d, new Object[][] { { Percentile.EstimationType.LEGACY, 2.5d },
263 { Percentile.EstimationType.R_1, 2d }, { Percentile.EstimationType.R_2, 2.5d }, { Percentile.EstimationType.R_3, 2d }, { Percentile.EstimationType.R_4, 2d },
264 { Percentile.EstimationType.R_5, 2.5 },{ Percentile.EstimationType.R_6, 2.5 },{ Percentile.EstimationType.R_7, 2.5 },
265 { Percentile.EstimationType.R_8, 2.5 },{ Percentile.EstimationType.R_9, 2.5 } }, 50d, 1.0e-05);
266
267
268 for (final Percentile.EstimationType e : Percentile.EstimationType.values()) {
269 try {
270 reset(-1.0, e);
271 getUnivariateStatistic().evaluate(d, 0, d.length);
272 fail();
273 } catch (final MathIllegalArgumentException ex) {
274
275 }
276 }
277
278 for (final Percentile.EstimationType e : Percentile.EstimationType.values()) {
279 try {
280 reset(101.0, e);
281 getUnivariateStatistic().evaluate(d, 0, d.length);
282 fail();
283 } catch (final MathIllegalArgumentException ex) {
284
285 }
286 }
287 }
288
289 @Test
290 public void testAllTechniquesPercentileUsingMedianOf3Pivoting() {
291 kthSelector = new KthSelector(PivotingStrategy.MEDIAN_OF_3);
292 checkAllTechniquesPercentile();
293 }
294
295 @Test
296 public void testAllTechniquesPercentileUsingCentralPivoting() {
297 kthSelector = new KthSelector(PivotingStrategy.CENTRAL);
298 checkAllTechniquesPercentile();
299 }
300
301 @Test
302 public void testAllTechniquesNISTExample() {
303 final double[] d =
304 new double[] { 95.1772, 95.1567, 95.1937, 95.1959, 95.1442, 95.0610,
305 95.1591, 95.1195, 95.1772, 95.0925, 95.1990, 95.1682 };
306
307 testAssertMappedValues(d, new Object[][] { { Percentile.EstimationType.LEGACY, 95.1981 },
308 { Percentile.EstimationType.R_1, 95.19590 }, { Percentile.EstimationType.R_2, 95.19590 }, { Percentile.EstimationType.R_3, 95.19590 },
309 { Percentile.EstimationType.R_4, 95.19546 }, { Percentile.EstimationType.R_5, 95.19683 }, { Percentile.EstimationType.R_6, 95.19807 },
310 { Percentile.EstimationType.R_7, 95.19568 }, { Percentile.EstimationType.R_8, 95.19724 }, { Percentile.EstimationType.R_9, 95.19714 } }, 90d,
311 1.0e-04);
312
313 for (final Percentile.EstimationType e : Percentile.EstimationType.values()) {
314 reset(100.0, e);
315 assertEquals(95.1990, getUnivariateStatistic().evaluate(d), 1.0e-4);
316 }
317 }
318
319 @Test
320 public void testAllTechniques5() {
321 reset(5, Percentile.EstimationType.LEGACY);
322 final UnivariateStatistic percentile = getUnivariateStatistic();
323 assertEquals(this.percentile5, percentile.evaluate(testArray), getTolerance());
324 testAssertMappedValues(testArray,
325 new Object[][] { { Percentile.EstimationType.LEGACY, percentile5 }, { Percentile.EstimationType.R_1, 8.8000 },
326 { Percentile.EstimationType.R_2, 8.8000 }, { Percentile.EstimationType.R_3, 8.2000 }, { Percentile.EstimationType.R_4, 8.2600 },
327 { Percentile.EstimationType.R_5, 8.5600 }, { Percentile.EstimationType.R_6, 8.2900 },
328 { Percentile.EstimationType.R_7, 8.8100 }, { Percentile.EstimationType.R_8, 8.4700 },
329 { Percentile.EstimationType.R_9, 8.4925 }}, 5d, getTolerance());
330 }
331
332 @Test
333 public void testAllTechniquesNullEmpty() {
334
335 final double[] nullArray = null;
336 final double[] emptyArray = new double[] {};
337 for (final Percentile.EstimationType e : Percentile.EstimationType.values()) {
338 reset (50, e);
339 final UnivariateStatistic percentile = getUnivariateStatistic();
340 try {
341 percentile.evaluate(nullArray);
342 fail("Expecting NullArgumentException "
343 + "for null array");
344 } catch (final NullArgumentException ex) {
345
346 }
347 assertTrue(Double.isNaN(percentile.evaluate(emptyArray)));
348 }
349
350 }
351
352 @Test
353 public void testAllTechniquesSingleton() {
354 final double[] singletonArray = new double[] { 1d };
355 for (final Percentile.EstimationType e : Percentile.EstimationType.values()) {
356 reset (50, e);
357 final UnivariateStatistic percentile = getUnivariateStatistic();
358 assertEquals(1d, percentile.evaluate(singletonArray), 0);
359 assertEquals(1d, percentile.evaluate(singletonArray, 0, 1), 0);
360 assertEquals(1d, new Percentile().evaluate(singletonArray, 0, 1, 5), 0);
361 assertEquals(1d, new Percentile().evaluate(singletonArray, 0, 1, 100), 0);
362 assertTrue(Double.isNaN(percentile.evaluate(singletonArray, 0, 0)));
363 }
364 }
365
366 @Test
367 public void testAllTechniquesEmpty() {
368 final double[] singletonArray = new double[] { };
369 for (final Percentile.EstimationType e : Percentile.EstimationType.values()) {
370 reset (50, e);
371 final UnivariateStatistic percentile = getUnivariateStatistic();
372 assertEquals(Double.NaN, percentile.evaluate(singletonArray), 0);
373 assertEquals(Double.NaN, percentile.evaluate(singletonArray, 0, 0), 0);
374 assertEquals(Double.NaN, new Percentile().evaluate(singletonArray, 0, 0, 5), 0);
375 assertEquals(Double.NaN, new Percentile().evaluate(singletonArray, 0, 0, 100), 0);
376 assertTrue(Double.isNaN(percentile.evaluate(singletonArray, 0, 0)));
377 }
378 }
379
380 @Test
381 public void testReplaceNanInRange() {
382 final double[] specialValues =
383 new double[] { 0d, 1d, 2d, 3d, 4d, Double.NaN, Double.NaN, 5d, 7d, Double.NaN, 8d};
384 assertEquals(3.5, new Percentile(50d).evaluate(specialValues), 0d);
385 reset (50, Percentile.EstimationType.R_1);
386 assertEquals(3d, getUnivariateStatistic().evaluate(specialValues), 0d);
387 reset (50, Percentile.EstimationType.R_2);
388 assertEquals(3.5d, getUnivariateStatistic().evaluate(specialValues), 0d);
389 assertEquals(Double.POSITIVE_INFINITY,
390 new Percentile(70).withNaNStrategy(NaNStrategy.MAXIMAL).evaluate(specialValues),
391 0d);
392 }
393
394 @Test
395 public void testRemoveNan() {
396 final double[] specialValues = new double[] { 0d, 1d, 2d, 3d, 4d, Double.NaN };
397 final double[] expectedValues = new double[] { 0d, 1d, 2d, 3d, 4d };
398 reset (50, Percentile.EstimationType.R_1);
399 assertEquals(2.0, getUnivariateStatistic().evaluate(specialValues), 0d);
400 assertEquals(2.0, getUnivariateStatistic().evaluate(expectedValues),0d);
401 assertTrue(Double.isNaN(getUnivariateStatistic().evaluate(specialValues,5,1)));
402 assertEquals(4d, getUnivariateStatistic().evaluate(specialValues, 4, 2), 0d);
403 assertEquals(3d, getUnivariateStatistic().evaluate(specialValues,3,3),0d);
404 reset(50, Percentile.EstimationType.R_2);
405 assertEquals(3.5d, getUnivariateStatistic().evaluate(specialValues,3,3),0d);
406 }
407
408 @Test
409 public void testPercentileCopy() {
410 reset(50d, Percentile.EstimationType.LEGACY);
411 final Percentile original = getUnivariateStatistic();
412 final Percentile copy = new Percentile(original);
413 assertEquals(original.getNaNStrategy(),copy.getNaNStrategy());
414 assertEquals(original.getQuantile(), copy.getQuantile(),0d);
415 assertEquals(original.getEstimationType(),copy.getEstimationType());
416 assertEquals(NaNStrategy.FIXED, original.getNaNStrategy());
417 }
418
419 @Test
420 public void testAllTechniquesSpecialValues() {
421 reset(50d, Percentile.EstimationType.LEGACY);
422 final UnivariateStatistic percentile = getUnivariateStatistic();
423 double[] specialValues = new double[] { 0d, 1d, 2d, 3d, 4d, Double.NaN };
424 assertEquals(2.5d, percentile.evaluate(specialValues), 0);
425
426 testAssertMappedValues(specialValues, new Object[][] {
427 { Percentile.EstimationType.LEGACY, 2.5d }, { Percentile.EstimationType.R_1, 2.0 }, { Percentile.EstimationType.R_2, 2.0 }, { Percentile.EstimationType.R_3, 1.0 },
428 { Percentile.EstimationType.R_4, 1.5 }, { Percentile.EstimationType.R_5, 2.0 }, { Percentile.EstimationType.R_6, 2.0 },
429 { Percentile.EstimationType.R_7, 2.0 }, { Percentile.EstimationType.R_8, 2.0 }, { Percentile.EstimationType.R_9, 2.0 }}, 50d, 0d);
430
431 specialValues =
432 new double[] { Double.NEGATIVE_INFINITY, 1d, 2d, 3d, Double.NaN, Double.POSITIVE_INFINITY };
433 assertEquals(2.5d, percentile.evaluate(specialValues), 0);
434
435 testAssertMappedValues(specialValues, new Object[][] {
436 { Percentile.EstimationType.LEGACY, 2.5d }, { Percentile.EstimationType.R_1, 2.0 }, { Percentile.EstimationType.R_2, 2.0 }, { Percentile.EstimationType.R_3, 1.0 },
437 { Percentile.EstimationType.R_4, 1.5 }, { Percentile.EstimationType.R_5, 2.0 }, { Percentile.EstimationType.R_7, 2.0 }, { Percentile.EstimationType.R_7, 2.0 },
438 { Percentile.EstimationType.R_8, 2.0 }, { Percentile.EstimationType.R_9, 2.0 } }, 50d, 0d);
439
440 specialValues =
441 new double[] { 1d, 1d, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY };
442 assertTrue(Double.isInfinite(percentile.evaluate(specialValues)));
443
444 testAssertMappedValues(specialValues, new Object[][] {
445
446 { Percentile.EstimationType.LEGACY, Double.POSITIVE_INFINITY },
447 { Percentile.EstimationType.R_1,Double.NaN },
448 { Percentile.EstimationType.R_2, Double.NaN },
449 { Percentile.EstimationType.R_3, Double.NaN }, { Percentile.EstimationType.R_4, Double.NaN },
450 { Percentile.EstimationType.R_5, Double.POSITIVE_INFINITY },
451 { Percentile.EstimationType.R_6, Double.POSITIVE_INFINITY },
452 { Percentile.EstimationType.R_7, Double.POSITIVE_INFINITY },
453 { Percentile.EstimationType.R_8, Double.POSITIVE_INFINITY },
454 { Percentile.EstimationType.R_9, Double.POSITIVE_INFINITY }, }, 50d, 0d);
455
456 specialValues = new double[] { 1d, 1d, Double.NaN, Double.NaN };
457 assertTrue(Double.isNaN(percentile.evaluate(specialValues)));
458 testAssertMappedValues(specialValues, new Object[][] {
459 { Percentile.EstimationType.LEGACY, Double.NaN }, { Percentile.EstimationType.R_1, 1.0 }, { Percentile.EstimationType.R_2, 1.0 }, { Percentile.EstimationType.R_3, 1.0 },
460 { Percentile.EstimationType.R_4, 1.0 }, { Percentile.EstimationType.R_5, 1.0 },{ Percentile.EstimationType.R_6, 1.0 },{ Percentile.EstimationType.R_7, 1.0 },
461 { Percentile.EstimationType.R_8, 1.0 }, { Percentile.EstimationType.R_9, 1.0 },}, 50d, 0d);
462
463 specialValues =
464 new double[] { 1d, 1d, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY };
465
466 testAssertMappedValues(specialValues, new Object[][] {
467 { Percentile.EstimationType.LEGACY, Double.NaN }, { Percentile.EstimationType.R_1, Double.NaN },
468 { Percentile.EstimationType.R_2, Double.NaN }, { Percentile.EstimationType.R_3, Double.NaN }, { Percentile.EstimationType.R_4, Double.NaN },
469 { Percentile.EstimationType.R_5, Double.NaN }, { Percentile.EstimationType.R_6, Double.NaN },
470 { Percentile.EstimationType.R_7, Double.NaN }, { Percentile.EstimationType.R_8, Double.NaN }, { Percentile.EstimationType.R_9, Double.NaN }
471 }, 50d, 0d);
472 }
473
474 @Test
475 public void testAllTechniquesSetQuantile() {
476 for (final Percentile.EstimationType e : Percentile.EstimationType.values()) {
477 reset(10, e);
478 final Percentile percentile = getUnivariateStatistic();
479 percentile.setQuantile(100);
480 assertEquals(100, percentile.getQuantile(), 0);
481 try {
482 percentile.setQuantile(0);
483 fail("Expecting MathIllegalArgumentException");
484 } catch (final MathIllegalArgumentException ex) {
485
486 }
487 try {
488 new Percentile(0);
489 fail("Expecting MathIllegalArgumentException");
490 } catch (final MathIllegalArgumentException ex) {
491
492 }
493 }
494 }
495
496 @Test
497 public void testAllTechniquesEvaluateArraySegmentWeighted() {
498 for (final Percentile.EstimationType e : Percentile.EstimationType.values()) {
499 reset(quantile, e);
500 testEvaluateArraySegmentWeighted();
501 }
502 }
503
504 @Test
505 public void testAllTechniquesEvaluateArraySegment() {
506 for (final Percentile.EstimationType e : Percentile.EstimationType.values()) {
507 reset(quantile, e);
508 testEvaluateArraySegment();
509 }
510 }
511
512 @Test
513 public void testAllTechniquesWeightedConsistency() {
514 for (final Percentile.EstimationType e : Percentile.EstimationType.values()) {
515 reset(quantile, e);
516 testWeightedConsistency();
517 }
518 }
519
520 @Test
521 public void testAllTechniquesEvaluation() {
522
523 testAssertMappedValues(testArray, new Object[][] { { Percentile.EstimationType.LEGACY, 20.820 },
524 { Percentile.EstimationType.R_1, 19.800 }, { Percentile.EstimationType.R_2, 19.800 }, { Percentile.EstimationType.R_3, 19.800 },
525 { Percentile.EstimationType.R_4, 19.310 }, { Percentile.EstimationType.R_5, 20.280 }, { Percentile.EstimationType.R_6, 20.820 },
526 { Percentile.EstimationType.R_7, 19.555 }, { Percentile.EstimationType.R_8, 20.460 },{ Percentile.EstimationType.R_9, 20.415} },
527 DEFAULT_PERCENTILE, tolerance);
528 }
529
530 @Test
531 public void testPercentileWithTechnique() {
532 reset (50, Percentile.EstimationType.LEGACY);;
533 final Percentile p = getUnivariateStatistic();
534 assertTrue(Percentile.EstimationType.LEGACY.equals(p.getEstimationType()));
535 assertFalse(Percentile.EstimationType.R_1.equals(p.getEstimationType()));
536 }
537
538 static final int TINY = 10, SMALL = 50, NOMINAL = 100, MEDIUM = 500,
539 STANDARD = 1000, BIG = 10000, VERY_BIG = 50000, LARGE = 1000000,
540 VERY_LARGE = 10000000;
541 static final int[] sampleSizes= { TINY, SMALL, NOMINAL, MEDIUM, STANDARD, BIG };
542
543 @Test
544 public void testStoredVsDirect() {
545 final RandomDataGenerator randomDataGenerator = new RandomDataGenerator(100);
546 final NormalDistribution normalDistribution = new NormalDistribution(4000, 50);
547 for (final int sampleSize:sampleSizes) {
548 final double[] data = randomDataGenerator.nextDeviates(normalDistribution, sampleSize);
549 for (final double p:new double[] {50d,95d}) {
550 for (final Percentile.EstimationType e : Percentile.EstimationType.values()) {
551 reset(p, e);
552 final Percentile pStoredData = getUnivariateStatistic();
553 pStoredData.setData(data);
554 final double storedDataResult=pStoredData.evaluate();
555 pStoredData.setData(null);
556 final Percentile pDirect = getUnivariateStatistic();
557 assertEquals("Sample="+sampleSize+",P="+p+" e="+e,
558 storedDataResult,
559 pDirect.evaluate(data), 0d);
560 }
561 }
562 }
563 }
564
565 @Test
566 public void testPercentileWithDataRef() {
567 reset(50.0, Percentile.EstimationType.R_7);
568 final Percentile p = getUnivariateStatistic();
569 p.setData(testArray);
570 assertTrue(Percentile.EstimationType.R_7.equals(p.getEstimationType()));
571 assertFalse(Percentile.EstimationType.R_1.equals(p.getEstimationType()));
572 assertEquals(12d, p.evaluate(), 0d);
573 assertEquals(12.16d, p.evaluate(60d), 0d);
574 }
575
576 @Test(expected=NullArgumentException.class)
577 public void testNullEstimation() {
578 type = null;
579 getUnivariateStatistic();
580 }
581
582 @Test
583 public void testAllEstimationTechniquesOnlyLimits() {
584 final int N=testArray.length;
585
586 final double[] input = testArray.clone();
587 Arrays.sort(input);
588 final double min = input[0];
589 final double max=input[input.length-1];
590
591 final Object[][] map =
592 new Object[][] { { Percentile.EstimationType.LEGACY, 0d, 1d }, { Percentile.EstimationType.R_1, 0d, 1d },
593 { Percentile.EstimationType.R_2, 0d,1d }, { Percentile.EstimationType.R_3, 0.5/N,1d },
594 { Percentile.EstimationType.R_4, 1d/N-0.001,1d },
595 { Percentile.EstimationType.R_5, 0.5/N-0.001,(N-0.5)/N}, { Percentile.EstimationType.R_6, 0.99d/(N+1),
596 1.01d*N/(N+1)},
597 { Percentile.EstimationType.R_7, 0d,1d}, { Percentile.EstimationType.R_8, 1.99d/3/(N+1d/3),
598 (N-1d/3)/(N+1d/3)},
599 { Percentile.EstimationType.R_9, 4.99d/8/(N+0.25), (N-3d/8)/(N+0.25)} };
600
601 for(final Object[] arr:map) {
602 final Percentile.EstimationType t= (Percentile.EstimationType) arr[0];
603 double pMin=(Double)arr[1];
604 final double pMax=(Double)arr[2];
605 assertEquals("Type:"+t,0d, t.index(pMin, N),0d);
606 assertEquals("Type:"+t,N, t.index(pMax, N),0.5d);
607 pMin=pMin==0d?pMin+0.01:pMin;
608 testAssertMappedValues(testArray, new Object[][] { { t, min }}, pMin, 0.01);
609 testAssertMappedValues(testArray, new Object[][] { { t, max }}, pMax * 100, tolerance);
610 }
611 }
612
613 @Test
614 public void testAllEstimationTechniquesOnly() {
615 assertEquals("Legacy Hipparchus",Percentile.EstimationType.LEGACY.getName());
616 final Object[][] map =
617 new Object[][] { { Percentile.EstimationType.LEGACY, 20.82 }, { Percentile.EstimationType.R_1, 19.8 },
618 { Percentile.EstimationType.R_2, 19.8 }, { Percentile.EstimationType.R_3, 19.8 }, { Percentile.EstimationType.R_4, 19.310 },
619 { Percentile.EstimationType.R_5, 20.280}, { Percentile.EstimationType.R_6, 20.820},
620 { Percentile.EstimationType.R_7, 19.555 }, { Percentile.EstimationType.R_8, 20.460 },{Percentile.EstimationType.R_9,20.415} };
621 try {
622 Percentile.EstimationType.LEGACY.evaluate(testArray, -1d, new KthSelector(PivotingStrategy.MEDIAN_OF_3));
623 } catch (final MathIllegalArgumentException oore) {
624 }
625 try {
626 Percentile.EstimationType.LEGACY.evaluate(testArray, 101d, new KthSelector());
627 } catch (final MathIllegalArgumentException oore) {
628 }
629 try {
630 Percentile.EstimationType.LEGACY.evaluate(testArray, 50d, new KthSelector());
631 } catch(final MathIllegalArgumentException oore) {
632 }
633 for (final Object[] o : map) {
634 final Percentile.EstimationType e = (Percentile.EstimationType) o[0];
635 final double expected = (Double) o[1];
636 final double result = e.evaluate(testArray, DEFAULT_PERCENTILE, new KthSelector());
637 assertEquals("expected[" + e + "] = " + expected +
638 " but was = " + result, expected, result, tolerance);
639 }
640 }
641
642 @Test
643 public void testAllEstimationTechniquesOnlyForAllPivotingStrategies() {
644
645 assertEquals("Legacy Hipparchus",Percentile.EstimationType.LEGACY.getName());
646
647 for (final PivotingStrategy strategy : PivotingStrategy.values()) {
648 kthSelector = new KthSelector(strategy);
649 testAllEstimationTechniquesOnly();
650 }
651 }
652
653 @Test
654 public void testAllEstimationTechniquesOnlyForExtremeIndexes() {
655 final double MAX=100;
656 final Object[][] map =
657 new Object[][] { { Percentile.EstimationType.LEGACY, 0d, MAX}, { Percentile.EstimationType.R_1, 0d,MAX+0.5 },
658 { Percentile.EstimationType.R_2, 0d,MAX}, { Percentile.EstimationType.R_3, 0d,MAX }, { Percentile.EstimationType.R_4, 0d,MAX },
659 { Percentile.EstimationType.R_5, 0d,MAX }, { Percentile.EstimationType.R_6, 0d,MAX },
660 { Percentile.EstimationType.R_7, 0d,MAX }, { Percentile.EstimationType.R_8, 0d,MAX }, { Percentile.EstimationType.R_9, 0d,MAX } };
661 for (final Object[] o : map) {
662 final Percentile.EstimationType e = (Percentile.EstimationType) o[0];
663 assertEquals(((Double)o[1]).doubleValue(), e.index(0d, (int)MAX),0d);
664 assertEquals("Enum:"+e,((Double)o[2]).doubleValue(), e.index(1.0, (int)MAX),0d);
665 }
666 }
667
668 @Test
669 public void testAllEstimationTechniquesOnlyForNullsAndOOR() {
670
671 final Object[][] map =
672 new Object[][] { { Percentile.EstimationType.LEGACY, 20.82 }, { Percentile.EstimationType.R_1, 19.8 },
673 { Percentile.EstimationType.R_2, 19.8 }, { Percentile.EstimationType.R_3, 19.8 }, { Percentile.EstimationType.R_4, 19.310 },
674 { Percentile.EstimationType.R_5, 20.280}, { Percentile.EstimationType.R_6, 20.820},
675 { Percentile.EstimationType.R_7, 19.555 }, { Percentile.EstimationType.R_8, 20.460 },{ Percentile.EstimationType.R_9, 20.415 } };
676 for (final Object[] o : map) {
677 final Percentile.EstimationType e = (Percentile.EstimationType) o[0];
678 try {
679 e.evaluate(null, DEFAULT_PERCENTILE, new KthSelector());
680 fail("Expecting NullArgumentException");
681 } catch (final NullArgumentException nae) {
682
683 }
684 try {
685 e.evaluate(testArray, 120, new KthSelector());
686 fail("Expecting MathIllegalArgumentException");
687 } catch (final MathIllegalArgumentException oore) {
688
689 }
690 }
691 }
692
693
694
695
696
697
698
699
700
701
702 protected void testAssertMappedValues(final double[] data, final Object[][] map,
703 final Double p, final Double tolerance) {
704 for (final Object[] o : map) {
705 final Percentile.EstimationType e = (Percentile.EstimationType) o[0];
706 final double expected = (Double) o[1];
707 try {
708 reset(p, e);
709 final double result = getUnivariateStatistic().evaluate(data);
710 assertEquals("expected[" + e + "] = " + expected +
711 " but was = " + result, expected, result, tolerance);
712 } catch(final Exception ex) {
713 fail("Exception occured for estimation type "+e+":"+
714 ex.getLocalizedMessage());
715 }
716 }
717 }
718
719
720 @Test
721 public void testNanStrategySpecific() {
722 double[] specialValues = new double[] { 0d, 1d, 2d, 3d, 4d, Double.NaN };
723 assertTrue(Double.isNaN(new Percentile(50d).withEstimationType(Percentile.EstimationType.LEGACY).withNaNStrategy(NaNStrategy.MAXIMAL).evaluate(specialValues, 3, 3)));
724 assertEquals(2d,new Percentile(50d).withEstimationType(Percentile.EstimationType.R_1).withNaNStrategy(NaNStrategy.REMOVED).evaluate(specialValues),0d);
725 assertEquals(Double.NaN,new Percentile(50d).withEstimationType(Percentile.EstimationType.R_5).withNaNStrategy(NaNStrategy.REMOVED).evaluate(new double[] {Double.NaN,Double.NaN,Double.NaN}),0d);
726 assertEquals(50d,new Percentile(50d).withEstimationType(Percentile.EstimationType.R_7).withNaNStrategy(NaNStrategy.MINIMAL).evaluate(new double[] {50d,50d,50d},1,2),0d);
727
728 specialValues = new double[] { 0d, 1d, 2d, 3d, 4d, Double.NaN, Double.NaN };
729 assertEquals(3.5,new Percentile().evaluate(specialValues, 3, 4),0d);
730 assertEquals(4d,new Percentile().evaluate(specialValues, 4, 3),0d);
731 assertTrue(Double.isNaN(new Percentile().evaluate(specialValues, 5, 2)));
732
733 specialValues = new double[] { 0d, 1d, 2d, 3d, 4d, Double.NaN, Double.NaN, 5d, 6d };
734 assertEquals(4.5,new Percentile().evaluate(specialValues, 3, 6),0d);
735 assertEquals(5d,new Percentile().evaluate(specialValues, 4, 5),0d);
736 assertTrue(Double.isNaN(new Percentile().evaluate(specialValues, 5, 2)));
737 assertTrue(Double.isNaN(new Percentile().evaluate(specialValues, 5, 1)));
738 assertEquals(5.5,new Percentile().evaluate(specialValues, 5, 4),0d);
739 }
740
741
742 @Test(expected=MathIllegalArgumentException.class)
743 public void testNanStrategyFailed() {
744 double[] specialValues =
745 new double[] { 0d, 1d, 2d, 3d, 4d, Double.NaN };
746 new Percentile(50d).
747 withEstimationType(Percentile.EstimationType.R_9).
748 withNaNStrategy(NaNStrategy.FAILED).
749 evaluate(specialValues);
750 }
751
752 @Test
753 public void testAllTechniquesSpecialValuesWithNaNStrategy() {
754 double[] specialValues =
755 new double[] { 0d, 1d, 2d, 3d, 4d, Double.NaN };
756 try {
757 new Percentile(50d).withEstimationType(Percentile.EstimationType.LEGACY).withNaNStrategy(null);
758 fail("Expecting NullArgumentArgumentException "
759 + "for null Nan Strategy");
760 } catch (NullArgumentException ex) {
761
762 }
763
764 testAssertMappedValues(specialValues, new Object[][] {
765 { Percentile.EstimationType.LEGACY, 2.5d }, { Percentile.EstimationType.R_1, 2.0 }, { Percentile.EstimationType.R_2, 2.0 }, { Percentile.EstimationType.R_3, 1.0 },
766 { Percentile.EstimationType.R_4, 1.5 }, { Percentile.EstimationType.R_5, 2.0 }, { Percentile.EstimationType.R_6, 2.0 },
767 { Percentile.EstimationType.R_7, 2.0 }, { Percentile.EstimationType.R_8, 2.0 }, { Percentile.EstimationType.R_9, 2.0 }}, 50d, 0d);
768
769
770 testAssertMappedValues(specialValues, new Object[][] {
771 { Percentile.EstimationType.LEGACY, 2.5d }, { Percentile.EstimationType.R_1, 2.0 }, { Percentile.EstimationType.R_2, 2.5 }, { Percentile.EstimationType.R_3, 2.0 },
772 { Percentile.EstimationType.R_4, 2.0 }, { Percentile.EstimationType.R_5, 2.5 }, { Percentile.EstimationType.R_6, 2.5 },
773 { Percentile.EstimationType.R_7, 2.5 }, { Percentile.EstimationType.R_8, 2.5 }, { Percentile.EstimationType.R_9, 2.5 }}, 50d, 0d,
774 NaNStrategy.MAXIMAL);
775
776
777 testAssertMappedValues(specialValues, new Object[][] {
778 { Percentile.EstimationType.LEGACY, 1.5d }, { Percentile.EstimationType.R_1, 1.0 }, { Percentile.EstimationType.R_2, 1.5 }, { Percentile.EstimationType.R_3, 1.0 },
779 { Percentile.EstimationType.R_4, 1.0 }, { Percentile.EstimationType.R_5, 1.5 }, { Percentile.EstimationType.R_6, 1.5 },
780 { Percentile.EstimationType.R_7, 1.5 }, { Percentile.EstimationType.R_8, 1.5 }, { Percentile.EstimationType.R_9, 1.5 }}, 50d, 0d,
781 NaNStrategy.MINIMAL);
782
783
784
785 testAssertMappedValues(specialValues, new Object[][] {
786 { Percentile.EstimationType.LEGACY, 2.0 }, { Percentile.EstimationType.R_1, 2.0 }, { Percentile.EstimationType.R_2, 2.0 }, { Percentile.EstimationType.R_3, 1.0 },
787 { Percentile.EstimationType.R_4, 1.5 }, { Percentile.EstimationType.R_5, 2.0 }, { Percentile.EstimationType.R_6, 2.0 },
788 { Percentile.EstimationType.R_7, 2.0 }, { Percentile.EstimationType.R_8, 2.0 }, { Percentile.EstimationType.R_9, 2.0 }}, 50d, 0d,
789 NaNStrategy.REMOVED);
790 }
791
792
793
794
795
796
797
798
799
800
801 protected void testAssertMappedValues(double[] data, Object[][] map,
802 Double p, Double tolerance, NaNStrategy nanStrategy) {
803 for (Object[] o : map) {
804 Percentile.EstimationType e = (Percentile.EstimationType) o[0];
805 double expected = (Double) o[1];
806 try {
807 double result = new Percentile(p).withEstimationType(e).withNaNStrategy(nanStrategy).evaluate(data);
808 assertEquals("expected[" + e + "] = " + expected + " but was = " + result,
809 expected, result, tolerance);
810 } catch(Exception ex) {
811 fail("Exception occured for estimation type " + e + ":" + ex.getLocalizedMessage());
812 }
813 }
814 }
815
816 }