Forgottent seeded pcg32

This commit is contained in:
Zaher Salman
2026-06-19 17:14:53 +02:00
parent a44db47586
commit c721259556
2 changed files with 29 additions and 8 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
# 4-Feb-2013 ZS, clean up makefile and include random number generator
# in the code. Use gfortran which is now a standard part of gcc.
# 18-Jun-2026 ZS, add explicit release/debug/profile build modes.
# 19-Jun-2026 ZA, add optional random number generators to improve speed
# 19-Jun-2026 ZS, add optional random number generators to improve speed
FC = gfortran
PROGRAM = trimspNL
+28 -7
View File
@@ -9,8 +9,13 @@
* which gfortran resolves to pcg32_random_uniform_().
*
* The generator is deterministic and self-contained. It returns REAL*4
* values in (0,1) to avoid exact zero in legacy transport code. The high 24 bits of each 32-bit PCG output are used,
* matching the precision of a single-precision uniform variate.
* values in (0,1) to avoid exact zero in legacy transport code.
* The high 24 bits of each 32-bit PCG output are used, matching the
* precision of a single-precision uniform variate.
*
* trimspNL calls pcg32_seed_() with the three existing input seeds
* RI, RI2 and RI3. This keeps PCG32 runs reproducible from the same
* input deck without changing the file format.
*/
static uint64_t pcg32_state = 0x853c49e6748fea9bULL;
@@ -61,12 +66,28 @@ pcg32_random_uniform_(float *values, int *n_values)
}
}
/* Optional explicit seed hook for later experiments. Not used by trimspNL yet. */
void
pcg32_seed_(int *seed1, int *seed2)
static uint64_t
pcg32_mix(uint64_t x)
{
uint64_t initstate = (uint32_t)(*seed1);
uint64_t initseq = (uint32_t)(*seed2);
x += 0x9e3779b97f4a7c15ULL;
x = (x ^ (x >> 30u)) * 0xbf58476d1ce4e5b9ULL;
x = (x ^ (x >> 27u)) * 0x94d049bb133111ebULL;
return x ^ (x >> 31u);
}
void
pcg32_seed_(int *seed1, int *seed2, int *seed3)
{
uint64_t s1 = (uint32_t)(*seed1);
uint64_t s2 = (uint32_t)(*seed2);
uint64_t s3 = (uint32_t)(*seed3);
uint64_t initstate;
uint64_t initseq;
initstate = pcg32_mix(s1 ^ (s2 << 21u) ^ (s3 << 42u)
^ 0x4d595df4d0f33173ULL);
initseq = pcg32_mix(s3 ^ (s2 << 17u) ^ (s1 << 34u)
^ 0x14057b7ef767814fULL);
pcg32_state = 0U;
pcg32_inc = (initseq << 1u) | 1u;