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 }