Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||||||
Variance |
|
| 2.2857142857142856;2.286 |
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; |
|
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 { |
|
51 | ||
52 | /** Serializable version identifier */ |
|
53 | static final long serialVersionUID = -9111962718267217978L; |
|
54 | ||
55 | /** SecondMoment is used in incremental calculation of Variance*/ |
|
56 | 29736 | 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 | 29736 | 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 | 29736 | private boolean isBiasCorrected = true; |
71 | ||
72 | /** |
|
73 | * Constructs a Variance with default (true) <code>isBiasCorrected</code> |
|
74 | * property. |
|
75 | */ |
|
76 | 128 | public Variance() { |
77 | 128 | moment = new SecondMoment(); |
78 | 128 | } |
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 | 29600 | public Variance(final SecondMoment m2) { |
87 | 29600 | incMoment = false; |
88 | 29600 | this.moment = m2; |
89 | 29600 | } |
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 | 4 | public Variance(boolean isBiasCorrected) { |
100 | 4 | moment = new SecondMoment(); |
101 | 4 | this.isBiasCorrected = isBiasCorrected; |
102 | 4 | } |
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 | 4 | public Variance(boolean isBiasCorrected, SecondMoment m2) { |
114 | 4 | incMoment = false; |
115 | 4 | this.moment = m2; |
116 | 4 | this.isBiasCorrected = isBiasCorrected; |
117 | 4 | } |
118 | ||
119 | /** |
|
120 | * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#increment(double) |
|
121 | */ |
|
122 | public void increment(final double d) { |
|
123 | 748 | if (incMoment) { |
124 | 748 | moment.increment(d); |
125 | } |
|
126 | 748 | } |
127 | ||
128 | /** |
|
129 | * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#getResult() |
|
130 | */ |
|
131 | public double getResult() { |
|
132 | 29810 | if (moment.n == 0) { |
133 | 202 | return Double.NaN; |
134 | 29608 | } else if (moment.n == 1) { |
135 | 76 | return 0d; |
136 | } else { |
|
137 | 29532 | if (isBiasCorrected) { |
138 | 29520 | return moment.m2 / ((double) moment.n - 1d); |
139 | } else { |
|
140 | 12 | 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 | 116 | return moment.getN(); |
150 | } |
|
151 | ||
152 | /** |
|
153 | * @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#clear() |
|
154 | */ |
|
155 | public void clear() { |
|
156 | 286 | if (incMoment) { |
157 | 286 | moment.clear(); |
158 | } |
|
159 | 286 | } |
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 | 188 | if (values == null) { |
179 | 0 | throw new IllegalArgumentException("input values array is null"); |
180 | } |
|
181 | 188 | 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 | 260 | double var = Double.NaN; |
207 | ||
208 | 260 | if (test(values, begin, length)) { |
209 | 242 | clear(); |
210 | 242 | if (length == 1) { |
211 | 16 | var = 0.0; |
212 | 226 | } else if (length > 1) { |
213 | 226 | Mean mean = new Mean(); |
214 | 226 | double m = mean.evaluate(values, begin, length); |
215 | 226 | var = evaluate(values, m, begin, length); |
216 | } |
|
217 | } |
|
218 | 258 | 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 | 230 | double var = Double.NaN; |
251 | ||
252 | 230 | if (test(values, begin, length)) { |
253 | 230 | if (length == 1) { |
254 | 0 | var = 0.0; |
255 | 230 | } else if (length > 1) { |
256 | 230 | double accum = 0.0; |
257 | 230 | double accum2 = 0.0; |
258 | 13650 | for (int i = begin; i < begin + length; i++) { |
259 | 13420 | accum += Math.pow((values[i] - mean), 2.0); |
260 | 13420 | accum2 += (values[i] - mean); |
261 | } |
|
262 | 230 | if (isBiasCorrected) { |
263 | 222 | var = (accum - (Math.pow(accum2, 2) / ((double) length))) / |
264 | (double) (length - 1); |
|
265 | } else { |
|
266 | 8 | var = (accum - (Math.pow(accum2, 2) / ((double) length))) / |
267 | (double) length; |
|
268 | } |
|
269 | } |
|
270 | } |
|
271 | 230 | 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 | 2 | return evaluate(values, mean, 0, values.length); |
301 | } |
|
302 | ||
303 | /** |
|
304 | * @return Returns the isBiasCorrected. |
|
305 | */ |
|
306 | public boolean isBiasCorrected() { |
|
307 | 0 | return isBiasCorrected; |
308 | } |
|
309 | ||
310 | /** |
|
311 | * @param isBiasCorrected The isBiasCorrected to set. |
|
312 | */ |
|
313 | public void setBiasCorrected(boolean isBiasCorrected) { |
|
314 | 4 | this.isBiasCorrected = isBiasCorrected; |
315 | 4 | } |
316 | ||
317 | } |