/* 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; /** This class provides an estimator for the aggregation function <TT>SUM</TT>. * The expected sum is computed by S_e = size_of_entirety * running_average, i.e., * the totally number of elements must be given in advance.<BR> * If the already processed data exceeds the given size of the entirety there are three * different strategies available to solve this: <BR> * 1. RESTRICTIVE: Throw an IllegalStateException <BR> * 3. ADAPTIVE: Adapt the given size of the entirety to the number of already processed data <BR> * 3. QUIET: Do nothing <BR> * The used strategy is passed to the estimator by an int. * * <br> * <p><b>Objects of this type are recommended for the usage with aggregator cursors!</b></p> * <br> * 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> * Objects of this class don't use any internally stored information to obtain the estimated sum, * so one could say objects of this type or 'status-less'. * See {@link xxl.core.math.statistics.parametric.aggregates.OnlineAggregation OnlineAggregation} for further details about * aggregation function using internally stored information. * * Consider the following example: * <code><pre> * Aggregator aggregator = new Aggregator( new RandomIntegers(100, 50), // input-Cursor new SumEstimator() // aggregate function ); * <\code><\pre> * <br> * * @see xxl.core.cursors.mappers.Aggregator * @see xxl.core.functions.Function */ public class SumEstimator extends AggregationFunction<Number,Number> { /** Some constant indicating strategy number 1 will be used */ public static final int RESTRICTIVE = 1; /** Some constant indicating strategy number 2 will be used */ public static final int ADAPTIVE = 2; /** Some constant indicating strategy number 3 will be used */ public static final int QUIET = 3; // ---- /** the number of data elements in the processed stream */ protected long N; /** number of already processed data */ protected long n; /** internally used function for computing the average of the already processed data */ protected StatefulAverage avg; /** actual computed average */ protected Number a; /** used strategy for error handling */ protected int strategy; /** Constructs a new Object of this type. * * @param size number of data elements in the processed stream * @param strategy used strategy for error handling */ public SumEstimator(long size, int strategy) { N = size; avg = new StatefulAverage(); a = null; n = 0; this.strategy = strategy; } /** Constructs a new Object of this type using the restrictive-strategy * for error handling by default. * * @param size number of data elements in the processed stream */ public SumEstimator(long size) { this(size, RESTRICTIVE); } /** 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 expectedSum result of the aggregation function in the previous computation step * @param next next number used for computation * @return aggregation value after n steps * @throws IllegalStateException if the number or already processed data exceeds the given size of entirety */ public Number invoke(Number expectedSum, Number next) throws IllegalStateException { n++; if (n > N) { switch (strategy) { case RESTRICTIVE : throw new IllegalStateException("Maximum number of data resp. given size of entirety exceeded!"); case ADAPTIVE : N = n; break; } } a = avg.invoke(a, next); return new Double(N * ((Number) a).doubleValue()); } }