KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > math > stat > descriptive > moment > Variance


1 /*
2  * Copyright 2003-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.math.stat.descriptive.moment;
17
18 import java.io.Serializable JavaDoc;
19
20 import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
21
22 /**
23  * Computes the variance of the available values. By default, the unbiased
24  * "sample variance" definitional formula is used:
25  * <p>
26  * variance = sum((x_i - mean)^2) / (n - 1)
27  * <p>
28  * where mean is the {@link Mean} and <code>n</code> is the number
29  * of sample observations.
30  * <p>
31  * The definitional formula does not have good numerical properties, so
32  * this implementation uses updating formulas based on West's algorithm
33  * as described in <a HREF="http://doi.acm.org/10.1145/359146.359152">
34  * Chan, T. F. andJ. G. Lewis 1979, <i>Communications of the ACM</i>,
35  * vol. 22 no. 9, pp. 526-531.</a>.
36  * <p>
37  * The "population variance" ( sum((x_i - mean)^2) / n ) can also
38  * be computed using this statistic. The <code>isBiasCorrected</code>
39  * property determines whether the "population" or "sample" value is
40  * returned by the <code>evaluate</code> and <code>getResult</code> methods.
41  * To compute population variances, set this property to <code>false.</code>
42  *
43  * <strong>Note that this implementation is not synchronized.</strong> If
44  * multiple threads access an instance of this class concurrently, and at least
45  * one of the threads invokes the <code>increment()</code> or
46  * <code>clear()</code> method, it must be synchronized externally.
47  *
48  * @version $Revision$ $Date: 2005-02-26 05:11:52 -0800 (Sat, 26 Feb 2005) $
49  */

50 public class Variance extends AbstractStorelessUnivariateStatistic implements Serializable JavaDoc {
51
52     /** Serializable version identifier */
53     static final long serialVersionUID = -9111962718267217978L;
54       
55     /** SecondMoment is used in incremental calculation of Variance*/
56     protected SecondMoment moment = null;
57
58     /**
59      * Boolean test to determine if this Variance should also increment
60      * the second moment, this evaluates to false when this Variance is
61      * constructed with an external SecondMoment as a parameter.
62      */

63     protected boolean incMoment = true;
64     
65     /**
66      * Determines whether or not bias correction is applied when computing the
67      * value of the statisic. True means that bias is corrected. See
68      * {@link Variance} for details on the formula.
69      */

70     private boolean isBiasCorrected = true;
71
72     /**
73      * Constructs a Variance with default (true) <code>isBiasCorrected</code>
74      * property.
75      */

76     public Variance() {
77         moment = new SecondMoment();
78     }
79
80     /**
81      * Constructs a Variance based on an external second moment.
82      *
83      * @param m2 the SecondMoment (Thrid or Fourth moments work
84      * here as well.)
85      */

86     public Variance(final SecondMoment m2) {
87         incMoment = false;
88         this.moment = m2;
89     }
90     
91     /**
92      * Constructs a Variance with the specified <code>isBiasCorrected</code>
93      * property
94      *
95      * @param isBiasCorrected setting for bias correction - true means
96      * bias will be corrected and is equivalent to using the argumentless
97      * constructor
98      */

99     public Variance(boolean isBiasCorrected) {
100         moment = new SecondMoment();
101         this.isBiasCorrected = isBiasCorrected;
102     }
103     
104     /**
105      * Constructs a Variance with the specified <code>isBiasCorrected</code>
106      * property and the supplied external second moment.
107      *
108      * @param isBiasCorrected setting for bias correction - true means
109      * bias will be corrected
110      * @param m2 the SecondMoment (Thrid or Fourth moments work
111      * here as well.)
112      */

113     public Variance(boolean isBiasCorrected, SecondMoment m2) {
114         incMoment = false;
115         this.moment = m2;
116         this.isBiasCorrected = isBiasCorrected;
117     }
118    
119     /**
120      * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#increment(double)
121      */

122     public void increment(final double d) {
123         if (incMoment) {
124             moment.increment(d);
125         }
126     }
127
128     /**
129      * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#getResult()
130      */

131     public double getResult() {
132             if (moment.n == 0) {
133                 return Double.NaN;
134             } else if (moment.n == 1) {
135                 return 0d;
136             } else {
137                 if (isBiasCorrected) {
138                     return moment.m2 / ((double) moment.n - 1d);
139                 } else {
140                     return moment.m2 / ((double) moment.n);
141                 }
142             }
143     }
144
145     /**
146      * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#getN()
147      */

148     public long getN() {
149         return moment.getN();
150     }
151     
152     /**
153      * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#clear()
154      */

155     public void clear() {
156         if (incMoment) {
157             moment.clear();
158         }
159     }
160     
161     /**
162      * Returns the variance of the entries in the input array, or
163      * <code>Double.NaN</code> if the array is empty.
164      * <p>
165      * See {@link Variance} for details on the computing algorithm.
166      * <p>
167      * Returns 0 for a single-value (i.e. length = 1) sample.
168      * <p>
169      * Throws <code>IllegalArgumentException</code> if the array is null.
170      * <p>
171      * Does not change the internal state of the statistic.
172      *
173      * @param values the input array
174      * @return the variance of the values or Double.NaN if length = 0
175      * @throws IllegalArgumentException if the array is null
176      */

177     public double evaluate(final double[] values) {
178         if (values == null) {
179             throw new IllegalArgumentException JavaDoc("input values array is null");
180         }
181         return evaluate(values, 0, values.length);
182     }
183
184     /**
185      * Returns the variance of the entries in the specified portion of
186      * the input array, or <code>Double.NaN</code> if the designated subarray
187      * is empty.
188      * <p>
189      * See {@link Variance} for details on the computing algorithm.
190      * <p>
191      * Returns 0 for a single-value (i.e. length = 1) sample.
192      * <p>
193      * Does not change the internal state of the statistic.
194      * <p>
195      * Throws <code>IllegalArgumentException</code> if the array is null.
196      *
197      * @param values the input array
198      * @param begin index of the first array element to include
199      * @param length the number of elements to include
200      * @return the variance of the values or Double.NaN if length = 0
201      * @throws IllegalArgumentException if the array is null or the array index
202      * parameters are not valid
203      */

204     public double evaluate(final double[] values, final int begin, final int length) {
205
206         double var = Double.NaN;
207
208         if (test(values, begin, length)) {
209             clear();
210             if (length == 1) {
211                 var = 0.0;
212             } else if (length > 1) {
213                 Mean mean = new Mean();
214                 double m = mean.evaluate(values, begin, length);
215                 var = evaluate(values, m, begin, length);
216             }
217         }
218         return var;
219     }
220     
221     /**
222      * Returns the variance of the entries in the specified portion of
223      * the input array, using the precomputed mean value. Returns
224      * <code>Double.NaN</code> if the designated subarray is empty.
225      * <p>
226      * See {@link Variance} for details on the computing algorithm.
227      * <p>
228      * The formula used assumes that the supplied mean value is the arithmetic
229      * mean of the sample data, not a known population parameter. This method
230      * is supplied only to save computation when the mean has already been
231      * computed.
232      * <p>
233      * Returns 0 for a single-value (i.e. length = 1) sample.
234      * <p>
235      * Throws <code>IllegalArgumentException</code> if the array is null.
236      * <p>
237      * Does not change the internal state of the statistic.
238      *
239      * @param values the input array
240      * @param mean the precomputed mean value
241      * @param begin index of the first array element to include
242      * @param length the number of elements to include
243      * @return the variance of the values or Double.NaN if length = 0
244      * @throws IllegalArgumentException if the array is null or the array index
245      * parameters are not valid
246      */

247     public double evaluate(final double[] values, final double mean,
248             final int begin, final int length) {
249         
250         double var = Double.NaN;
251
252         if (test(values, begin, length)) {
253             if (length == 1) {
254                 var = 0.0;
255             } else if (length > 1) {
256                 double accum = 0.0;
257                 double accum2 = 0.0;
258                 for (int i = begin; i < begin + length; i++) {
259                     accum += Math.pow((values[i] - mean), 2.0);
260                     accum2 += (values[i] - mean);
261                 }
262                 if (isBiasCorrected) {
263                     var = (accum - (Math.pow(accum2, 2) / ((double) length))) /
264                     (double) (length - 1);
265                 } else {
266                     var = (accum - (Math.pow(accum2, 2) / ((double) length))) /
267                     (double) length;
268                 }
269             }
270         }
271         return var;
272     }
273     
274     /**
275      * Returns the variance of the entries in the input array, using the
276      * precomputed mean value. Returns <code>Double.NaN</code> if the array
277      * is empty.
278      * <p>
279      * See {@link Variance} for details on the computing algorithm.
280      * <p>
281      * If <code>isBiasCorrected</code> is <code>true</code> the formula used
282      * assumes that the supplied mean value is the arithmetic mean of the
283      * sample data, not a known population parameter. If the mean is a known
284      * population parameter, or if the "population" version of the variance is
285      * desired, set <code>isBiasCorrected</code> to <code>false</code> before
286      * invoking this method.
287      * <p>
288      * Returns 0 for a single-value (i.e. length = 1) sample.
289      * <p>
290      * Throws <code>IllegalArgumentException</code> if the array is null.
291      * <p>
292      * Does not change the internal state of the statistic.
293      *
294      * @param values the input array
295      * @param mean the precomputed mean value
296      * @return the variance of the values or Double.NaN if the array is empty
297      * @throws IllegalArgumentException if the array is null
298      */

299     public double evaluate(final double[] values, final double mean) {
300         return evaluate(values, mean, 0, values.length);
301     }
302
303     /**
304      * @return Returns the isBiasCorrected.
305      */

306     public boolean isBiasCorrected() {
307         return isBiasCorrected;
308     }
309
310     /**
311      * @param isBiasCorrected The isBiasCorrected to set.
312      */

313     public void setBiasCorrected(boolean isBiasCorrected) {
314         this.isBiasCorrected = isBiasCorrected;
315     }
316
317 }
318
Popular Tags