summaryrefslogtreecommitdiff
path: root/absl/random/gaussian_distribution.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/random/gaussian_distribution.h')
-rw-r--r--absl/random/gaussian_distribution.h29
1 files changed, 21 insertions, 8 deletions
diff --git a/absl/random/gaussian_distribution.h b/absl/random/gaussian_distribution.h
index 8ee95148..4b07a5c0 100644
--- a/absl/random/gaussian_distribution.h
+++ b/absl/random/gaussian_distribution.h
@@ -28,12 +28,13 @@
#include <limits>
#include <type_traits>
-#include "absl/random/internal/distribution_impl.h"
+#include "absl/base/config.h"
#include "absl/random/internal/fast_uniform_bits.h"
+#include "absl/random/internal/generate_real.h"
#include "absl/random/internal/iostream_state_saver.h"
namespace absl {
-inline namespace lts_2019_08_08 {
+ABSL_NAMESPACE_BEGIN
namespace random_internal {
// absl::gaussian_distribution_base implements the underlying ziggurat algorithm
@@ -43,7 +44,7 @@ namespace random_internal {
// The specific algorithm has some of the improvements suggested by the
// 2005 paper, "An Improved Ziggurat Method to Generate Normal Random Samples",
// Jurgen A Doornik. (https://www.doornik.com/research/ziggurat.pdf)
-class gaussian_distribution_base {
+class ABSL_DLL gaussian_distribution_base {
public:
template <typename URBG>
inline double zignor(URBG& g); // NOLINT(runtime/references)
@@ -208,12 +209,18 @@ namespace random_internal {
template <typename URBG>
inline double gaussian_distribution_base::zignor_fallback(URBG& g, bool neg) {
+ using random_internal::GeneratePositiveTag;
+ using random_internal::GenerateRealFromBits;
+
// This fallback path happens approximately 0.05% of the time.
double x, y;
do {
// kRInv = 1/r, U(0, 1)
- x = kRInv * std::log(RandU64ToDouble<PositiveValueT, false>(fast_u64_(g)));
- y = -std::log(RandU64ToDouble<PositiveValueT, false>(fast_u64_(g)));
+ x = kRInv *
+ std::log(GenerateRealFromBits<double, GeneratePositiveTag, false>(
+ fast_u64_(g)));
+ y = -std::log(
+ GenerateRealFromBits<double, GeneratePositiveTag, false>(fast_u64_(g)));
} while ((y + y) < (x * x));
return neg ? (x - kR) : (kR - x);
}
@@ -221,6 +228,10 @@ inline double gaussian_distribution_base::zignor_fallback(URBG& g, bool neg) {
template <typename URBG>
inline double gaussian_distribution_base::zignor(
URBG& g) { // NOLINT(runtime/references)
+ using random_internal::GeneratePositiveTag;
+ using random_internal::GenerateRealFromBits;
+ using random_internal::GenerateSignedTag;
+
while (true) {
// We use a single uint64_t to generate both a double and a strip.
// These bits are unused when the generated double is > 1/2^5.
@@ -228,7 +239,8 @@ inline double gaussian_distribution_base::zignor(
// values (those smaller than 1/2^5, which all end up on the left tail).
uint64_t bits = fast_u64_(g);
int i = static_cast<int>(bits & kMask); // pick a random strip
- double j = RandU64ToDouble<SignedValueT, false>(bits); // U(-1, 1)
+ double j = GenerateRealFromBits<double, GenerateSignedTag, false>(
+ bits); // U(-1, 1)
const double x = j * zg_.x[i];
// Retangular box. Handles >97% of all cases.
@@ -245,7 +257,8 @@ inline double gaussian_distribution_base::zignor(
}
// i > 0: Wedge samples using precomputed values.
- double v = RandU64ToDouble<PositiveValueT, false>(fast_u64_(g)); // U(0, 1)
+ double v = GenerateRealFromBits<double, GeneratePositiveTag, false>(
+ fast_u64_(g)); // U(0, 1)
if ((zg_.f[i + 1] + v * (zg_.f[i] - zg_.f[i + 1])) <
std::exp(-0.5 * x * x)) {
return x;
@@ -256,7 +269,7 @@ inline double gaussian_distribution_base::zignor(
}
} // namespace random_internal
-} // inline namespace lts_2019_08_08
+ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_RANDOM_GAUSSIAN_DISTRIBUTION_H_