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 }