    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    }