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 }