1 #ifndef OMEGA_H_RANDOM_INLINE_HPP
2 #define OMEGA_H_RANDOM_INLINE_HPP
4 #include <random123/philox.h>
5 #include <Omega_h_few.hpp>
6 #include <Omega_h_scalar.hpp>
7 #include <Omega_h_vector.hpp>
11 OMEGA_H_INLINE Few<std::uint64_t, 2> run_philox_cbrng(
12 Few<std::uint64_t, 2> ctr, std::uint64_t key) {
13 using PhiloxType = r123::Philox4x32;
14 using ctr_type =
typename PhiloxType::ctr_type;
15 using key_type =
typename PhiloxType::key_type;
16 PhiloxType philox_cbrng;
19 ctr_philox[0] =
static_cast<std::uint32_t
>(ctr[0]);
20 ctr_philox[1] =
static_cast<std::uint32_t
>(ctr[0] >> 32);
21 ctr_philox[2] =
static_cast<std::uint32_t
>(ctr[1]);
22 ctr_philox[3] =
static_cast<std::uint32_t
>(ctr[1] >> 32);
23 key_philox[0] =
static_cast<std::uint32_t
>(key);
24 key_philox[1] =
static_cast<std::uint32_t
>(key >> 32);
25 ctr_philox = philox_cbrng(ctr_philox, key_philox);
26 ctr[0] = ctr_philox[1];
28 ctr[0] |= ctr_philox[0];
29 ctr[1] = ctr_philox[3];
31 ctr[1] |= ctr_philox[2];
35 OMEGA_H_INLINE Real unit_uniform_deviate_from_uint64(std::uint64_t x) {
36 return static_cast<Real
>(x) /
37 static_cast<Real
>(ArithTraits<std::uint64_t>::max());
43 I64 seed_in, I64 key_in, I64 counter_in) {
44 counter[1] =
static_cast<std::uint64_t
>(seed_in);
45 key =
static_cast<std::uint64_t
>(key_in);
46 counter[0] =
static_cast<std::uint64_t
>(counter_in);
53 OMEGA_H_INLINE Real operator()() {
56 ret = unit_uniform_deviate_from_uint64(state[1]);
59 ret = unit_uniform_deviate_from_uint64(state[0]);
66 OMEGA_H_INLINE
void even_step() {
68 state = run_philox_cbrng(counter, key);
105 auto U_1 = uniform_rng();
106 auto U_2 = uniform_rng();
111 if (U_1 == 0.0) U_1 = DBL_MIN;
112 auto common = std::sqrt(-2.0 * std::log(U_1));
113 state[0] = common * std::cos(2.0 * Omega_h::PI * U_2);
114 state[1] = common * std::sin(2.0 * Omega_h::PI * U_2);
130 OMEGA_H_INLINE Real weibull_quantile(Real shape, Real scale, Real p) {
131 auto one_minus_p = 1.0 - p;
132 if (one_minus_p == 0) one_minus_p = DBL_MIN;
133 return scale * std::pow(
double(-std::log(one_minus_p)),
double(1.0 / shape));
136 OMEGA_H_INLINE Real standard_normal_density(Real value) {
137 constexpr
auto one_over_sqrt_two_pi = 0.3989422804014327;
138 return one_over_sqrt_two_pi * std::exp((-1.0 / 2.0) * square(value));
141 OMEGA_H_INLINE Real general_normal_density(
142 Real mean, Real standard_deviation, Real value) {
143 return (1.0 / standard_deviation) *
144 standard_normal_density((value - mean) / standard_deviation);
147 OMEGA_H_INLINE Real weibull_density(Real shape, Real scale, Real value) {
148 if (value < 0.0)
return 0.0;
149 return (shape / scale) * std::pow(value / scale, shape - 1.0) *
150 std::exp(-std::pow(value / scale, shape));
154 OMEGA_H_INLINE Real regularized_lower_incomplete_gamma(Real s, Real z) {
157 for (Int k = 1; k < 100; ++k) {
160 if (sum > 1e100)
return 1.0;
161 if (x / sum < 1e-14)
break;
163 auto a = s * std::log(z) - z - std::lgamma(s + 1.0);
164 return std::exp(a + std::log(sum));
167 OMEGA_H_INLINE Real cumulative_chi_squared_density(
168 Real ndofs, Real chi_squared) {
169 if (chi_squared < 0.0 || ndofs < 1.0)
return 0.0;
170 return regularized_lower_incomplete_gamma(ndofs / 2.0, chi_squared / 2.0);
173 OMEGA_H_INLINE Real cumulative_standard_normal_density(Real x) {
174 return (1.0 / 2.0) * (1.0 + std::erf(x / std::sqrt(2.0)));
177 OMEGA_H_INLINE Real cumulative_general_normal_density(
178 Real mean, Real standard_deviation, Real x) {
179 return cumulative_standard_normal_density((x - mean) / standard_deviation);
182 OMEGA_H_INLINE Real cumulative_weibull_density(Real shape, Real scale, Real x) {
183 return 1.0 - std::exp(-std::pow(x / scale, shape));
Definition: Omega_h_random_inline.hpp:97
Definition: amr_mpi_test.cpp:6