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