00001 #include ".\normals.h"
00002
00003
00004
00005
00006
00007 #include <cmath>
00008
00009
00010 #if !defined(_MSC_VER)
00011 using namespace std;
00012 #endif
00013
00014 const Real OneOverRootTwoPi = 0.398942280401433;
00015
00016
00017 Real NormalDensity(Real x)
00018 {
00019 return OneOverRootTwoPi*exp(-x*x/2);
00020 }
00021
00022
00023 Real InverseCumulativeNormal(Real u)
00024 {
00025
00026
00027 static Real a[4]={ 2.50662823884,
00028 -18.61500062529,
00029 41.39119773534,
00030 -25.44106049637};
00031
00032 static Real b[4]={-8.47351093090,
00033 23.08336743743,
00034 -21.06224101826,
00035 3.13082909833};
00036
00037 static Real c[9]={0.3374754822726147,
00038 0.9761690190917186,
00039 0.1607979714918209,
00040 0.0276438810333863,
00041 0.0038405729373609,
00042 0.0003951896511919,
00043 0.0000321767881768,
00044 0.0000002888167364,
00045 0.0000003960315187};
00046
00047
00048 Real x=u-0.5;
00049 Real r;
00050
00051 if (fabs(x)<0.42)
00052 {
00053 Real y=x*x;
00054
00055 r=x*(((a[3]*y+a[2])*y+a[1])*y+a[0])/
00056 ((((b[3]*y+b[2])*y+b[1])*y+b[0])*y+1.0);
00057
00058 }
00059 else
00060 {
00061
00062 r=u;
00063
00064 if (x>0.0)
00065 r=1.0-u;
00066
00067 r=log(-log(r));
00068
00069 r=c[0]+r*(c[1]+r*(c[2]+r*(c[3]+r*(c[4]+r*(c[5]+r*(c[6]+
00070 r*(c[7]+r*c[8])))))));
00071
00072 if (x<0.0)
00073 r=-r;
00074
00075 }
00076
00077 return r;
00078 }
00079
00080
00081
00082 Real CumulativeNormal(Real x)
00083 {
00084 static Real a[5] = { 0.319381530,
00085 -0.356563782,
00086 1.781477937,
00087 -1.821255978,
00088 1.330274429};
00089
00090 Real result;
00091
00092 if (x<-7.0)
00093 result = NormalDensity(x)/sqrt(1.+x*x);
00094
00095 else
00096 {
00097 if (x>7.0)
00098 result = 1.0 - CumulativeNormal(-x);
00099 else
00100 {
00101 Real tmp = 1.0/(1.0+0.2316419*fabs(x));
00102
00103 result=1-NormalDensity(x)*
00104 (tmp*(a[0]+tmp*(a[1]+tmp*(a[2]+tmp*(a[3]+tmp*a[4])))));
00105
00106 if (x<=0.0)
00107 result=1.0-result;
00108
00109 }
00110 }
00111
00112 return result;
00113 }
00114
00115
00116 Real Average(valarray<Real> Ptr,LongNatural dim)
00117 {
00118 LongNatural i;
00119 Real result=0;
00120
00121 for (i=0;i<dim;i++)
00122 {
00123 result+=Ptr[i];
00124 }
00125
00126 result/=Real(dim);
00127 return result;
00128 }
00129
00130 Real Maximize(valarray<Real> Ptr,LongNatural dim)
00131 {
00132 LongNatural i;
00133 Real result=0;
00134
00135 for (i=0;i<dim;i++)
00136 {
00137 if (Ptr[i]>result)
00138 result=Ptr[i];
00139 }
00140
00141 return result;
00142 }
00143
00144 Real CumulativeBivariateNormal(Real a,Real b,Real rho)
00145 {
00146 static Real aarray[5]= {0.24840615, 0.39233107, 0.21141819, 0.03324666, 0.00082485334};
00147 static Real barray[5]={0.10024215, 0.48281397, 1.0609498, 1.7797294, 2.6697604};
00148
00149
00150 Real rho1 , rho2 , delta ;
00151 Real ap , bp ;
00152 Real Sum, Pi;
00153 Real sgnA,sgnB;
00154 Natural i , j ;
00155 Real BivN, denum;
00156
00157 sgnA=(Real)sign(a);
00158 sgnB=(Real)sign(b);
00159
00160 Pi = 3.14159265358979;
00161 if(pow(rho,2)==1)
00162 rho=(Real)sign(rho)*0.99999;
00163 ap = a / sqrt(2 * (1 - pow(rho,2)));
00164 bp = b / sqrt(2 * (1 - pow(rho,2)));
00165
00166 if( (a <= 0) && (b <= 0) && (rho <= 0) ){
00167 Sum = 0;
00168 for (i = 0 ;i< 5;i++)
00169 for (j = 0 ;j< 5;j++)
00170 Sum += + aarray[i] * aarray[j] * SubFunctionForBivariateNormal(barray[i], barray[j], ap, bp, rho);
00171 BivN = Sum * sqrt(1 - pow(rho,2)) / Pi;
00172 }
00173 else if ((a <= 0 )&& (b >= 0) && (rho >= 0))
00174 BivN = CumulativeNormal(a) - CumulativeBivariateNormal(a, -b, -rho);
00175 else if ((a >= 0) && (b <= 0) && (rho >= 0))
00176 BivN = CumulativeNormal(b) - CumulativeBivariateNormal(-a, b, -rho);
00177 else if ((a >= 0) && (b >= 0) && (rho <= 0))
00178 BivN = CumulativeNormal(a) + CumulativeNormal(b) - 1 + CumulativeBivariateNormal(-a, -b, rho);
00179 else if (a * b * rho >= 0) {
00180 denum = sqrt(pow(a,2) - 2 * rho * a * b + pow(b,2));
00181 rho1 = (rho * a - b) * sgnA / denum;
00182 rho2 = (rho * b - a) * sgnB / denum;
00183 delta = (1 - sgnA*sgnB) / 4;
00184 BivN = CumulativeBivariateNormal(a, 0, rho1) + CumulativeBivariateNormal(b, 0, rho2) - delta;
00185 }
00186 return BivN;
00187 }
00188
00189 Real SubFunctionForBivariateNormal(Real X,Real y,Real ap,Real bp,Real rho){
00190 Real r;
00191 r = ap * (2 * X - ap) + bp * (2 * y - bp) + 2 * rho * (X - ap) * (y - bp);
00192 return exp(r);
00193 }