Improved javadoc, simplified implemenentation.

git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@141341 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Phil Steitz 2004-06-27 19:37:51 +00:00
parent 0ad427869d
commit 6e21d23996
7 changed files with 135 additions and 138 deletions

View File

@ -20,57 +20,59 @@ import java.io.Serializable;
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: 1.15 $ $Date: 2004/06/23 16:26:15 $
* @version $Revision: 1.16 $ $Date: 2004/06/27 19:37:51 $
*/
public class FirstMoment extends AbstractStorelessUnivariateStatistic implements Serializable{
/** 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
/**
* Deviation of most recently added value from previous first moment.
* Retained to prevent repeated computation in higher order moments.
*/
protected double dev = 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 v = 0.0;
/**
* temporary internal state made available for
* 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 class FirstMoment extends AbstractStorelessUnivariateStatistic implements
public void clear() {
m1 = Double.NaN;
n = 0;
dev = 0.0;
v = 0.0;
n0 = 0.0;
dev = Double.NaN;
nDev = Double.NaN;
}
/**

View File

@ -18,11 +18,28 @@ package org.apache.commons.math.stat.univariate.moment;
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.
* @version $Revision: 1.17 $ $Date: 2004/06/23 16:26:15 $
* 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: 1.18 $ $Date: 2004/06/27 19:37:51 $
*/
public class FourthMoment extends ThirdMoment implements Serializable{
@ -32,13 +49,6 @@ public class FourthMoment extends ThirdMoment implements Serializable{
/** 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 @@ public class FourthMoment extends ThirdMoment implements Serializable{
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 class FourthMoment extends ThirdMoment implements Serializable{
public void clear() {
super.clear();
m4 = Double.NaN;
prevM3 = 0.0;
n3 = 0.0;
}
}

View File

@ -31,7 +31,7 @@ import org.apache.commons.math.stat.univariate.AbstractStorelessUnivariateStatis
* Note that this statistic is undefined for n < 4. <code>Double.Nan</code> is returned when
* there is not sufficient data to compute the statistic.
*
* @version $Revision: 1.22 $ $Date: 2004/06/23 16:26:14 $
* @version $Revision: 1.23 $ $Date: 2004/06/27 19:37:51 $
*/
public class Kurtosis extends AbstractStorelessUnivariateStatistic implements Serializable {
@ -86,14 +86,14 @@ public class Kurtosis extends AbstractStorelessUnivariateStatistic implements Se
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;

View File

@ -18,11 +18,20 @@ package org.apache.commons.math.stat.univariate.moment;
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.
* @version $Revision: 1.16 $ $Date: 2004/06/23 16:26:15 $
* 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: 1.17 $ $Date: 2004/06/27 19:37:51 $
*/
public class SecondMoment extends FirstMoment implements Serializable {
@ -32,9 +41,6 @@ public class SecondMoment extends FirstMoment implements Serializable {
/** 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 @@ public class SecondMoment extends FirstMoment implements Serializable {
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 class SecondMoment extends FirstMoment implements Serializable {
public void clear() {
super.clear();
m2 = Double.NaN;
n1 = 0.0;
}
/**

View File

@ -26,27 +26,27 @@ import org.apache.commons.math.stat.univariate.AbstractStorelessUnivariateStatis
* <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: 1.21 $ $Date: 2004/06/23 16:26:14 $
* @version $Revision: 1.22 $ $Date: 2004/06/27 19:37:51 $
*/
public class Skewness extends AbstractStorelessUnivariateStatistic implements Serializable {
/** 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 @@ public class Skewness extends AbstractStorelessUnivariateStatistic implements Se
* @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 @@ public class Skewness extends AbstractStorelessUnivariateStatistic implements Se
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 @@ public class Skewness extends AbstractStorelessUnivariateStatistic implements Se
double skew = Double.NaN;
if (test(values, begin, length)) {
Mean mean = new Mean();
if (length <= 2) {
skew = 0.0;
} else {

View File

@ -18,11 +18,21 @@ package org.apache.commons.math.stat.univariate.moment;
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.
* @version $Revision: 1.16 $ $Date: 2004/06/23 16:26:14 $
* 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: 1.17 $ $Date: 2004/06/27 19:37:51 $
*/
public class ThirdMoment extends SecondMoment implements Serializable {
@ -32,14 +42,13 @@ public class ThirdMoment extends SecondMoment implements Serializable {
/** 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;
/**
* 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 n2 = 0.0;
/** 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 class ThirdMoment extends SecondMoment implements Serializable {
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 class ThirdMoment extends SecondMoment implements Serializable {
public void clear() {
super.clear();
m3 = Double.NaN;
v2 = 0.0;
n2 = 0.0;
prevM2 = 0.0;
nDevSq = Double.NaN;
}
}

View File

@ -33,7 +33,7 @@ import org.apache.commons.math.stat.univariate.AbstractStorelessUnivariateStatis
* Chan, T. F. andJ. G. Lewis 1979, <i>Communications of the ACM</i>,
* vol. 22 no. 9, pp. 526-531.</a>.
*
* @version $Revision: 1.21 $ $Date: 2004/06/26 23:33:27 $
* @version $Revision: 1.22 $ $Date: 2004/06/27 19:37:51 $
*/
public class Variance extends AbstractStorelessUnivariateStatistic implements Serializable {
@ -84,7 +84,7 @@ public class Variance extends AbstractStorelessUnivariateStatistic implements Se
} else if (moment.n == 1) {
return 0d;
} else {
return moment.m2 / (moment.n0 - 1);
return moment.m2 / ((double) moment.n - 1d);
}
}