/*********************************************************************** 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.Semi_Supervised_Learning.Basic; public class NormalDistribution{ private double mu; private double sigma; public void setMean(double value){ mu=value; } public void setSigma(double value){ sigma=value; } public double getMean(){ return mu; } public double getSigma(){ return sigma; } public NormalDistribution(){ } public double getProbability(double x){ double value=0.0; value=Math.pow(Math.E,-(x-mu)*(x-mu)/(2.0*sigma*sigma)); value/=Math.sqrt(2.0*Math.PI*sigma*sigma); return value; } public double getCumulatedProbability(double x){ double value; double z= ((x-mu)/sigma); value=getTipifiedProbability(z, false); return value; } /** * <p> * Computes cumulative N(0,1) distribution. Based om Algorithm AS66 Applied Statistics (1973) vol22 no.3 * </p> * @param z x value * @param upper A boolean value, if true the integral is evaluated from z to infinity, from minus infinity to z otherwise * @return The value of the cumulative N(0,1) distribution for z */ public double getTipifiedProbability(double z, boolean upper) { //Algorithm AS 66: "The Normal Integral" //Applied Statistics double ltone = 7.0, utzero = 18.66, con = 1.28, a1 = 0.398942280444, a2 = 0.399903438504, a3 = 5.75885480458, a4 = 29.8213557808, a5 = 2.62433121679, a6 = 48.6959930692, a7 = 5.92885724438, b1 = 0.398942280385, b2 = 3.8052e-8, b3 = 1.00000615302, b4 = 3.98064794e-4, b5 = 1.986153813664, b6 = 0.151679116635, b7 = 5.29330324926, b8 = 4.8385912808, b9 = 15.1508972451, b10 = 0.742380924027, b11 = 30.789933034, b12 = 3.99019417011; double y, alnorm; if (z < 0) { upper = !upper; z = -z; } if (z <= ltone || upper && z <= utzero) { y = 0.5 * z * z; if (z > con) { alnorm = b1 * Math.exp( -y) / (z - b2 + b3 / (z + b4 + b5 / (z - b6 + b7 / (z + b8 - b9 / (z + b10 + b11 / (z + b12)))))); } else { alnorm = 0.5 - z * (a1 - a2 * y / (y + a3 - a4 / (y + a5 + a6 / (y + a7)))); } } else { alnorm = 0; } if (!upper) { alnorm = 1 - alnorm; } return (alnorm); } /* * From http://home.online.no/~pjacklam/notes/invnorm/ * Error is bounded to 1.15E-09 * */ public double inverseNormalDistribution(double p){ double a1 = -3.969683028665376e+01; double a2 = 2.209460984245205e+02; double a3 = -2.759285104469687e+02; double a4 = 1.383577518672690e+02; double a5 = -3.066479806614716e+01; double a6 = 2.506628277459239e+00; double b1 = -5.447609879822406e+01; double b2 = 1.615858368580409e+02; double b3 = -1.556989798598866e+02; double b4 = 6.680131188771972e+01; double b5 = -1.328068155288572e+01; double c1 = -7.784894002430293e-03; double c2 = -3.223964580411365e-01; double c3 = -2.400758277161838e+00; double c4 = -2.549732539343734e+00; double c5 = 4.374664141464968e+00; double c6 = 2.938163982698783e+00; double d1 = 7.784695709041462e-03; double d2 = 3.224671290700398e-01; double d3 = 2.445134137142996e+00; double d4 = 3.754408661907416e+00; double p_low = 0.02425; double p_high = 1.0 - p_low; double q; double x=0.0; double r; if(p<=0){ return Double.NEGATIVE_INFINITY; } if(p>=1){ return Double.POSITIVE_INFINITY; } //Rational approximation for lower region. if (p < p_low){ q = Math.sqrt(-2.0*Math.log(p)); x = (((((c1*q+c2)*q+c3)*q+c4)*q+c5)*q+c6) / ((((d1*q+d2)*q+d3)*q+d4)*q+1.0); return x; } //Rational approximation for central region. if (p <= p_high){ q = p - 0.5; r = q*q; x = (((((a1*r+a2)*r+a3)*r+a4)*r+a5)*r+a6)*q / (((((b1*r+b2)*r+b3)*r+b4)*r+b5)*r+1.0); return x; } //Rational approximation for upper region. if (p_high < p){ q = Math.sqrt(-2.0*Math.log(1.0-p)); x = -(((((c1*q+c2)*q+c3)*q+c4)*q+c5)*q+c6) / ((((d1*q+d2)*q+d3)*q+d4)*q+1.0); return x; } return x; } }