/*
 * 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.legacy.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.legacy.distribution.AbstractRealDistribution;
import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
import org.apache.commons.math4.legacy.exception.NullArgumentException;
import org.apache.commons.math4.legacy.exception.OutOfRangeException;
import org.apache.commons.rng.UniformRandomProvider;
import org.apache.commons.rng.simple.RandomSource;
import org.apache.commons.math4.legacy.stat.descriptive.StorelessUnivariateStatistic;
import org.apache.commons.math4.legacy.stat.descriptive.StorelessUnivariateStatisticAbstractTest;
import org.apache.commons.math4.legacy.stat.descriptive.UnivariateStatistic;
import org.apache.commons.math4.legacy.stat.descriptive.rank.PSquarePercentile.PSquareMarkers;
import org.apache.commons.math4.legacy.core.jdkmath.AccurateMath;
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.WELL_19937_C.create(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 = AccurateMath.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.assertEquals(replica, master);
        Assert.assertEquals(master, 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.assertEquals(replica, master);
        Assert.assertEquals(master, 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 = AccurateMath.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.assertEquals(replica, master);
        Assert.assertEquals(master, 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.assertEquals(master, master);
        Assert.assertEquals(replica, replica);
        Assert.assertEquals(replica, master);
        Assert.assertEquals(master, 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.assertEquals(markers, markers);
        Assert.assertNotEquals(markers, null);
        Assert.assertNotEquals(markers, "");
        // Check for null markers test during equality testing
        // Until 5 elements markers are not initialized
        PSquarePercentile p1 = new PSquarePercentile();
        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.assertNotEquals(p1, p2);
        Assert.assertNotEquals(p2, 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.assertNotEquals(p1, 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.assertEquals(markers, markersNew);
        // If just one element of markers got changed then its still false.
        markersNew.processDataPoint(39);
        Assert.assertNotEquals(markers, 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.assertEquals(m1, 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.assertEquals(mThis, mThis);
        Assert.assertNotEquals(mThis, mThat);
        String s1="";
        Assert.assertNotEquals(mThis, s1);
        for (int i = 0; i < testArray.length; i++) {
            mThat.processDataPoint(testArray[i]);
        }
        setMarkers.add(mThat);
        setMarkers.add(mThis);
        Assert.assertEquals(mThat, 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.assertNotEquals(ptile, null);
        Assert.assertNotEquals(ptile, "");
        // 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 = AccurateMath.max(a, b);
            double percentage = AccurateMath.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);

    }

    private final int TINY = 10;
    private final int SMALL = 50;
    private final int NOMINAL = 100;
    private final int MEDIUM = 500;
    private final int STANDARD = 1000;
    private final int BIG = 10000;
    private final int VERY_BIG = 50000;
    private final int LARGE = 1000000;
    private final int VERY_LARGE = 10000000;

    private void doDistributionTest(ContinuousDistribution distribution) {
        final ContinuousDistribution.Sampler sampler =
            distribution.createSampler(RandomSource.WELL_19937_C.create(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);
    }
}
