12 bool lower_tail =
true,
15 if (!(sd > 0.0) || !std::isfinite(sd)) {
16 return std::numeric_limits<double>::quiet_NaN();
22 if (p > 0.0)
return std::numeric_limits<double>::quiet_NaN();
28 if (!lower_tail) pp = 1.0 - pp;
31 if (pp <= 0.0)
return -std::numeric_limits<double>::infinity();
32 if (pp >= 1.0)
return std::numeric_limits<double>::infinity();
35 static const double a[8] = {
36 3.3871328727963666080,
37 1.3314166789178437745e+2,
38 1.9715909503065514427e+3,
39 1.3731693765509461125e+4,
40 4.5921953931549871457e+4,
41 6.7265770927008700853e+4,
42 3.3430575583588128105e+4,
43 2.5090809287301226727e+3
45 static const double b[8] = {
47 4.2313330701600911252e+1,
48 6.8718700749205790830e+2,
49 5.3941960214247511077e+3,
50 2.1213794301586595867e+4,
51 3.9307895800092710610e+4,
52 2.8729085735721942674e+4,
53 5.2264952788528545610e+3
55 static const double c[8] = {
56 1.42343711074968357734,
57 4.63033784615654529590,
58 5.76949722146069140550,
59 3.64784832476320460504,
60 1.27045825245236838258,
61 2.41780725177450611770e-1,
62 2.27238449892691845833e-2,
63 7.74545014278341407640e-4
65 static const double d[8] = {
67 2.05319162663775882187,
68 1.67638483018380384940,
69 6.89767334985100004550e-1,
70 1.48103976427480074590e-1,
71 1.51986665636164571966e-2,
72 5.47593808499534494600e-4,
73 1.05075007164441684324e-9
75 static const double e[8] = {
76 6.65790464350110377720,
77 5.46378491116411436990,
78 1.78482653991729133580,
79 2.96560571828504891230e-1,
80 2.65321895265761230930e-2,
81 1.24266094738807843860e-3,
82 2.71155556874348757815e-5,
83 2.01033439929228813265e-7
85 static const double f[8] = {
87 5.99832206555887937690e-1,
88 1.36929880922735805310e-1,
89 1.48753612908506148525e-2,
90 7.86869131145613259100e-4,
91 1.84631831751005468180e-5,
92 1.42151175831644588870e-7,
93 2.04426310338993978564e-15
96 auto poly = [](
const double* coef,
int n,
double x) {
98 double v = coef[n - 1];
99 for (
int i = n - 2; i >= 0; --i) v = v * x + coef[i];
103 constexpr double split1 = 0.425;
104 constexpr double split2 = 5.0;
105 constexpr double const1 = 0.180625;
106 constexpr double const2 = 1.6;
111 if (std::fabs(q) <= split1) {
113 double r = const1 - q*q;
114 z = q * poly(a, 8, r) / poly(b, 8, r);
117 double r = (q < 0.0) ? pp : (1.0 - pp);
118 r = std::sqrt(-std::log(r));
122 z = poly(c, 8, r) / poly(d, 8, r);
125 z = poly(e, 8, r) / poly(f, 8, r);
130 return mean + sd * z;