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/06/27 21:37:52 UTC
cvs commit: jakarta-commons/math/src/java/org/apache/commons/math/stat/univariate/moment FirstMoment.java FourthMoment.java Kurtosis.java SecondMoment.java Skewness.java ThirdMoment.java Variance.java
psteitz 2004/06/27 12:37:52
Modified: math/src/java/org/apache/commons/math/stat/univariate/moment
FirstMoment.java FourthMoment.java Kurtosis.java
SecondMoment.java Skewness.java ThirdMoment.java
Variance.java
Log:
Improved javadoc, simplified implemenentation.
Revision Changes Path
1.16 +33 -32 jakarta-commons/math/src/java/org/apache/commons/math/stat/univariate/moment/FirstMoment.java
Index: FirstMoment.java
===================================================================
RCS file: /home/cvs/jakarta-commons/math/src/java/org/apache/commons/math/stat/univariate/moment/FirstMoment.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- FirstMoment.java 23 Jun 2004 16:26:15 -0000 1.15
+++ FirstMoment.java 27 Jun 2004 19:37:51 -0000 1.16
@@ -20,12 +20,21 @@
import org.apache.commons.math.stat.univariate.AbstractStorelessUnivariateStatistic;
/**
- * FirstMoment.java
+ * Computes the first moment (arithmetic mean). Uses the definitional formula:
+ * <p>
+ * mean = sum(x_i) / n
+ * <p>
+ * where <code>n</code> is the number of observations.
+ * <p>
+ * To limit numeric errors, the value of the statistic is computed using the
+ * following recursive updating algorithm:
+ * <p>
+ * <ol>
+ * <li>Initialize <code>m = </code> the first value</li>
+ * <li>For each additional value, update using <br>
+ * <code>m = m + (new value - m) / (number of observations)</code></li>
+ * </ol>
*
- * The FirstMoment (arithmentic mean) is calculated using the following
- * <a href="http://www.spss.com/tech/stat/Algorithms/11.5/descriptives.pdf">
- * recursive strategy
- * </a>. Both incremental and evaluation strategies currently use this approach.
* @version $Revision$ $Date$
*/
public class FirstMoment extends AbstractStorelessUnivariateStatistic implements Serializable{
@@ -33,44 +42,37 @@
/** Serializable version identifier */
static final long serialVersionUID = -803343206421984070L;
- /** count of values that have been added */
+ /** Count of values that have been added */
protected long n = 0;
- /** first moment of values that have been added */
+ /** First moment of values that have been added */
protected double m1 = Double.NaN;
-
- /**
- * temporary internal state made available for
- * higher order moments
- */
- protected double dev = 0.0;
-
- /**
- * temporary internal state made available for
- * higher order moments
+
+ /**
+ * Deviation of most recently added value from previous first moment.
+ * Retained to prevent repeated computation in higher order moments.
*/
- protected double v = 0.0;
-
+ protected double dev = Double.NaN;
+
/**
- * temporary internal state made available for
- * higher order moments
+ * Deviation of most recently added value from previous first moment,
+ * normalized by previous sample size. Retained to prevent repeated
+ * computation in higher order moments
*/
- protected double n0 = 0.0;
+ protected double nDev = Double.NaN;
/**
* @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#increment(double)
*/
public void increment(final double d) {
- if (n < 1) {
+ if (n == 0) {
m1 = 0.0;
}
-
n++;
+ double n0 = (double) n;
dev = d - m1;
- n0 = (double) n;
- v = dev / n0;
-
- m1 += v;
+ nDev = dev / n0;
+ m1 += nDev;
}
/**
@@ -79,9 +81,8 @@
public void clear() {
m1 = Double.NaN;
n = 0;
- dev = 0.0;
- v = 0.0;
- n0 = 0.0;
+ dev = Double.NaN;
+ nDev = Double.NaN;
}
/**
1.18 +29 -22 jakarta-commons/math/src/java/org/apache/commons/math/stat/univariate/moment/FourthMoment.java
Index: FourthMoment.java
===================================================================
RCS file: /home/cvs/jakarta-commons/math/src/java/org/apache/commons/math/stat/univariate/moment/FourthMoment.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- FourthMoment.java 23 Jun 2004 16:26:15 -0000 1.17
+++ FourthMoment.java 27 Jun 2004 19:37:51 -0000 1.18
@@ -18,10 +18,27 @@
import java.io.Serializable;
/**
- * The FourthMoment is calculated using the following
- * <a href="http://www.spss.com/tech/stat/Algorithms/11.5/descriptives.pdf">
- * recursive strategy
- * </a>. Both incremental and evaluation strategies currently use this approach.
+ * Computes a statistic related to the Fourth Central Moment. Specifically,
+ * what is computed is the sum of
+ * <p>
+ * (x_i - xbar) ^ 4,
+ * <p>
+ * where the x_i are the
+ * sample observations and xbar is the sample mean.
+ * <p>
+ * The following recursive updating formula is used:
+ * <p>
+ * Let <ul>
+ * <li> dev = (current obs - previous mean) </li>
+ * <li> m2 = previous value of {@link SecondMoment} </li>
+ * <li> m2 = previous value of {@link ThirdMoment} </li>
+ * <li> n = number of observations (including current obs) </li>
+ * </ul>
+ * Then
+ * <p>
+ * new value = old value - 4 * (dev/n) * m3 + 6 * (dev/n)^2 * m2 + <br>
+ * [n^2 - 3 * (n-1)] * dev^4 * (n-1) / n^3
+ *
* @version $Revision$ $Date$
*/
public class FourthMoment extends ThirdMoment implements Serializable{
@@ -32,13 +49,6 @@
/** fourth moment of values that have been added */
protected double m4 = Double.NaN;
- /** temporary internal state made available for higher order moments */
- protected double prevM3 = 0.0;
-
- /** temporary internal state made available for higher order moments */
- protected double n3 = 0.0;
-
-
/**
* @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#increment(double)
*/
@@ -50,16 +60,15 @@
m1 = 0.0;
}
- /* retain previous m3 */
- prevM3 = m3;
-
- /* increment m1, m2 and m3 (and prevM2, _n0, _n1, _n2, _v, _v2) */
+ double prevM3 = m3;
+ double prevM2 = m2;
+
super.increment(d);
+
+ double n0 = (double) n;
- n3 = (double) (n - 3);
-
- m4 = m4 - (4.0 * v * prevM3) + (6.0 * v2 * prevM2) +
- ((n0 * n0) - 3 * n1) * (v2 * v2 * n1 * n0);
+ m4 = m4 - 4.0 * nDev * prevM3 + 6.0 * nDevSq * prevM2 +
+ ((n0 * n0) - 3 * (n0 -1)) * (nDevSq * nDevSq * (n0 - 1) * n0);
}
/**
@@ -75,8 +84,6 @@
public void clear() {
super.clear();
m4 = Double.NaN;
- prevM3 = 0.0;
- n3 = 0.0;
}
}
1.23 +5 -5 jakarta-commons/math/src/java/org/apache/commons/math/stat/univariate/moment/Kurtosis.java
Index: Kurtosis.java
===================================================================
RCS file: /home/cvs/jakarta-commons/math/src/java/org/apache/commons/math/stat/univariate/moment/Kurtosis.java,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- Kurtosis.java 23 Jun 2004 16:26:14 -0000 1.22
+++ Kurtosis.java 27 Jun 2004 19:37:51 -0000 1.23
@@ -86,14 +86,14 @@
double kurtosis = Double.NaN;
if (moment.getN() > 3) {
double variance = moment.m2 / (double) (moment.n - 1);
-
if (moment.n <= 3 || variance < 10E-20) {
kurtosis = 0.0;
} else {
+ double n = (double) moment.n;
kurtosis =
- (moment.n0 * (moment.n0 + 1) * moment.m4 -
- 3 * moment.m2 * moment.m2 * moment.n1) /
- (moment.n1 * moment.n2 * moment.n3 * variance * variance);
+ (n * (n + 1) * moment.m4 -
+ 3 * moment.m2 * moment.m2 * (n - 1)) /
+ ((n - 1) * (n -2) * (n -3) * variance * variance);
}
}
return kurtosis;
1.17 +15 -17 jakarta-commons/math/src/java/org/apache/commons/math/stat/univariate/moment/SecondMoment.java
Index: SecondMoment.java
===================================================================
RCS file: /home/cvs/jakarta-commons/math/src/java/org/apache/commons/math/stat/univariate/moment/SecondMoment.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- SecondMoment.java 23 Jun 2004 16:26:15 -0000 1.16
+++ SecondMoment.java 27 Jun 2004 19:37:51 -0000 1.17
@@ -18,10 +18,19 @@
import java.io.Serializable;
/**
- * The SecondMoment is calculated using the following
- * <a href="http://www.spss.com/tech/stat/Algorithms/11.5/descriptives.pdf">
- * recursive strategy
- * </a>. Both incremental and evaluation strategies currently use this approach.
+ * Computes a statistic related to the Second Central Moment. Specifically,
+ * what is computed is the sum of squared deviations from the sample mean.
+ * <p>
+ * The following recursive updating formula is used:
+ * <p>
+ * Let <ul>
+ * <li> dev = (current obs - previous mean) </li>
+ * <li> n = number of observations (including current obs) </li>
+ * </ul>
+ * Then
+ * <p>
+ * new value = old value + dev^2 * (n -1) / n.
+ *
* @version $Revision$ $Date$
*/
public class SecondMoment extends FirstMoment implements Serializable {
@@ -32,9 +41,6 @@
/** second moment of values that have been added */
protected double m2 = Double.NaN;
- /** temporary internal state made availabel for higher order moments */
- protected double n1 = 0.0;
-
/**
* @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#increment(double)
*/
@@ -42,15 +48,8 @@
if (n < 1) {
m1 = m2 = 0.0;
}
-
- /* increment m1 and _n0, _dev, _v) */
super.increment(d);
-
- n1 = n0 - 1;
-
- /* increment and return m2 */
- m2 += n1 * dev * v;
-
+ m2 += ((double) n - 1) * dev * nDev;
}
/**
@@ -59,7 +58,6 @@
public void clear() {
super.clear();
m2 = Double.NaN;
- n1 = 0.0;
}
/**
1.22 +23 -33 jakarta-commons/math/src/java/org/apache/commons/math/stat/univariate/moment/Skewness.java
Index: Skewness.java
===================================================================
RCS file: /home/cvs/jakarta-commons/math/src/java/org/apache/commons/math/stat/univariate/moment/Skewness.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- Skewness.java 23 Jun 2004 16:26:14 -0000 1.21
+++ Skewness.java 27 Jun 2004 19:37:51 -0000 1.22
@@ -26,7 +26,8 @@
* <p>
* skewness = [n / (n -1) (n - 2)] sum[(x_i - mean)^3] / std^3
* <p>
- * where n is the number of values, mean is the {@link Mean} and std is the {@link StandardDeviation}
+ * where n is the number of values, mean is the {@link Mean} and std is the
+ * {@link StandardDeviation}
*
* @version $Revision$ $Date$
*/
@@ -35,18 +36,17 @@
/** Serializable version identifier */
static final long serialVersionUID = 7101857578996691352L;
- /** */
+ /** Third moment on which this statistic is based */
protected ThirdMoment moment = null;
- /** */
+ /**
+ * Determines whether or not this statistic can be incremented or cleared.
+ * <p>
+ * Statistics based on (constructed from) external moments cannot
+ * be incremented or cleared.
+ */
protected boolean incMoment = true;
- /** */
- protected double skewness = Double.NaN;
-
- /** */
- private long n = 0;
-
/**
* Constructs a Skewness
*/
@@ -80,21 +80,18 @@
* @return the skewness of the available values.
*/
public double getResult() {
- if (n < moment.n) {
- if (moment.n <= 0) {
- skewness = Double.NaN;
- }
-
- double variance =
- (moment.n < 1) ? 0.0 : moment.m2 / (double) (moment.n - 1);
-
- if (moment.n <= 2 || variance < 10E-20) {
- skewness = 0.0;
- } else {
- skewness = (moment.n0 * moment.m3) /
- (moment.n1 * moment.n2 * Math.sqrt(variance) * variance);
- }
- n = moment.n;
+
+ if (moment.n < 3) {
+ return Double.NaN;
+ }
+ double variance = moment.m2 / (double) (moment.n - 1);
+ double skewness = Double.NaN;
+ if (variance < 10E-20) {
+ skewness = 0.0;
+ } else {
+ double n0 = (double) moment.getN();
+ skewness = (n0 * moment.m3) /
+ ((n0 - 1) * (n0 -2) * Math.sqrt(variance) * variance);
}
return skewness;
}
@@ -113,15 +110,8 @@
if (incMoment) {
moment.clear();
}
- skewness = Double.NaN;
- n = 0;
}
- /*UnvariateStatistic Approach */
-
- /** */
- Mean mean = new Mean();
-
/**
* Returns the Skewness of the values array.
* <p>
@@ -142,7 +132,7 @@
double skew = Double.NaN;
if (test(values, begin, length)) {
-
+ Mean mean = new Mean();
if (length <= 2) {
skew = 0.0;
} else {
1.17 +28 -27 jakarta-commons/math/src/java/org/apache/commons/math/stat/univariate/moment/ThirdMoment.java
Index: ThirdMoment.java
===================================================================
RCS file: /home/cvs/jakarta-commons/math/src/java/org/apache/commons/math/stat/univariate/moment/ThirdMoment.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- ThirdMoment.java 23 Jun 2004 16:26:14 -0000 1.16
+++ ThirdMoment.java 27 Jun 2004 19:37:51 -0000 1.17
@@ -18,10 +18,20 @@
import java.io.Serializable;
/**
- * The ThirdMoment (arithmentic mean) is calculated using the following
- * <a href="http://www.spss.com/tech/stat/Algorithms/11.5/descriptives.pdf">
- * recursive strategy
- * </a>. Both incremental and evaluation strategies currently use this approach.
+ * Computes a statistic related to the Third Central Moment. Specifically,
+ * what is computed is the sum of cubed deviations from the sample mean.
+ * <p>
+ * The following recursive updating formula is used:
+ * <p>
+ * Let <ul>
+ * <li> dev = (current obs - previous mean) </li>
+ * <li> m2 = previous value of {@link SecondMoment} </li>
+ * <li> n = number of observations (including current obs) </li>
+ * </ul>
+ * Then
+ * <p>
+ * new value = old value - 3 * (dev/n) * m2 + (n-1) * (n -2) * (dev^3/n^2)
+ *
* @version $Revision$ $Date$
*/
public class ThirdMoment extends SecondMoment implements Serializable {
@@ -32,14 +42,13 @@
/** third moment of values that have been added */
protected double m3 = Double.NaN;
- /** temporary internal state made availabel for higher order moments */
- protected double v2 = 0.0;
-
- /** temporary internal state made availabel for higher order moments */
- protected double n2 = 0.0;
+ /**
+ * Square of deviation of most recently added value from previous first
+ * moment, normalized by previous sample size. Retained to prevent
+ * repeated computation in higher order moments. nDevSq = nDev * nDev.
+ */
+ protected double nDevSq = Double.NaN;
- /** temporary internal state made availabel for higher order moments */
- protected double prevM2 = 0.0;
/**
* @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#increment(double)
@@ -47,19 +56,13 @@
public void increment(final double d) {
if (n < 1) {
m3 = m2 = m1 = 0.0;
- }
-
- /* retain a reference to the last m2*/
- prevM2 = m2;
-
- /* increment m1 and m2 (and _n0, _n1, _v) */
+ }
+
+ double prevM2 = m2;
super.increment(d);
-
- v2 = v * v;
- n2 = (double) (n - 2);
-
- m3 = m3 - (3.0 * v * prevM2) + (n0 * n1 * n2 * v2 * v);
-
+ nDevSq = nDev * nDev;
+ double n0 = (double) n;
+ m3 = m3 - 3.0 * nDev * prevM2 + (n0 - 1) * (n0 - 2) * nDevSq * dev;
}
/**
@@ -75,9 +78,7 @@
public void clear() {
super.clear();
m3 = Double.NaN;
- v2 = 0.0;
- n2 = 0.0;
- prevM2 = 0.0;
+ nDevSq = Double.NaN;
}
}
1.22 +2 -2 jakarta-commons/math/src/java/org/apache/commons/math/stat/univariate/moment/Variance.java
Index: Variance.java
===================================================================
RCS file: /home/cvs/jakarta-commons/math/src/java/org/apache/commons/math/stat/univariate/moment/Variance.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- Variance.java 26 Jun 2004 23:33:27 -0000 1.21
+++ Variance.java 27 Jun 2004 19:37:51 -0000 1.22
@@ -84,7 +84,7 @@
} else if (moment.n == 1) {
return 0d;
} else {
- return moment.m2 / (moment.n0 - 1);
+ return moment.m2 / ((double) moment.n - 1d);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org