    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.descriptive.moment;
    018
    019    import java.io.Serializable;
    020
    021    import org.apache.commons.math3.exception.MathIllegalArgumentException;
    022    import org.apache.commons.math3.exception.NullArgumentException;
    023    import org.apache.commons.math3.stat.descriptive.AbstractStorelessUnivariateStatistic;
    024    import org.apache.commons.math3.util.FastMath;
    025    import org.apache.commons.math3.util.MathUtils;
    026
    027    /**
    028     * Computes the sample standard deviation.  The standard deviation
    029     * is the positive square root of the variance.  This implementation wraps a
    030     * {@link Variance} instance.  The <code>isBiasCorrected</code> property of the
    031     * wrapped Variance instance is exposed, so that this class can be used to
    032     * compute both the "sample standard deviation" (the square root of the
    033     * bias-corrected "sample variance") or the "population standard deviation"
    034     * (the square root of the non-bias-corrected "population variance"). See
    035     * {@link Variance} for more information.
    036     * <p>
    037     * <strong>Note that this implementation is not synchronized.</strong> If
    038     * multiple threads access an instance of this class concurrently, and at least
    039     * one of the threads invokes the <code>increment()</code> or
    040     * <code>clear()</code> method, it must be synchronized externally.</p>
    041     *
    042     * @version $Id: StandardDeviation.java 1416643 2012-12-03 19:37:14Z tn $
    043     */
    044    public class StandardDeviation extends AbstractStorelessUnivariateStatistic
    045        implements Serializable {
    046
    047        /** Serializable version identifier */
    048        private static final long serialVersionUID = 5728716329662425188L;
    049
    050        /** Wrapped Variance instance */
    051        private Variance variance = null;
    052
    053        /**
    054         * Constructs a StandardDeviation.  Sets the underlying {@link Variance}
    055         * instance's <code>isBiasCorrected</code> property to true.
    056         */
    057        public StandardDeviation() {
    058            variance = new Variance();
    059        }
    060
    061        /**
    062         * Constructs a StandardDeviation from an external second moment.
    063         *
    064         * @param m2 the external moment
    065         */
    066        public StandardDeviation(final SecondMoment m2) {
    067            variance = new Variance(m2);
    068        }
    069
    070        /**
    071         * Copy constructor, creates a new {@code StandardDeviation} identical
    072         * to the {@code original}
    073         *
    074         * @param original the {@code StandardDeviation} instance to copy
    075         * @throws NullArgumentException if original is null
    076         */
    077        public StandardDeviation(StandardDeviation original) throws NullArgumentException {
    078            copy(original, this);
    079        }
    080
    081        /**
    082         * Contructs a StandardDeviation with the specified value for the
    083         * <code>isBiasCorrected</code> property.  If this property is set to
    084         * <code>true</code>, the {@link Variance} used in computing results will
    085         * use the bias-corrected, or "sample" formula.  See {@link Variance} for
    086         * details.
    087         *
    088         * @param isBiasCorrected  whether or not the variance computation will use
    089         * the bias-corrected formula
    090         */
    091        public StandardDeviation(boolean isBiasCorrected) {
    092            variance = new Variance(isBiasCorrected);
    093        }
    094
    095        /**
    096         * Contructs a StandardDeviation with the specified value for the
    097         * <code>isBiasCorrected</code> property and the supplied external moment.
    098         * If <code>isBiasCorrected</code> is set to <code>true</code>, the
    099         * {@link Variance} used in computing results will use the bias-corrected,
    100         * or "sample" formula.  See {@link Variance} for details.
    101         *
    102         * @param isBiasCorrected  whether or not the variance computation will use
    103         * the bias-corrected formula
    104          * @param m2 the external moment
    105         */
    106        public StandardDeviation(boolean isBiasCorrected, SecondMoment m2) {
    107            variance = new Variance(isBiasCorrected, m2);
    108        }
    109
    110        /**
    111         * {@inheritDoc}
    112         */
    113        @Override
    114        public void increment(final double d) {
    115            variance.increment(d);
    116        }
    117
    118        /**
    119         * {@inheritDoc}
    120         */
    121        public long getN() {
    122            return variance.getN();
    123        }
    124
    125        /**
    126         * {@inheritDoc}
    127         */
    128        @Override
    129        public double getResult() {
    130            return FastMath.sqrt(variance.getResult());
    131        }
    132
    133        /**
    134         * {@inheritDoc}
    135         */
    136        @Override
    137        public void clear() {
    138            variance.clear();
    139        }
    140
    141        /**
    142         * Returns the Standard Deviation of the entries in the input array, or
    143         * <code>Double.NaN</code> if the array is empty.
    144         * <p>
    145         * Returns 0 for a single-value (i.e. length = 1) sample.</p>
    146         * <p>
    147         * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
    148         * <p>
    149         * Does not change the internal state of the statistic.</p>
    150         *
    151         * @param values the input array
    152         * @return the standard deviation of the values or Double.NaN if length = 0
    153         * @throws MathIllegalArgumentException if the array is null
    154         */
    155        @Override
    156        public double evaluate(final double[] values) throws MathIllegalArgumentException  {
    157            return FastMath.sqrt(variance.evaluate(values));
    158        }
    159
    160        /**
    161         * Returns the Standard Deviation of the entries in the specified portion of
    162         * the input array, or <code>Double.NaN</code> if the designated subarray
    163         * is empty.
    164         * <p>
    165         * Returns 0 for a single-value (i.e. length = 1) sample. </p>
    166         * <p>
    167         * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
    168         * <p>
    169         * Does not change the internal state of the statistic.</p>
    170         *
    171         * @param values the input array
    172         * @param begin index of the first array element to include
    173         * @param length the number of elements to include
    174         * @return the standard deviation of the values or Double.NaN if length = 0
    175         * @throws MathIllegalArgumentException if the array is null or the array index
    176         *  parameters are not valid
    177         */
    178        @Override
    179        public double evaluate(final double[] values, final int begin, final int length)
    180        throws MathIllegalArgumentException  {
    181           return FastMath.sqrt(variance.evaluate(values, begin, length));
    182        }
    183
    184        /**
    185         * Returns the Standard Deviation of the entries in the specified portion of
    186         * the input array, using the precomputed mean value.  Returns
    187         * <code>Double.NaN</code> if the designated subarray is empty.
    188         * <p>
    189         * Returns 0 for a single-value (i.e. length = 1) sample.</p>
    190         * <p>
    191         * The formula used assumes that the supplied mean value is the arithmetic
    192         * mean of the sample data, not a known population parameter.  This method
    193         * is supplied only to save computation when the mean has already been
    194         * computed.</p>
    195         * <p>
    196         * Throws <code>IllegalArgumentException</code> if the array is null.</p>
    197         * <p>
    198         * Does not change the internal state of the statistic.</p>
    199         *
    200         * @param values the input array
    201         * @param mean the precomputed mean value
    202         * @param begin index of the first array element to include
    203         * @param length the number of elements to include
    204         * @return the standard deviation of the values or Double.NaN if length = 0
    205         * @throws MathIllegalArgumentException if the array is null or the array index
    206         *  parameters are not valid
    207         */
    208        public double evaluate(final double[] values, final double mean,
    209                final int begin, final int length) throws MathIllegalArgumentException  {
    210            return FastMath.sqrt(variance.evaluate(values, mean, begin, length));
    211        }
    212
    213        /**
    214         * Returns the Standard Deviation of the entries in the input array, using
    215         * the precomputed mean value.  Returns
    216         * <code>Double.NaN</code> if the designated subarray is empty.
    217         * <p>
    218         * Returns 0 for a single-value (i.e. length = 1) sample.</p>
    219         * <p>
    220         * The formula used assumes that the supplied mean value is the arithmetic
    221         * mean of the sample data, not a known population parameter.  This method
    222         * is supplied only to save computation when the mean has already been
    223         * computed.</p>
    224         * <p>
    225         * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
    226         * <p>
    227         * Does not change the internal state of the statistic.</p>
    228         *
    229         * @param values the input array
    230         * @param mean the precomputed mean value
    231         * @return the standard deviation of the values or Double.NaN if length = 0
    232         * @throws MathIllegalArgumentException if the array is null
    233         */
    234        public double evaluate(final double[] values, final double mean)
    235        throws MathIllegalArgumentException  {
    236            return FastMath.sqrt(variance.evaluate(values, mean));
    237        }
    238
    239        /**
    240         * @return Returns the isBiasCorrected.
    241         */
    242        public boolean isBiasCorrected() {
    243            return variance.isBiasCorrected();
    244        }
    245
    246        /**
    247         * @param isBiasCorrected The isBiasCorrected to set.
    248         */
    249        public void setBiasCorrected(boolean isBiasCorrected) {
    250            variance.setBiasCorrected(isBiasCorrected);
    251        }
    252
    253        /**
    254         * {@inheritDoc}
    255         */
    256        @Override
    257        public StandardDeviation copy() {
    258            StandardDeviation result = new StandardDeviation();
    259            // No try-catch or advertised exception because args are guaranteed non-null
    260            copy(this, result);
    261            return result;
    262        }
    263
    264
    265        /**
    266         * Copies source to dest.
    267         * <p>Neither source nor dest can be null.</p>
    268         *
    269         * @param source StandardDeviation to copy
    270         * @param dest StandardDeviation to copy to
    271         * @throws NullArgumentException if either source or dest is null
    272         */
    273        public static void copy(StandardDeviation source, StandardDeviation dest)
    274            throws NullArgumentException {
    275            MathUtils.checkNotNull(source);
    276            MathUtils.checkNotNull(dest);
    277            dest.setData(source.getDataRef());
    278            dest.variance = source.variance.copy();
    279        }
    280
    281    }