/* 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.nonparametric.kernels; import java.util.List; import xxl.core.functions.AbstractFunction; import xxl.core.functions.Function; import xxl.core.math.functions.Integrable; import xxl.core.math.functions.RealFunction; /** * This class implements an abstract preimplementation * of a <tt>kernel based cdf estimator</tt> * {@link xxl.core.math.statistics.nonparametric.kernels.AbstractKernelCDF AbstractKernelCDF} * that doesn't use an explicit technique for avoiding boundary effects. * Additionally, this class provides a FACTORY for generating <tt>native kernel based cdf estimators</tt>. * * @see xxl.core.math.statistics.nonparametric.kernels.KernelFunction * @see xxl.core.math.statistics.nonparametric.kernels.KernelBandwidths * @see xxl.core.math.functions.AbstractRealFunctionFunction * @see xxl.core.math.statistics.nonparametric.kernels.AbstractKernelCDF * @see xxl.core.math.statistics.nonparametric.kernels.ReflectionKernelCDF * */ public class NativeKernelCDF extends AbstractKernelCDF { /** Provides a factory for a * {@link xxl.core.math.statistics.nonparametric.kernels.NativeKernelCDF native kernel cdf estimator} * , i.e., an estimator * without any boundary treatment technique. * The parameters needed for construction are passed to the factory by an * <tt>Object[]</tt> <code>o</code> containing: <BR> * <code>o[0]</code>: used {@link xxl.core.math.statistics.nonparametric.kernels.KernelFunction kernel function} <BR> * <code>o[1]</code>: used sample as <tt>Object[]</tt> containing numerical data <BR> * <code>o[2]</code>: used bandwidth as Object of type <tt>Number</tt> <BR> */ public static Function FACTORY = new AbstractFunction<Object,NativeKernelCDF>() { public NativeKernelCDF invoke(List<? extends Object> list) { return new NativeKernelCDF( (KernelFunction) list.get(0), // kernel function (Object[]) list.get(1), // sample ((Number) list.get(2)).doubleValue() // bandwidth ); } }; /** * Constructs a new kernel based cdf estimator. * * @param kf used {@link xxl.core.math.statistics.nonparametric.kernels.KernelFunction Kernel function} with * support restricted to [-1,1] * @param sample sample of a data set given as <tt>Object[]</tt> containing * objects of type <tt>Number</tt>. * @param h used bandwidth for computing the estimation * @throws IllegalArgumentException if a kernel function without restricted support to * <tt>[-1,1]</tt> is given or a kernel function is given that doesn't implement the * interface {@link xxl.core.math.functions.Integrable Integrable} * * @see xxl.core.math.statistics.nonparametric.kernels.KernelFunction * @see xxl.core.math.statistics.nonparametric.kernels.KernelBandwidths */ public NativeKernelCDF(KernelFunction kf, Object[] sample, double h) throws IllegalArgumentException { super(kf, sample, h); } /** Evaluates the cdf estimator at the given point x. * * @param x argument where to evaluate the cdf * @return value of the estimated cdf at x */ protected double evalKDE(double x) { double r = 0.0; RealFunction prim = ((Integrable) kf).primitive(); int size = sample.length; for (int i = 0; i < size; i++) { double xi = ((Number) sample[i]).doubleValue(); if (xi <= x - h) r += 1.0; else { if (xi <= x + h) { r += prim.eval((x - xi) / h); } } } return r / size; } /** Returns an estimation of the window (interval) selectivity given. * * @param left left border of the window * @param right right border of the window * @return an estimation of the window selectivity */ public double windowQuery(Object left, Object right) { if (hasChanged()) reinit(); double a = ((Number) left).doubleValue(); double b = ((Number) right).doubleValue(); double al = a; // temp var for restricted kernel support double bl = b; // temp var for restricted kernel support double r = 0.0; RealFunction prim = ((Integrable) kf).primitive(); int size = sample.length; for (int i = 0; i < size; i++) { double xi = ((Number) sample[i]).doubleValue(); if ((xi > a - h) && (xi < b + h)) { if ((xi >= a + h) && (xi <= b - h)) r += 1.0; else { al = Math.max((a - xi) / h, -1.0); bl = Math.min((b - xi) / h, 1.0); r += prim.eval(bl) - prim.eval(al); } } } return r / size; } }