@@ -28,16 +28,7 @@ const int BIGINT = 2000000000;
28
28
* @param p argument between 0 and 1 inclusive
29
29
* @return Real value of the inverse cdf for the standard normal distribution.
30
30
*/
31
- inline double inv_Phi_lambda (double p) {
32
- check_bounded (" inv_Phi" , " Probability variable" , p, 0 , 1 );
33
-
34
- if (p < 8e-311 ) {
35
- return NEGATIVE_INFTY;
36
- }
37
- if (p == 1 ) {
38
- return INFTY;
39
- }
40
-
31
+ inline double inv_Phi_impl (double p, bool log_p) {
41
32
static constexpr double log_a[8 ]
42
33
= {1.2199838032983212 , 4.8914137334471356 , 7.5865960847956080 ,
43
34
9.5274618535358388 , 10.734698580862359 , 11.116406781896242 ,
@@ -95,7 +86,7 @@ inline double inv_Phi_lambda(double p) {
95
86
}
96
87
97
88
// As computation requires evaluating r^8, this causes a loss of precision,
98
- // even when using log space. We can mitigate this by scaling the
89
+ // even when on the log space. We can mitigate this by scaling the
99
90
// exponentiated result (dividing by 10), since the same scaling is applied
100
91
// to the numerator and denominator.
101
92
Eigen::VectorXd log_r_pow = Eigen::ArrayXd::LinSpaced (8 , 0 , 7 ) * log (inner_r)
@@ -121,9 +112,17 @@ inline double inv_Phi_lambda(double p) {
121
112
* @return real value of the inverse cdf for the standard normal distribution
122
113
*/
123
114
inline double inv_Phi (double p) {
124
- return p >= 0.9999 ? -internal::inv_Phi_lambda (
125
- (internal::BIGINT - internal::BIGINT * p) / internal::BIGINT)
126
- : internal::inv_Phi_lambda (p);
115
+ check_bounded (" inv_Phi" , " Probability variable" , p, 0 , 1 );
116
+
117
+ if (p < 8e-311 ) {
118
+ return NEGATIVE_INFTY;
119
+ }
120
+ if (p == 1 ) {
121
+ return INFTY;
122
+ }
123
+ return p >= 0.9999 ? -internal::inv_Phi_impl (
124
+ (internal::BIGINT - internal::BIGINT * p) / internal::BIGINT, false )
125
+ : internal::inv_Phi_impl (p, false );
127
126
}
128
127
129
128
/* *
0 commit comments