Added getSumOfLogs method to SummaryStatistics and made

sum of logs instance used by GeometricMean configurable.
JIRA: MATH-191


git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@620221 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Phil Steitz 2008-02-09 23:42:44 +00:00
parent 8f10ef7c0e
commit f18c6b1aff
4 changed files with 75 additions and 42 deletions

View File

@ -120,7 +120,7 @@ public class SummaryStatistics implements StatisticalSummary, Serializable {
protected SumOfLogs sumLog = new SumOfLogs();
/** geoMean of values that have been added */
protected GeometricMean geoMean = new GeometricMean();
protected GeometricMean geoMean = new GeometricMean(sumLog);
/** mean of values that have been added */
protected Mean mean = new Mean();
@ -174,16 +174,18 @@ public class SummaryStatistics implements StatisticalSummary, Serializable {
minImpl.increment(value);
maxImpl.increment(value);
sumLogImpl.increment(value);
geoMean.increment(value);
secondMoment.increment(value);
// If mean or variance have been overridden,
// need to increment these, since they don't have secondMoment
// If mean, variance or geomean have been overridden,
// need to increment these
if (!(meanImpl instanceof Mean)) {
meanImpl.increment(value);
}
if (!(varianceImpl instanceof Variance)) {
varianceImpl.increment(value);
}
if (!(geoMeanImpl instanceof GeometricMean)) {
geoMeanImpl.increment(value);
}
n++;
}
@ -296,6 +298,17 @@ public class SummaryStatistics implements StatisticalSummary, Serializable {
return geoMeanImpl.getResult();
}
/**
* Returns the sum of the logs of the values that have been added.
* <p>
* Double.NaN is returned if no values have been added.</p>
*
* @return the sum of logs
*/
public double getSumOfLogs() {
return sumLogImpl.getResult();
}
/**
* Generates a text report displaying
* summary statistics from values that
@ -313,6 +326,7 @@ public class SummaryStatistics implements StatisticalSummary, Serializable {
outBuffer.append("variance: " + getVariance() + "\n");
outBuffer.append("sum of squares: " + getSumsq() + "\n");
outBuffer.append("standard deviation: " + getStandardDeviation() + "\n");
outBuffer.append("sum of logs: " + getSumOfLogs() + "\n");
return outBuffer.toString();
}
@ -505,6 +519,7 @@ public class SummaryStatistics implements StatisticalSummary, Serializable {
StorelessUnivariateStatistic sumLogImpl) {
checkEmpty();
this.sumLogImpl = sumLogImpl;
geoMean.setSumLogImpl(sumLogImpl);
}
/**

View File

@ -17,6 +17,7 @@
package org.apache.commons.math.stat.descriptive.moment;
import org.apache.commons.math.stat.descriptive.AbstractStorelessUnivariateStatistic;
import org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic;
import org.apache.commons.math.stat.descriptive.summary.SumOfLogs;
/**
@ -49,7 +50,7 @@ public class GeometricMean extends AbstractStorelessUnivariateStatistic {
private static final long serialVersionUID = -8178734905303459453L;
/** Wrapped SumOfLogs instance */
private SumOfLogs sumOfLogs;
private StorelessUnivariateStatistic sumOfLogs;
/**
* Create a GeometricMean instance
@ -58,6 +59,13 @@ public class GeometricMean extends AbstractStorelessUnivariateStatistic {
sumOfLogs = new SumOfLogs();
}
/**
* Create a GeometricMean instance using the given SumOfLogs instance
*/
public GeometricMean(SumOfLogs sumOfLogs) {
this.sumOfLogs = sumOfLogs;
}
/**
* @see org.apache.commons.math.stat.descriptive.StorelessUnivariateStatistic#increment(double)
*/
@ -111,5 +119,41 @@ public class GeometricMean extends AbstractStorelessUnivariateStatistic {
public long getN() {
return sumOfLogs.getN();
}
/**
* <p>Sets the implementation for the sum of logs.</p>
* <p>This method must be activated before any data has been added - i.e.,
* before {@link #addValue(double) addValue} has been used to add data;
* otherwise an IllegalStateException will be thrown.</p>
*
* @param sumLogImpl the StorelessUnivariateStatistic instance to use
* for computing the log sum
* @throws IllegalStateException if data has already been added
* (i.e if n > 0)
*/
public void setSumLogImpl(
StorelessUnivariateStatistic sumLogImpl) {
checkEmpty();
this.sumOfLogs = sumLogImpl;
}
/**
* Returns the currently configured sum of logs implementation
*
* @return the StorelessUnivariateStatistic implementing the log sum
*/
public StorelessUnivariateStatistic getSumLogImpl() {
return sumOfLogs;
}
/**
* Throws IllegalStateException if n > 0.
*/
private void checkEmpty() {
if (getN() > 0) {
throw new IllegalStateException(
"Implementation must be configured before values are added.");
}
}
}

View File

@ -162,7 +162,11 @@ Commons Math Release Notes</title>
covariance)
</action>
<action dev="luc" type="add" >
Added multivariate summary statistics
Added multivariate summary statistics.
</action>
<action dev="psteitz" type="update" issue="MATH-191">
Added getSumOfLogs method to SummaryStatistics and made SumOfLogs
instance used by GeometricMean configurable.
</action>
</release>
<release version="1.1" date="2005-12-17"

View File

@ -21,6 +21,7 @@ import junit.framework.Test;
import junit.framework.TestSuite;
import org.apache.commons.math.stat.descriptive.moment.Mean;
import org.apache.commons.math.stat.descriptive.summary.Sum;
/**
* Test cases for the {@link SummaryStatistics} class.
* When SummaryStatisticsImpl is removed in math 2.0, test cases from
@ -47,10 +48,13 @@ public final class SummaryStatisticsTest extends SummaryStatisticsAbstractTest {
public void testSetterInjection() throws Exception {
SummaryStatistics u = createSummaryStatistics();
u.setMeanImpl(new sumMean());
u.setMeanImpl(new Sum());
u.setSumLogImpl(new Sum());
u.addValue(1);
u.addValue(3);
assertEquals(4, u.getMean(), 1E-14);
assertEquals(4, u.getSumOfLogs(), 1E-14);
assertEquals(Math.exp(2), u.getGeometricMean(), 1E-14);
u.clear();
u.addValue(1);
u.addValue(2);
@ -64,44 +68,10 @@ public final class SummaryStatisticsTest extends SummaryStatisticsAbstractTest {
u.addValue(1);
u.addValue(3);
try {
u.setMeanImpl(new sumMean());
u.setMeanImpl(new Sum());
fail("Expecting IllegalStateException");
} catch (IllegalStateException ex) {
// expected
}
}
/**
* Bogus mean implementation to test setter injection.
* Returns the sum instead of the mean.
*/
static class sumMean implements StorelessUnivariateStatistic {
private static final long serialVersionUID = 6492471391340853423L;
private double sum = 0;
private long n = 0;
public double evaluate(double[] values, int begin, int length) {
return 0;
}
public double evaluate(double[] values) {
return 0;
}
public void clear() {
sum = 0;
n = 0;
}
public long getN() {
return n;
}
public double getResult() {
return sum;
}
public void increment(double d) {
sum += d;
n++;
}
public void incrementAll(double[] values, int start, int length) {
}
public void incrementAll(double[] values) {
}
}
}