You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ps...@apache.org on 2004/10/10 22:40:52 UTC
cvs commit: jakarta-commons/math/src/test/org/apache/commons/math/stat/descriptive/moment VarianceTest.java
psteitz 2004/10/10 13:40:52
Modified: math/src/java/org/apache/commons/math/stat/descriptive/moment
Variance.java
math/src/test/org/apache/commons/math/stat/descriptive/moment
VarianceTest.java
Log:
Added support for population variance computation.
Revision Changes Path
1.2 +80 -10 jakarta-commons/math/src/java/org/apache/commons/math/stat/descriptive/moment/Variance.java
Index: Variance.java
===================================================================
RCS file: /home/cvs/jakarta-commons/math/src/java/org/apache/commons/math/stat/descriptive/moment/Variance.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Variance.java 8 Oct 2004 05:08:17 -0000 1.1
+++ Variance.java 10 Oct 2004 20:40:52 -0000 1.2
@@ -20,7 +20,8 @@
import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
/**
- * Computes the (unbiased) sample variance. Uses the definitional formula:
+ * Computes the variance of the available values. By default, the unbiased
+ * "sample variance" definitional formula is used:
* <p>
* variance = sum((x_i - mean)^2) / (n - 1)
* <p>
@@ -32,7 +33,13 @@
* as described in <a href="http://doi.acm.org/10.1145/359146.359152">
* Chan, T. F. andJ. G. Lewis 1979, <i>Communications of the ACM</i>,
* vol. 22 no. 9, pp. 526-531.</a>.
-* <p>
+ * <p>
+ * The "population variance" ( sum((x_i - mean)^2) / n ) can also
+ * be computed using this statistic. The <code>isBiasCorrected</code>
+ * property determines whether the "population" or "sample" value is
+ * returned by the <code>evaluate</code> and <code>getResult</code> methods.
+ * To compute population variances, set this property to <code>false.</code>
+ *
* <strong>Note that this implementation is not synchronized.</strong> If
* multiple threads access an instance of this class concurrently, and at least
* one of the threads invokes the <code>increment()</code> or
@@ -54,6 +61,13 @@
* constructed with an external SecondMoment as a parameter.
*/
protected boolean incMoment = true;
+
+ /**
+ * Determines whether or not bias correction is applied when computing the
+ * value of the statisic. True means that bias is corrected. See
+ * {@link Variance} for details on the formula.
+ */
+ private boolean isBiasCorrected = true;
/**
* Constructs a Variance.
@@ -64,6 +78,7 @@
/**
* Constructs a Variance based on an external second moment.
+ *
* @param m2 the SecondMoment (Thrid or Fourth moments work
* here as well.)
*/
@@ -71,6 +86,36 @@
incMoment = false;
this.moment = m2;
}
+
+ /**
+ * Constructs a Variance with the specified <code>isBiasCorrected</code>
+ * property
+ *
+ * @param isBiasCorrected setting for bias correction - true means
+ * bias will be corrected and is equivalent to using the argumentless
+ * constructor
+ */
+ public Variance(boolean isBiasCorrected) {
+ moment = new SecondMoment();
+ this.isBiasCorrected = isBiasCorrected;
+ }
+
+ /**
+ * Constructs a Variance with the specified <code>isBiasCorrected</code>
+ * property and the supplied external second moment.
+ *
+ * @param isBiasCorrected setting for bias correction - true means
+ * bias will be corrected and is equivalent to using the argumentless
+ * constructor
+ * @param m2 the SecondMoment (Thrid or Fourth moments work
+ * here as well.)
+ */
+ public Variance(boolean isBiasCorrected, SecondMoment m2) {
+ incMoment = false;
+ this.moment = m2;
+ this.isBiasCorrected = isBiasCorrected;
+ }
+
/**
* @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#increment(double)
*/
@@ -89,7 +134,11 @@
} else if (moment.n == 1) {
return 0d;
} else {
- return moment.m2 / ((double) moment.n - 1d);
+ if (isBiasCorrected) {
+ return moment.m2 / ((double) moment.n - 1d);
+ } else {
+ return moment.m2 / ((double) moment.n);
+ }
}
}
@@ -210,8 +259,13 @@
accum += Math.pow((values[i] - mean), 2.0);
accum2 += (values[i] - mean);
}
- var = (accum - (Math.pow(accum2, 2) / ((double) length))) /
- (double) (length - 1);
+ if (isBiasCorrected) {
+ var = (accum - (Math.pow(accum2, 2) / ((double) length))) /
+ (double) (length - 1);
+ } else {
+ var = (accum - (Math.pow(accum2, 2) / ((double) length))) /
+ (double) length;
+ }
}
}
return var;
@@ -224,10 +278,12 @@
* <p>
* See {@link Variance} for details on the computing algorithm.
* <p>
- * The formula used assumes that the supplied mean value is the arithmetic
- * mean of the sample data, not a known population parameter. This method
- * is supplied only to save computation when the mean has already been
- * computed.
+ * If <code>isBiasCorrected</code> is <code>true</code> the formula used
+ * assumes that the supplied mean value is the arithmetic mean of the
+ * sample data, not a known population parameter. If the mean is a known
+ * population parameter, or if the "population" version of the variance is
+ * desired, set <code>isBiasCorrected</code> to <code>false</code> before
+ * invoking this method.
* <p>
* Returns 0 for a single-value (i.e. length = 1) sample.
* <p>
@@ -242,6 +298,20 @@
*/
public double evaluate(final double[] values, final double mean) {
return evaluate(values, mean, 0, values.length);
+ }
+
+ /**
+ * @return Returns the isBiasCorrected.
+ */
+ public boolean isBiasCorrected() {
+ return isBiasCorrected;
+ }
+
+ /**
+ * @param isBiasCorrected The isBiasCorrected to set.
+ */
+ public void setBiasCorrected(boolean isBiasCorrected) {
+ this.isBiasCorrected = isBiasCorrected;
}
}
1.2 +29 -1 jakarta-commons/math/src/test/org/apache/commons/math/stat/descriptive/moment/VarianceTest.java
Index: VarianceTest.java
===================================================================
RCS file: /home/cvs/jakarta-commons/math/src/test/org/apache/commons/math/stat/descriptive/moment/VarianceTest.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- VarianceTest.java 8 Oct 2004 05:08:20 -0000 1.1
+++ VarianceTest.java 10 Oct 2004 20:40:52 -0000 1.2
@@ -67,5 +67,33 @@
std.increment(1d);
assertEquals(0d, std.getResult(), 0);
}
+
+ /**
+ * Test population version of variance
+ */
+ public void testPopulation() {
+ double[] values = {-1.0d, 3.1d, 4.0d, -2.1d, 22d, 11.7d, 3d, 14d};
+ SecondMoment m = new SecondMoment();
+ m.evaluate(values); // side effect is to add values
+ Variance v1 = new Variance();
+ v1.setBiasCorrected(false);
+ assertEquals(populationVariance(values), v1.evaluate(values), 1E-14);
+ v1.incrementAll(values);
+ assertEquals(populationVariance(values), v1.getResult(), 1E-14);
+ v1 = new Variance(false, m);
+ assertEquals(populationVariance(values), v1.getResult(), 1E-14);
+ }
+
+ /**
+ * Definitional formula for population variance
+ */
+ protected double populationVariance(double[] v) {
+ double mean = new Mean().evaluate(v);
+ double sum = 0;
+ for (int i = 0; i < v.length; i++) {
+ sum += (v[i] - mean) * (v[i] - mean);
+ }
+ return sum / (double) v.length;
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org