| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.commons.math4.stat.descriptive.rank; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.LinkedHashSet; |
| import java.util.Set; |
| |
| import org.apache.commons.statistics.distribution.LogNormalDistribution; |
| import org.apache.commons.statistics.distribution.NormalDistribution; |
| import org.apache.commons.statistics.distribution.ContinuousDistribution; |
| import org.apache.commons.math4.distribution.AbstractRealDistribution; |
| import org.apache.commons.math4.exception.MathIllegalArgumentException; |
| import org.apache.commons.math4.exception.NullArgumentException; |
| import org.apache.commons.math4.exception.OutOfRangeException; |
| import org.apache.commons.rng.UniformRandomProvider; |
| import org.apache.commons.rng.simple.RandomSource; |
| import org.apache.commons.math4.stat.descriptive.StorelessUnivariateStatistic; |
| import org.apache.commons.math4.stat.descriptive.StorelessUnivariateStatisticAbstractTest; |
| import org.apache.commons.math4.stat.descriptive.UnivariateStatistic; |
| import org.apache.commons.math4.stat.descriptive.rank.PSquarePercentile; |
| import org.apache.commons.math4.stat.descriptive.rank.Percentile; |
| import org.apache.commons.math4.stat.descriptive.rank.PSquarePercentile.PSquareMarkers; |
| import org.apache.commons.math4.util.FastMath; |
| import org.junit.Assert; |
| import org.junit.Test; |
| |
| /** |
| * Test cases for the {@link PSquarePercentile} class which naturally extends |
| * {@link StorelessUnivariateStatisticAbstractTest}. |
| */ |
| public class PSquarePercentileTest extends |
| StorelessUnivariateStatisticAbstractTest { |
| |
| protected double percentile5 = 8.2299d; |
| protected double percentile95 = 16.72195;// 20.82d; this is approximation |
| protected double tolerance = 10E-12; |
| |
| private final UniformRandomProvider randomGenerator = RandomSource.create(RandomSource.WELL_19937_C, 1000); |
| |
| @Override |
| public double getTolerance() { |
| return 1.0e-2;// tolerance limit changed as this is an approximation |
| // algorithm and also gets accurate after few tens of |
| // samples |
| } |
| |
| /** |
| * Verifies that copied statistics remain equal to originals when |
| * incremented the same way by making the copy after a majority of elements |
| * are incremented |
| */ |
| @Test |
| public void testCopyConsistencyWithInitialMostElements() { |
| |
| StorelessUnivariateStatistic master = |
| (StorelessUnivariateStatistic) getUnivariateStatistic(); |
| |
| StorelessUnivariateStatistic replica = null; |
| |
| // select a portion of testArray till 75 % of the length to load first |
| long index = FastMath.round(0.75 * testArray.length); |
| |
| // Put first half in master and copy master to replica |
| master.incrementAll(testArray, 0, (int) index); |
| replica = master.copy(); |
| |
| // Check same |
| Assert.assertTrue(replica.equals(master)); |
| Assert.assertTrue(master.equals(replica)); |
| |
| // Now add second part to both and check again |
| master.incrementAll(testArray, (int) index, |
| (int) (testArray.length - index)); |
| replica.incrementAll(testArray, (int) index, |
| (int) (testArray.length - index)); |
| Assert.assertTrue(replica.equals(master)); |
| Assert.assertTrue(master.equals(replica)); |
| } |
| |
| /** |
| * Verifies that copied statistics remain equal to originals when |
| * incremented the same way by way of copying original after just a few |
| * elements are incremented |
| */ |
| @Test |
| public void testCopyConsistencyWithInitialFirstFewElements() { |
| |
| StorelessUnivariateStatistic master = |
| (StorelessUnivariateStatistic) getUnivariateStatistic(); |
| |
| StorelessUnivariateStatistic replica = null; |
| |
| // select a portion of testArray which is 10% of the length to load |
| // first |
| long index = FastMath.round(0.1 * testArray.length); |
| |
| // Put first half in master and copy master to replica |
| master.incrementAll(testArray, 0, (int) index); |
| replica = master.copy(); |
| |
| // Check same |
| Assert.assertTrue(replica.equals(master)); |
| Assert.assertTrue(master.equals(replica)); |
| // Now add second part to both and check again |
| master.incrementAll(testArray, (int) index, |
| (int) (testArray.length - index)); |
| replica.incrementAll(testArray, (int) index, |
| (int) (testArray.length - index)); |
| Assert.assertTrue(master.equals(master)); |
| Assert.assertTrue(replica.equals(replica)); |
| Assert.assertTrue(replica.equals(master)); |
| Assert.assertTrue(master.equals(replica)); |
| } |
| |
| @Test(expected = MathIllegalArgumentException.class) |
| public void testNullListInMarkers() { |
| // In case of null list Markers cannot be instantiated..is getting |
| // verified |
| // new Markers(null, 0, PSquarePercentile.newEstimator()); |
| PSquarePercentile.newMarkers(null, 0); |
| |
| } |
| |
| @Test |
| public void testMiscellaniousFunctionsInMarkers() { |
| double p = 0.5; |
| PSquareMarkers markers = |
| PSquarePercentile.newMarkers( |
| Arrays.asList(new Double[] { 0.02, 1.18, 9.15, 21.91, |
| 38.62 }), p); |
| // Markers equality |
| Assert.assertTrue(markers.equals(markers)); |
| Assert.assertFalse(markers.equals(null)); |
| Assert.assertFalse(markers.equals(new String())); |
| // Check for null markers test during equality testing |
| // Until 5 elements markers are not initialized |
| PSquarePercentile p1 = new PSquarePercentile(), p2 = |
| new PSquarePercentile(); |
| Assert.assertEquals(p1, p2); |
| p1.evaluate(new double[] { 1.0, 2.0, 3.0 }); |
| p2.evaluate(new double[] { 1.0, 2.0, 3.0 }); |
| Assert.assertEquals(p1, p2); |
| // Move p2 alone with more values just to make sure markers are not null |
| // for p2 |
| p2.incrementAll(new double[] { 5.0, 7.0, 11.0 }); |
| Assert.assertFalse(p1.equals(p2)); |
| Assert.assertFalse(p2.equals(p1)); |
| // Next add different data to p1 to make number of elements match and |
| // markers are not null however actual results will vary |
| p1.incrementAll(new double[] { 20, 21, 22, 23 }); |
| Assert.assertFalse(p1.equals(p2));// though markers are non null, N |
| // matches, results wont |
| |
| } |
| |
| @Test(expected = OutOfRangeException.class) |
| public void testMarkersOORLow() { |
| PSquarePercentile.newMarkers( |
| Arrays.asList(new Double[] { 0.02, 1.18, 9.15, 21.91, 38.62 }), |
| 0.5).estimate(0); |
| } |
| |
| @Test(expected = OutOfRangeException.class) |
| public void testMarkersOORHigh() { |
| PSquarePercentile.newMarkers( |
| Arrays.asList(new Double[] { 0.02, 1.18, 9.15, 21.91, 38.62 }), |
| 0.5).estimate(5); |
| } |
| |
| @Test |
| public void testMarkers2() { |
| double p = 0.5; |
| PSquareMarkers markers = |
| PSquarePercentile.newMarkers( |
| Arrays.asList(new Double[] { 0.02, 1.18, 9.15, 21.91, |
| 38.62 }), p); |
| |
| PSquareMarkers markersNew = |
| PSquarePercentile.newMarkers( |
| Arrays.asList(new Double[] { 0.02, 1.18, 9.15, 21.91, |
| 38.62 }), p); |
| |
| Assert.assertTrue(markers.equals(markersNew)); |
| // If just one element of markers got changed then its still false. |
| markersNew.processDataPoint(39); |
| Assert.assertFalse(markers.equals(markersNew)); |
| |
| } |
| |
| @Test |
| public void testHashCodeInMarkers() { |
| PSquarePercentile p = new PSquarePercentile(95); |
| PSquarePercentile p2 = new PSquarePercentile(95); |
| Set<PSquarePercentile> s = new HashSet<>(); |
| s.add(p); |
| s.add(p2); |
| Assert.assertEquals(1, s.size()); |
| Assert.assertEquals(p, s.iterator().next()); |
| double[] d = |
| new double[] { 95.1772, 95.1567, 95.1937, 95.1959, 95.1442, |
| 95.0610, 95.1591, 95.1195, 95.1772, 95.0925, 95.1990, |
| 95.1682 }; |
| Assert.assertEquals(95.1981, p.evaluate(d), 1.0e-2); // change |
| Assert.assertEquals(95.1981, p2.evaluate(d), 1.0e-2); // change |
| s.clear(); |
| s.add(p); |
| s.add(p2); |
| Assert.assertEquals(1, s.size()); |
| Assert.assertEquals(p, s.iterator().next()); |
| |
| PSquareMarkers m1 = |
| PSquarePercentile.newMarkers( |
| Arrays.asList(new Double[] { 95.1772, 95.1567, 95.1937, |
| 95.1959, 95.1442, 95.0610, 95.1591, 95.1195, |
| 95.1772, 95.0925, 95.1990, 95.1682 }), 0.0); |
| PSquareMarkers m2 = |
| PSquarePercentile.newMarkers( |
| Arrays.asList(new Double[] { 95.1772, 95.1567, 95.1937, |
| 95.1959, 95.1442, 95.0610, 95.1591, 95.1195, |
| 95.1772, 95.0925, 95.1990, 95.1682 }), 0.0); |
| Assert.assertTrue(m1.equals(m2)); |
| Set<PSquareMarkers> setMarkers = new LinkedHashSet<>(); |
| Assert.assertTrue(setMarkers.add(m1)); |
| Assert.assertFalse(setMarkers.add(m2)); |
| Assert.assertEquals(1, setMarkers.size()); |
| |
| PSquareMarkers mThis = |
| PSquarePercentile.newMarkers( |
| Arrays.asList(new Double[] { 195.1772, 195.1567, |
| 195.1937, 195.1959, 95.1442, 195.0610, |
| 195.1591, 195.1195, 195.1772, 95.0925, 95.1990, |
| 195.1682 }), 0.50); |
| PSquareMarkers mThat = |
| PSquarePercentile.newMarkers( |
| Arrays.asList(new Double[] { 95.1772, 95.1567, 95.1937, |
| 95.1959, 95.1442, 95.0610, 95.1591, 95.1195, |
| 95.1772, 95.0925, 95.1990, 95.1682 }), 0.50); |
| Assert.assertTrue(mThis.equals(mThis)); |
| Assert.assertFalse(mThis.equals(mThat)); |
| String s1=""; |
| Assert.assertFalse(mThis.equals(s1)); |
| for (int i = 0; i < testArray.length; i++) { |
| mThat.processDataPoint(testArray[i]); |
| } |
| setMarkers.add(mThat); |
| setMarkers.add(mThis); |
| Assert.assertTrue(mThat.equals(mThat)); |
| Assert.assertTrue(setMarkers.contains(mThat)); |
| Assert.assertTrue(setMarkers.contains(mThis)); |
| Assert.assertEquals(3, setMarkers.size()); |
| Iterator<PSquareMarkers> iterator=setMarkers.iterator(); |
| Assert.assertEquals(m1, iterator.next()); |
| Assert.assertEquals(mThat, iterator.next()); |
| Assert.assertEquals(mThis, iterator.next()); |
| } |
| |
| @Test(expected = OutOfRangeException.class) |
| public void testMarkersWithLowerIndex() { |
| PSquareMarkers mThat = |
| PSquarePercentile.newMarkers( |
| Arrays.asList(new Double[] { 95.1772, 95.1567, 95.1937, |
| 95.1959, 95.1442, 95.0610, 95.1591, 95.1195, |
| 95.1772, 95.0925, 95.1990, 95.1682 }), 0.50); |
| for (int i = 0; i < testArray.length; i++) { |
| mThat.processDataPoint(testArray[i]); |
| } |
| mThat.estimate(0); |
| } |
| |
| @Test(expected = OutOfRangeException.class) |
| public void testMarkersWithHigherIndex() { |
| PSquareMarkers mThat = |
| PSquarePercentile.newMarkers( |
| Arrays.asList(new Double[] { 95.1772, 95.1567, 95.1937, |
| 95.1959, 95.1442, 95.0610, 95.1591, 95.1195, |
| 95.1772, 95.0925, 95.1990, 95.1682 }), 0.50); |
| for (int i = 0; i < testArray.length; i++) { |
| mThat.processDataPoint(testArray[i]); |
| } |
| mThat.estimate(6); |
| } |
| |
| @Test(expected = OutOfRangeException.class) |
| public void testMarkerHeightWithLowerIndex() { |
| PSquareMarkers mThat = |
| PSquarePercentile.newMarkers( |
| Arrays.asList(new Double[] { 95.1772, 95.1567, 95.1937, |
| 95.1959, 95.1442, 95.0610, 95.1591, 95.1195, |
| 95.1772, 95.0925, 95.1990, 95.1682 }), 0.50); |
| mThat.height(0); |
| } |
| |
| @Test(expected = OutOfRangeException.class) |
| public void testMarkerHeightWithHigherIndex() { |
| PSquareMarkers mThat = |
| PSquarePercentile.newMarkers( |
| Arrays.asList(new Double[] { 95.1772, 95.1567, 95.1937, |
| 95.1959, 95.1442, 95.0610, 95.1591, 95.1195, |
| 95.1772, 95.0925, 95.1990, 95.1682 }), 0.50); |
| mThat.height(6); |
| } |
| |
| @Test |
| public void testPSquaredEqualsAndMin() { |
| PSquarePercentile ptile = new PSquarePercentile(0); |
| Assert.assertEquals(ptile, ptile); |
| Assert.assertFalse(ptile.equals(null)); |
| Assert.assertFalse(ptile.equals(new String())); |
| // Just to check if there is no data get result for zeroth and 100th |
| // ptile returns NAN |
| Assert.assertTrue(Double.isNaN(ptile.getResult())); |
| Assert.assertTrue(Double.isNaN(new PSquarePercentile(100).getResult())); |
| |
| double[] d = new double[] { 1, 3, 2, 4, 9, 10, 11 }; |
| ptile.incrementAll(d); |
| Assert.assertEquals(ptile, ptile); |
| Assert.assertEquals(1d, ptile.getResult(), 1e-02);// this calls min |
| } |
| |
| @Test |
| public void testString() { |
| PSquarePercentile ptile = new PSquarePercentile(95); |
| Assert.assertNotNull(ptile.toString()); |
| ptile.increment(1); |
| ptile.increment(2); |
| ptile.increment(3); |
| Assert.assertNotNull(ptile.toString()); |
| Assert.assertEquals(expectedValue(), ptile.evaluate(testArray), getTolerance()); |
| Assert.assertNotNull(ptile.toString()); |
| } |
| |
| @Override |
| public UnivariateStatistic getUnivariateStatistic() { |
| PSquarePercentile ptile = new PSquarePercentile(95); |
| // Assert.assertNull(ptile.markers()); |
| return ptile; |
| } |
| |
| @Override |
| public double expectedValue() { |
| return this.percentile95; |
| } |
| |
| @Test |
| public void testHighPercentile() { |
| double[] d = new double[] { 1, 2, 3 }; |
| PSquarePercentile p = new PSquarePercentile(75.0); |
| Assert.assertEquals(2, p.evaluate(d), 1.0e-5); |
| PSquarePercentile p95 = new PSquarePercentile(); |
| Assert.assertEquals(2, p95.evaluate(d), 1.0e-5); |
| } |
| |
| @Test |
| public void testLowPercentile() { |
| double[] d = new double[] { 0, 1 }; |
| PSquarePercentile p = new PSquarePercentile(25.0); |
| Assert.assertEquals(0d, p.evaluate(d), Double.MIN_VALUE); |
| } |
| |
| @Test |
| public void testPercentile() { |
| double[] d = new double[] { 1, 3, 2, 4 }; |
| PSquarePercentile p = new PSquarePercentile(30d); |
| Assert.assertEquals(1.0, p.evaluate(d), 1.0e-5); |
| p = new PSquarePercentile(25); |
| Assert.assertEquals(1.0, p.evaluate(d), 1.0e-5); |
| p = new PSquarePercentile(75); |
| Assert.assertEquals(3.0, p.evaluate(d), 1.0e-5); |
| p = new PSquarePercentile(50); |
| Assert.assertEquals(2d, p.evaluate(d), 1.0e-5); |
| |
| } |
| |
| @Test(expected = MathIllegalArgumentException.class) |
| public void testInitial() { |
| PSquarePercentile.newMarkers(new ArrayList<Double>(), 0.5); |
| Assert.fail(); |
| } |
| |
| @Test(expected = MathIllegalArgumentException.class) |
| public void testNegativeInvalidValues() { |
| double[] d = |
| new double[] { 95.1772, 95.1567, 95.1937, 95.1959, 95.1442, |
| 95.0610, 95.1591, 95.1195, 95.1772, 95.0925, 95.1990, |
| 95.1682 }; |
| PSquarePercentile p = new PSquarePercentile(-1.0); |
| p.evaluate(d, 0, d.length); |
| Assert.fail("This method has had to throw exception..but it is not.."); |
| |
| } |
| |
| @Test(expected = MathIllegalArgumentException.class) |
| public void testPositiveInvalidValues() { |
| double[] d = |
| new double[] { 95.1772, 95.1567, 95.1937, 95.1959, 95.1442, |
| 95.0610, 95.1591, 95.1195, 95.1772, 95.0925, 95.1990, |
| 95.1682 }; |
| PSquarePercentile p = new PSquarePercentile(101.0); |
| p.evaluate(d, 0, d.length); |
| Assert.fail("This method has had to throw exception..but it is not.."); |
| |
| } |
| |
| @Test |
| public void testNISTExample() { |
| double[] d = |
| new double[] { 95.1772, 95.1567, 95.1937, 95.1959, 95.1442, |
| 95.0610, 95.1591, 95.1195, 95.1772, 95.0925, 95.1990, |
| 95.1682 }; |
| Assert.assertEquals(95.1981, new PSquarePercentile(90d).evaluate(d), |
| 1.0e-2); // changed the accuracy to 1.0e-2 |
| Assert.assertEquals(95.061, new PSquarePercentile(0d).evaluate(d), 0); |
| Assert.assertEquals(95.1990, |
| new PSquarePercentile(100d).evaluate(d, 0, d.length), 0); |
| } |
| |
| @Test |
| public void test5() { |
| PSquarePercentile percentile = new PSquarePercentile(5d); |
| Assert.assertEquals(this.percentile5, percentile.evaluate(testArray), |
| 1.0);// changed the accuracy to 1 instead of tolerance |
| } |
| |
| @Test(expected = NullArgumentException.class) |
| public void testNull() { |
| PSquarePercentile percentile = new PSquarePercentile(50d); |
| double[] nullArray = null; |
| percentile.evaluate(nullArray); |
| } |
| |
| @Test |
| public void testEmpty() { |
| PSquarePercentile percentile = new PSquarePercentile(50d); |
| double[] emptyArray = new double[] {}; |
| Assert.assertTrue(Double.isNaN(percentile.evaluate(emptyArray))); |
| } |
| |
| @Test |
| public void testSingleton() { |
| PSquarePercentile percentile = new PSquarePercentile(50d); |
| double[] singletonArray = new double[] { 1d }; |
| Assert.assertEquals(1d, percentile.evaluate(singletonArray), 0); |
| Assert.assertEquals(1d, percentile.evaluate(singletonArray, 0, 1), 0); |
| percentile = new PSquarePercentile(5); |
| Assert.assertEquals(1d, percentile.evaluate(singletonArray, 0, 1), 0); |
| percentile = new PSquarePercentile(100); |
| Assert.assertEquals(1d, percentile.evaluate(singletonArray, 0, 1), 0); |
| percentile = new PSquarePercentile(100); |
| Assert.assertTrue(Double.isNaN(percentile |
| .evaluate(singletonArray, 0, 0))); |
| } |
| |
| @Test |
| public void testSpecialValues() { |
| PSquarePercentile percentile = new PSquarePercentile(50d); |
| double[] specialValues = |
| new double[] { 0d, 1d, 2d, 3d, 4d, Double.NaN }; |
| Assert.assertEquals(2d, percentile.evaluate(specialValues), 0); |
| specialValues = |
| new double[] { Double.NEGATIVE_INFINITY, 1d, 2d, 3d, |
| Double.NaN, Double.POSITIVE_INFINITY }; |
| Assert.assertEquals(2d, percentile.evaluate(specialValues), 0); |
| specialValues = |
| new double[] { 1d, 1d, Double.POSITIVE_INFINITY, |
| Double.POSITIVE_INFINITY }; |
| Assert.assertFalse(Double.isInfinite(percentile.evaluate(specialValues))); |
| specialValues = new double[] { 1d, 1d, Double.NaN, Double.NaN }; |
| Assert.assertFalse(Double.isNaN(percentile.evaluate(specialValues))); |
| specialValues = |
| new double[] { 1d, 1d, Double.NEGATIVE_INFINITY, |
| Double.NEGATIVE_INFINITY }; |
| percentile = new PSquarePercentile(50d); |
| // Interpolation results in NEGATIVE_INFINITY + POSITIVE_INFINITY |
| // changed the result check to infinity instead of NaN |
| Assert.assertTrue(Double.isInfinite(percentile.evaluate(specialValues))); |
| } |
| |
| @Test |
| public void testArrayExample() { |
| Assert.assertEquals(expectedValue(), |
| new PSquarePercentile(95d).evaluate(testArray), getTolerance()); |
| } |
| |
| @Test |
| public void testSetQuantile() { |
| PSquarePercentile percentile = new PSquarePercentile(10d); |
| |
| percentile = new PSquarePercentile(100); // OK |
| Assert.assertEquals(1.0, percentile.quantile(), 0); |
| try { |
| percentile = new PSquarePercentile(0); |
| // Assert.fail("Expecting MathIllegalArgumentException"); |
| } catch (MathIllegalArgumentException ex) { |
| // expected |
| } |
| try { |
| new PSquarePercentile(0d); |
| // Assert.fail("Expecting MathIllegalArgumentException"); |
| } catch (MathIllegalArgumentException ex) { |
| // expected |
| } |
| } |
| |
| private Double[] randomTestData(int factor, int values) { |
| Double[] test = new Double[values]; |
| for (int i = 0; i < test.length; i++) { |
| test[i] = Math.abs(randomGenerator.nextDouble() * factor); |
| } |
| return test; |
| } |
| |
| @Test |
| public void testAccept() { |
| PSquarePercentile psquared = new PSquarePercentile(0.99); |
| Assert.assertTrue(Double.isNaN(psquared.getResult())); |
| Double[] test = randomTestData(100, 10000); |
| |
| for (Double value : test) { |
| psquared.increment(value); |
| Assert.assertTrue(psquared.getResult() >= 0); |
| } |
| } |
| |
| private void assertValues(Double a, Double b, double delta) { |
| if (Double.isNaN(a)) { |
| Assert.assertTrue("" + b + " is not NaN.", Double.isNaN(a)); |
| } else { |
| double max = FastMath.max(a, b); |
| double percentage = FastMath.abs(a - b) / max; |
| double deviation = delta; |
| Assert.assertTrue(String.format( |
| "Deviated = %f and is beyond %f as a=%f, b=%f", |
| percentage, deviation, a, b), percentage < deviation); |
| } |
| } |
| |
| private void doCalculatePercentile(Double percentile, Number[] test) { |
| doCalculatePercentile(percentile, test, Double.MAX_VALUE); |
| } |
| |
| private void doCalculatePercentile(Double percentile, Number[] test, |
| double delta) { |
| PSquarePercentile psquared = new PSquarePercentile(percentile); |
| for (Number value : test) { |
| psquared.increment(value.doubleValue()); |
| } |
| |
| Percentile p2 = new Percentile(percentile * 100); |
| |
| double[] dall = new double[test.length]; |
| for (int i = 0; i < test.length; i++) { |
| dall[i] = test[i].doubleValue(); |
| } |
| |
| Double referenceValue = p2.evaluate(dall); |
| assertValues(psquared.getResult(), referenceValue, delta); |
| } |
| |
| private void doCalculatePercentile(double percentile, double[] test, |
| double delta) { |
| PSquarePercentile psquared = new PSquarePercentile(percentile); |
| for (double value : test) { |
| psquared.increment(value); |
| } |
| |
| Percentile p2 = |
| new Percentile(percentile < 1 ? percentile * 100 : percentile); |
| /* |
| * double[] dall = new double[test.length]; for (int i = 0; i < |
| * test.length; i++) dall[i] = test[i]; |
| */ |
| Double referenceValue = p2.evaluate(test); |
| assertValues(psquared.getResult(), referenceValue, delta); |
| } |
| |
| @Test |
| public void testCannedDataSet() { |
| // test.unoverride("dump"); |
| Integer[] seedInput = |
| new Integer[] { 283, 285, 298, 304, 310, 31, 319, 32, 33, 339, |
| 342, 348, 350, 354, 354, 357, 36, 36, 369, 37, 37, 375, |
| 378, 383, 390, 396, 405, 408, 41, 414, 419, 416, 42, |
| 420, 430, 430, 432, 444, 447, 447, 449, 45, 451, 456, |
| 468, 470, 471, 474, 600, 695, 70, 83, 97, 109, 113, 128 }; |
| Integer[] input = new Integer[seedInput.length * 100]; |
| for (int i = 0; i < input.length; i++) { |
| input[i] = seedInput[i % seedInput.length] + i; |
| } |
| // Arrays.sort(input); |
| doCalculatePercentile(0.50d, input); |
| doCalculatePercentile(0.95d, input); |
| |
| } |
| |
| @Test |
| public void test99Percentile() { |
| Double[] test = randomTestData(100, 10000); |
| doCalculatePercentile(0.99d, test); |
| } |
| |
| @Test |
| public void test90Percentile() { |
| Double[] test = randomTestData(100, 10000); |
| doCalculatePercentile(0.90d, test); |
| } |
| |
| @Test |
| public void test20Percentile() { |
| Double[] test = randomTestData(100, 100000); |
| doCalculatePercentile(0.20d, test); |
| } |
| |
| @Test |
| public void test5Percentile() { |
| Double[] test = randomTestData(50, 990000); |
| doCalculatePercentile(0.50d, test); |
| } |
| |
| @Test |
| public void test99PercentileHighValues() { |
| Double[] test = randomTestData(100000, 10000); |
| doCalculatePercentile(0.99d, test); |
| } |
| |
| @Test |
| public void test90PercentileHighValues() { |
| Double[] test = randomTestData(100000, 100000); |
| doCalculatePercentile(0.90d, test); |
| } |
| |
| @Test |
| public void test20PercentileHighValues() { |
| Double[] test = randomTestData(100000, 100000); |
| doCalculatePercentile(0.20d, test); |
| } |
| |
| @Test |
| public void test5PercentileHighValues() { |
| Double[] test = randomTestData(100000, 100000); |
| doCalculatePercentile(0.05d, test); |
| } |
| |
| @Test |
| public void test0PercentileValuesWithFewerThan5Values() { |
| double[] test = { 1d, 2d, 3d, 4d }; |
| PSquarePercentile p = new PSquarePercentile(0d); |
| Assert.assertEquals(1d, p.evaluate(test), 0); |
| Assert.assertNotNull(p.toString()); |
| } |
| |
| @Test |
| public void testPSQuaredEvalFuncWithPapersExampleData() throws IOException { |
| |
| // This data as input is considered from |
| // http://www.cs.wustl.edu/~jain/papers/ftp/psqr.pdf |
| double[] data = |
| { 0.02, 0.5, 0.74, 3.39, 0.83, 22.37, 10.15, 15.43, 38.62, |
| 15.92, 34.6, 10.28, 1.47, 0.4, 0.05, 11.39, 0.27, 0.42, |
| 0.09, 11.37, |
| |
| 11.39, 15.43, 15.92, 22.37, 34.6, 38.62, 18.9, 19.2, |
| 27.6, 12.8, 13.7, 21.9 |
| |
| }; |
| |
| PSquarePercentile psquared = new PSquarePercentile(50); |
| |
| Double p2value = 0d; |
| for (int i = 0; i < 20; i++) { |
| psquared.increment(data[i]); |
| p2value = psquared.getResult(); |
| // System.out.println(psquared.toString());//uncomment here to see |
| // the papers example output |
| } |
| // System.out.println("p2value=" + p2value); |
| Double expected = 4.44d;// 13d; // From The Paper |
| // http://www.cs.wustl.edu/~jain/papers/ftp/psqr.pdf. |
| // Pl refer Pg 1061 Look at the mid marker |
| // height |
| // expected = new Percentile(50).evaluate(data,0,20); |
| // Well the values deviate in our calculation by 0.25 so its 4.25 vs |
| // 4.44 |
| Assert.assertEquals( |
| String.format("Expected=%f, Actual=%f", expected, p2value), |
| expected, p2value, 0.25); |
| |
| } |
| |
| final int TINY = 10, SMALL = 50, NOMINAL = 100, MEDIUM = 500, |
| STANDARD = 1000, BIG = 10000, VERY_BIG = 50000, LARGE = 1000000, |
| VERY_LARGE = 10000000; |
| |
| private void doDistributionTest(ContinuousDistribution distribution) { |
| final ContinuousDistribution.Sampler sampler = |
| distribution.createSampler(RandomSource.create(RandomSource.WELL_19937_C, 1000)); |
| double data[]; |
| |
| data = AbstractRealDistribution.sample(VERY_LARGE, sampler); |
| doCalculatePercentile(50, data, 0.0001); |
| doCalculatePercentile(95, data, 0.0001); |
| |
| data = AbstractRealDistribution.sample(LARGE, sampler); |
| doCalculatePercentile(50, data, 0.001); |
| doCalculatePercentile(95, data, 0.001); |
| |
| data = AbstractRealDistribution.sample(VERY_BIG, sampler); |
| doCalculatePercentile(50, data, 0.001); |
| doCalculatePercentile(95, data, 0.001); |
| |
| data = AbstractRealDistribution.sample(BIG, sampler); |
| doCalculatePercentile(50, data, 0.001); |
| doCalculatePercentile(95, data, 0.001); |
| |
| data = AbstractRealDistribution.sample(STANDARD, sampler); |
| doCalculatePercentile(50, data, 0.005); |
| doCalculatePercentile(95, data, 0.005); |
| |
| data = AbstractRealDistribution.sample(MEDIUM, sampler); |
| doCalculatePercentile(50, data, 0.005); |
| doCalculatePercentile(95, data, 0.005); |
| |
| data = AbstractRealDistribution.sample(NOMINAL, sampler); |
| doCalculatePercentile(50, data, 0.01); |
| doCalculatePercentile(95, data, 0.01); |
| |
| data = AbstractRealDistribution.sample(SMALL, sampler); |
| doCalculatePercentile(50, data, 0.01); |
| doCalculatePercentile(95, data, 0.01); |
| |
| data = AbstractRealDistribution.sample(TINY, sampler); |
| doCalculatePercentile(50, data, 0.05); |
| doCalculatePercentile(95, data, 0.05); |
| |
| } |
| |
| /** |
| * Test Various Dist |
| */ |
| @Test |
| public void testDistribution() { |
| doDistributionTest(new NormalDistribution(4000, 50)); |
| doDistributionTest(new LogNormalDistribution(4000, 50)); |
| // doDistributionTest((new ExponentialDistribution(4000)); |
| // doDistributionTest(new GammaDistribution(5d,1d),0.1); |
| } |
| } |