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    *      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 }