quant-pricer-cpp
Loading...
Searching...
No Matches
rng.hpp
Go to the documentation of this file.
1
2#pragma once
3
4#include <algorithm>
5#include <cstdint>
6#include <limits>
7
8#include "quant/math.hpp"
9
10namespace quant::rng {
11
13enum class Mode {
14 Mt19937,
15 Counter
16};
17
18namespace detail {
19
20constexpr std::uint64_t kMixConst1 = 0x9E3779B97F4A7C15ULL;
21constexpr std::uint64_t kMixConst2 = 0xBF58476D1CE4E5B9ULL;
22constexpr std::uint64_t kMixConst3 = 0x94D049BB133111EBULL;
23
24inline std::uint64_t splitmix64(std::uint64_t x) {
25 x += kMixConst1;
26 x = (x ^ (x >> 30)) * kMixConst2;
27 x = (x ^ (x >> 27)) * kMixConst3;
28 x ^= (x >> 31);
29 return x;
30}
31
32inline std::uint64_t hash_combine(std::uint64_t x, std::uint64_t y) {
33 x ^= y + kMixConst1 + (x << 6) + (x >> 2);
34 return splitmix64(x);
35}
36
37inline double to_unit_interval(std::uint64_t bits) {
38 constexpr double kInvPow2_53 = 1.0 / static_cast<double>(1ULL << 53);
39 const std::uint64_t mantissa = (bits >> 11); // keep top 53 bits
40 double u = (static_cast<double>(mantissa) + 0.5) * kInvPow2_53;
41 const double eps = std::numeric_limits<double>::epsilon();
42 u = std::clamp(u, eps, 1.0 - eps);
43 return u;
44}
45
46} // namespace detail
47
49inline double uniform(std::uint64_t master_seed, std::uint64_t path_id, std::uint32_t step_id,
50 std::uint32_t dim_id, std::uint32_t stream_id) {
52 std::uint64_t h = detail::splitmix64(master_seed + detail::kMixConst1);
53 h = hash_combine(h, path_id);
54 h = hash_combine(h, (static_cast<std::uint64_t>(step_id) << 32) | dim_id);
55 h = hash_combine(h, stream_id);
57}
58
60inline double normal(std::uint64_t master_seed, std::uint64_t path_id, std::uint32_t step_id,
61 std::uint32_t dim_id, std::uint32_t stream_id) {
62 const double u = uniform(master_seed, path_id, step_id, dim_id, stream_id);
64}
65
66} // namespace quant::rng
double inverse_normal_cdf(double p)
Definition math.hpp:15
std::uint64_t hash_combine(std::uint64_t x, std::uint64_t y)
Definition rng.hpp:32
constexpr std::uint64_t kMixConst2
Definition rng.hpp:21
double to_unit_interval(std::uint64_t bits)
Definition rng.hpp:37
constexpr std::uint64_t kMixConst3
Definition rng.hpp:22
std::uint64_t splitmix64(std::uint64_t x)
Definition rng.hpp:24
constexpr std::uint64_t kMixConst1
Definition rng.hpp:20
Deterministic random number generation utilities.
Definition rng.hpp:10
double uniform(std::uint64_t master_seed, std::uint64_t path_id, std::uint32_t step_id, std::uint32_t dim_id, std::uint32_t stream_id)
Deterministic hash of RNG identifiers -> uniform (0,1)
Definition rng.hpp:49
double normal(std::uint64_t master_seed, std::uint64_t path_id, std::uint32_t step_id, std::uint32_t dim_id, std::uint32_t stream_id)
Deterministic standard normal draw via inverse CDF transform.
Definition rng.hpp:60
Mode
RNG mode selection: traditional PRNG or deterministic counter-based.
Definition rng.hpp:13
@ Counter
Counter-based, reproducible across threading schedules.
@ Mt19937
PCG/Mersenne Twister style PRNG (per-thread stateful)