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