15 #ifndef ABSL_RANDOM_GAUSSIAN_DISTRIBUTION_H_
16 #define ABSL_RANDOM_GAUSSIAN_DISTRIBUTION_H_
29 #include <type_traits>
31 #include "absl/base/config.h"
32 #include "absl/random/internal/fast_uniform_bits.h"
33 #include "absl/random/internal/generate_real.h"
34 #include "absl/random/internal/iostream_state_saver.h"
38 namespace random_internal {
47 class ABSL_DLL gaussian_distribution_base {
49 template <
typename URBG>
50 inline double zignor(URBG& g);
53 friend class TableGenerator;
55 template <
typename URBG>
56 inline double zignor_fallback(URBG&
g,
60 static constexpr
double kR = 3.442619855899;
61 static constexpr
double kRInv = 0.29047645161474317;
62 static constexpr
double kV = 9.91256303526217e-3;
63 static constexpr
uint64_t kMask = 0x07f;
78 static const Tables zg_;
79 random_internal::FastUniformBits<uint64_t> fast_u64_;
86 template <
typename RealType =
double>
87 class gaussian_distribution : random_internal::gaussian_distribution_base {
106 return a.mean_ ==
b.mean_ &&
a.stddev_ ==
b.stddev_;
119 "Class-template absl::gaussian_distribution<> must be parameterized "
120 "using a floating-point type.");
133 template <
typename URBG>
138 template <
typename URBG>
140 const param_type& p);
146 return -std::numeric_limits<result_type>::infinity();
149 return std::numeric_limits<result_type>::infinity();
157 return a.param_ ==
b.param_;
161 return a.param_ !=
b.param_;
172 template <
typename RealType>
173 template <
typename URBG>
177 const param_type& p) {
178 return p.mean() + p.stddev() *
static_cast<result_type>(zignor(g));
181 template <
typename CharT,
typename Traits,
typename RealType>
182 std::basic_ostream<CharT, Traits>&
operator<<(
183 std::basic_ostream<CharT, Traits>& os,
184 const gaussian_distribution<RealType>& x) {
187 os <<
x.mean() << os.fill() <<
x.stddev();
191 template <
typename CharT,
typename Traits,
typename RealType>
192 std::basic_istream<CharT, Traits>&
operator>>(
193 std::basic_istream<CharT, Traits>& is,
194 gaussian_distribution<RealType>& x) {
196 using param_type =
typename gaussian_distribution<RealType>::param_type;
199 auto mean = random_internal::read_floating_point<result_type>(is);
200 if (is.fail())
return is;
201 auto stddev = random_internal::read_floating_point<result_type>(is);
203 x.param(param_type(mean, stddev));
208 namespace random_internal {
210 template <
typename URBG>
212 using random_internal::GeneratePositiveTag;
220 std::log(GenerateRealFromBits<double, GeneratePositiveTag, false>(
223 GenerateRealFromBits<double, GeneratePositiveTag, false>(
fast_u64_(g)));
224 }
while ((
y +
y) < (x * x));
225 return neg ? (
x -
kR) : (
kR - x);
228 template <
typename URBG>
231 using random_internal::GeneratePositiveTag;
233 using random_internal::GenerateSignedTag;
242 double j = GenerateRealFromBits<double, GenerateSignedTag, false>(
249 if (std::abs(x) <
zg_.
x[i + 1]) {
260 double v = GenerateRealFromBits<double, GeneratePositiveTag, false>(
263 std::exp(-0.5 * x * x)) {
275 #endif // ABSL_RANDOM_GAUSSIAN_DISTRIBUTION_H_