001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.math3.stat;
018    
019    import org.apache.commons.math3.exception.MathIllegalArgumentException;
020    import org.apache.commons.math3.exception.NumberIsTooSmallException;
021    import org.apache.commons.math3.exception.DimensionMismatchException;
022    import org.apache.commons.math3.exception.NoDataException;
023    import org.apache.commons.math3.exception.util.LocalizedFormats;
024    import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
025    import org.apache.commons.math3.stat.descriptive.UnivariateStatistic;
026    import org.apache.commons.math3.stat.descriptive.moment.GeometricMean;
027    import org.apache.commons.math3.stat.descriptive.moment.Mean;
028    import org.apache.commons.math3.stat.descriptive.moment.Variance;
029    import org.apache.commons.math3.stat.descriptive.rank.Max;
030    import org.apache.commons.math3.stat.descriptive.rank.Min;
031    import org.apache.commons.math3.stat.descriptive.rank.Percentile;
032    import org.apache.commons.math3.stat.descriptive.summary.Product;
033    import org.apache.commons.math3.stat.descriptive.summary.Sum;
034    import org.apache.commons.math3.stat.descriptive.summary.SumOfLogs;
035    import org.apache.commons.math3.stat.descriptive.summary.SumOfSquares;
036    
037    /**
038     * StatUtils provides static methods for computing statistics based on data
039     * stored in double[] arrays.
040     *
041     * @version $Id: StatUtils.java 1416643 2012-12-03 19:37:14Z tn $
042     */
043    public final class StatUtils {
044    
045        /** sum */
046        private static final UnivariateStatistic SUM = new Sum();
047    
048        /** sumSq */
049        private static final UnivariateStatistic SUM_OF_SQUARES = new SumOfSquares();
050    
051        /** prod */
052        private static final UnivariateStatistic PRODUCT = new Product();
053    
054        /** sumLog */
055        private static final UnivariateStatistic SUM_OF_LOGS = new SumOfLogs();
056    
057        /** min */
058        private static final UnivariateStatistic MIN = new Min();
059    
060        /** max */
061        private static final UnivariateStatistic MAX = new Max();
062    
063        /** mean */
064        private static final UnivariateStatistic MEAN = new Mean();
065    
066        /** variance */
067        private static final Variance VARIANCE = new Variance();
068    
069        /** percentile */
070        private static final Percentile PERCENTILE = new Percentile();
071    
072        /** geometric mean */
073        private static final GeometricMean GEOMETRIC_MEAN = new GeometricMean();
074    
075        /**
076         * Private Constructor
077         */
078        private StatUtils() {
079        }
080    
081        /**
082         * Returns the sum of the values in the input array, or
083         * <code>Double.NaN</code> if the array is empty.
084         * <p>
085         * Throws <code>IllegalArgumentException</code> if the input array
086         * is null.</p>
087         *
088         * @param values  array of values to sum
089         * @return the sum of the values or <code>Double.NaN</code> if the array
090         * is empty
091         * @throws MathIllegalArgumentException if the array is null
092         */
093        public static double sum(final double[] values)
094        throws MathIllegalArgumentException {
095            return SUM.evaluate(values);
096        }
097    
098        /**
099         * Returns the sum of the entries in the specified portion of
100         * the input array, or <code>Double.NaN</code> if the designated subarray
101         * is empty.
102         * <p>
103         * Throws <code>IllegalArgumentException</code> if the array is null.</p>
104         *
105         * @param values the input array
106         * @param begin index of the first array element to include
107         * @param length the number of elements to include
108         * @return the sum of the values or Double.NaN if length = 0
109         * @throws MathIllegalArgumentException if the array is null or the array index
110         *  parameters are not valid
111         */
112        public static double sum(final double[] values, final int begin,
113                final int length) throws MathIllegalArgumentException {
114            return SUM.evaluate(values, begin, length);
115        }
116    
117        /**
118         * Returns the sum of the squares of the entries in the input array, or
119         * <code>Double.NaN</code> if the array is empty.
120         * <p>
121         * Throws <code>IllegalArgumentException</code> if the array is null.</p>
122         *
123         * @param values  input array
124         * @return the sum of the squared values or <code>Double.NaN</code> if the
125         * array is empty
126         * @throws MathIllegalArgumentException if the array is null
127         */
128        public static double sumSq(final double[] values) throws MathIllegalArgumentException {
129            return SUM_OF_SQUARES.evaluate(values);
130        }
131    
132        /**
133         * Returns the sum of the squares of the entries in the specified portion of
134         * the input array, or <code>Double.NaN</code> if the designated subarray
135         * is empty.
136         * <p>
137         * Throws <code>IllegalArgumentException</code> if the array is null.</p>
138         *
139         * @param values the input array
140         * @param begin index of the first array element to include
141         * @param length the number of elements to include
142         * @return the sum of the squares of the values or Double.NaN if length = 0
143         * @throws MathIllegalArgumentException if the array is null or the array index
144         * parameters are not valid
145         */
146        public static double sumSq(final double[] values, final int begin,
147                final int length) throws MathIllegalArgumentException {
148            return SUM_OF_SQUARES.evaluate(values, begin, length);
149        }
150    
151        /**
152         * Returns the product of the entries in the input array, or
153         * <code>Double.NaN</code> if the array is empty.
154         * <p>
155         * Throws <code>IllegalArgumentException</code> if the array is null.</p>
156         *
157         * @param values the input array
158         * @return the product of the values or Double.NaN if the array is empty
159         * @throws MathIllegalArgumentException if the array is null
160         */
161        public static double product(final double[] values)
162        throws MathIllegalArgumentException {
163            return PRODUCT.evaluate(values);
164        }
165    
166        /**
167         * Returns the product of the entries in the specified portion of
168         * the input array, or <code>Double.NaN</code> if the designated subarray
169         * is empty.
170         * <p>
171         * Throws <code>IllegalArgumentException</code> if the array is null.</p>
172         *
173         * @param values the input array
174         * @param begin index of the first array element to include
175         * @param length the number of elements to include
176         * @return the product of the values or Double.NaN if length = 0
177         * @throws MathIllegalArgumentException if the array is null or the array index
178         * parameters are not valid
179         */
180        public static double product(final double[] values, final int begin,
181                final int length) throws MathIllegalArgumentException {
182            return PRODUCT.evaluate(values, begin, length);
183        }
184    
185        /**
186         * Returns the sum of the natural logs of the entries in the input array, or
187         * <code>Double.NaN</code> if the array is empty.
188         * <p>
189         * Throws <code>IllegalArgumentException</code> if the array is null.</p>
190         * <p>
191         * See {@link org.apache.commons.math3.stat.descriptive.summary.SumOfLogs}.
192         * </p>
193         *
194         * @param values the input array
195         * @return the sum of the natural logs of the values or Double.NaN if
196         * the array is empty
197         * @throws MathIllegalArgumentException if the array is null
198         */
199        public static double sumLog(final double[] values)
200        throws MathIllegalArgumentException {
201            return SUM_OF_LOGS.evaluate(values);
202        }
203    
204        /**
205         * Returns the sum of the natural logs of the entries in the specified portion of
206         * the input array, or <code>Double.NaN</code> if the designated subarray
207         * is empty.
208         * <p>
209         * Throws <code>IllegalArgumentException</code> if the array is null.</p>
210         * <p>
211         * See {@link org.apache.commons.math3.stat.descriptive.summary.SumOfLogs}.
212         * </p>
213         *
214         * @param values the input array
215         * @param begin index of the first array element to include
216         * @param length the number of elements to include
217         * @return the sum of the natural logs of the values or Double.NaN if
218         * length = 0
219         * @throws MathIllegalArgumentException if the array is null or the array index
220         * parameters are not valid
221         */
222        public static double sumLog(final double[] values, final int begin,
223                final int length) throws MathIllegalArgumentException {
224            return SUM_OF_LOGS.evaluate(values, begin, length);
225        }
226    
227        /**
228         * Returns the arithmetic mean of the entries in the input array, or
229         * <code>Double.NaN</code> if the array is empty.
230         * <p>
231         * Throws <code>IllegalArgumentException</code> if the array is null.</p>
232         * <p>
233         * See {@link org.apache.commons.math3.stat.descriptive.moment.Mean} for
234         * details on the computing algorithm.</p>
235         *
236         * @param values the input array
237         * @return the mean of the values or Double.NaN if the array is empty
238         * @throws MathIllegalArgumentException if the array is null
239         */
240        public static double mean(final double[] values)
241        throws MathIllegalArgumentException {
242            return MEAN.evaluate(values);
243        }
244    
245        /**
246         * Returns the arithmetic mean of the entries in the specified portion of
247         * the input array, or <code>Double.NaN</code> if the designated subarray
248         * is empty.
249         * <p>
250         * Throws <code>IllegalArgumentException</code> if the array is null.</p>
251         * <p>
252         * See {@link org.apache.commons.math3.stat.descriptive.moment.Mean} for
253         * details on the computing algorithm.</p>
254         *
255         * @param values the input array
256         * @param begin index of the first array element to include
257         * @param length the number of elements to include
258         * @return the mean of the values or Double.NaN if length = 0
259         * @throws MathIllegalArgumentException if the array is null or the array index
260         * parameters are not valid
261         */
262        public static double mean(final double[] values, final int begin,
263                final int length) throws MathIllegalArgumentException {
264            return MEAN.evaluate(values, begin, length);
265        }
266    
267        /**
268         * Returns the geometric mean of the entries in the input array, or
269         * <code>Double.NaN</code> if the array is empty.
270         * <p>
271         * Throws <code>IllegalArgumentException</code> if the array is null.</p>
272         * <p>
273         * See {@link org.apache.commons.math3.stat.descriptive.moment.GeometricMean}
274         * for details on the computing algorithm.</p>
275         *
276         * @param values the input array
277         * @return the geometric mean of the values or Double.NaN if the array is empty
278         * @throws MathIllegalArgumentException if the array is null
279         */
280        public static double geometricMean(final double[] values)
281        throws MathIllegalArgumentException {
282            return GEOMETRIC_MEAN.evaluate(values);
283        }
284    
285        /**
286         * Returns the geometric mean of the entries in the specified portion of
287         * the input array, or <code>Double.NaN</code> if the designated subarray
288         * is empty.
289         * <p>
290         * Throws <code>IllegalArgumentException</code> if the array is null.</p>
291         * <p>
292         * See {@link org.apache.commons.math3.stat.descriptive.moment.GeometricMean}
293         * for details on the computing algorithm.</p>
294         *
295         * @param values the input array
296         * @param begin index of the first array element to include
297         * @param length the number of elements to include
298         * @return the geometric mean of the values or Double.NaN if length = 0
299         * @throws MathIllegalArgumentException if the array is null or the array index
300         * parameters are not valid
301         */
302        public static double geometricMean(final double[] values, final int begin,
303                final int length) throws MathIllegalArgumentException {
304            return GEOMETRIC_MEAN.evaluate(values, begin, length);
305        }
306    
307    
308        /**
309         * Returns the variance of the entries in the input array, or
310         * <code>Double.NaN</code> if the array is empty.
311         *
312         * <p>This method returns the bias-corrected sample variance (using {@code n - 1} in
313         * the denominator).  Use {@link #populationVariance(double[])} for the non-bias-corrected
314         * population variance.</p>
315         * <p>
316         * See {@link org.apache.commons.math3.stat.descriptive.moment.Variance} for
317         * details on the computing algorithm.</p>
318         * <p>
319         * Returns 0 for a single-value (i.e. length = 1) sample.</p>
320         * <p>
321         * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
322         *
323         * @param values the input array
324         * @return the variance of the values or Double.NaN if the array is empty
325         * @throws MathIllegalArgumentException if the array is null
326         */
327        public static double variance(final double[] values) throws MathIllegalArgumentException {
328            return VARIANCE.evaluate(values);
329        }
330    
331        /**
332         * Returns the variance of the entries in the specified portion of
333         * the input array, or <code>Double.NaN</code> if the designated subarray
334         * is empty.
335         *
336         * <p>This method returns the bias-corrected sample variance (using {@code n - 1} in
337         * the denominator).  Use {@link #populationVariance(double[], int, int)} for the non-bias-corrected
338         * population variance.</p>
339         * <p>
340         * See {@link org.apache.commons.math3.stat.descriptive.moment.Variance} for
341         * details on the computing algorithm.</p>
342         * <p>
343         * Returns 0 for a single-value (i.e. length = 1) sample.</p>
344         * <p>
345         * Throws <code>MathIllegalArgumentException</code> if the array is null or the
346         * array index parameters are not valid.</p>
347         *
348         * @param values the input array
349         * @param begin index of the first array element to include
350         * @param length the number of elements to include
351         * @return the variance of the values or Double.NaN if length = 0
352         * @throws MathIllegalArgumentException if the array is null or the array index
353         *  parameters are not valid
354         */
355        public static double variance(final double[] values, final int begin,
356                final int length) throws MathIllegalArgumentException {
357            return VARIANCE.evaluate(values, begin, length);
358        }
359    
360        /**
361         * Returns the variance of the entries in the specified portion of
362         * the input array, using the precomputed mean value.  Returns
363         * <code>Double.NaN</code> if the designated subarray is empty.
364         *
365         * <p>This method returns the bias-corrected sample variance (using {@code n - 1} in
366         * the denominator).  Use {@link #populationVariance(double[], double, int, int)} for the non-bias-corrected
367         * population variance.</p>
368         * <p>
369         * See {@link org.apache.commons.math3.stat.descriptive.moment.Variance} for
370         * details on the computing algorithm.</p>
371         * <p>
372         * The formula used assumes that the supplied mean value is the arithmetic
373         * mean of the sample data, not a known population parameter.  This method
374         * is supplied only to save computation when the mean has already been
375         * computed.</p>
376         * <p>
377         * Returns 0 for a single-value (i.e. length = 1) sample.</p>
378         * <p>
379         * Throws <code>MathIllegalArgumentException</code> if the array is null or the
380         * array index parameters are not valid.</p>
381         *
382         * @param values the input array
383         * @param mean the precomputed mean value
384         * @param begin index of the first array element to include
385         * @param length the number of elements to include
386         * @return the variance of the values or Double.NaN if length = 0
387         * @throws MathIllegalArgumentException if the array is null or the array index
388         *  parameters are not valid
389         */
390        public static double variance(final double[] values, final double mean,
391                final int begin, final int length) throws MathIllegalArgumentException {
392            return VARIANCE.evaluate(values, mean, begin, length);
393        }
394    
395        /**
396         * Returns the variance of the entries in the input array, using the
397         * precomputed mean value.  Returns <code>Double.NaN</code> if the array
398         * is empty.
399         *
400         * <p>This method returns the bias-corrected sample variance (using {@code n - 1} in
401         * the denominator).  Use {@link #populationVariance(double[], double)} for the non-bias-corrected
402         * population variance.</p>
403         * <p>
404         * See {@link org.apache.commons.math3.stat.descriptive.moment.Variance} for
405         * details on the computing algorithm.</p>
406         * <p>
407         * The formula used assumes that the supplied mean value is the arithmetic
408         * mean of the sample data, not a known population parameter.  This method
409         * is supplied only to save computation when the mean has already been
410         * computed.</p>
411         * <p>
412         * Returns 0 for a single-value (i.e. length = 1) sample.</p>
413         * <p>
414         * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
415         *
416         * @param values the input array
417         * @param mean the precomputed mean value
418         * @return the variance of the values or Double.NaN if the array is empty
419         * @throws MathIllegalArgumentException if the array is null
420         */
421        public static double variance(final double[] values, final double mean)
422        throws MathIllegalArgumentException {
423            return VARIANCE.evaluate(values, mean);
424        }
425    
426        /**
427         * Returns the <a href="http://en.wikibooks.org/wiki/Statistics/Summary/Variance">
428         * population variance</a> of the entries in the input array, or
429         * <code>Double.NaN</code> if the array is empty.
430         * <p>
431         * See {@link org.apache.commons.math3.stat.descriptive.moment.Variance} for
432         * details on the formula and computing algorithm.</p>
433         * <p>
434         * Returns 0 for a single-value (i.e. length = 1) sample.</p>
435         * <p>
436         * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
437         *
438         * @param values the input array
439         * @return the population variance of the values or Double.NaN if the array is empty
440         * @throws MathIllegalArgumentException if the array is null
441         */
442        public static double populationVariance(final double[] values)
443        throws MathIllegalArgumentException {
444            return new Variance(false).evaluate(values);
445        }
446    
447        /**
448         * Returns the <a href="http://en.wikibooks.org/wiki/Statistics/Summary/Variance">
449         * population variance</a> of the entries in the specified portion of
450         * the input array, or <code>Double.NaN</code> if the designated subarray
451         * is empty.
452         * <p>
453         * See {@link org.apache.commons.math3.stat.descriptive.moment.Variance} for
454         * details on the computing algorithm.</p>
455         * <p>
456         * Returns 0 for a single-value (i.e. length = 1) sample.</p>
457         * <p>
458         * Throws <code>MathIllegalArgumentException</code> if the array is null or the
459         * array index parameters are not valid.</p>
460         *
461         * @param values the input array
462         * @param begin index of the first array element to include
463         * @param length the number of elements to include
464         * @return the population variance of the values or Double.NaN if length = 0
465         * @throws MathIllegalArgumentException if the array is null or the array index
466         *  parameters are not valid
467         */
468        public static double populationVariance(final double[] values, final int begin,
469                final int length) throws MathIllegalArgumentException {
470            return new Variance(false).evaluate(values, begin, length);
471        }
472    
473        /**
474         * Returns the <a href="http://en.wikibooks.org/wiki/Statistics/Summary/Variance">
475         * population variance</a> of the entries in the specified portion of
476         * the input array, using the precomputed mean value.  Returns
477         * <code>Double.NaN</code> if the designated subarray is empty.
478         * <p>
479         * See {@link org.apache.commons.math3.stat.descriptive.moment.Variance} for
480         * details on the computing algorithm.</p>
481         * <p>
482         * The formula used assumes that the supplied mean value is the arithmetic
483         * mean of the sample data, not a known population parameter.  This method
484         * is supplied only to save computation when the mean has already been
485         * computed.</p>
486         * <p>
487         * Returns 0 for a single-value (i.e. length = 1) sample.</p>
488         * <p>
489         * Throws <code>MathIllegalArgumentException</code> if the array is null or the
490         * array index parameters are not valid.</p>
491         *
492         * @param values the input array
493         * @param mean the precomputed mean value
494         * @param begin index of the first array element to include
495         * @param length the number of elements to include
496         * @return the population variance of the values or Double.NaN if length = 0
497         * @throws MathIllegalArgumentException if the array is null or the array index
498         *  parameters are not valid
499         */
500        public static double populationVariance(final double[] values, final double mean,
501                final int begin, final int length) throws MathIllegalArgumentException {
502            return new Variance(false).evaluate(values, mean, begin, length);
503        }
504    
505        /**
506         * Returns the <a href="http://en.wikibooks.org/wiki/Statistics/Summary/Variance">
507         * population variance</a> of the entries in the input array, using the
508         * precomputed mean value.  Returns <code>Double.NaN</code> if the array
509         * is empty.
510         * <p>
511         * See {@link org.apache.commons.math3.stat.descriptive.moment.Variance} for
512         * details on the computing algorithm.</p>
513         * <p>
514         * The formula used assumes that the supplied mean value is the arithmetic
515         * mean of the sample data, not a known population parameter.  This method
516         * is supplied only to save computation when the mean has already been
517         * computed.</p>
518         * <p>
519         * Returns 0 for a single-value (i.e. length = 1) sample.</p>
520         * <p>
521         * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
522         *
523         * @param values the input array
524         * @param mean the precomputed mean value
525         * @return the population variance of the values or Double.NaN if the array is empty
526         * @throws MathIllegalArgumentException if the array is null
527         */
528        public static double populationVariance(final double[] values, final double mean)
529        throws MathIllegalArgumentException {
530            return new Variance(false).evaluate(values, mean);
531        }
532    
533        /**
534         * Returns the maximum of the entries in the input array, or
535         * <code>Double.NaN</code> if the array is empty.
536         * <p>
537         * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
538         * <p>
539         * <ul>
540         * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
541         * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
542         * <li>If any of the values equals <code>Double.POSITIVE_INFINITY</code>,
543         * the result is <code>Double.POSITIVE_INFINITY.</code></li>
544         * </ul></p>
545         *
546         * @param values the input array
547         * @return the maximum of the values or Double.NaN if the array is empty
548         * @throws MathIllegalArgumentException if the array is null
549         */
550        public static double max(final double[] values) throws MathIllegalArgumentException {
551            return MAX.evaluate(values);
552        }
553    
554        /**
555         * Returns the maximum of the entries in the specified portion of
556         * the input array, or <code>Double.NaN</code> if the designated subarray
557         * is empty.
558         * <p>
559         * Throws <code>MathIllegalArgumentException</code> if the array is null or
560         * the array index parameters are not valid.</p>
561         * <p>
562         * <ul>
563         * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
564         * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
565         * <li>If any of the values equals <code>Double.POSITIVE_INFINITY</code>,
566         * the result is <code>Double.POSITIVE_INFINITY.</code></li>
567         * </ul></p>
568         *
569         * @param values the input array
570         * @param begin index of the first array element to include
571         * @param length the number of elements to include
572         * @return the maximum of the values or Double.NaN if length = 0
573         * @throws MathIllegalArgumentException if the array is null or the array index
574         * parameters are not valid
575         */
576        public static double max(final double[] values, final int begin,
577                final int length) throws MathIllegalArgumentException {
578            return MAX.evaluate(values, begin, length);
579        }
580    
581         /**
582         * Returns the minimum of the entries in the input array, or
583         * <code>Double.NaN</code> if the array is empty.
584         * <p>
585         * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
586         * <p>
587         * <ul>
588         * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
589         * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
590         * <li>If any of the values equals <code>Double.NEGATIVE_INFINITY</code>,
591         * the result is <code>Double.NEGATIVE_INFINITY.</code></li>
592         * </ul> </p>
593         *
594         * @param values the input array
595         * @return the minimum of the values or Double.NaN if the array is empty
596         * @throws MathIllegalArgumentException if the array is null
597         */
598        public static double min(final double[] values) throws MathIllegalArgumentException {
599            return MIN.evaluate(values);
600        }
601    
602         /**
603         * Returns the minimum of the entries in the specified portion of
604         * the input array, or <code>Double.NaN</code> if the designated subarray
605         * is empty.
606         * <p>
607         * Throws <code>MathIllegalArgumentException</code> if the array is null or
608         * the array index parameters are not valid.</p>
609         * <p>
610         * <ul>
611         * <li>The result is <code>NaN</code> iff all values are <code>NaN</code>
612         * (i.e. <code>NaN</code> values have no impact on the value of the statistic).</li>
613         * <li>If any of the values equals <code>Double.NEGATIVE_INFINITY</code>,
614         * the result is <code>Double.NEGATIVE_INFINITY.</code></li>
615         * </ul></p>
616         *
617         * @param values the input array
618         * @param begin index of the first array element to include
619         * @param length the number of elements to include
620         * @return the minimum of the values or Double.NaN if length = 0
621         * @throws MathIllegalArgumentException if the array is null or the array index
622         * parameters are not valid
623         */
624        public static double min(final double[] values, final int begin,
625                final int length) throws MathIllegalArgumentException {
626            return MIN.evaluate(values, begin, length);
627        }
628    
629        /**
630         * Returns an estimate of the <code>p</code>th percentile of the values
631         * in the <code>values</code> array.
632         * <p>
633         * <ul>
634         * <li>Returns <code>Double.NaN</code> if <code>values</code> has length
635         * <code>0</code></li></p>
636         * <li>Returns (for any value of <code>p</code>) <code>values[0]</code>
637         *  if <code>values</code> has length <code>1</code></li>
638         * <li>Throws <code>IllegalArgumentException</code> if <code>values</code>
639         * is null  or p is not a valid quantile value (p must be greater than 0
640         * and less than or equal to 100)</li>
641         * </ul></p>
642         * <p>
643         * See {@link org.apache.commons.math3.stat.descriptive.rank.Percentile} for
644         * a description of the percentile estimation algorithm used.</p>
645         *
646         * @param values input array of values
647         * @param p the percentile value to compute
648         * @return the percentile value or Double.NaN if the array is empty
649         * @throws MathIllegalArgumentException if <code>values</code> is null
650         * or p is invalid
651         */
652        public static double percentile(final double[] values, final double p)
653        throws MathIllegalArgumentException {
654                return PERCENTILE.evaluate(values,p);
655        }
656    
657         /**
658         * Returns an estimate of the <code>p</code>th percentile of the values
659         * in the <code>values</code> array, starting with the element in (0-based)
660         * position <code>begin</code> in the array and including <code>length</code>
661         * values.
662         * <p>
663         * <ul>
664         * <li>Returns <code>Double.NaN</code> if <code>length = 0</code></li>
665         * <li>Returns (for any value of <code>p</code>) <code>values[begin]</code>
666         *  if <code>length = 1 </code></li>
667         * <li>Throws <code>MathIllegalArgumentException</code> if <code>values</code>
668         *  is null , <code>begin</code> or <code>length</code> is invalid, or
669         * <code>p</code> is not a valid quantile value (p must be greater than 0
670         * and less than or equal to 100)</li>
671         * </ul></p>
672         * <p>
673         * See {@link org.apache.commons.math3.stat.descriptive.rank.Percentile} for
674         * a description of the percentile estimation algorithm used.</p>
675         *
676         * @param values array of input values
677         * @param p  the percentile to compute
678         * @param begin  the first (0-based) element to include in the computation
679         * @param length  the number of array elements to include
680         * @return  the percentile value
681         * @throws MathIllegalArgumentException if the parameters are not valid or the
682         * input array is null
683         */
684        public static double percentile(final double[] values, final int begin,
685                final int length, final double p) throws MathIllegalArgumentException {
686            return PERCENTILE.evaluate(values, begin, length, p);
687        }
688    
689        /**
690         * Returns the sum of the (signed) differences between corresponding elements of the
691         * input arrays -- i.e., sum(sample1[i] - sample2[i]).
692         *
693         * @param sample1  the first array
694         * @param sample2  the second array
695         * @return sum of paired differences
696         * @throws DimensionMismatchException if the arrays do not have the same
697         * (positive) length.
698         * @throws NoDataException if the sample arrays are empty.
699         */
700        public static double sumDifference(final double[] sample1, final double[] sample2)
701        throws DimensionMismatchException, NoDataException {
702            int n = sample1.length;
703            if (n != sample2.length) {
704                throw new DimensionMismatchException(n, sample2.length);
705            }
706            if (n <= 0) {
707                throw new NoDataException(LocalizedFormats.INSUFFICIENT_DIMENSION);
708            }
709            double result = 0;
710            for (int i = 0; i < n; i++) {
711                result += sample1[i] - sample2[i];
712            }
713            return result;
714        }
715    
716        /**
717         * Returns the mean of the (signed) differences between corresponding elements of the
718         * input arrays -- i.e., sum(sample1[i] - sample2[i]) / sample1.length.
719         *
720         * @param sample1  the first array
721         * @param sample2  the second array
722         * @return mean of paired differences
723         * @throws DimensionMismatchException if the arrays do not have the same
724         * (positive) length.
725         * @throws NoDataException if the sample arrays are empty.
726         */
727        public static double meanDifference(final double[] sample1, final double[] sample2)
728        throws DimensionMismatchException, NoDataException{
729            return sumDifference(sample1, sample2) / sample1.length;
730        }
731    
732        /**
733         * Returns the variance of the (signed) differences between corresponding elements of the
734         * input arrays -- i.e., var(sample1[i] - sample2[i]).
735         *
736         * @param sample1  the first array
737         * @param sample2  the second array
738         * @param meanDifference   the mean difference between corresponding entries
739         * @see #meanDifference(double[],double[])
740         * @return variance of paired differences
741         * @throws DimensionMismatchException if the arrays do not have the same
742         * length.
743         * @throws NumberIsTooSmallException if the arrays length is less than 2.
744         */
745        public static double varianceDifference(final double[] sample1,
746                final double[] sample2, double meanDifference) throws DimensionMismatchException,
747                NumberIsTooSmallException {
748            double sum1 = 0d;
749            double sum2 = 0d;
750            double diff = 0d;
751            int n = sample1.length;
752            if (n != sample2.length) {
753                throw new DimensionMismatchException(n, sample2.length);
754            }
755            if (n < 2) {
756                throw new NumberIsTooSmallException(n, 2, true);
757            }
758            for (int i = 0; i < n; i++) {
759                diff = sample1[i] - sample2[i];
760                sum1 += (diff - meanDifference) *(diff - meanDifference);
761                sum2 += diff - meanDifference;
762            }
763            return (sum1 - (sum2 * sum2 / n)) / (n - 1);
764        }
765    
766        /**
767         * Normalize (standardize) the sample, so it is has a mean of 0 and a standard deviation of 1.
768         *
769         * @param sample Sample to normalize.
770         * @return normalized (standardized) sample.
771         * @since 2.2
772         */
773        public static double[] normalize(final double[] sample) {
774            DescriptiveStatistics stats = new DescriptiveStatistics();
775    
776            // Add the data from the series to stats
777            for (int i = 0; i < sample.length; i++) {
778                stats.addValue(sample[i]);
779            }
780    
781            // Compute mean and standard deviation
782            double mean = stats.getMean();
783            double standardDeviation = stats.getStandardDeviation();
784    
785            // initialize the standardizedSample, which has the same length as the sample
786            double[] standardizedSample = new double[sample.length];
787    
788            for (int i = 0; i < sample.length; i++) {
789                // z = (x- mean)/standardDeviation
790                standardizedSample[i] = (sample[i] - mean) / standardDeviation;
791            }
792            return standardizedSample;
793        }
794    }