inverse_normal_cdf.h

00001 /* MLPACK 0.2
00002  *
00003  * Copyright (c) 2008, 2009 Alexander Gray,
00004  *                          Garry Boyer,
00005  *                          Ryan Riegel,
00006  *                          Nikolaos Vasiloglou,
00007  *                          Dongryeol Lee,
00008  *                          Chip Mappus, 
00009  *                          Nishant Mehta,
00010  *                          Hua Ouyang,
00011  *                          Parikshit Ram,
00012  *                          Long Tran,
00013  *                          Wee Chin Wong
00014  *
00015  * Copyright (c) 2008, 2009 Georgia Institute of Technology
00016  *
00017  * This program is free software; you can redistribute it and/or
00018  * modify it under the terms of the GNU General Public License as
00019  * published by the Free Software Foundation; either version 2 of the
00020  * License, or (at your option) any later version.
00021  *
00022  * This program is distributed in the hope that it will be useful, but
00023  * WITHOUT ANY WARRANTY; without even the implied warranty of
00024  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00025  * General Public License for more details.
00026  *
00027  * You should have received a copy of the GNU General Public License
00028  * along with this program; if not, write to the Free Software
00029  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00030  * 02110-1301, USA.
00031  */
00032 #ifndef INVERSE_NORMAL_CDF_H
00033 #define INVERSE_NORMAL_CDF_H
00034 
00035 class InverseNormalCDF {
00036 
00037  public:
00038 
00039 #define  A1  (-3.969683028665376e+01)
00040 #define  A2   2.209460984245205e+02
00041 #define  A3  (-2.759285104469687e+02)
00042 #define  A4   1.383577518672690e+02
00043 #define  A5  (-3.066479806614716e+01)
00044 #define  A6   2.506628277459239e+00
00045 
00046 #define  B1  (-5.447609879822406e+01)
00047 #define  B2   1.615858368580409e+02
00048 #define  B3  (-1.556989798598866e+02)
00049 #define  B4   6.680131188771972e+01
00050 #define  B5  (-1.328068155288572e+01)
00051 
00052 #define  C1  (-7.784894002430293e-03)
00053 #define  C2  (-3.223964580411365e-01)
00054 #define  C3  (-2.400758277161838e+00)
00055 #define  C4  (-2.549732539343734e+00)
00056 #define  C5   4.374664141464968e+00
00057 #define  C6   2.938163982698783e+00
00058 
00059 #define  D1   7.784695709041462e-03
00060 #define  D2   3.224671290700398e-01
00061 #define  D3   2.445134137142996e+00
00062 #define  D4   3.754408661907416e+00
00063 
00064 #define P_LOW   0.02425
00065 /* P_high = 1 - p_low*/
00066 #define P_HIGH  0.97575
00067 
00068   static double Compute(double p) {
00069 
00070     long double x = 0;
00071     long double q, r, u, e;
00072     if ((0 < p )  && (p < P_LOW)){
00073       q = sqrt(-2*log(p));
00074       x = (((((C1*q+C2)*q+C3)*q+C4)*q+C5)*q+C6) / ((((D1*q+D2)*q+D3)*q+D4)*q+1);
00075     }
00076     else{
00077       if ((P_LOW <= p) && (p <= P_HIGH)){
00078         q = p - 0.5;
00079         r = q*q;
00080         x = (((((A1*r+A2)*r+A3)*r+A4)*r+A5)*r+A6)*q /(((((B1*r+B2)*r+B3)*r+B4)*r+B5)*r+1);
00081       }
00082       else{
00083         if ((P_HIGH < p)&&(p < 1)){
00084           q = sqrt(-2*log(1-p));
00085           x = -(((((C1*q+C2)*q+C3)*q+C4)*q+C5)*q+C6) / ((((D1*q+D2)*q+D3)*q+D4)*q+1);
00086         }
00087       }
00088     }
00089     
00090     // If you are compiling this under UNIX OR LINUX, you may
00091     // uncomment this block for better accuracy.
00092     if(( 0 < p)&&(p < 1)){
00093       e = 0.5 * erfc(-x/sqrt(2)) - p;
00094       u = e * sqrt(2*M_PI) * exp(x*x/2);
00095       x = x - u/(1 + x*u/2);
00096     }
00097     return x;
00098   }
00099 };
00100 
00101 #endif
Generated on Mon Jan 24 12:04:38 2011 for FASTlib by  doxygen 1.6.3