Added AggregateSummaryStatistics class to support aggregation of SummaryStatistics.

JIRA: MATH-224
Reported by Andre Panisson
Patched by John Bollinger


git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@768921 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Phil Steitz 2009-04-27 10:51:52 +00:00
parent 6f47f883d6
commit 4566fcf22c
4 changed files with 324 additions and 0 deletions

View File

@ -105,6 +105,9 @@
<contributor> <contributor>
<name>R&#233;mi Arntzen</name> <name>R&#233;mi Arntzen</name>
</contributor> </contributor>
<contributor>
<name>John Bollinger</name>
</contributor>
<contributor> <contributor>
<name>Cyril Briquet</name> <name>Cyril Briquet</name>
</contributor> </contributor>

View File

@ -0,0 +1,245 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.stat.descriptive;
import java.io.Serializable;
/**
* <p>
* A StatisticalSummary that aggregates statistics from several data sets or
* data set partitions. In its simplest usage mode, the client creates an
* instance via the zero-argument constructor, then uses
* {@link #createContributingStatistics()} to obtain a {@code SummaryStatistics}
* for each individual data set / partition. The per-set statistics objects
* are used as normal, and at any time the aggregate statistics for all the
* contributors can be obtained from this object.
* </p><p>
* Clients with specialized requirements can use alternative constructors to
* control the statistics implementations and initial values used by the
* contributing and the internal aggregate {@code SummaryStatistics} objects.
* </p>
*
* @since 2.0
* @version $Revision:$ $Date:$
*
*/
public class AggregateSummaryStatistics implements StatisticalSummary,
Serializable {
/**
* The serialization version of this class
*/
private static final long serialVersionUID = 1L;
/**
* A SummaryStatistics serving as a prototype for creating SummaryStatistics
* contributing to this aggregate
*/
private SummaryStatistics statisticsPrototype;
/**
* The SummaryStatistics in which aggregate statistics are accumulated
*/
private SummaryStatistics statistics;
/**
* Initializes a new AggregateSummaryStatistics with default statistics
* implementations.
*
* @see SummaryStatistics#SummaryStatistics()
*/
public AggregateSummaryStatistics() {
this(new SummaryStatistics());
}
/**
* Initializes a new AggregateSummaryStatistics with the specified statistics
* object as a prototype for contributing statistics and for the internal
* aggregate statistics. This provides for customized statistics implementations
* to be used by contributing and aggregate statistics.
*
* @param prototypeStatistics a {@code SummaryStatistics} serving as a
* prototype both for the internal aggregate statistics and for
* contributing statistics obtained via the
* {@code createContributingStatistics()} method. Being a prototype
* means that other objects are initialized by copying this object's state.
* If {@code null}, a new, default statistics object is used. Any statistic
* values in the prototype are propagated to contributing statistics
* objects and (once) into these aggregate statistics.
* @see #createContributingStatistics()
*/
public AggregateSummaryStatistics(SummaryStatistics prototypeStatistics) {
this(prototypeStatistics, (prototypeStatistics == null ? null :
new SummaryStatistics(prototypeStatistics)));
}
/**
* Initializes a new AggregateSummaryStatistics with the specified statistics
* object as a prototype for contributing statistics and for the internal
* aggregate statistics. This provides for different statistics implementations
* to be used by contributing and aggregate statistics and for an initial
* state to be supplied for the aggregate statistics.
*
* @param prototypeStatistics a {@code SummaryStatistics} serving as a
* prototype both for the internal aggregate statistics and for
* contributing statistics obtained via the
* {@code createContributingStatistics()} method. Being a prototype
* means that other objects are initialized by copying this object's state.
* If {@code null}, a new, default statistics object is used. Any statistic
* values in the prototype are propagated to contributing statistics
* objects, but not into these aggregate statistics.
* @param initialStatistics a {@code SummaryStatistics} to serve as the
* internal aggregate statistics object. If {@code null}, a new, default
* statistics object is used.
* @see #createContributingStatistics()
*/
public AggregateSummaryStatistics(SummaryStatistics prototypeStatistics,
SummaryStatistics initialStatistics) {
this.statisticsPrototype = ((prototypeStatistics == null) ?
new SummaryStatistics() : prototypeStatistics);
this.statistics = ((initialStatistics == null) ?
new SummaryStatistics() : initialStatistics);
}
/**
* {@inheritDoc}. This version returns the maximum over all the aggregated
* data.
*
* @see StatisticalSummary#getMax()
*/
public double getMax() {
return statistics.getMax();
}
/**
* {@inheritDoc}. This version returns the mean of all the aggregated data.
*
* @see StatisticalSummary#getMean()
*/
public double getMean() {
return statistics.getMean();
}
/**
* {@inheritDoc}. This version returns the minimum over all the aggregated
* data.
*
* @see StatisticalSummary#getMin()
*/
public double getMin() {
return statistics.getMin();
}
/**
* {@inheritDoc}. This version returns a count of all the aggregated data.
*
* @see StatisticalSummary#getN()
*/
public long getN() {
return statistics.getN();
}
/**
* {@inheritDoc}. This version returns the standard deviation of all the
* aggregated data.
*
* @see StatisticalSummary#getStandardDeviation()
*/
public double getStandardDeviation() {
return statistics.getStandardDeviation();
}
/**
* {@inheritDoc}. This version returns a sum of all the aggregated data.
*
* @see StatisticalSummary#getSum()
*/
public double getSum() {
return statistics.getSum();
}
/**
* {@inheritDoc}. This version returns the variance of all the aggregated
* data.
*
* @see StatisticalSummary#getVariance()
*/
public double getVariance() {
return statistics.getVariance();
}
/**
* Creates and returns a {@code SummaryStatistics} whose data will be
* aggregated with those of this {@code AggregateSummaryStatistics}.
*
* @return a {@code SummaryStatistics} whose data will be aggregated with
* those of this {@code AggregateSummaryStatistics}. The initial state
* is a copy of the configured prototype statistics.
*/
public SummaryStatistics createContributingStatistics() {
SummaryStatistics contributingStatistics
= new AggregatingSummaryStatistics(statistics);
SummaryStatistics.copy(statisticsPrototype, contributingStatistics);
return contributingStatistics;
}
/**
* A SummaryStatistics that also forwards all values added to it to a second
* {@code SummaryStatistics} for aggregation.
*
* @since 2.0
*/
private static class AggregatingSummaryStatistics extends SummaryStatistics {
/**
* The serialization version of this class
*/
private static final long serialVersionUID = 1L;
/**
* An additional SummaryStatistics into which values added to these
* statistics (and possibly others) are aggregated
*/
private SummaryStatistics aggregateStatistics;
/**
* Initializes a new AggregatingSummaryStatistics with the specified
* aggregate statistics object
*
* @param aggregateStatistics a {@code SummaryStatistics} into which
* values added to this statistics object should be aggregated
*/
public AggregatingSummaryStatistics(SummaryStatistics aggregateStatistics) {
this.aggregateStatistics = aggregateStatistics;
}
/**
* {@inheritDoc}. This version adds the provided value to the configured
* aggregate after adding it to these statistics.
*
* @see SummaryStatistics#addValue(double)
*/
@Override
public void addValue(double value) {
super.addValue(value);
aggregateStatistics.addValue(value);
}
}
}

View File

@ -43,6 +43,9 @@ The <action> type attribute can be add,update,fix,remove.
Added support for any type of field in linear algebra (FielxMatrix, FieldVector, Added support for any type of field in linear algebra (FielxMatrix, FieldVector,
FieldLUDecomposition) FieldLUDecomposition)
</action> </action>
<action dev="psteitz" type="add" due-to="John Bollinger">
Added AggregateSummaryStatistics class to support aggregation of SummaryStatistics.
</action>
<action dev="luc" type="add" > <action dev="luc" type="add" >
Added general Field and FieldElement interfaces to allow generic algorithms Added general Field and FieldElement interfaces to allow generic algorithms
to operate on fields. The library already provides several implementations: to operate on fields. The library already provides several implementations:

View File

@ -0,0 +1,73 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.stat.descriptive;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test cases for {@link AggregateSummaryStatistics}
*
*/
public class AggregateSummaryStatisticsTest extends TestCase {
/**
* Tests the standard aggregation behavior
*/
public void testAggregation() {
AggregateSummaryStatistics aggregate = new AggregateSummaryStatistics();
SummaryStatistics setOneStats = aggregate.createContributingStatistics();
SummaryStatistics setTwoStats = aggregate.createContributingStatistics();
assertNotNull("The set one contributing stats are null", setOneStats);
assertNotNull("The set two contributing stats are null", setTwoStats);
assertNotSame("Contributing stats objects are the same", setOneStats, setTwoStats);
setOneStats.addValue(2);
setOneStats.addValue(3);
setOneStats.addValue(5);
setOneStats.addValue(7);
setOneStats.addValue(11);
assertEquals("Wrong number of set one values", 5, setOneStats.getN());
assertEquals("Wrong sum of set one values", 28.0, setOneStats.getSum());
setTwoStats.addValue(2);
setTwoStats.addValue(4);
setTwoStats.addValue(8);
assertEquals("Wrong number of set two values", 3, setTwoStats.getN());
assertEquals("Wrong sum of set two values", 14.0, setTwoStats.getSum());
assertEquals("Wrong number of aggregate values", 8, aggregate.getN());
assertEquals("Wrong aggregate sum", 42.0, aggregate.getSum());
}
/**
* Creates and returns a {@code Test} representing all the test cases in this
* class
*
* @return a {@code Test} representing all the test cases in this class
*/
public static Test suite() {
TestSuite suite = new TestSuite(AggregateSummaryStatisticsTest.class);
suite.setName("AggregateSummaryStatistics tests");
return suite;
}
}