/* 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;
/**
* This class provides some static methods for computing respectively processing
* kernel estimators and the corresponding bandwidths, e.g., estimating
* the roughness of function.
*
* @see xxl.core.math.statistics.nonparametric.kernels.AbstractKernelDensityEstimator
* @see xxl.core.math.statistics.nonparametric.kernels.AbstractKernelCDF
* @see xxl.core.math.statistics.nonparametric.kernels.KernelFunction
*
*/
public class Kernels {
/**
* The default constructor has private access in order to ensure
* non-instantiability.
*/
private Kernels() {}
/** Returns an estimation of the roughness of a function f using a kernel estimator.
* The roughness R_r(f) of degree r is defined by R_r(f) = \int f^r(x) dx.
*
* @param g used bandwidth
* @param sample used sample to compute the estimation. Given as Objects of type <TT>Number</TT>.
* @param r degree of the derivative
* @return an estimation of the roughness of a function f
*/
public static double roughnessEstimator(double g, Object[] sample, int r) {
double xi = 0.0;
double xj = 0.0;
int size = sample.length;
double re = 0.0;
for (int i = 0; i < size; i++) {
xi = ((Number) sample[i]).doubleValue();
for (int j = 0; j < size; j++) {
xj = ((Number) sample[j]).doubleValue();
re += normalDerivatives(r, (xi - xj) / g);
}
}
return re / g / (size * size);
}
/** Returns the r-th derivative of the Gaussian kernel evaluated at 0.
*
* @param r degree of the derivative
* @return value of the r-th derivative of the Gaussian kernel at 0
*/
public static double normalDerivativeAt0(int r) {
double re = Math.pow(-1.0, (r / 2.0));
re = re / Math.sqrt(2.0 * Math.PI);
re = re * xxl.core.math.Maths.oddFactorial(r);
return xxl.core.math.Maths.isEven(r) ? re : 0.0;
}
/** Computes the r-th derivative of the Gaussian function at x.
*
* @param r degree of the derivative
* @param x function argument
* @return value of the r-th derivative of the pdf of the N(0,1) distribution at x
*/
public static double normalDerivatives(int r, double x) {
return Math.pow(-1.0, r)
* xxl.core.math.Maths.hermitePolynomial(r, x)
* xxl.core.math.Statistics.gaussian(x);
}
/** Computes an estimation of the r-th derivative of f at x using the r-th derivative or the Gaussian
* kernel, a given bandwidth g and a random sample.
*
* @param x where to evaluate the estimation
* @param sample used sample to compute the estimation. Given as Objects of type <TT>Number</TT>.
* @param degree degree of the derivative
* @param g used bandwidth
*
* @return an estimation f^(r)_g (x) of f^(r)(x)
*/
public static double kernelDerivativeEstimator(double x, Object[] sample, int degree, double g) {
double xi = 0.0;
int size = sample.length;
double r = 0.0;
for (int i = 0; i < size; i++) {
xi = ((Number) sample[i]).doubleValue();
r = r + normalDerivatives(degree, (x - xi) / g);
}
r = r / size;
r = r / Math.pow(g, degree);
return r;
}
}