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    *      https://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  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
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.assertNotNull;
27  import static org.junit.Assert.assertTrue;
28  
29  import java.io.IOException;
30  import java.util.ArrayList;
31  import java.util.Arrays;
32  import java.util.HashSet;
33  import java.util.Iterator;
34  import java.util.LinkedHashSet;
35  import java.util.Set;
36  
37  import org.hipparchus.distribution.RealDistribution;
38  import org.hipparchus.distribution.continuous.LogNormalDistribution;
39  import org.hipparchus.distribution.continuous.NormalDistribution;
40  import org.hipparchus.exception.MathIllegalArgumentException;
41  import org.hipparchus.exception.NullArgumentException;
42  import org.hipparchus.random.RandomDataGenerator;
43  import org.hipparchus.random.RandomGenerator;
44  import org.hipparchus.random.Well19937c;
45  import org.hipparchus.stat.descriptive.StorelessUnivariateStatistic;
46  import org.hipparchus.stat.descriptive.StorelessUnivariateStatisticAbstractTest;
47  import org.hipparchus.stat.descriptive.rank.PSquarePercentile.PSquareMarkers;
48  import org.hipparchus.util.FastMath;
49  import org.junit.Test;
50  
51  /**
52   * Test cases for the {@link PSquarePercentile} class which naturally extends
53   * {@link StorelessUnivariateStatisticAbstractTest}.
54   */
55  public class PSquarePercentileTest extends
56          StorelessUnivariateStatisticAbstractTest {
57  
58      protected double percentile5 = 8.2299d;
59      protected double percentile95 = 16.72195;// 20.82d; this is approximation
60      protected double tolerance = 10E-12;
61  
62      private final RandomGenerator randomGenerator = new Well19937c(1000);
63  
64      @Override
65      public PSquarePercentile getUnivariateStatistic() {
66          return new PSquarePercentile(95);
67      }
68  
69      @Override
70      public double expectedValue() {
71          return this.percentile95;
72      }
73  
74      @Override
75      public double getTolerance() {
76          // tolerance limit changed as this is an approximation
77          // algorithm and also gets accurate after few tens of samples
78          return 1.0e-2;
79      }
80  
81      /**
82       * Verifies that copied statistics remain equal to originals when
83       * incremented the same way by making the copy after a majority of elements
84       * are incremented
85       */
86      @Test
87      public void testCopyConsistencyWithInitialMostElements() {
88  
89          StorelessUnivariateStatistic master = getUnivariateStatistic();
90          StorelessUnivariateStatistic replica = null;
91  
92          // select a portion of testArray till 75 % of the length to load first
93          long index = FastMath.round(0.75 * testArray.length);
94  
95          // Put first half in master and copy master to replica
96          master.incrementAll(testArray, 0, (int) index);
97          replica = master.copy();
98  
99          // Check same
100         assertTrue(replica.equals(master));
101         assertTrue(master.equals(replica));
102 
103         // Now add second part to both and check again
104         master.incrementAll(testArray, (int) index, (int) (testArray.length - index));
105         replica.incrementAll(testArray, (int) index, (int) (testArray.length - index));
106         assertTrue(replica.equals(master));
107         assertTrue(master.equals(replica));
108     }
109 
110     /**
111      * Verifies that copied statistics remain equal to originals when
112      * incremented the same way by way of copying original after just a few
113      * elements are incremented
114      */
115     @Test
116     public void testCopyConsistencyWithInitialFirstFewElements() {
117 
118         StorelessUnivariateStatistic master = getUnivariateStatistic();
119         StorelessUnivariateStatistic replica = null;
120 
121         // select a portion of testArray which is 10% of the length to load
122         // first
123         long index = FastMath.round(0.1 * testArray.length);
124 
125         // Put first half in master and copy master to replica
126         master.incrementAll(testArray, 0, (int) index);
127         replica = master.copy();
128 
129         // Check same
130         assertTrue(replica.equals(master));
131         assertTrue(master.equals(replica));
132         // Now add second part to both and check again
133         master.incrementAll(testArray, (int) index, (int) (testArray.length - index));
134         replica.incrementAll(testArray, (int) index, (int) (testArray.length - index));
135         assertTrue(master.equals(master));
136         assertTrue(replica.equals(replica));
137         assertTrue(replica.equals(master));
138         assertTrue(master.equals(replica));
139     }
140 
141     @Test(expected = MathIllegalArgumentException.class)
142     public void testNullListInMarkers() {
143         // In case of null list Markers cannot be instantiated..is getting verified
144         // new Markers(null, 0, PSquarePercentile.newEstimator());
145         PSquarePercentile.newMarkers(null, 0);
146     }
147 
148     @SuppressWarnings("unlikely-arg-type")
149     @Test
150     public void testMiscellaniousFunctionsInMarkers() {
151         double p = 0.5;
152         PSquareMarkers markers =
153                 PSquarePercentile.newMarkers(
154                         Arrays.asList(new Double[] { 0.02, 1.18, 9.15, 21.91, 38.62 }), p);
155         // Markers equality
156         assertTrue(markers.equals(markers));
157         assertFalse(markers.equals(null));
158         assertFalse(markers.equals(new String()));
159         // Check for null markers test during equality testing
160         // Until 5 elements markers are not initialized
161         PSquarePercentile p1 = new PSquarePercentile();
162         PSquarePercentile p2 = new PSquarePercentile();
163         assertEquals(p1, p2);
164         p1.evaluate(new double[] { 1.0, 2.0, 3.0 });
165         p2.evaluate(new double[] { 1.0, 2.0, 3.0 });
166         assertEquals(p1, p2);
167         // Move p2 alone with more values just to make sure markers are not null
168         // for p2
169         p2.incrementAll(new double[] { 5.0, 7.0, 11.0 });
170         assertFalse(p1.equals(p2));
171         assertFalse(p2.equals(p1));
172         // Next add different data to p1 to make number of elements match and
173         // markers are not null however actual results will vary
174         p1.incrementAll(new double[] { 20, 21, 22, 23 });
175         assertFalse(p1.equals(p2));// though markers are non null, N matches, results wont
176     }
177 
178     @Test(expected = MathIllegalArgumentException.class)
179     public void testMarkersOORLow() {
180         PSquarePercentile.newMarkers(
181                 Arrays.asList(new Double[] { 0.02, 1.18, 9.15, 21.91, 38.62 }), 0.5).estimate(0);
182     }
183 
184     @Test(expected = MathIllegalArgumentException.class)
185     public void testMarkersOORHigh() {
186         PSquarePercentile.newMarkers(
187                 Arrays.asList(new Double[] { 0.02, 1.18, 9.15, 21.91, 38.62 }), 0.5).estimate(5);
188     }
189 
190     @Test
191     public void testMarkers2() {
192         double p = 0.5;
193         PSquareMarkers markers =
194                 PSquarePercentile.newMarkers(
195                         Arrays.asList(new Double[] { 0.02, 1.18, 9.15, 21.91, 38.62 }), p);
196 
197         PSquareMarkers markersNew =
198                 PSquarePercentile.newMarkers(
199                         Arrays.asList(new Double[] { 0.02, 1.18, 9.15, 21.91, 38.62 }), p);
200 
201         assertTrue(markers.equals(markersNew));
202         // If just one element of markers got changed then its still false.
203         markersNew.processDataPoint(39);
204         assertFalse(markers.equals(markersNew));
205     }
206 
207     @SuppressWarnings("unlikely-arg-type")
208     @Test
209     public void testHashCodeInMarkers() {
210         PSquarePercentile p = new PSquarePercentile(95);
211         PSquarePercentile p2 = new PSquarePercentile(95);
212         Set<PSquarePercentile> s = new HashSet<>();
213         s.add(p);
214         s.add(p2);
215         assertEquals(1, s.size());
216         assertEquals(p, s.iterator().next());
217         double[] d =
218                 new double[] { 95.1772, 95.1567, 95.1937, 95.1959, 95.1442, 95.0610,
219                                95.1591, 95.1195, 95.1772, 95.0925, 95.1990, 95.1682 };
220         assertEquals(95.1981, p.evaluate(d), 1.0e-2); // change
221         assertEquals(95.1981, p2.evaluate(d), 1.0e-2); // change
222         s.clear();
223         s.add(p);
224         s.add(p2);
225         assertEquals(1, s.size());
226         assertEquals(p, s.iterator().next());
227 
228         PSquareMarkers m1 =
229                 PSquarePercentile.newMarkers(
230                         Arrays.asList(new Double[] { 95.1772, 95.1567, 95.1937,
231                                 95.1959, 95.1442, 95.0610, 95.1591, 95.1195,
232                                 95.1772, 95.0925, 95.1990, 95.1682 }), 0.0);
233         PSquareMarkers m2 =
234                 PSquarePercentile.newMarkers(
235                         Arrays.asList(new Double[] { 95.1772, 95.1567, 95.1937,
236                                 95.1959, 95.1442, 95.0610, 95.1591, 95.1195,
237                                 95.1772, 95.0925, 95.1990, 95.1682 }), 0.0);
238         assertTrue(m1.equals(m2));
239         Set<PSquareMarkers> setMarkers = new LinkedHashSet<PSquareMarkers>();
240         assertTrue(setMarkers.add(m1));
241         assertFalse(setMarkers.add(m2));
242         assertEquals(1, setMarkers.size());
243 
244         PSquareMarkers mThis =
245                 PSquarePercentile.newMarkers(
246                         Arrays.asList(new Double[] { 195.1772, 195.1567,
247                                 195.1937, 195.1959, 95.1442, 195.0610,
248                                 195.1591, 195.1195, 195.1772, 95.0925, 95.1990,
249                                 195.1682 }), 0.50);
250         PSquareMarkers mThat =
251                 PSquarePercentile.newMarkers(
252                         Arrays.asList(new Double[] { 95.1772, 95.1567, 95.1937,
253                                 95.1959, 95.1442, 95.0610, 95.1591, 95.1195,
254                                 95.1772, 95.0925, 95.1990, 95.1682 }), 0.50);
255         assertTrue(mThis.equals(mThis));
256         assertFalse(mThis.equals(mThat));
257         String s1="";
258         assertFalse(mThis.equals(s1));
259         for (int i = 0; i < testArray.length; i++) {
260             mThat.processDataPoint(testArray[i]);
261         }
262         setMarkers.add(mThat);
263         setMarkers.add(mThis);
264         assertTrue(mThat.equals(mThat));
265         assertTrue(setMarkers.contains(mThat));
266         assertTrue(setMarkers.contains(mThis));
267         assertEquals(3, setMarkers.size());
268         Iterator<PSquareMarkers> iterator=setMarkers.iterator();
269         assertEquals(m1, iterator.next());
270         assertEquals(mThat, iterator.next());
271         assertEquals(mThis, iterator.next());
272     }
273 
274     @Test(expected = MathIllegalArgumentException.class)
275     public void testMarkersWithLowerIndex() {
276         PSquareMarkers mThat =
277                 PSquarePercentile.newMarkers(
278                         Arrays.asList(new Double[] { 95.1772, 95.1567, 95.1937,
279                                 95.1959, 95.1442, 95.0610, 95.1591, 95.1195,
280                                 95.1772, 95.0925, 95.1990, 95.1682 }), 0.50);
281         for (int i = 0; i < testArray.length; i++) {
282             mThat.processDataPoint(testArray[i]);
283         }
284         mThat.estimate(0);
285     }
286 
287     @Test(expected = MathIllegalArgumentException.class)
288     public void testMarkersWithHigherIndex() {
289         PSquareMarkers mThat =
290                 PSquarePercentile.newMarkers(
291                         Arrays.asList(new Double[] { 95.1772, 95.1567, 95.1937,
292                                 95.1959, 95.1442, 95.0610, 95.1591, 95.1195,
293                                 95.1772, 95.0925, 95.1990, 95.1682 }), 0.50);
294         for (int i = 0; i < testArray.length; i++) {
295             mThat.processDataPoint(testArray[i]);
296         }
297         mThat.estimate(6);
298     }
299 
300     @Test(expected = MathIllegalArgumentException.class)
301     public void testMarkerHeightWithLowerIndex() {
302         PSquareMarkers mThat =
303                 PSquarePercentile.newMarkers(
304                         Arrays.asList(new Double[] { 95.1772, 95.1567, 95.1937,
305                                 95.1959, 95.1442, 95.0610, 95.1591, 95.1195,
306                                 95.1772, 95.0925, 95.1990, 95.1682 }), 0.50);
307         mThat.height(0);
308     }
309 
310     @Test(expected = MathIllegalArgumentException.class)
311     public void testMarkerHeightWithHigherIndex() {
312         PSquareMarkers mThat =
313                 PSquarePercentile.newMarkers(
314                         Arrays.asList(new Double[] { 95.1772, 95.1567, 95.1937,
315                                 95.1959, 95.1442, 95.0610, 95.1591, 95.1195,
316                                 95.1772, 95.0925, 95.1990, 95.1682 }), 0.50);
317         mThat.height(6);
318     }
319 
320     @SuppressWarnings("unlikely-arg-type")
321     @Test
322     public void testPSquaredEqualsAndMin() {
323         PSquarePercentile ptile = new PSquarePercentile(0);
324         assertEquals(ptile, ptile);
325         assertFalse(ptile.equals(null));
326         assertFalse(ptile.equals(new String()));
327         // Just to check if there is no data get result for zeroth and 100th
328         // ptile returns NAN
329         assertTrue(Double.isNaN(ptile.getResult()));
330         assertTrue(Double.isNaN(new PSquarePercentile(100).getResult()));
331 
332         double[] d = new double[] { 1, 3, 2, 4, 9, 10, 11 };
333         ptile.incrementAll(d);
334         assertEquals(ptile, ptile);
335         assertEquals(1d, ptile.getResult(), 1e-02);// this calls min
336         assertEquals(0.0, ptile.getQuantile(), 1.0e-15);
337     }
338 
339     @Test
340     public void testString() {
341         PSquarePercentile ptile = new PSquarePercentile(95);
342         assertNotNull(ptile.toString());
343         ptile.increment(1);
344         ptile.increment(2);
345         ptile.increment(3);
346         assertNotNull(ptile.toString());
347         assertEquals(expectedValue(), ptile.evaluate(testArray), getTolerance());
348         assertNotNull(ptile.toString());
349         assertEquals(0.95, ptile.getQuantile(), 1.0e-15);
350     }
351 
352     @Test
353     public void testHighPercentile() {
354         double[] d = new double[] { 1, 2, 3 };
355         PSquarePercentile p = new PSquarePercentile(75.0);
356         assertEquals(2, p.evaluate(d), 1.0e-5);
357         PSquarePercentile p95 = new PSquarePercentile();
358         assertEquals(2, p95.evaluate(d), 1.0e-5);
359     }
360 
361     @Test
362     public void testLowPercentile() {
363         double[] d = new double[] { 0, 1 };
364         PSquarePercentile p = new PSquarePercentile(25.0);
365         assertEquals(0d, p.evaluate(d), Double.MIN_VALUE);
366     }
367 
368     @Test
369     public void testPercentile() {
370         double[] d = new double[] { 1, 3, 2, 4 };
371         PSquarePercentile p = new PSquarePercentile(30d);
372         assertEquals(1.0, p.evaluate(d), 1.0e-5);
373         p = new PSquarePercentile(25);
374         assertEquals(1.0, p.evaluate(d), 1.0e-5);
375         p = new PSquarePercentile(75);
376         assertEquals(3.0, p.evaluate(d), 1.0e-5);
377         p = new PSquarePercentile(50);
378         assertEquals(2d, p.evaluate(d), 1.0e-5);
379     }
380 
381     @Test(expected = MathIllegalArgumentException.class)
382     public void testInitial() {
383         PSquarePercentile.newMarkers(new ArrayList<Double>(), 0.5);
384     }
385 
386     @Test(expected = MathIllegalArgumentException.class)
387     public void testNegativeInvalidValues() {
388         double[] d =
389                 new double[] { 95.1772, 95.1567, 95.1937, 95.1959, 95.1442,
390                         95.0610, 95.1591, 95.1195, 95.1772, 95.0925, 95.1990,
391                         95.1682 };
392         PSquarePercentile p = new PSquarePercentile(-1.0);
393         p.evaluate(d, 0, d.length);
394     }
395 
396     @Test(expected = MathIllegalArgumentException.class)
397     public void testPositiveInvalidValues() {
398         double[] d =
399                 new double[] { 95.1772, 95.1567, 95.1937, 95.1959, 95.1442,
400                         95.0610, 95.1591, 95.1195, 95.1772, 95.0925, 95.1990,
401                         95.1682 };
402         PSquarePercentile p = new PSquarePercentile(101.0);
403         p.evaluate(d, 0, d.length);
404     }
405 
406     @Test
407     public void testNISTExample() {
408         double[] d =
409                 new double[] { 95.1772, 95.1567, 95.1937, 95.1959, 95.1442,
410                         95.0610, 95.1591, 95.1195, 95.1772, 95.0925, 95.1990,
411                         95.1682 };
412         assertEquals(95.1981, new PSquarePercentile(90d).evaluate(d), 1.0e-2); // changed the accuracy to 1.0e-2
413         assertEquals(95.061, new PSquarePercentile(0d).evaluate(d), 0);
414         assertEquals(95.1990, new PSquarePercentile(100d).evaluate(d, 0, d.length), 0);
415     }
416 
417     @Test
418     public void test5() {
419         PSquarePercentile percentile = new PSquarePercentile(5d);
420         assertEquals(this.percentile5, percentile.evaluate(testArray), 1.0); // changed the accuracy to 1 instead of tolerance
421     }
422 
423     @Test(expected = NullArgumentException.class)
424     public void testNull() {
425         PSquarePercentile percentile = new PSquarePercentile(50d);
426         double[] nullArray = null;
427         percentile.evaluate(nullArray);
428     }
429 
430     @Test
431     public void testEmpty() {
432         PSquarePercentile percentile = new PSquarePercentile(50d);
433         double[] emptyArray = new double[] {};
434         assertTrue(Double.isNaN(percentile.evaluate(emptyArray)));
435     }
436 
437     @Test
438     public void testSingleton() {
439         PSquarePercentile percentile = new PSquarePercentile(50d);
440         double[] singletonArray = new double[] { 1d };
441         assertEquals(1d, percentile.evaluate(singletonArray), 0);
442         assertEquals(1d, percentile.evaluate(singletonArray, 0, 1), 0);
443         percentile = new PSquarePercentile(5);
444         assertEquals(1d, percentile.evaluate(singletonArray, 0, 1), 0);
445         percentile = new PSquarePercentile(100);
446         assertEquals(1d, percentile.evaluate(singletonArray, 0, 1), 0);
447         percentile = new PSquarePercentile(100);
448         assertTrue(Double.isNaN(percentile.evaluate(singletonArray, 0, 0)));
449     }
450 
451     @Test
452     public void testSpecialValues() {
453         PSquarePercentile percentile = new PSquarePercentile(50d);
454         double[] specialValues = new double[] { 0d, 1d, 2d, 3d, 4d, Double.NaN };
455         assertEquals(2d, percentile.evaluate(specialValues), 0);
456         specialValues =
457             new double[] { Double.NEGATIVE_INFINITY, 1d, 2d, 3d, Double.NaN, Double.POSITIVE_INFINITY };
458         assertEquals(2d, percentile.evaluate(specialValues), 0);
459         specialValues =
460             new double[] { 1d, 1d, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY };
461         assertFalse(Double.isInfinite(percentile.evaluate(specialValues)));
462         specialValues = new double[] { 1d, 1d, Double.NaN, Double.NaN };
463         assertFalse(Double.isNaN(percentile.evaluate(specialValues)));
464         specialValues =
465             new double[] { 1d, 1d, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY };
466         percentile = new PSquarePercentile(50d);
467         // Interpolation results in NEGATIVE_INFINITY + POSITIVE_INFINITY
468         // changed the result check to infinity instead of NaN
469         assertTrue(Double.isInfinite(percentile.evaluate(specialValues)));
470     }
471 
472     @Test
473     public void testArrayExample() {
474         assertEquals(expectedValue(), new PSquarePercentile(95d).evaluate(testArray), getTolerance());
475     }
476 
477     @Test
478     public void testSetQuantile() {
479         PSquarePercentile percentile = new PSquarePercentile(10d);
480 
481         percentile = new PSquarePercentile(100); // OK
482         assertEquals(1.0, percentile.quantile(), 0);
483         try {
484             percentile = new PSquarePercentile(0);
485             // fail("Expecting MathIllegalArgumentException");
486         } catch (MathIllegalArgumentException ex) {
487             // expected
488         }
489         try {
490             new PSquarePercentile(0d);
491             // fail("Expecting MathIllegalArgumentException");
492         } catch (MathIllegalArgumentException ex) {
493             // expected
494         }
495     }
496 
497     private Double[] randomTestData(int factor, int values) {
498         Double[] test = new Double[values];
499         for (int i = 0; i < test.length; i++) {
500             test[i] = Math.abs(randomGenerator.nextDouble() * factor);
501         }
502         return test;
503     }
504 
505     @Test
506     public void testAccept() {
507         PSquarePercentile psquared = new PSquarePercentile(0.99);
508         assertTrue(Double.isNaN(psquared.getResult()));
509         Double[] test = randomTestData(100, 10000);
510 
511         for (Double value : test) {
512             psquared.increment(value);
513             assertTrue(psquared.getResult() >= 0);
514         }
515     }
516 
517     private void assertValues(Double a, Double b, double delta) {
518         if (Double.isNaN(a)) {
519             assertTrue("" + b + " is not NaN.", Double.isNaN(a));
520         } else {
521             double max = FastMath.max(a, b);
522             double percentage = FastMath.abs(a - b) / max;
523             double deviation = delta;
524             assertTrue(String.format("Deviated = %f and is beyond %f as a=%f,  b=%f",
525                                      percentage, deviation, a, b), percentage < deviation);
526         }
527     }
528 
529     private void doCalculatePercentile(Double percentile, Number[] test) {
530         doCalculatePercentile(percentile, test, Double.MAX_VALUE);
531     }
532 
533     private void doCalculatePercentile(Double percentile, Number[] test, double delta) {
534         PSquarePercentile psquared = new PSquarePercentile(percentile);
535         for (Number value : test) {
536             psquared.increment(value.doubleValue());
537         }
538 
539         Percentile p2 = new Percentile(percentile * 100);
540 
541         double[] dall = new double[test.length];
542         for (int i = 0; i < test.length; i++) {
543             dall[i] = test[i].doubleValue();
544         }
545 
546         Double referenceValue = p2.evaluate(dall);
547         assertValues(psquared.getResult(), referenceValue, delta);
548     }
549 
550     private void doCalculatePercentile(double percentile, double[] test, double delta) {
551         PSquarePercentile psquared = new PSquarePercentile(percentile);
552         for (double value : test) {
553             psquared.increment(value);
554         }
555 
556         Percentile p2 = new Percentile(percentile < 1 ? percentile * 100 : percentile);
557         /*
558          * double[] dall = new double[test.length]; for (int i = 0; i <
559          * test.length; i++) dall[i] = test[i];
560          */
561         Double referenceValue = p2.evaluate(test);
562         assertValues(psquared.getResult(), referenceValue, delta);
563     }
564 
565     @Test
566     public void testCannedDataSet() {
567         // test.unoverride("dump");
568         Integer[] seedInput =
569                 new Integer[] { 283, 285, 298, 304, 310, 31, 319, 32, 33, 339,
570                         342, 348, 350, 354, 354, 357, 36, 36, 369, 37, 37, 375,
571                         378, 383, 390, 396, 405, 408, 41, 414, 419, 416, 42,
572                         420, 430, 430, 432, 444, 447, 447, 449, 45, 451, 456,
573                         468, 470, 471, 474, 600, 695, 70, 83, 97, 109, 113, 128 };
574         Integer[] input = new Integer[seedInput.length * 100];
575         for (int i = 0; i < input.length; i++) {
576             input[i] = seedInput[i % seedInput.length] + i;
577         }
578         // Arrays.sort(input);
579         doCalculatePercentile(0.50d, input);
580         doCalculatePercentile(0.95d, input);
581     }
582 
583     @Test
584     public void test99Percentile() {
585         Double[] test = randomTestData(100, 10000);
586         doCalculatePercentile(0.99d, test);
587     }
588 
589     @Test
590     public void test90Percentile() {
591         Double[] test = randomTestData(100, 10000);
592         doCalculatePercentile(0.90d, test);
593     }
594 
595     @Test
596     public void test20Percentile() {
597         Double[] test = randomTestData(100, 100000);
598         doCalculatePercentile(0.20d, test);
599     }
600 
601     @Test
602     public void test5Percentile() {
603         Double[] test = randomTestData(50, 990000);
604         doCalculatePercentile(0.50d, test);
605     }
606 
607     @Test
608     public void test99PercentileHighValues() {
609         Double[] test = randomTestData(100000, 10000);
610         doCalculatePercentile(0.99d, test);
611     }
612 
613     @Test
614     public void test90PercentileHighValues() {
615         Double[] test = randomTestData(100000, 100000);
616         doCalculatePercentile(0.90d, test);
617     }
618 
619     @Test
620     public void test20PercentileHighValues() {
621         Double[] test = randomTestData(100000, 100000);
622         doCalculatePercentile(0.20d, test);
623     }
624 
625     @Test
626     public void test5PercentileHighValues() {
627         Double[] test = randomTestData(100000, 100000);
628         doCalculatePercentile(0.05d, test);
629     }
630 
631     @Test
632     public void test0PercentileValuesWithFewerThan5Values() {
633         double[] test = { 1d, 2d, 3d, 4d };
634         PSquarePercentile p = new PSquarePercentile(0d);
635         assertEquals(1d, p.evaluate(test), 0);
636         assertNotNull(p.toString());
637     }
638 
639     @Test
640     public void testPSQuaredEvalFuncWithPapersExampleData() throws IOException {
641 
642         // This data as input is considered from
643         // http://www.cs.wustl.edu/~jain/papers/ftp/psqr.pdf
644         double[] data =
645                 { 0.02, 0.5, 0.74, 3.39, 0.83, 22.37, 10.15, 15.43, 38.62,
646                   15.92, 34.6, 10.28, 1.47, 0.4, 0.05, 11.39, 0.27, 0.42,
647                   0.09, 11.37,
648 
649                   11.39, 15.43, 15.92, 22.37, 34.6, 38.62, 18.9, 19.2,
650                   27.6, 12.8, 13.7, 21.9
651                 };
652 
653         PSquarePercentile psquared = new PSquarePercentile(50);
654 
655         Double p2value = 0d;
656         for (int i = 0; i < 20; i++) {
657             psquared.increment(data[i]);
658             p2value = psquared.getResult();
659             // System.out.println(psquared.toString());//uncomment here to see
660             // the papers example output
661         }
662         // System.out.println("p2value=" + p2value);
663         Double expected = 4.44d;// 13d; // From The Paper
664         // http://www.cs.wustl.edu/~jain/papers/ftp/psqr.pdf.
665         // Pl refer Pg 1061 Look at the mid marker
666         // height
667         // expected = new Percentile(50).evaluate(data,0,20);
668         // Well the values deviate in our calculation by 0.25 so its 4.25 vs
669         // 4.44
670         assertEquals(String.format("Expected=%f, Actual=%f", expected, p2value),
671                      expected, p2value, 0.25);
672     }
673 
674     final int TINY = 10, SMALL = 50, NOMINAL = 100, MEDIUM = 500,
675               STANDARD = 1000, BIG = 10000, VERY_BIG = 50000, LARGE = 1000000,
676               VERY_LARGE = 10000000;
677 
678     private void doDistributionTest(RealDistribution distribution) {
679         double[] data;
680 
681 //        data = distribution.sample(VERY_LARGE);
682 //        doCalculatePercentile(50, data, 0.0001);
683 //        doCalculatePercentile(95, data, 0.0001);
684 
685         final RandomDataGenerator randomDataGenerator = new RandomDataGenerator(100);
686         data = randomDataGenerator.nextDeviates(distribution, LARGE);
687         doCalculatePercentile(50, data, 0.001);
688         doCalculatePercentile(95, data, 0.001);
689 
690         data = randomDataGenerator.nextDeviates(distribution, VERY_BIG);
691         doCalculatePercentile(50, data, 0.001);
692         doCalculatePercentile(95, data, 0.001);
693 
694         data = randomDataGenerator.nextDeviates(distribution, BIG);
695         doCalculatePercentile(50, data, 0.001);
696         doCalculatePercentile(95, data, 0.001);
697 
698         data = randomDataGenerator.nextDeviates(distribution, STANDARD);
699         doCalculatePercentile(50, data, 0.005);
700         doCalculatePercentile(95, data, 0.005);
701 
702         data = randomDataGenerator.nextDeviates(distribution, MEDIUM);
703         doCalculatePercentile(50, data, 0.005);
704         doCalculatePercentile(95, data, 0.005);
705 
706         data = randomDataGenerator.nextDeviates(distribution, NOMINAL);
707         doCalculatePercentile(50, data, 0.01);
708         doCalculatePercentile(95, data, 0.01);
709 
710         data = randomDataGenerator.nextDeviates(distribution, SMALL);
711         doCalculatePercentile(50, data, 0.01);
712         doCalculatePercentile(95, data, 0.01);
713 
714         data = randomDataGenerator.nextDeviates(distribution, TINY);
715         doCalculatePercentile(50, data, 0.05);
716         doCalculatePercentile(95, data, 0.05);
717     }
718 
719     /**
720      * Test Various Dist
721      */
722     @Test
723     public void testDistribution() {
724         doDistributionTest(new NormalDistribution(4000, 50));
725         doDistributionTest(new LogNormalDistribution(4000, 50));
726         // doDistributionTest((new ExponentialDistribution(4000));
727         // doDistributionTest(new GammaDistribution(5d,1d),0.1);
728     }
729 }