eFinancialPlanner  V1.0 (proof of concept)
Personal Financial Planning based on Maslowian Portfolio Theory
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros Pages
normdist.h
Go to the documentation of this file.
1 
5 static const double a[] =
6 {
7  -3.969683028665376e+01,
8  2.209460984245205e+02,
9  -2.759285104469687e+02,
10  1.383577518672690e+02,
11  -3.066479806614716e+01,
12  2.506628277459239e+00
13 };
14 
15 static const double b[] =
16 {
17  -5.447609879822406e+01,
18  1.615858368580409e+02,
19  -1.556989798598866e+02,
20  6.680131188771972e+01,
21  -1.328068155288572e+01
22 };
23 
24 static const double c[] =
25 {
26  -7.784894002430293e-03,
27  -3.223964580411365e-01,
28  -2.400758277161838e+00,
29  -2.549732539343734e+00,
30  4.374664141464968e+00,
31  2.938163982698783e+00
32 };
33 
34 static const double d[] =
35 {
36  7.784695709041462e-03,
37  3.224671290700398e-01,
38  2.445134137142996e+00,
39  3.754408661907416e+00
40 };
41 
71 #define LOW 0.02425
72 #define HIGH 0.97575
73 template <class type> type norminv(type p)
74 {
75  type q, r;
76  errno = 0;
77  if (p < 0 || p > 1)
78  {
79  errno = EDOM;
80  return 0.0;
81  }
82  else if (p == 0)
83  {
84  errno = ERANGE;
85  return -HUGE_VAL /* minus "infinity" */;
86  }
87  else if (p == 1)
88  {
89  errno = ERANGE;
90  return HUGE_VAL /* "infinity" */;
91  }
92  else if (p < LOW)
93  {
94  /* Rational approximation for lower region */
95  q = sqrt(-2*log(p));
96  return (((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) /
97  ((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1);
98  }
99  else if (p > HIGH)
100  {
101  /* Rational approximation for upper region */
102  q = sqrt(-2*log(1-p));
103  return -(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) /
104  ((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1);
105  }
106  else
107  {
108  /* Rational approximation for central region */
109  q = p - 0.5;
110  r = q*q;
111  return (((((a[0]*r+a[1])*r+a[2])*r+a[3])*r+a[4])*r+a[5])*q /
112  (((((b[0]*r+b[1])*r+b[2])*r+b[3])*r+b[4])*r+1);
113  }
114 }
115 
123 template <class type> type phi(type x)
124 {
125  // constants
126  type a1 = 0.254829592;
127  type a2 = -0.284496736;
128  type a3 = 1.421413741;
129  type a4 = -1.453152027;
130  type a5 = 1.061405429;
131  type p = 0.3275911;
132 
133  // Save the sign of x
134  int sign = 1;
135  if (x < 0)
136  sign = -1;
137  x = fabs(x)/sqrt(2.0);
138 
139  // A&S formula 7.1.26
140  type t = 1.0/(1.0 + p*x);
141  type y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x);
142 
143  return 0.5*(1.0 + sign*y);
144 }
145 
146 
154 inline float fast_erfinv(float x)
155 {
156  float tmp;
157  int neg;
158 
159  if((neg=(x < 0.0))) x = -x;
160  if(x <= 0.7)
161  {
162  tmp = x*x;
163  x *= (((-0.140543331*tmp+0.914624893)*tmp-1.645349621)*tmp+0.886226899)/((((0.012229801*tmp-0.329097515)*tmp+1.442710462)*tmp-2.118377725)*tmp+1.0);
164  }
165  else
166  {
167  tmp = sqrt(-log(0.5*(1.0-x)));
168  x = (((1.641345311*tmp+3.429567803)*tmp-1.624906493)*tmp-1.970840454)/((1.637067800*tmp+3.543889200)*tmp+1.0);
169  }
170  return(neg?-x:x);
171 }
172 
173 
182 double erfinv(double x)
183 {
184  double res;
185 
186  res = fast_erfinv(x);
187  res -= (erf(res)-x)*exp(res*res)*0.886226925452757941;
188  res -= (erf(res)-x)*exp(res*res)*0.886226925452757941;
189  return(res);
190 }
#define LOW
Definition: normdist.h:71
type norminv(type p)
Definition: normdist.h:73
float fast_erfinv(float x)
Definition: normdist.h:154
#define HIGH
Definition: normdist.h:72
static const double c[]
Definition: normdist.h:24
double erfinv(double x)
Definition: normdist.h:182
type phi(type x)
Definition: normdist.h:123
static const double b[]
Definition: normdist.h:15
static const double d[]
Definition: normdist.h:34
static const double a[]
Definition: normdist.h:5