View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.math4.legacy.stat.descriptive.moment;
18  
19  import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
20  import org.apache.commons.math4.legacy.exception.NullArgumentException;
21  import org.apache.commons.math4.legacy.stat.descriptive.AbstractStorelessUnivariateStatistic;
22  import org.apache.commons.math4.core.jdkmath.JdkMath;
23  
24  /**
25   * Computes the sample standard deviation.  The standard deviation
26   * is the positive square root of the variance.  This implementation wraps a
27   * {@link Variance} instance.  The <code>isBiasCorrected</code> property of the
28   * wrapped Variance instance is exposed, so that this class can be used to
29   * compute both the "sample standard deviation" (the square root of the
30   * bias-corrected "sample variance") or the "population standard deviation"
31   * (the square root of the non-bias-corrected "population variance"). See
32   * {@link Variance} for more information.
33   * <p>
34   * <strong>Note that this implementation is not synchronized.</strong> If
35   * multiple threads access an instance of this class concurrently, and at least
36   * one of the threads invokes the <code>increment()</code> or
37   * <code>clear()</code> method, it must be synchronized externally.</p>
38   */
39  public class StandardDeviation extends AbstractStorelessUnivariateStatistic {
40      /** Wrapped Variance instance. */
41      private Variance variance;
42  
43      /**
44       * Constructs a StandardDeviation.  Sets the underlying {@link Variance}
45       * instance's <code>isBiasCorrected</code> property to true.
46       */
47      public StandardDeviation() {
48          variance = new Variance();
49      }
50  
51      /**
52       * Constructs a StandardDeviation from an external second moment.
53       *
54       * @param m2 the external moment
55       */
56      public StandardDeviation(final SecondMoment m2) {
57          variance = new Variance(m2);
58      }
59  
60      /**
61       * Copy constructor, creates a new {@code StandardDeviation} identical
62       * to the {@code original}.
63       *
64       * @param original the {@code StandardDeviation} instance to copy
65       * @throws NullArgumentException if original is null
66       */
67      public StandardDeviation(StandardDeviation original) throws NullArgumentException {
68          copy(original, this);
69      }
70  
71      /**
72       * Constructs a StandardDeviation with the specified value for the
73       * <code>isBiasCorrected</code> property.  If this property is set to
74       * <code>true</code>, the {@link Variance} used in computing results will
75       * use the bias-corrected, or "sample" formula.  See {@link Variance} for
76       * details.
77       *
78       * @param isBiasCorrected  whether or not the variance computation will use
79       * the bias-corrected formula
80       */
81      public StandardDeviation(boolean isBiasCorrected) {
82          variance = new Variance(isBiasCorrected);
83      }
84  
85      /**
86       * Constructs a StandardDeviation with the specified value for the
87       * <code>isBiasCorrected</code> property and the supplied external moment.
88       * If <code>isBiasCorrected</code> is set to <code>true</code>, the
89       * {@link Variance} used in computing results will use the bias-corrected,
90       * or "sample" formula.  See {@link Variance} for details.
91       *
92       * @param isBiasCorrected  whether or not the variance computation will use
93       * the bias-corrected formula
94        * @param m2 the external moment
95       */
96      public StandardDeviation(boolean isBiasCorrected, SecondMoment m2) {
97          variance = new Variance(isBiasCorrected, m2);
98      }
99  
100     /**
101      * {@inheritDoc}
102      */
103     @Override
104     public void increment(final double d) {
105         variance.increment(d);
106     }
107 
108     /**
109      * {@inheritDoc}
110      */
111     @Override
112     public long getN() {
113         return variance.getN();
114     }
115 
116     /**
117      * {@inheritDoc}
118      */
119     @Override
120     public double getResult() {
121         return JdkMath.sqrt(variance.getResult());
122     }
123 
124     /**
125      * {@inheritDoc}
126      */
127     @Override
128     public void clear() {
129         variance.clear();
130     }
131 
132     /**
133      * Returns the Standard Deviation of the entries in the input array, or
134      * <code>Double.NaN</code> if the array is empty.
135      * <p>
136      * Returns 0 for a single-value (i.e. length = 1) sample.</p>
137      * <p>
138      * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
139      * <p>
140      * Does not change the internal state of the statistic.</p>
141      *
142      * @param values the input array
143      * @return the standard deviation of the values or Double.NaN if length = 0
144      * @throws MathIllegalArgumentException if the array is null
145      */
146     @Override
147     public double evaluate(final double[] values) throws MathIllegalArgumentException  {
148         return JdkMath.sqrt(variance.evaluate(values));
149     }
150 
151     /**
152      * Returns the Standard Deviation of the entries in the specified portion of
153      * the input array, or <code>Double.NaN</code> if the designated subarray
154      * is empty.
155      * <p>
156      * Returns 0 for a single-value (i.e. length = 1) sample. </p>
157      * <p>
158      * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
159      * <p>
160      * Does not change the internal state of the statistic.</p>
161      *
162      * @param values the input array
163      * @param begin index of the first array element to include
164      * @param length the number of elements to include
165      * @return the standard deviation of the values or Double.NaN if length = 0
166      * @throws MathIllegalArgumentException if the array is null or the array index
167      *  parameters are not valid
168      */
169     @Override
170     public double evaluate(final double[] values, final int begin, final int length)
171         throws MathIllegalArgumentException  {
172         return JdkMath.sqrt(variance.evaluate(values, begin, length));
173     }
174 
175     /**
176      * Returns the Standard Deviation of the entries in the specified portion of
177      * the input array, using the precomputed mean value.  Returns
178      * <code>Double.NaN</code> if the designated subarray is empty.
179      * <p>
180      * Returns 0 for a single-value (i.e. length = 1) sample.</p>
181      * <p>
182      * The formula used assumes that the supplied mean value is the arithmetic
183      * mean of the sample data, not a known population parameter.  This method
184      * is supplied only to save computation when the mean has already been
185      * computed.</p>
186      * <p>
187      * Throws <code>IllegalArgumentException</code> if the array is null.</p>
188      * <p>
189      * Does not change the internal state of the statistic.</p>
190      *
191      * @param values the input array
192      * @param mean the precomputed mean value
193      * @param begin index of the first array element to include
194      * @param length the number of elements to include
195      * @return the standard deviation of the values or Double.NaN if length = 0
196      * @throws MathIllegalArgumentException if the array is null or the array index
197      *  parameters are not valid
198      */
199     public double evaluate(final double[] values, final double mean,
200                            final int begin, final int length) throws MathIllegalArgumentException  {
201         return JdkMath.sqrt(variance.evaluate(values, mean, begin, length));
202     }
203 
204     /**
205      * Returns the Standard Deviation of the entries in the input array, using
206      * the precomputed mean value.  Returns
207      * <code>Double.NaN</code> if the designated subarray is empty.
208      * <p>
209      * Returns 0 for a single-value (i.e. length = 1) sample.</p>
210      * <p>
211      * The formula used assumes that the supplied mean value is the arithmetic
212      * mean of the sample data, not a known population parameter.  This method
213      * is supplied only to save computation when the mean has already been
214      * computed.</p>
215      * <p>
216      * Throws <code>MathIllegalArgumentException</code> if the array is null.</p>
217      * <p>
218      * Does not change the internal state of the statistic.</p>
219      *
220      * @param values the input array
221      * @param mean the precomputed mean value
222      * @return the standard deviation of the values or Double.NaN if length = 0
223      * @throws MathIllegalArgumentException if the array is null
224      */
225     public double evaluate(final double[] values, final double mean)
226         throws MathIllegalArgumentException  {
227         return JdkMath.sqrt(variance.evaluate(values, mean));
228     }
229 
230     /**
231      * @return Returns the isBiasCorrected.
232      */
233     public boolean isBiasCorrected() {
234         return variance.isBiasCorrected();
235     }
236 
237     /**
238      * @param isBiasCorrected The isBiasCorrected to set.
239      */
240     public void setBiasCorrected(boolean isBiasCorrected) {
241         variance.setBiasCorrected(isBiasCorrected);
242     }
243 
244     /**
245      * {@inheritDoc}
246      */
247     @Override
248     public StandardDeviation copy() {
249         StandardDeviation result = new StandardDeviation();
250         // No try-catch or advertised exception because args are guaranteed non-null
251         copy(this, result);
252         return result;
253     }
254 
255     /**
256      * Copies source to dest.
257      * <p>Neither source nor dest can be null.</p>
258      *
259      * @param source StandardDeviation to copy
260      * @param dest StandardDeviation to copy to
261      * @throws NullArgumentException if either source or dest is null
262      */
263     public static void copy(StandardDeviation source, StandardDeviation dest) throws NullArgumentException {
264         NullArgumentException.check(source);
265         NullArgumentException.check(dest);
266         dest.variance = source.variance.copy();
267     }
268 }