Skip to content

Commit d7a8421

Browse files
src/common/dnmtools_gaussinv.cpp: replacing loops with accumulates when computing the rational functions
1 parent 4497381 commit d7a8421

File tree

1 file changed

+6
-12
lines changed

1 file changed

+6
-12
lines changed

src/common/dnmtools_gaussinv.cpp

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,21 +79,19 @@
7979
#include <cmath>
8080
#include <cstddef>
8181
#include <cstdint>
82+
#include <iterator>
8283
#include <limits>
84+
#include <numeric>
8385

84-
// ADS: they are all magic...
86+
// ADS: so much magic.
8587

8688
template <std::size_t a_size, std::size_t b_size>
8789
[[nodiscard]] static inline double
8890
rat_eval(const std::array<double, a_size> &a,
8991
const std::array<double, b_size> &b, const double x) {
90-
double u{};
91-
for (const auto aa : a)
92-
u = x * u + aa;
93-
double v{};
94-
for (const auto bb : b)
95-
v = x * v + bb;
96-
return u / v;
92+
const auto acc = [&](const auto t, const auto y) { return x * t + y; };
93+
return std::accumulate(std::cbegin(a), std::cend(a), 0.0, acc) /
94+
std::accumulate(std::cbegin(b), std::cend(b), 0.0, acc);
9795
}
9896

9997
[[nodiscard]] static double
@@ -188,14 +186,12 @@ tail(const double r) {
188186
dnmt_gsl_cdf_ugaussian_Pinv(const double P) {
189187
static constexpr auto cutoff_for_small = 0.425;
190188
const auto dP = P - 0.5;
191-
192189
if (P == 1.0)
193190
return std::numeric_limits<double>::infinity();
194191
if (P == 0.0)
195192
return -std::numeric_limits<double>::infinity();
196193
if (std::abs(dP) <= cutoff_for_small)
197194
return small(dP);
198-
199195
const double pp = P < 0.5 ? P : 1.0 - P;
200196
const double r = std::sqrt(-std::log(pp));
201197
const double x = (r <= 5.0) ? intermediate(r) : tail(r);
@@ -206,14 +202,12 @@ dnmt_gsl_cdf_ugaussian_Pinv(const double P) {
206202
dnmt_gsl_cdf_ugaussian_Qinv(const double Q) {
207203
static constexpr auto cutoff_for_small = 0.425;
208204
const double dQ = Q - 0.5;
209-
210205
if (Q == 1.0)
211206
return -std::numeric_limits<double>::infinity();
212207
if (Q == 0.0)
213208
return std::numeric_limits<double>::infinity();
214209
if (std::abs(dQ) <= cutoff_for_small)
215210
return -small(dQ);
216-
217211
const double pp = Q < 0.5 ? Q : 1.0 - Q;
218212
const double r = std::sqrt(-std::log(pp));
219213
const double x = (r <= 5.0) ? intermediate(r) : tail(r);

0 commit comments

Comments
 (0)