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 * https://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
18 /*
19 * This is not the original file distributed by the Apache Software Foundation
20 * It has been modified by the Hipparchus project
21 */
22 package org.hipparchus.stat.descriptive.moment;
23
24 import java.io.Serializable;
25
26 import org.hipparchus.exception.MathIllegalArgumentException;
27 import org.hipparchus.exception.NullArgumentException;
28 import org.hipparchus.stat.descriptive.AbstractStorelessUnivariateStatistic;
29 import org.hipparchus.util.FastMath;
30 import org.hipparchus.util.MathUtils;
31
32 /**
33 * Computes the sample standard deviation.
34 * <p>
35 * The standard deviation is the positive square root of the variance.
36 * This implementation wraps a {@link Variance} instance.
37 * <p>
38 * The <code>isBiasCorrected</code> property of the wrapped Variance
39 * instance is exposed, so that this class can be used to compute both
40 * the "sample standard deviation" (the square root of the bias-corrected
41 * "sample variance") or the "population standard deviation" (the square
42 * root of the non-bias-corrected "population variance").
43 * See {@link Variance} for more information.
44 * <p>
45 * <strong>Note that this implementation is not synchronized.</strong> If
46 * multiple threads access an instance of this class concurrently, and at least
47 * one of the threads invokes the <code>increment()</code> or
48 * <code>clear()</code> method, it must be synchronized externally.
49 */
50 public class StandardDeviation extends AbstractStorelessUnivariateStatistic
51 implements Serializable {
52
53 /** Serializable version identifier */
54 private static final long serialVersionUID = 20150412L;
55
56 /** Wrapped Variance instance */
57 private final Variance variance;
58
59 /**
60 * Constructs a StandardDeviation. Sets the underlying {@link Variance}
61 * instance's <code>isBiasCorrected</code> property to true.
62 */
63 public StandardDeviation() {
64 this(new Variance());
65 }
66
67 /**
68 * Constructs a StandardDeviation from an external second moment.
69 *
70 * @param m2 the external moment
71 */
72 public StandardDeviation(final SecondMoment m2) {
73 this(new Variance(m2));
74 }
75
76 /**
77 * Constructs a StandardDeviation with the specified value for the
78 * <code>isBiasCorrected</code> property. If this property is set to
79 * <code>true</code>, the {@link Variance} used in computing results will
80 * use the bias-corrected, or "sample" formula. See {@link Variance} for
81 * details.
82 *
83 * @param isBiasCorrected whether or not the variance computation will use
84 * the bias-corrected formula
85 */
86 public StandardDeviation(boolean isBiasCorrected) {
87 this(new Variance(isBiasCorrected));
88 }
89
90 /**
91 * Constructs a StandardDeviation with the specified value for the
92 * <code>isBiasCorrected</code> property and the supplied external moment.
93 * If <code>isBiasCorrected</code> is set to <code>true</code>, the
94 * {@link Variance} used in computing results will use the bias-corrected,
95 * or "sample" formula. See {@link Variance} for details.
96 *
97 * @param isBiasCorrected whether or not the variance computation will use
98 * the bias-corrected formula
99 * @param m2 the external moment
100 */
101 public StandardDeviation(boolean isBiasCorrected, SecondMoment m2) {
102 this(new Variance(isBiasCorrected, m2));
103 }
104
105 /**
106 * Create a new instance with the given variance.
107 * @param variance the variance to use
108 */
109 private StandardDeviation(Variance variance) {
110 this.variance = variance;
111 }
112
113 /**
114 * Copy constructor, creates a new {@code StandardDeviation} identical
115 * to the {@code original}.
116 *
117 * @param original the {@code StandardDeviation} instance to copy
118 * @throws NullArgumentException if original is null
119 */
120 public StandardDeviation(StandardDeviation original) throws NullArgumentException {
121 MathUtils.checkNotNull(original);
122 this.variance = original.variance.copy();
123 }
124
125 /** {@inheritDoc} */
126 @Override
127 public void increment(final double d) {
128 variance.increment(d);
129 }
130
131 /** {@inheritDoc} */
132 @Override
133 public long getN() {
134 return variance.getN();
135 }
136
137 /** {@inheritDoc} */
138 @Override
139 public double getResult() {
140 return FastMath.sqrt(variance.getResult());
141 }
142
143 /** {@inheritDoc} */
144 @Override
145 public void clear() {
146 variance.clear();
147 }
148
149 /**
150 * Returns the Standard Deviation of the entries in the specified portion of
151 * the input array, or <code>Double.NaN</code> if the designated subarray
152 * is empty.
153 * <p>
154 * Returns 0 for a single-value (i.e. length = 1) sample.
155 * <p>
156 * Does not change the internal state of the statistic.
157 *
158 * @param values the input array
159 * @param begin index of the first array element to include
160 * @param length the number of elements to include
161 * @return the standard deviation of the values or Double.NaN if length = 0
162 * @throws MathIllegalArgumentException if the array is null or the array index
163 * parameters are not valid
164 */
165 @Override
166 public double evaluate(final double[] values, final int begin, final int length)
167 throws MathIllegalArgumentException {
168 return FastMath.sqrt(variance.evaluate(values, begin, length));
169 }
170
171 /**
172 * Returns the Standard Deviation of the entries in the specified portion of
173 * the input array, using the precomputed mean value. Returns
174 * <code>Double.NaN</code> if the designated subarray is empty.
175 * <p>
176 * Returns 0 for a single-value (i.e. length = 1) sample.
177 * <p>
178 * The formula used assumes that the supplied mean value is the arithmetic
179 * mean of the sample data, not a known population parameter. This method
180 * is supplied only to save computation when the mean has already been
181 * computed.
182 * <p>
183 * Does not change the internal state of the statistic.
184 *
185 * @param values the input array
186 * @param mean the precomputed mean value
187 * @param begin index of the first array element to include
188 * @param length the number of elements to include
189 * @return the standard deviation of the values or Double.NaN if length = 0
190 * @throws MathIllegalArgumentException if the array is null or the array index
191 * parameters are not valid
192 */
193 public double evaluate(final double[] values, final double mean,
194 final int begin, final int length)
195 throws MathIllegalArgumentException {
196 return FastMath.sqrt(variance.evaluate(values, mean, begin, length));
197 }
198
199 /**
200 * Returns the Standard Deviation of the entries in the input array, using
201 * the precomputed mean value. Returns
202 * <code>Double.NaN</code> if the designated subarray is empty.
203 * <p>
204 * Returns 0 for a single-value (i.e. length = 1) sample.
205 * <p>
206 * The formula used assumes that the supplied mean value is the arithmetic
207 * mean of the sample data, not a known population parameter. This method
208 * is supplied only to save computation when the mean has already been
209 * computed.
210 * <p>
211 * Does not change the internal state of the statistic.
212 *
213 * @param values the input array
214 * @param mean the precomputed mean value
215 * @return the standard deviation of the values or Double.NaN if length = 0
216 * @throws MathIllegalArgumentException if the array is null
217 */
218 public double evaluate(final double[] values, final double mean)
219 throws MathIllegalArgumentException {
220 return FastMath.sqrt(variance.evaluate(values, mean));
221 }
222
223 /** Check if bias is corrected.
224 * @return Returns the isBiasCorrected.
225 */
226 public boolean isBiasCorrected() {
227 return variance.isBiasCorrected();
228 }
229
230 /**
231 * Returns a new copy of this standard deviation with the given
232 * bias correction setting.
233 *
234 * @param biasCorrection The bias correction flag to set.
235 * @return a copy of this instance with the given bias correction setting
236 */
237 public StandardDeviation withBiasCorrection(boolean biasCorrection) {
238 return new StandardDeviation(variance.withBiasCorrection(biasCorrection));
239 }
240
241 /** {@inheritDoc} */
242 @Override
243 public StandardDeviation copy() {
244 return new StandardDeviation(this);
245 }
246
247 }