header_utils
Loading...
Searching...
No Matches
random_seq.h
1
4
5#pragma once
6
7#include "random.h"
8//#include "hashes.h"
9#include "noise.h"
10
11namespace ghassanpl::noise
12{
17
18 [[nodiscard]] constexpr uint64_t seeded_noise64(uint64_t position, uint64_t seed)
19 {
20 const uint64_t BIT_NOISE1 = 0xB5297A4DB5297A4D;
21 const uint64_t BIT_NOISE2 = 0x68E31DA468E31DA4;
22 const uint64_t BIT_NOISE3 = 0x1B56C4E91B56C4E9;
23
24 uint64_t mangled = position;
25 mangled *= BIT_NOISE1;
26 mangled += seed;
27 mangled ^= (mangled >> 8);
28 mangled += BIT_NOISE2;
29 mangled ^= (mangled << 8);
30 mangled *= BIT_NOISE3;
31 mangled ^= (mangled >> 8);
32 return mangled;
33 }
34
35 [[nodiscard]] constexpr uint32_t seeded_noise(int32_t position, uint32_t seed)
36 {
37 constexpr uint32_t SQ5_BIT_NOISE1 = 0xd2a80a3f; // 11010010101010000000101000111111
38 constexpr uint32_t SQ5_BIT_NOISE2 = 0xa884f197; // 10101000100001001111000110010111
39 constexpr uint32_t SQ5_BIT_NOISE3 = 0x6C736F4B; // 01101100011100110110111101001011
40 constexpr uint32_t SQ5_BIT_NOISE4 = 0xB79F3ABB; // 10110111100111110011101010111011
41 constexpr uint32_t SQ5_BIT_NOISE5 = 0x1b56c4f5; // 00011011010101101100010011110101
42
43 auto mangledBits = (uint32_t)position;
44 mangledBits *= SQ5_BIT_NOISE1;
45 mangledBits += seed;
46 mangledBits ^= (mangledBits >> 9);
47 mangledBits += SQ5_BIT_NOISE2;
48 mangledBits ^= (mangledBits >> 11);
49 mangledBits *= SQ5_BIT_NOISE3;
50 mangledBits ^= (mangledBits >> 13);
51 mangledBits += SQ5_BIT_NOISE4;
52 mangledBits ^= (mangledBits >> 15);
53 mangledBits *= SQ5_BIT_NOISE5;
54 mangledBits ^= (mangledBits >> 17);
55 return mangledBits;
56 }
57
58 [[nodiscard]] constexpr uint32_t seeded_noise2d(int32_t indexX, int32_t indexY, uint32_t seed)
59 {
60 constexpr int PRIME_NUMBER = 198491317; // Large prime number with non-boring bits
61 return seeded_noise(indexX + (PRIME_NUMBER * indexY), seed);
62 }
63
64 [[nodiscard]] constexpr double seeded_noise_normalized(int32_t index, uint32_t seed)
65 {
66 constexpr double ONE_OVER_MAX_UINT = (1.0 / (double)0xFFFFFFFF);
67 return ONE_OVER_MAX_UINT * (double)seeded_noise(index, seed);
68 }
69
70 [[nodiscard]] constexpr double seeded_noise2d_normalized(int32_t indexX, int32_t indexY, uint32_t seed)
71 {
72 constexpr double ONE_OVER_MAX_UINT = (1.0 / (double)0xFFFFFFFF);
73 return ONE_OVER_MAX_UINT * (double)seeded_noise2d(indexX, indexY, seed);
74 }
75}
76
77namespace ghassanpl::random
78{
79 constexpr uint64_t xorshift64(uint64_t& state) noexcept
80 {
81 uint64_t x = state;
82 x ^= x >> 12;
83 x ^= x << 25;
84 x ^= x >> 27;
85 state = x;
86 return x * 0x2545F4914F6CDD1D;
87 }
88
89 constexpr inline uint64_t numrep_hash(uint64_t index)
90 {
91 uint64_t v = index * 3935559000370003845LL + 2691343689449507681LL;
92 v ^= v >> 21; v ^= v << 37; v ^= v >> 4;
93 v *= 4768777513237032717LL;
94 v ^= v << 20; v ^= v >> 41; v ^= v << 5;
95 return v;
96 }
97
98 /*
99 inline std::pair<uint32_t, uint32_t> philox2x32_R(unsigned int R, std::pair<uint32_t, uint32_t> sequence_index, uint32_t sequence_key)
100 {
101 static constexpr auto _philox2x32round = [](std::pair<uint32_t, uint32_t> sequence_index, uint32_t sequence_key) -> std::pair<uint32_t, uint32_t> {
102 uint64_t product = (((uint64_t)0xd256d193)) * sequence_index.first;
103 uint32_t hi = (uint32_t)(product >> 32);
104 uint32_t lo = (uint32_t)product;
105 return { hi ^ sequence_key ^ sequence_index.second, lo };
106 };
107 sequence_index = _philox2x32round(sequence_index, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
108 sequence_index = _philox2x32round(sequence_index, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
109 sequence_index = _philox2x32round(sequence_index, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
110 sequence_index = _philox2x32round(sequence_index, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
111 sequence_index = _philox2x32round(sequence_index, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
112 sequence_index = _philox2x32round(sequence_index, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
113 sequence_index = _philox2x32round(sequence_index, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
114 sequence_index = _philox2x32round(sequence_index, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
115 sequence_index = _philox2x32round(sequence_index, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
116 sequence_index = _philox2x32round(sequence_index, sequence_key);
117 return sequence_index;
118 }
119 */
120
121 constexpr uint64_t philox64(uint64_t sequence_index, uint32_t sequence_key)
122 {
123 constexpr auto _philox2x32round = [](std::pair<uint32_t, uint32_t> ctr, uint32_t key) -> std::pair<uint32_t, uint32_t> {
124 uint64_t product = (((uint64_t)0xd256d193)) * ctr.first;
125 uint32_t hi = (uint32_t)(product >> 32);
126 uint32_t lo = (uint32_t)product;
127 return { hi ^ key ^ ctr.second, lo };
128 };
129 auto ctrPair = std::pair<uint32_t, uint32_t>{ (uint32_t)sequence_index, (uint32_t)(sequence_index >> 32) };
130 ctrPair = _philox2x32round(ctrPair, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
131 ctrPair = _philox2x32round(ctrPair, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
132 ctrPair = _philox2x32round(ctrPair, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
133 ctrPair = _philox2x32round(ctrPair, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
134 ctrPair = _philox2x32round(ctrPair, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
135 ctrPair = _philox2x32round(ctrPair, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
136 ctrPair = _philox2x32round(ctrPair, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
137 ctrPair = _philox2x32round(ctrPair, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
138 ctrPair = _philox2x32round(ctrPair, sequence_key); sequence_key += ((uint32_t)0x9E3779B9);
139 ctrPair = _philox2x32round(ctrPair, sequence_key);
140 return uint64_t(ctrPair.first) | (uint64_t(ctrPair.second) << 32ULL);
141 }
142
144 struct philox64_engine
145 {
146 using result_type = uint64_t;
147
148 [[nodiscard]] constexpr result_type operator()() noexcept { return philox64(m_index + n++, m_key); }
149 constexpr philox64_engine(uint64_t index = 0, uint32_t key = 0) noexcept : m_index(index), m_key(key), n(0) { }
150
151 static constexpr result_type min() { return 0; }
152 static constexpr result_type max() { return ~((result_type)0); }
153
154 [[nodiscard]] constexpr uint64_t index() const noexcept { return m_index; }
155 [[nodiscard]] constexpr uint32_t key() const noexcept { return m_key; }
156 constexpr void reset(uint64_t index, uint32_t key) noexcept
157 {
158 m_index = index;
159 m_key = key;
160 n = 0;
161 }
162 private:
163 uint64_t m_index;
164 uint32_t m_key;
165 uint64_t n;
166 };
167
168#if GHPL_CPP20
169 static_assert(std::uniform_random_bit_generator<philox64_engine>);
170#endif
171
173}
auto index(T &cont, RANDOM &rng=::ghassanpl::random::default_random_engine)
Returns an index of a random element in cont.
Definition random.h:331
Shamelessly stolen from https://github.com/SRombauts/SimplexNoise/.
Definition noise.h:13