/* XXL: The eXtensible and fleXible Library for data processing
Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger
Head of the Database Research Group
Department of Mathematics and Computer Science
University of Marburg
Germany
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; If not, see <http://www.gnu.org/licenses/>.
http://code.google.com/p/xxl/
*/
package xxl.core.math.statistics.parametric.aggregates;
import xxl.core.math.functions.AggregationFunction;
/**
* Estimates iteratively the average of given
* {@link java.lang.Number numerical data} without any error control. In
* contrast to aggregation functions provided by
* {@link xxl.core.math.statistics.parametric.aggregates.ConfidenceAggregationFunction}
* objects of this class don't compute confidence intervals for processed data.
* The average itself is computed iteratively, i.e. the data is successively
* consumed and the current average is computed with the 'old' average and the
* new data element.
*
* <p><b>Objects of this type are recommended for the usage with aggregator
* cursors!</b></p>
*
* <p>Generally, each aggregation function must support a function call of the
* following type:<br>
* <tt>agg_n = f (agg_n-1, next)</tt>, <br>
* where <tt>agg_n</tt> denotes the computed aggregation value after <tt>n</tt>
* steps, <tt>f</tt> the aggregation function, <tt>agg_n-1</tt> the computed
* aggregation value after <tt>n-1</tt> steps and <tt>next</tt> the next object
* to use for computation. An aggregation function delivers only <tt>null</tt>
* as aggregation result as long as the aggregation function has not yet fully
* initialized.<br>
* Consider the following example:
* <code><pre>
Aggregator aggregator = new Aggregator(
new DiscreteRandomNumber(new JavaDiscreteRandomWrapper(100), 50), // input cuursor
new StatefulAverage() // aggregate function
);
* </pre></code>
*
* A more detailed coverage of online aggregation is given in [HHW97]: P. Haas,
* J. Hellerstein, H. Wang. Online Aggregation. 1997.
*
* @see xxl.core.cursors.mappers.Aggregator
* @see xxl.core.functions.Function
*/
public class StatefulAverage extends AggregationFunction<Number,Number> {
/** stores the number of already processed objects */
protected long count;
/** Two-figured function call for supporting aggregation by this function.
* Each aggregation function must support a function call like <tt>agg_n = f (agg_n-1, next)</tt>,
* where <tt>agg_n</tt> denotes the computed aggregation value after <tt>n</tt> steps, <tt>f</tt>
* the aggregation function, <tt>agg_n-1</tt> the computed aggregation value after <tt>n-1</tt> steps
* and <tt>next</tt> the next object to use for computation.
* This method delivers only <tt>null</tt> as aggregation result as long as the aggregation
* has not yet initialized.
*
* @param average result of the aggregation function in the previous computation step
* @param next next number used for computation
* @return aggregation value after n steps
*/
@Override
public Number invoke(Number average, Number next) {
if (next == null)
return average;
if (average == null) {
count = 1;
return next;
}
count++;
return ((count - 1d) * average.doubleValue() + next.doubleValue()) / count;
}
}