/*********************************************************************** This file is part of KEEL-software, the Data Mining tool for regression, classification, clustering, pattern mining and so on. Copyright (C) 2004-2010 F. Herrera (herrera@decsai.ugr.es) L. S�nchez (luciano@uniovi.es) J. Alcal�-Fdez (jalcala@decsai.ugr.es) S. Garc�a (sglopez@ujaen.es) A. Fern�ndez (alberto.fernandez@ujaen.es) J. Luengo (julianlm@decsai.ugr.es) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ **********************************************************************/ package keel.Algorithms.Discretizers.MVD; /** * <p> * This class implements the Chi2 table. * </p> */ public class Chi2 { final static double CHI_EPSILON=0.000001; final static double CHI_MAX=99999.0; final static double LOG_SQRT_PI=0.5723649429247000870717135; final static double I_SQRT_PI=0.5641895835477562869480795; final static double BIGX=20.0; final static double Z_EPSILON=0.000001 ; final static double Z_MAX=6.0 ; double poz_orig (double z) { double y, x, w; if (z == 0.0) x = 0.0; else { y = 0.5 * Math.abs (z); if (y >= (Z_MAX * 0.5)) x = 1.0; else if (y < 1.0) { w = y*y; x = ((((((((0.000124818987 * w -0.001075204047) * w +0.005198775019) * w -0.019198292004) * w +0.059054035642) * w -0.151968751364) * w +0.319152932694) * w -0.531923007300) * w +0.797884560593) * y * 2.0; } else { y -= 2.0; x = (((((((((((((-0.000045255659 * y +0.000152529290) * y -0.000019538132) * y -0.000676904986) * y +0.001390604284) * y -0.000794620820) * y -0.002034254874) * y +0.006549791214) * y -0.010557625006) * y +0.011630447319) * y -0.009279453341) * y +0.005353579108) * y -0.002141268741) * y +0.000535310849) * y +0.999936657524; } } return (z > 0.0 ? ((x + 1.0) * 0.5) : ((1.0 - x) * 0.5)); } double ex(double x) { return (((x) < -BIGX) ? 0.0 : Math.exp (x)); } double pochisq(double x, int df) { double a, y=0, s; double e, c, z; boolean even; /* true if df is an even number */ if (x <= 0.0 || df < 1) return (1.0); a = 0.5 * x; even = (2 * (df / 2)) == df; if (df > 1) y = ex(-a); s = (even ? y : (2.0 * poz_orig(-Math.sqrt(x)))); if (df > 2) { x = 0.5 * (df - 1.0); z = (even ? 1.0 : 0.5); if (a > BIGX) { e = (even ? 0.0 : LOG_SQRT_PI); c = Math.log(a); while (z <= x) { e = Math.log(z) + e; s += ex(c * z - a - e); z += 1.0; } return (s); } else { e = (even ? 1.0 : (I_SQRT_PI / Math.sqrt(a))); c = 0.0; while (z <= x) { e = e * (a / z); c = c + e; z += 1.0; } return (c * y + s); } } else return (s); } /** * This method obtains the p-value from a Chi square distribution * @param p the distribution value * @param df the degrees of freedom * @return the associated p-value */ public double critchi (double p, int df) { double minchisq = 0.0; double maxchisq = CHI_MAX; double chisqval; if (p <= 0.0) return (maxchisq); else if (p >= 1.0) return (0.0); chisqval = df / Math.sqrt (p); /* fair first value */ while (maxchisq - minchisq > CHI_EPSILON) { if (pochisq (chisqval, df) < p) maxchisq = chisqval; else minchisq = chisqval; chisqval = (maxchisq + minchisq) * 0.5; } return (chisqval); } }