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