diff --git a/src/java/org/apache/commons/math/stat/univariate/moment/FirstMoment.java b/src/java/org/apache/commons/math/stat/univariate/moment/FirstMoment.java new file mode 100644 index 000000000..6cddbe8d8 --- /dev/null +++ b/src/java/org/apache/commons/math/stat/univariate/moment/FirstMoment.java @@ -0,0 +1,112 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2003 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Commons", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.commons.math.stat.univariate.moment; + +import org.apache.commons.math.stat.univariate.AbstractStorelessUnivariateStatistic; + +/** + * + */ +public class FirstMoment extends AbstractStorelessUnivariateStatistic { + + /** count of values that have been added */ + protected int n = 0; + + /** 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 */ + protected double v = 0.0; + + /** temporary internal state made available for higher order moments */ + protected double n0 = 0.0; + + /** + * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#increment(double) + */ + public double increment(double d) { + if (n < 1) { + m1 = 0.0; + } + + n++; + dev = d - m1; + n0 = (double)n; + v = dev / n0; + + return m1 += v; + } + + /** + * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#clear() + */ + public void clear() { + m1 = Double.NaN; + n = 0; + dev = 0.0; + v = 0.0; + n0 = 0.0; + } + + /** + * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#getValue() + */ + public double getValue() { + return m1; + } + +} \ No newline at end of file diff --git a/src/java/org/apache/commons/math/stat/univariate/moment/FourthMoment.java b/src/java/org/apache/commons/math/stat/univariate/moment/FourthMoment.java index 08cd7ba6d..cf3e76f13 100644 --- a/src/java/org/apache/commons/math/stat/univariate/moment/FourthMoment.java +++ b/src/java/org/apache/commons/math/stat/univariate/moment/FourthMoment.java @@ -54,14 +54,21 @@ package org.apache.commons.math.stat.univariate.moment; /** - * @author Mark Diggory + * * */ public class FourthMoment extends ThirdMoment { /** 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) */ @@ -70,30 +77,23 @@ public class FourthMoment extends ThirdMoment { m4 = m3 = m2 = m1 = 0.0; } - n++; - double dev = d - m1; - double v = dev / ((double) n); - double v2 = v * v; - - double n0 = (double) n; - double n1 = (double) (n - 1); - double n2 = (double) (n - 2); + /* retain previous m3 */ + prevM3 = m3; + + /* increment m1, m2 and m3 (and prevM2, _n0, _n1, _n2, _v, _v2) */ + super.increment(d); + n3 = (double) (n - 3); + m4 = m4 - - (4.0 * v * m3) - + (6.0 * v2 * m2) + - (4.0 * v * prevM3) + + (6.0 * v2 * prevM2) + ((n0 * n0) - 3 * n1) * (v2 * v2 * n1 * n0); - m3 = m3 - (3.0 * v * m2) + (n0 * n1 * n2 * v2 * v); - - m2 = m2 + n1 * dev * v; - - m1 = m1 + v; - return m4; } - + /** * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#getValue() */ @@ -107,6 +107,8 @@ public class FourthMoment extends ThirdMoment { public void clear() { super.clear(); m4 = Double.NaN; + prevM3 = 0.0; + n3 = 0.0; } } diff --git a/src/java/org/apache/commons/math/stat/univariate/moment/GeometricMean.java b/src/java/org/apache/commons/math/stat/univariate/moment/GeometricMean.java index e076206c3..808dc5568 100644 --- a/src/java/org/apache/commons/math/stat/univariate/moment/GeometricMean.java +++ b/src/java/org/apache/commons/math/stat/univariate/moment/GeometricMean.java @@ -56,13 +56,11 @@ package org.apache.commons.math.stat.univariate.moment; import org.apache.commons.math.stat.univariate.summary.SumOfLogs; /** - * @author Mark Diggory + * * */ public class GeometricMean extends SumOfLogs { - //private SumOfLogs sumLog = new SumOfLogs(); - private double geoMean = Double.NaN; private int n = 0; @@ -92,6 +90,12 @@ public class GeometricMean extends SumOfLogs { } /** + * Returns the geometric mean for this collection of values + * @param values Is a double[] containing the values + * @param begin processing at this point in the array + * @param length processing at this point in the array + * @return the geometric mean or Double.NaN if the array is empty or + * any of the values are <= 0. * @see org.apache.commons.math.stat.univariate.UnivariateStatistic#evaluate(double[], int, int) */ public double evaluate(double[] values, int begin, int length) { diff --git a/src/java/org/apache/commons/math/stat/univariate/moment/Kurtosis.java b/src/java/org/apache/commons/math/stat/univariate/moment/Kurtosis.java index bca1bd5c1..063998579 100644 --- a/src/java/org/apache/commons/math/stat/univariate/moment/Kurtosis.java +++ b/src/java/org/apache/commons/math/stat/univariate/moment/Kurtosis.java @@ -53,93 +53,131 @@ */ package org.apache.commons.math.stat.univariate.moment; +import org + .apache + .commons + .math + .stat + .univariate + .AbstractStorelessUnivariateStatistic; + /** - * @author Mark Diggory + * */ -public class Kurtosis extends FourthMoment { +public class Kurtosis extends AbstractStorelessUnivariateStatistic { private double kurtosis = Double.NaN; + protected FourthMoment moment = null; + + protected boolean incMoment = true; + + public Kurtosis() { + moment = new FourthMoment(); + } + + public Kurtosis(FourthMoment m4) { + incMoment = false; + this.moment = m4; + } + /** * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#increment(double) */ public double increment(double d) { - super.increment(d); - - double variance = (n <= 1) ? 0.0 : m2 / (double) (n - 1); + if (incMoment) { + moment.increment(d); + } + + double variance = + (moment.n < 1) ? 0.0 : moment.m2 / (double) (moment.n - 1); kurtosis = - (n <= 3 || variance < 10E-20) + (moment.n <= 3 || variance < 10E-20) ? 0.0 - : ((double)n * ((double)n + 1) * m4 - 3 * m2 * m2 * (n-1)) - / ((n-1) * (n-2) * (n-3) * variance * variance); - + : (moment.n0 * (moment.n0 + 1) * moment.m4 + - 3 * moment.m2 * moment.m2 * moment.n1) + / (moment.n1 * moment.n2 * moment.n3 * variance * variance); + return kurtosis; } - + /** * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#getValue() */ public double getValue() { return kurtosis; } - + /** * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#clear() */ public void clear() { - super.clear(); + if (incMoment) { + moment.clear(); + } kurtosis = Double.NaN; } + /*UnvariateStatistic Approach */ + + Mean mean = new Mean(); + /** - * Returns the kurtosis for this collection of values. Kurtosis is a - * measure of the "peakedness" of a distribution. - * @param values Is a double[] containing the values - * @param begin processing at this point in the array - * @param length processing at this point in the array - * @return the kurtosis of the values or Double.NaN if the array is empty - */ - public double evaluate(double[] values, int begin, int length) { - test(values, begin, length); + * This algorithm uses a corrected two pass algorithm of the following + * + * corrected two pass formula (14.1.8), and also referenced in:

+ * "Algorithms for Computing the Sample Variance: Analysis and + * Recommendations", Chan, T.F., Golub, G.H., and LeVeque, R.J. + * 1983, American Statistician, vol. 37, pp. 242?247. + *

+ * Returns the kurtosis for this collection of values. Kurtosis is a + * measure of the "peakedness" of a distribution. + * @param values Is a double[] containing the values + * @param begin processing at this point in the array + * @param length processing at this point in the array + * @return the kurtosis of the values or Double.NaN if the array is empty + */ + public double evaluate(double[] values, int begin, int length) { + test(values, begin, length); - // Initialize the kurtosis - double kurt = Double.NaN; + // Initialize the kurtosis + double kurt = Double.NaN; - // Get the mean and the standard deviation - double mean = super.evaluate(values, begin, length); + // Get the mean and the standard deviation + double m = mean.evaluate(values, begin, length); - // Calc the std, this is implemented here instead of using the - // standardDeviation method eliminate a duplicate pass to get the mean - double accum = 0.0; - double accum2 = 0.0; - for (int i = begin; i < begin + length; i++) { - accum += Math.pow((values[i] - mean), 2.0); - accum2 += (values[i] - mean); - } - - double stdDev = - Math.sqrt( - (accum - (Math.pow(accum2, 2) / ((double) length))) - / (double) (length - 1)); + // Calc the std, this is implemented here instead of using the + // standardDeviation method eliminate a duplicate pass to get the mean + double accum = 0.0; + double accum2 = 0.0; + for (int i = begin; i < begin + length; i++) { + accum += Math.pow((values[i] - m), 2.0); + accum2 += (values[i] - m); + } - // Sum the ^4 of the distance from the mean divided by the - // standard deviation - double accum3 = 0.0; - for (int i = begin; i < begin + length; i++) { - accum3 += Math.pow((values[i] - mean) / stdDev, 4.0); - } + double stdDev = + Math.sqrt( + (accum - (Math.pow(accum2, 2) / ((double) length))) + / (double) (length - 1)); - // Get N - double n = length; + // Sum the ^4 of the distance from the mean divided by the + // standard deviation + double accum3 = 0.0; + for (int i = begin; i < begin + length; i++) { + accum3 += Math.pow((values[i] - m) / stdDev, 4.0); + } - double coefficientOne = (n * (n + 1)) / ((n - 1) * (n - 2) * (n - 3)); - double termTwo = ((3 * Math.pow(n - 1, 2.0)) / ((n - 2) * (n - 3))); - - // Calculate kurtosis - kurt = (coefficientOne * accum3) - termTwo; + // Get N + double n = length; + + double coefficientOne = (n * (n + 1)) / ((n - 1) * (n - 2) * (n - 3)); + double termTwo = ((3 * Math.pow(n - 1, 2.0)) / ((n - 2) * (n - 3))); + + // Calculate kurtosis + kurt = (coefficientOne * accum3) - termTwo; + + return kurt; + } - return kurt; - } - } diff --git a/src/java/org/apache/commons/math/stat/univariate/moment/Mean.java b/src/java/org/apache/commons/math/stat/univariate/moment/Mean.java index 4f0eccbe2..945630e7f 100644 --- a/src/java/org/apache/commons/math/stat/univariate/moment/Mean.java +++ b/src/java/org/apache/commons/math/stat/univariate/moment/Mean.java @@ -53,57 +53,77 @@ */ package org.apache.commons.math.stat.univariate.moment; -import org.apache.commons.math.stat.univariate.AbstractStorelessUnivariateStatistic; +import org + .apache + .commons + .math + .stat + .univariate + .AbstractStorelessUnivariateStatistic; import org.apache.commons.math.stat.univariate.summary.Sum; /** - * @author Mark Diggory + * */ public class Mean extends AbstractStorelessUnivariateStatistic { - - /** count of values that have been added */ - protected int n = 0; - /** first moment of values that have been added */ - protected double m1 = Double.NaN; - - private Sum sum = new Sum(); - + protected FirstMoment moment = null; + + protected boolean incMoment = true; + + public Mean() { + moment = new FirstMoment(); + } + + public Mean(FirstMoment m1) { + this.moment = m1; + incMoment = false; + } + /** * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#increment(double) */ public double increment(double d) { - if (n < 1) { - m1 = 0.0; + if (incMoment) { + moment.increment(d); } - - n++; - m1 += (d - m1) / ((double) n); - return m1; + + return moment.m1; } - + /** * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#clear() */ public void clear() { - m1 = Double.NaN; - n = 0; + if (incMoment) { + moment.clear(); + } } - + /** * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#getValue() */ public double getValue() { - return m1; + return moment.m1; } + /*UnvariateStatistic Approach */ + Sum sum = new Sum(); + /** + * Returns the + * arithmetic mean of the available values + * @param values Is a double[] containing the values + * @param begin processing at this point in the array + * @param length processing at this point in the array + * @return the mean of the values or Double.NaN if the array is empty * @see org.apache.commons.math.stat.univariate.UnivariateStatistic#evaluate(double[], int, int) */ public double evaluate(double[] values, int begin, int length) { - if(test(values,begin,length)) + if (test(values, begin, length)) { return sum.evaluate(values, begin, length) / ((double) length); + } return Double.NaN; } diff --git a/src/java/org/apache/commons/math/stat/univariate/moment/SecondMoment.java b/src/java/org/apache/commons/math/stat/univariate/moment/SecondMoment.java index f63719534..25b261f51 100644 --- a/src/java/org/apache/commons/math/stat/univariate/moment/SecondMoment.java +++ b/src/java/org/apache/commons/math/stat/univariate/moment/SecondMoment.java @@ -53,23 +53,18 @@ */ package org.apache.commons.math.stat.univariate.moment; -import org - .apache - .commons - .math - .stat - .univariate - .AbstractStorelessUnivariateStatistic; - /** - * @author Mark Diggory + * * */ -public class SecondMoment extends Mean { +public class SecondMoment extends FirstMoment { /** 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) */ @@ -77,16 +72,17 @@ public class SecondMoment extends Mean { if (n < 1) { m1 = m2 = 0.0; } + + /* increment m1 and _n0, _dev, _v) */ + super.increment(d); - n++; - - double dev = d - m1; - double v = dev / ((double) n); - - m2 += ((double)(n - 1)) * dev * v; - m1 += v; + n1 = n0 - 1; + + /* increment and return m2 */ + m2 += n1 * dev * v; return m2; + } /** @@ -95,6 +91,7 @@ public class SecondMoment extends Mean { public void clear() { super.clear(); m2 = Double.NaN; + n1 = 0.0; } /** diff --git a/src/java/org/apache/commons/math/stat/univariate/moment/Skewness.java b/src/java/org/apache/commons/math/stat/univariate/moment/Skewness.java index b087dc952..5f71f9a6e 100644 --- a/src/java/org/apache/commons/math/stat/univariate/moment/Skewness.java +++ b/src/java/org/apache/commons/math/stat/univariate/moment/Skewness.java @@ -53,28 +53,51 @@ */ package org.apache.commons.math.stat.univariate.moment; +import org + .apache + .commons + .math + .stat + .univariate + .AbstractStorelessUnivariateStatistic; + /** - * @author Mark Diggory + * * */ -public class Skewness extends ThirdMoment { +public class Skewness extends AbstractStorelessUnivariateStatistic { private double skewness = Double.NaN; + protected ThirdMoment moment = null; + + protected boolean incMoment = true; + + public Skewness() { + moment = new ThirdMoment(); + } + + public Skewness(ThirdMoment m3) { + incMoment = false; + this.moment = m3; + } + /** * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#increment(double) */ public double increment(double d) { + if (incMoment) { + moment.increment(d); + } - super.increment(d); - - double variance = (n <= 1) ? 0.0 : m2 / (double) (n - 1); + double variance = + (moment.n < 1) ? 0.0 : moment.m2 / (double) (moment.n - 1); skewness = - (n <= 2 || variance < 10E-20) + (moment.n <= 2 || variance < 10E-20) ? 0.0 - : (((double) n) * m3) - / ((n - 1) * (n - 2) * Math.sqrt(variance) * variance); + : (moment.n0 * moment.m3) + / (moment.n1 * moment.n2 * Math.sqrt(variance) * variance); return skewness; } @@ -90,55 +113,69 @@ public class Skewness extends ThirdMoment { * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#clear() */ public void clear() { - super.clear(); + if (incMoment) { + moment.clear(); + } skewness = Double.NaN; } + /*UnvariateStatistic Approach */ + + Mean mean = new Mean(); + /** - * Returns the skewness of a collection of values. Skewness is a - * measure of the assymetry of a given distribution. - * @param values Is a double[] containing the values - * @param begin processing at this point in the array - * @param length processing at this point in the array - * @return the skewness of the values or Double.NaN if the array is empty - */ - public double evaluate(double[] values, int begin, int length) { + * This algorithm uses a corrected two pass algorithm of the following + * + * corrected two pass formula (14.1.8), and also referenced in:

+ * "Algorithms for Computing the Sample Variance: Analysis and + * Recommendations", Chan, T.F., Golub, G.H., and LeVeque, R.J. + * 1983, American Statistician, vol. 37, pp. 242?247. + *

+ * Returns the skewness of a collection of values. Skewness is a + * measure of the assymetry of a given distribution. + * @param values Is a double[] containing the values + * @param begin processing at this point in the array + * @param length processing at this point in the array + * @return the skewness of the values or Double.NaN if the array is empty + * @see org.apache.commons.math.stat.univariate.UnivariateStatistic#evaluate(double[], int, int) + */ + public double evaluate(double[] values, int begin, int length) { - test(values, begin, length); + test(values, begin, length); - // Initialize the skewness - double skew = Double.NaN; + // Initialize the skewness + double skew = Double.NaN; - // Get the mean and the standard deviation - double mean = super.evaluate(values, begin, length); + // Get the mean and the standard deviation + double m = mean.evaluate(values, begin, length); - // Calc the std, this is implemented here instead of using the - // standardDeviation method eliminate a duplicate pass to get the mean - double accum = 0.0; - double accum2 = 0.0; - for (int i = begin; i < begin + length; i++) { - accum += Math.pow((values[i] - mean), 2.0); - accum2 += (values[i] - mean); - } - double stdDev = - Math.sqrt( - (accum - (Math.pow(accum2, 2) / ((double) length))) - / (double) (length - 1)); + // Calc the std, this is implemented here instead of using the + // standardDeviation method eliminate a duplicate pass to get the mean + double accum = 0.0; + double accum2 = 0.0; + for (int i = begin; i < begin + length; i++) { + accum += Math.pow((values[i] - m), 2.0); + accum2 += (values[i] - m); + } + double stdDev = + Math.sqrt( + (accum - (Math.pow(accum2, 2) / ((double) length))) + / (double) (length - 1)); - // Calculate the skew as the sum the cubes of the distance - // from the mean divided by the standard deviation. - double accum3 = 0.0; - for (int i = begin; i < begin + length; i++) { - accum3 += Math.pow((values[i] - mean) / stdDev, 3.0); - } + // Calculate the skew as the sum the cubes of the distance + // from the mean divided by the standard deviation. + double accum3 = 0.0; + for (int i = begin; i < begin + length; i++) { + accum3 += Math.pow((values[i] - m) / stdDev, 3.0); + } - // Get N - double n = length; + // Get N + double n = length; - // Calculate skewness - skew = (n / ((n - 1) * (n - 2))) * accum3; + // Calculate skewness + skew = (n / ((n - 1) * (n - 2))) * accum3; + + return skew; + } - return skew; - } - } diff --git a/src/java/org/apache/commons/math/stat/univariate/moment/StandardDeviation.java b/src/java/org/apache/commons/math/stat/univariate/moment/StandardDeviation.java index c65cefd90..c3f676b82 100644 --- a/src/java/org/apache/commons/math/stat/univariate/moment/StandardDeviation.java +++ b/src/java/org/apache/commons/math/stat/univariate/moment/StandardDeviation.java @@ -53,47 +53,57 @@ */ package org.apache.commons.math.stat.univariate.moment; -import org.apache.commons.math.stat.univariate.AbstractStorelessUnivariateStatistic; - /** - * @author Mark Diggory + * * */ -public class StandardDeviation extends AbstractStorelessUnivariateStatistic { +public class StandardDeviation extends Variance { - private double value = Double.NaN; + private double std = Double.NaN; - private Variance var = new Variance(); + public StandardDeviation(){ + super(); + } + + public StandardDeviation(SecondMoment m2){ + super(m2); + } /** * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#increment(double) */ public double increment(double d) { - var.increment(d); - value = Math.sqrt(var.getValue()); - return value; + super.increment(d); + std = (variance != 0.0) ? Math.sqrt(variance) : 0.0; + return std; } /** * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#getValue() */ public double getValue() { - return value; + return std; } /** * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#clear() */ public void clear() { - var.clear(); - value = Double.NaN; + super.clear(); + std = Double.NaN; } - /* (non-Javadoc) + /** + * Returns the Standard Deviation on an array of values. + * @param values Is a double[] containing the values + * @param begin processing at this point in the array + * @param length processing at this point in the array + * @return the result, Double.NaN if no values for an empty array + * or 0.0 for a single value set. * @see org.apache.commons.math.stat.univariate.UnivariateStatistic#evaluate(double[], int, int) */ public double evaluate(double[] values, int begin, int length) { - double tmp = var.evaluate(values, begin, length); + double tmp = super.evaluate(values, begin, length); return tmp != 0.0 ? Math.sqrt(tmp) : 0.0; } diff --git a/src/java/org/apache/commons/math/stat/univariate/moment/ThirdMoment.java b/src/java/org/apache/commons/math/stat/univariate/moment/ThirdMoment.java index f6d05a325..c699b5777 100644 --- a/src/java/org/apache/commons/math/stat/univariate/moment/ThirdMoment.java +++ b/src/java/org/apache/commons/math/stat/univariate/moment/ThirdMoment.java @@ -54,7 +54,7 @@ package org.apache.commons.math.stat.univariate.moment; /** - * @author Mark Diggory + * * */ public class ThirdMoment extends SecondMoment{ @@ -62,6 +62,15 @@ public class ThirdMoment extends SecondMoment{ /** 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; + + /** temporary internal state made availabel for higher order moments */ + protected double prevM2 = 0.0; + /** * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#increment(double) */ @@ -70,23 +79,17 @@ public class ThirdMoment extends SecondMoment{ m3 = m2 = m1 = 0.0; } - n++; + /* retain a reference to the last m2*/ + prevM2 = m2; - double dev = d - m1; - double v = dev / ((double) n); - double v2 = v * v; - - double n0 = (double) n; - double n1 = (double) (n - 1); - double n2 = (double) (n - 2); - + /* increment m1 and m2 (and _n0, _n1, _v) */ + super.increment(d); - m3 = m3 - (3.0 * v * m2) + (n0 * n1 * n2 * v2 * v); + v2 = v * v; + n2 = (double) (n - 2); - m2 = m2 + n1 * dev * v; + m3 = m3 - (3.0 * v * prevM2) + (n0 * n1 * n2 * v2 * v); - m1 = m1 + v; - return m3; } @@ -103,6 +106,9 @@ public class ThirdMoment extends SecondMoment{ public void clear() { super.clear(); m3 = Double.NaN; + v2 = 0.0; + n2 = 0.0; + prevM2 = 0.0; } } \ No newline at end of file diff --git a/src/java/org/apache/commons/math/stat/univariate/moment/Variance.java b/src/java/org/apache/commons/math/stat/univariate/moment/Variance.java index cf8838bb3..3ea591f63 100644 --- a/src/java/org/apache/commons/math/stat/univariate/moment/Variance.java +++ b/src/java/org/apache/commons/math/stat/univariate/moment/Variance.java @@ -53,29 +53,37 @@ */ package org.apache.commons.math.stat.univariate.moment; -import org - .apache - .commons - .math - .stat - .univariate - .AbstractStorelessUnivariateStatistic; +import org.apache.commons.math.stat.univariate.AbstractStorelessUnivariateStatistic; /** - * @author Mark Diggory + * * */ -public class Variance extends SecondMoment { +public class Variance extends AbstractStorelessUnivariateStatistic{ - private double variance = Double.NaN; + protected double variance = Double.NaN; + protected SecondMoment moment = null; + + protected boolean incMoment = true; + + public Variance(){ + moment = new SecondMoment(); + } + + public Variance(SecondMoment m2){ + incMoment = false; + this.moment = m2; + } /** * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#increment(double) */ public double increment(double d) { - super.increment(d); - - variance = (n < 1) ? 0.0 : m2 / (double)(n - 1); + if (incMoment) { + moment.increment(d); + } + + variance = (moment.n < 1) ? 0.0 : moment.m2 / (double)(moment.n - 1); return variance; } @@ -91,11 +99,30 @@ public class Variance extends SecondMoment { * @see org.apache.commons.math.stat.univariate.StorelessUnivariateStatistic#clear() */ public void clear() { - super.clear(); + if (incMoment) { + moment.clear(); + } variance = Double.NaN; } - /* (non-Javadoc) + /*UnvariateStatistic Approach */ + + Mean mean = new Mean(); + + /** + * Returns the variance of the available values. This uses a corrected + * two pass algorithm of the following + * + * corrected two pass formula (14.1.8), and also referenced in:

+ * "Algorithms for Computing the Sample Variance: Analysis and + * Recommendations", Chan, T.F., Golub, G.H., and LeVeque, R.J. + * 1983, American Statistician, vol. 37, pp. 242?247. + * + * @param values Is a double[] containing the values + * @param begin processing at this point in the array + * @param length processing at this point in the array + * @return the result, Double.NaN if no values for an empty array + * or 0.0 for a single value set. * @see org.apache.commons.math.stat.univariate.UnivariateStatistic#evaluate(double[], int, int) */ public double evaluate(double[] values, int begin, int length) { @@ -103,7 +130,7 @@ public class Variance extends SecondMoment { if (values.length == 1) { var = 0; } else if (values.length > 1) { - double m = super.evaluate(values, begin, length); + double m = mean.evaluate(values, begin, length); double accum = 0.0; double accum2 = 0.0; for (int i = begin; i < begin + length; i++) { diff --git a/src/java/org/apache/commons/math/stat/univariate/rank/Max.java b/src/java/org/apache/commons/math/stat/univariate/rank/Max.java index bce9084d2..d6df076e2 100644 --- a/src/java/org/apache/commons/math/stat/univariate/rank/Max.java +++ b/src/java/org/apache/commons/math/stat/univariate/rank/Max.java @@ -62,7 +62,7 @@ import org .AbstractStorelessUnivariateStatistic; /** - * @author Mark Diggory + * */ public class Max extends AbstractStorelessUnivariateStatistic { diff --git a/src/java/org/apache/commons/math/stat/univariate/rank/Median.java b/src/java/org/apache/commons/math/stat/univariate/rank/Median.java index 1eed93f60..0e4ba3bc3 100644 --- a/src/java/org/apache/commons/math/stat/univariate/rank/Median.java +++ b/src/java/org/apache/commons/math/stat/univariate/rank/Median.java @@ -55,7 +55,7 @@ package org.apache.commons.math.stat.univariate.rank; /** - * @author Mark Diggory + * */ public class Median extends Percentile { diff --git a/src/java/org/apache/commons/math/stat/univariate/rank/Min.java b/src/java/org/apache/commons/math/stat/univariate/rank/Min.java index 11aae1051..dcdf3d60f 100644 --- a/src/java/org/apache/commons/math/stat/univariate/rank/Min.java +++ b/src/java/org/apache/commons/math/stat/univariate/rank/Min.java @@ -62,7 +62,7 @@ import org .AbstractStorelessUnivariateStatistic; /** - * @author Mark Diggory + * */ public class Min extends AbstractStorelessUnivariateStatistic { diff --git a/src/java/org/apache/commons/math/stat/univariate/rank/Percentile.java b/src/java/org/apache/commons/math/stat/univariate/rank/Percentile.java index 57e98884b..961497572 100644 --- a/src/java/org/apache/commons/math/stat/univariate/rank/Percentile.java +++ b/src/java/org/apache/commons/math/stat/univariate/rank/Percentile.java @@ -57,9 +57,7 @@ import java.util.Arrays; import org.apache.commons.math.stat.univariate.AbstractUnivariateStatistic; /** - * @author Tim O'Brien - * @author Mark Diggory - * @author Phil Steitz + * */ public class Percentile extends AbstractUnivariateStatistic { diff --git a/src/java/org/apache/commons/math/stat/univariate/summary/Product.java b/src/java/org/apache/commons/math/stat/univariate/summary/Product.java index be1e02044..1baff8a6f 100644 --- a/src/java/org/apache/commons/math/stat/univariate/summary/Product.java +++ b/src/java/org/apache/commons/math/stat/univariate/summary/Product.java @@ -62,7 +62,7 @@ import org .AbstractStorelessUnivariateStatistic; /** - * @author Mark Diggory + * */ public class Product extends AbstractStorelessUnivariateStatistic { @@ -99,6 +99,11 @@ public class Product extends AbstractStorelessUnivariateStatistic { } /** + * Returns the product for this collection of values + * @param values Is a double[] containing the values + * @param begin processing at this point in the array + * @param length processing at this point in the array + * @return the product values or Double.NaN if the array is empty * @see org.apache.commons.math.stat.univariate.UnivariateStatistic#evaluate(double[], int, int) */ public double evaluate(double[] values, int begin, int length) { diff --git a/src/java/org/apache/commons/math/stat/univariate/summary/Sum.java b/src/java/org/apache/commons/math/stat/univariate/summary/Sum.java index bbbac6b1c..0d9b79d3e 100644 --- a/src/java/org/apache/commons/math/stat/univariate/summary/Sum.java +++ b/src/java/org/apache/commons/math/stat/univariate/summary/Sum.java @@ -62,7 +62,6 @@ import org .AbstractStorelessUnivariateStatistic; /** - * @author Mark Diggory * */ public class Sum extends AbstractStorelessUnivariateStatistic { @@ -99,6 +98,11 @@ public class Sum extends AbstractStorelessUnivariateStatistic { } /** + * The sum of the values that have been added to Univariate. + * @param values Is a double[] containing the values + * @param begin processing at this point in the array + * @param length processing at this point in the array + * @return the sum of the values or Double.NaN if the array is empty * @see org.apache.commons.math.stat.univariate.UnivariateStatistic#evaluate(double[], int, int) */ public double evaluate(double[] values, int begin, int length) { diff --git a/src/java/org/apache/commons/math/stat/univariate/summary/SumOfLogs.java b/src/java/org/apache/commons/math/stat/univariate/summary/SumOfLogs.java index f09838b0a..1b2b6676d 100644 --- a/src/java/org/apache/commons/math/stat/univariate/summary/SumOfLogs.java +++ b/src/java/org/apache/commons/math/stat/univariate/summary/SumOfLogs.java @@ -62,7 +62,6 @@ import org .AbstractStorelessUnivariateStatistic; /** - * @author Mark Diggory * */ public class SumOfLogs extends AbstractStorelessUnivariateStatistic { @@ -100,6 +99,11 @@ public class SumOfLogs extends AbstractStorelessUnivariateStatistic { } /** + * Returns the sum of the natural logs for this collection of values + * @param values Is a double[] containing the values + * @param begin processing at this point in the array + * @param length processing at this point in the array + * @return the sumLog value or Double.NaN if the array is empty * @see org.apache.commons.math.stat.univariate.UnivariateStatistic#evaluate(double[], int, int) */ public double evaluate(double[] values, int begin, int length) { diff --git a/src/java/org/apache/commons/math/stat/univariate/summary/SumOfSquares.java b/src/java/org/apache/commons/math/stat/univariate/summary/SumOfSquares.java index 9761a8be5..672e36893 100644 --- a/src/java/org/apache/commons/math/stat/univariate/summary/SumOfSquares.java +++ b/src/java/org/apache/commons/math/stat/univariate/summary/SumOfSquares.java @@ -62,7 +62,6 @@ import org .AbstractStorelessUnivariateStatistic; /** - * @author Mark Diggory * */ public class SumOfSquares extends AbstractStorelessUnivariateStatistic { @@ -99,6 +98,11 @@ public class SumOfSquares extends AbstractStorelessUnivariateStatistic { } /** + * Returns the sum of the squares of the available values. + * @param values Is a double[] containing the values + * @param begin processing at this point in the array + * @param length processing at this point in the array + * @return the sum of the squared values or Double.NaN if the array is empty * @see org.apache.commons.math.stat.univariate.UnivariateStatistic#evaluate(double[], int, int) */ public double evaluate(double[] values, int begin, int length) {