Java API By Example, From Geeks To Geeks.

# Java > Open Source Codes > org > apache > commons > math > stat > descriptive > rank > Percentile

 `1 /*2  * Copyright 2003-2004 The Apache Software Foundation.3  *4  * Licensed under the Apache License, Version 2.0 (the "License");5  * you may not use this file except in compliance with the License.6  * You may obtain a copy of the License at7  *8  * http://www.apache.org/licenses/LICENSE-2.09  *10  * Unless required by applicable law or agreed to in writing, software11  * distributed under the License is distributed on an "AS IS" BASIS,12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13  * See the License for the specific language governing permissions and14  * limitations under the License.15  */16 package org.apache.commons.math.stat.descriptive.rank;17 18 import java.io.Serializable ;19 import java.util.Arrays ;20 import org.apache.commons.math.stat.descriptive.AbstractUnivariateStatistic;21 22 /**23  * Provides percentile computation.24  *

25  * There are several commonly used methods for estimating percentiles (a.k.a. 26  * quantiles) based on sample data. For large samples, the different methods 27  * agree closely, but when sample sizes are small, different methods will give28  * significantly different results. The algorithm implemented here works as follows:29  *

30  *
1. Let n be the length of the (sorted) array and 31  * 0 < p <= 100 be the desired percentile.
2. 32  *
3. If n = 1 return the unique array element (regardless of 33  * the value of p); otherwise
4. 34  *
5. Compute the estimated percentile position 35  * pos = p * (n + 1) / 100 and the difference, d36  * between pos and floor(pos) (i.e. the fractional37  * part of pos). If pos >= n return the largest38  * element in the array; otherwise
6. 39  *
7. Let lower be the element in position 40  * floor(pos) in the array and let upper be the41  * next element in the array. Return lower + d * (upper - lower)42  *
8. 43  *
44  *

45  * To compute percentiles, the data must be (totally) ordered. Input arrays46  * are copied and then sorted using {@link java.util.Arrays#sort(double[])}.47  * The ordering used by Arrays.sort(double[]) is the one determined48  * by {@link java.lang.Double#compareTo(Double)}. This ordering makes 49  * Double.NaN larger than any other value (including 50  * Double.POSITIVE_INFINITY). Therefore, for example, the median51  * (50th percentile) of 52  * {0, 1, 2, 3, 4, Double.NaN} evaluates to 2.5. 53  *

54  * Since percentile estimation usually involves interpolation between array 55  * elements, arrays containing NaN or infinite values will often56  * result in NaN or infinite values returned.57  *

58  * Note that this implementation is not synchronized. If 59  * multiple threads access an instance of this class concurrently, and at least60  * one of the threads invokes the increment() or 61  * clear() method, it must be synchronized externally.62  * 63  * @version \$Revision\$ \$Date: 2005-02-26 05:11:52 -0800 (Sat, 26 Feb 2005) \$64  */65 public class Percentile extends AbstractUnivariateStatistic implements Serializable {66 67     /** Serializable version identifier */68     static final long serialVersionUID = -8091216485095130416L; 69        70     /** Determines what percentile is computed when evaluate() is activated 71      * with no quantile argument */72     private double quantile = 0.0;73 74     /**75      * Constructs a Percentile with a default quantile76      * value of 50.0.77      */78     public Percentile() {79         this(50.0);80     }81 82     /**83      * Constructs a Percentile with the specific quantile value.84      * @param p the quantile85      * @throws IllegalArgumentException if p is not greater than 0 and less86      * than or equal to 10087      */88     public Percentile(final double p) {89         setQuantile(p);90     }91 92     /**93      * Returns an estimate of the pth percentile of the values94      * in the values array.95      *

96      * Calls to this method do not modify the internal quantile97      * state of this statistic.98      *

99      *

100      *
• Returns Double.NaN if values has length 101      * 0
• 102      *
• Returns (for any value of p) values[0]103      * if values has length 1
• 104      *
• Throws IllegalArgumentException if values105      * is null or p is not a valid quantile value (p must be greater than 0106      * and less than or equal to 100)
• 107      *
108      *

109      * See {@link Percentile} for a description of the percentile estimation110      * algorithm used.111      * 112      * @param values input array of values113      * @param p the percentile value to compute114      * @return the percentile value or Double.NaN if the array is empty115      * @throws IllegalArgumentException if values is null 116      * or p is invalid117      */118     public double evaluate(final double[] values, final double p) {119         test(values, 0, 0);120         return evaluate(values, 0, values.length, p);121     }122 123     /**124      * Returns an estimate of the quantileth percentile of the125      * designated values in the values array. The quantile126      * estimated is determined by the quantile property.127      *

128      *

129      *
• Returns Double.NaN if length = 0
• 130      *
• Returns (for any value of quantile) 131      * values[begin] if length = 1
• 132      *
• Throws IllegalArgumentException if values133      * is null, or start or length 134      * is invalid
• 135      *
136      *

137      * See {@link Percentile} for a description of the percentile estimation138      * algorithm used.139      * 140      * @param values the input array141      * @param start index of the first array element to include142      * @param length the number of elements to include143      * @return the percentile value144      * @throws IllegalArgumentException if the parameters are not valid145      * 146      */147     public double evaluate( final double[] values, final int start, final int length) {148         return evaluate(values, start, length, quantile);149     }150 151      /**152      * Returns an estimate of the pth percentile of the values153      * in the values array, starting with the element in (0-based)154      * position begin in the array and including length155      * values.156      *

157      * Calls to this method do not modify the internal quantile158      * state of this statistic.159      *

160      *

161      *
• Returns Double.NaN if length = 0
• 162      *
• Returns (for any value of p) values[begin]163      * if length = 1
• 164      *
• Throws IllegalArgumentException if values165      * is null , begin or length is invalid, or 166      * p is not a valid quantile value (p must be greater than 0167      * and less than or equal to 100)
• 168      *
169      *

170       * See {@link Percentile} for a description of the percentile estimation171       * algorithm used.172      * 173      * @param values array of input values174      * @param p the percentile to compute175      * @param begin the first (0-based) element to include in the computation176      * @param length the number of array elements to include177      * @return the percentile value178      * @throws IllegalArgumentException if the parameters are not valid or the179      * input array is null180      */181     public double evaluate(final double[] values, final int begin, 182             final int length, final double p) {183 184         test(values, begin, length);185 186         if ((p > 100) || (p <= 0)) {187             throw new IllegalArgumentException ("invalid quantile value: " + p);188         }189         double n = (double) length;190         if (n == 0) {191             return Double.NaN;192         }193         if (n == 1) {194             return values[begin]; // always return single value for n = 1195 }196         double pos = p * (n + 1) / 100;197         double fpos = Math.floor(pos);198         int intPos = (int) fpos;199         double dif = pos - fpos;200         double[] sorted = new double[length];201         System.arraycopy(values, begin, sorted, 0, length);202         Arrays.sort(sorted);203 204         if (pos < 1) {205             return sorted[0];206         }207         if (pos >= n) {208             return sorted[length - 1];209         }210         double lower = sorted[intPos - 1];211         double upper = sorted[intPos];212         return lower + dif * (upper - lower);213     }214 215     /**216      * Returns the value of the quantile field (determines what percentile is217      * computed when evaluate() is called with no quantile argument).218      * 219      * @return quantile220      */221     public double getQuantile() {222         return quantile;223     }224 225     /**226      * Sets the value of the quantile field (determines what percentile is 227      * computed when evaluate() is called with no quantile argument).228      * 229      * @param p a value between 0 < p <= 100 230      * @throws IllegalArgumentException if p is not greater than 0 and less231      * than or equal to 100232      */233     public void setQuantile(final double p) {234         if (p <= 0 || p > 100) {235             throw new IllegalArgumentException ("Illegal quantile value: " + p);236         }237         quantile = p;238     }239 240 }` Popular Tags