Skip to content

Commit 95bb31e

Browse files
committed
Move more to log scale
1 parent 689103a commit 95bb31e

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

stan/math/prim/fun/inv_Phi.hpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,17 @@ inline double inv_Phi_lambda(double p) {
101101
pre_mult = q < 0 ? -1 : 1;
102102
}
103103

104-
Eigen::VectorXd r_pow = pow(inner_r, Eigen::ArrayXd::LinSpaced(8, 0, 7)) / 10.0;
105-
Eigen::Map<const Eigen::VectorXd> numerator_map(num_ptr, 8);
106-
Eigen::Map<const Eigen::VectorXd> denonimator_map(den_ptr, 8);
107-
return pre_mult * (numerator_map.dot(r_pow) * 10.0) / (denonimator_map.dot(r_pow) * 10.0);
104+
// As computation requires evaluating r^8, this causes a loss of precision,
105+
// even when using log space. We can mitigate this by scaling the
106+
// exponentiated result (dividing by 10), since the same scaling is applied
107+
// to the numerator and denominator.
108+
Eigen::VectorXd log_r_pow = Eigen::ArrayXd::LinSpaced(8, 0, 7) * log(inner_r)
109+
- LOG_TEN;
110+
Eigen::Map<const Eigen::VectorXd> num_map(num_ptr, 8);
111+
Eigen::Map<const Eigen::VectorXd> den_map(den_ptr, 8);
112+
double log_result = log_sum_exp(log_r_pow + log(num_map))
113+
- log_sum_exp(log_r_pow + log(den_map));
114+
return pre_mult * exp(log_result);
108115
}
109116
} // namespace internal
110117

0 commit comments

Comments
 (0)