/* 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.functions;
import xxl.core.functions.Function;
import xxl.core.math.Statistics;
import xxl.core.math.numerics.splines.CubicBezierSpline;
import xxl.core.math.numerics.splines.RB1CubicBezierSpline;
import xxl.core.math.statistics.parametric.aggregates.OnlineAggregation;
import xxl.core.predicates.AbstractPredicate;
import xxl.core.predicates.Predicate;
/**
* This class provides a compression algorithm based upon the approximation of real-valued
* one-dimensional functions by a cubic Bezier-Spline interpolate
* used as an aggregation
* function for online aggregation
* of given {@link java.lang.Number numerical data} without any error control.
* One is able to reduce the required memory to
* store a real-valued function as a result of a aggregation step by substituting the
* function by an approximating cubic Bezier-Spline interpolate with the first boundary condition.
* <br><br>
* Unlike aggregation functions provided by {@link xxl.core.math.statistics.parametric.aggregates.ConfidenceAggregationFunction}
* objects of
* this class don't compute confidence intervals for the processed data.
* Furthermore, this class implements the interface given by
* {@link xxl.core.math.statistics.parametric.aggregates.OnlineAggregation OnlineAggregation}.
* This interface provides special functionality of aggregation functions by supporting
* <tt>online</tt> features like watching and controlling .
* See {@link xxl.core.math.statistics.parametric.aggregates.OnlineAggregation OnlineAggregation} for further details.
* <br>
* <p><b>Objects of this type are recommended for the usage with aggregator cursors!</b></p>
* <br>
* This class shows how one can use an
* estimation function as an aggregate function using the
* {@link xxl.core.cursors.mappers.Aggregator aggregator cursor}.
* {@link xxl.core.functions.Function Functions} used in the context of online
* aggregation must support two-figured function calls.
*
* 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.
*
* @see xxl.core.functions.Function
* @see xxl.core.math.statistics.parametric.aggregates.OnlineAggregation
* @see xxl.core.math.statistics.nonparametric.kernels.NativeKernelDensityEstimator
* @see xxl.core.cursors.mappers.Aggregator
* @see xxl.core.math.numerics.splines.CubicBezierSpline
* @see xxl.core.math.numerics.splines.RB1CubicBezierSpline
*/
public class SplineCompressedFunctionAggregateFunction extends AggregationFunction implements OnlineAggregation {
/** aggregation function delivering real-valued one-dimensional functions
*/
protected AggregationFunction function;
/** function to compress, delivered by {@link #function} */
protected Object na = null;
/** used predicate to determine when to build up a new spline */
protected Predicate buildup;
/** indicates whether the internally used estimator function is initialized or not */
protected boolean initialized = false;
/** left interval border to evaluate the given function and
* also the support of the splines to build */
protected double a;
/** right interval border to evaluate the given function and
* also the support of the splines to build */
protected double b;
/** number of steps used to build the spline for compression*/
protected int n;
/** used grid for evaluating the function */
protected double[] grid;
/** internally built spline */
protected CubicBezierSpline spline;
/** Indicates built splines will be in cdf mode, i.e., evaluating
* the spline at x > maximum causes the spline to return 1.0 instead of 0.0.
* That is necessary for the approximation of a cumulative distribution function.
*/
protected boolean cdfMode;
/** function delivering the left border */
protected Function minimum = null;
/** function delivering the right border */
protected Function maximum = null;
/** function determining the grid points */
protected Function gridPoints = null;
/**
* number of build blocks
*/
int no=0;
/** Constructs a new Object of this class.
*
* @param function function to compress
* @param buildup predicate determining when to build up a new spline
* @param minimum function delivering the left border
* @param maximum function delivering the right border
* @param gridPoints function determining the grid points
* @param cdfMode indicates whether the spline is in cdf mode
*/
public SplineCompressedFunctionAggregateFunction(
AggregationFunction function,
Predicate buildup,
Function minimum,
Function maximum,
Function gridPoints,
boolean cdfMode) {
this.function = function;
this.buildup = buildup;
grid = null;
spline = null;
this.minimum = minimum;
this.maximum = maximum;
this.gridPoints = gridPoints;
this.cdfMode = cdfMode;
}
/** Constructs a new Object of this class.
*
* @param function function to compress
* @param buildup predicate determining when to build up a new spline
* @param a left border of the supported real-valued interval
* @param b right border of the supported real-valued interval
* @param n number of evaluation points used
* @param cdfMode indicates whether the spline is in cdf mode
*/
public SplineCompressedFunctionAggregateFunction(
AggregationFunction function,
Predicate buildup,
double a,
double b,
int n,
boolean cdfMode) {
this.function = function;
this.buildup = buildup;
this.a = a;
this.b = b;
this.n = n;
grid = null;
spline = null;
this.cdfMode = cdfMode;
}
/** Constructs a new Object of this class.
*
* @param function function to compress
* @param a left border of the supported real-valued interval
* @param b right border of the supported real-valued interval
* @param n number of evaluation points used
* @param cdfMode indicates whether the spline is in cdf mode
*/
public SplineCompressedFunctionAggregateFunction(AggregationFunction function, double a, double b, int n, boolean cdfMode) {
this.function = function;
buildup = new AbstractPredicate() {// indicates whether the current object and the last seen object are equal
Object last = null;
public boolean invoke(Object o) {
boolean r = !(o == last);
last = o;
return r;
}
};
this.a = a;
this.b = b;
this.n = n;
grid = null;
spline = null;
this.cdfMode = cdfMode;
}
/** Constructs a new Object of this class.
*
* @param function function to compress
* @param buildup predicate determining when to build up a new spline
* @param grid sorted grid determining the evaluation points
* @param cdfMode indicates whether the spline is in cdf mode
*/
public SplineCompressedFunctionAggregateFunction(
AggregationFunction function,
Predicate buildup,
double[] grid,
boolean cdfMode) {
this.function = function;
this.buildup = buildup;
this.n = -1;
this.grid = grid;
spline = null;
this.cdfMode = cdfMode;
}
/** 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 old result of the aggregation function in the previous computation step
* @param next next object used for computation
* @return aggregation value after n steps
*/
public Object invoke(Object old, Object next) {
na = function.invoke(old, next);
if (na == null) {
spline = null;
buildup.invoke( na);
} else {
initialized = true;
if (buildup.invoke(na)) {
if (grid == null) {
if (minimum != null)
a = ((Number) minimum.invoke(next)).doubleValue();
if (maximum != null)
b = ((Number) maximum.invoke(next)).doubleValue();
if (gridPoints != null)
n = ((Number) gridPoints.invoke(next)).intValue();
// building up spline with new (?) grid
spline =
new RB1CubicBezierSpline(
a,
b,
n,
Statistics.evalRealFunction(a, b, n, (RealFunction) na),
cdfMode);
} else {
System.out.println("Build block: "+(++no));
spline =
new RB1CubicBezierSpline(grid, Statistics.evalRealFunction(grid, (RealFunction) na), cdfMode);
}
}
}
return spline;
}
/** Returns the current status of the online aggregation function
* implementing the OnlineAggregation interface.
*
* @return current status of this function (here the current function to compress)
*/
public Object getState() {
if (initialized) {
return na;
} else
return null;
}
/** Sets a new status of the online aggregation function
* implementing the OnlineAgggregation interface (optional).
* This method is not supported by this class.
* It is implemented by throwing an UnsupportedOperationException.
*
* @param state current state of the function
* @throws UnsupportedOperationException if this method is not supported by this class
*/
public void setState(Object state) {
throw new UnsupportedOperationException("not supported");
}
/** Sets a new evaluation grid.
*
* @param newGrid new evaluation grid
*/
public void setGrid(double[] newGrid) {
n = -1;
grid = newGrid;
}
/** Sets a new evaluation grid.
*
* @param a left border of the supported real-valued interval
* @param b right border of the supported real-valued interval
* @param n number of evaluation points used
*/
public void setGrid(double a, double b, int n) {
this.a = a;
this.b = b;
this.n = n;
grid = null;
}
}