From f54d9e3405391915e2e8ae1315dd20fa2a454897 Mon Sep 17 00:00:00 2001 From: aantonyb Date: Sun, 13 Sep 2026 17:11:32 -0700 Subject: [PATCH 1/3] Implement PCG32 random number generator for platform-independent randomness - Added cardamom_random.c/h with PCG32 implementation - Replaced all random()/srandom() calls with cardarand()/cardarand_seed() - Replaced RAND_MAX with CARDAMOM_RAND_MAX - No macros, no environment dependencies - Guarantees identical random sequences across all platforms - Updated all MCMC functions to use new RNG --- C/auxi_fun/cardamom_random.c | 31 +++++++++++++++++++ C/auxi_fun/cardamom_random.h | 17 ++++++++++ C/auxi_fun/seedrandomnumber.c | 12 ++++--- C/math_fun/randn.c | 5 +-- C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC.c | 7 +++-- C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC_301.c | 7 +++-- C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMC.c | 7 +++-- C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMCZS.c | 9 +++--- C/mcmc_fun/MHMCMC/MCMC_FUN/DEMCMC.c | 7 +++-- C/mcmc_fun/MHMCMC/MCMC_FUN/DEMCMCZS.c | 9 +++--- C/mcmc_fun/MHMCMC/MCMC_FUN/DEMCMCZS_WARMUP.c | 6 ++-- C/mcmc_fun/MHMCMC/MCMC_FUN/DREAMZS.c | 11 ++++--- C/mcmc_fun/MHMCMC/MCMC_FUN/HYBRID_AIDE.c | 5 +-- .../MHMCMC/MCMC_FUN/HYBRID_AIDE_DEMCMC.c | 7 +++-- C/mcmc_fun/MHMCMC/MCMC_FUN/MHMCMC_119.c | 5 +-- C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_ADEMCMC.c | 2 +- C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_AFDEMCMC.c | 6 ++-- C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_DEMCMC.c | 4 +-- C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_DEMCMCZS.c | 14 ++++----- C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_DREAMZS.c | 10 +++--- C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_HYBRID_AIDE.c | 12 +++---- C/projects/CARDAMOM_MDF/CARDAMOM_MDF.c | 1 + 22 files changed, 128 insertions(+), 66 deletions(-) create mode 100644 C/auxi_fun/cardamom_random.c create mode 100644 C/auxi_fun/cardamom_random.h diff --git a/C/auxi_fun/cardamom_random.c b/C/auxi_fun/cardamom_random.c new file mode 100644 index 00000000..a09f8747 --- /dev/null +++ b/C/auxi_fun/cardamom_random.c @@ -0,0 +1,31 @@ +#include "cardamom_random.h" + +static pcg32_random_t pcg32_global = {0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL}; + +static uint32_t pcg32_random_r(pcg32_random_t* rng) { + uint64_t oldstate = rng->state; + rng->state = oldstate * 6364136223846793005ULL + rng->inc; + uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u; + uint32_t rot = oldstate >> 59u; + return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); +} + +static void pcg32_srandom_r(pcg32_random_t* rng, uint64_t initstate, uint64_t initseq) { + rng->state = 0U; + rng->inc = (initseq << 1u) | 1u; + pcg32_random_r(rng); + rng->state += initstate; + pcg32_random_r(rng); +} + +void cardarand_seed(uint64_t seed) { + pcg32_srandom_r(&pcg32_global, seed, 0xda3e39cb94b95bdbULL); +} + +long cardarand(void) { + return (long)(pcg32_random_r(&pcg32_global) & 0x7FFFFFFFL); +} + +double cardarand_uniform(void) { + return (double)pcg32_random_r(&pcg32_global) / (double)0x100000000ULL; +} diff --git a/C/auxi_fun/cardamom_random.h b/C/auxi_fun/cardamom_random.h new file mode 100644 index 00000000..34840b0b --- /dev/null +++ b/C/auxi_fun/cardamom_random.h @@ -0,0 +1,17 @@ +#ifndef CARDAMOM_RANDOM_H +#define CARDAMOM_RANDOM_H + +#include + +typedef struct { + uint64_t state; + uint64_t inc; +} pcg32_random_t; + +void cardarand_seed(uint64_t seed); +long cardarand(void); +double cardarand_uniform(void); + +#define CARDAMOM_RAND_MAX 2147483647L + +#endif diff --git a/C/auxi_fun/seedrandomnumber.c b/C/auxi_fun/seedrandomnumber.c index 92ada834..683ded3f 100644 --- a/C/auxi_fun/seedrandomnumber.c +++ b/C/auxi_fun/seedrandomnumber.c @@ -1,11 +1,12 @@ #pragma once -#include // rand(), srand() +#include #include -#include //for time +#include #include #include -#include // For explicit integer types +#include +#include "cardamom_random.h" /*triple-seeding in simple C code*/ @@ -59,13 +60,14 @@ int charseed_filename(const char *charinput){ int seedrandomnumber(const char *charinput){ long seed1=(long)charseed(charinput); - + // unsigned int seed1 = (unsigned int)charseed(charinput); // unsigned int seed2 = (unsigned int)time(NULL); // unsigned int seed3 = (unsigned int)(uintptr_t)&charinput; // srand(seed1 + seed2 + seed3); + // srandom(seed1); - srandom(seed1); + cardarand_seed((uint64_t)seed1); return 0;} diff --git a/C/math_fun/randn.c b/C/math_fun/randn.c index 51499755..9e47be29 100644 --- a/C/math_fun/randn.c +++ b/C/math_fun/randn.c @@ -1,9 +1,10 @@ #pragma once +#include "../auxi_fun/cardamom_random.h" double randn(){ double pi=3.141592653589793; -double r1=(double)random()/(double)RAND_MAX; -double r2=(double)random()/(double)RAND_MAX; +double r1=(double)cardarand()/(double)CARDAMOM_RAND_MAX; +double r2=(double)cardarand()/(double)CARDAMOM_RAND_MAX; double rn=sqrt(-2*log(r1)) * cos(2*pi*r2); diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC.c index 01409565..dba3106c 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC.c @@ -2,6 +2,7 @@ #include #include #include +#include "../../../auxi_fun/cardamom_random.h" #include "../../../math_fun/std.c" #include "NORMPARS.c" #include "STEP_DEMCMC.c" @@ -100,7 +101,7 @@ for (n=0;nPI.parmax[n] | parlr){ wrlocal=wrlocal+1; diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC_301.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC_301.c index 17138472..ee9579f0 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC_301.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC_301.c @@ -2,6 +2,7 @@ #include #include #include +#include "../../../auxi_fun/cardamom_random.h" #include "../../../math_fun/std.c" #include "NORMPARS.c" #include "STEP_DEMCMC.c" @@ -101,7 +102,7 @@ for (n=0;nPI.parmax[n] | parlr){ wrlocal=wrlocal+1; diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMC.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMC.c index c0f4d379..4ea6d5b2 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMC.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMC.c @@ -2,6 +2,7 @@ #include #include #include +#include "../../../auxi_fun/cardamom_random.h" #include "../../../math_fun/std.c" #include "NORMPARS.c" #include "STEP_DEMCMC.c" @@ -100,7 +101,7 @@ for (n=0;nPI.parmax[n] | parlr){ wrlocal=wrlocal+1; diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMCZS.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMCZS.c index e99a4a08..3aa3e721 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMCZS.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMCZS.c @@ -2,6 +2,7 @@ #include #include #include +#include "../../../auxi_fun/cardamom_random.h" #include "../../../math_fun/std.c" #include "NORMPARS.c" #include "STEP_AFDEMCMC.c" @@ -63,7 +64,7 @@ double par; for (nn=0;nnPI.parmax[n] || par #include #include +#include "../../../auxi_fun/cardamom_random.h" #include "../../../math_fun/std.c" #include "NORMPARS.c" #include "STEP_DEMCMC.c" @@ -97,7 +98,7 @@ for (n=0;n log((double)random() / (double)RAND_MAX)) { N.ACC = N.ACC + 1; + if (P_new - P[nn] > log((double)cardarand() / (double)CARDAMOM_RAND_MAX)) { N.ACC = N.ACC + 1; if (isinf(P_new)==0 && isinf(P[nn])){printf("pnew = %2.1f, p = %2.1f, (P_new-P[nn]) = %2.1f\n",P_new,P[nn],P_new-P[nn]);} diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/DEMCMCZS.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/DEMCMCZS.c index e8691634..08a053eb 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/DEMCMCZS.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/DEMCMCZS.c @@ -2,6 +2,7 @@ #include #include #include +#include "../../../auxi_fun/cardamom_random.h" #include "../../../math_fun/std.c" #include "NORMPARS.c" #include "STEP_DEMCMCZS.c" @@ -60,7 +61,7 @@ double par; for (nn=0;nnPI.parmax[n] || par #include #include +#include "../../../auxi_fun/cardamom_random.h" #include "../../../math_fun/std.c" #include "NORMPARS.c" #include "STEP_DREAMZS.c" @@ -55,7 +56,7 @@ double par; for (nn=0;nnPI.parmax[n] || par=nCR){cridx=nCR-1;} CR=CRvals[cridx]; withinrange=STEP_DREAMZS_PARALLEL(&X[nn*PI.npars],Z,M,pars_new,PI,CR,&nupdate); } totalupdates=totalupdates+nupdate; -lr=log((double)random()/(double)RAND_MAX); +lr=log((double)cardarand()/(double)CARDAMOM_RAND_MAX); if (withinrange==1){ wrlocal=wrlocal+1; diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/HYBRID_AIDE.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/HYBRID_AIDE.c index bdb7e43c..d29de152 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/HYBRID_AIDE.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/HYBRID_AIDE.c @@ -2,6 +2,7 @@ #include #include #include +#include "../../../auxi_fun/cardamom_random.h" #include "../../../math_fun/std.c" #include "NORMPARS.c" #include "STEP_HYBRID_AIDE.c" @@ -43,7 +44,7 @@ N.ACCRATE=0; for (nn=0;nn #include #include +#include "../../../auxi_fun/cardamom_random.h" #include "../../../math_fun/std.c" #include "NORMPARS.c" #include "STEP_HYBRID_AIDE.c" @@ -50,7 +51,7 @@ printf("HYBRID_AIDE_DEMCMC: AIDE phase ends at iteration %d out of %d\n",switch_ for (nn=0;nn #include #include +#include "../../../auxi_fun/cardamom_random.h" #include "../../../math_fun/std.c" #include "../../../math_fun/covariance.c" #include "NORMPARS.c" @@ -104,7 +105,7 @@ if (MCO.fixedpars!=1){PI.parfix[n]=0;} /*BUG IS HERE!!!4-9-2013*/ if (MCO.randparini==1 && PI.parfix[n]!=1){ /*random parameter if PI.parini = -9999*/ -PI.parini[n]=nor2par((double)random()/(double)RAND_MAX,PI.parmin[n],PI.parmax[n]);} +PI.parini[n]=nor2par((double)cardarand()/(double)CARDAMOM_RAND_MAX,PI.parmin[n],PI.parmax[n]);} /*printing parameter values*/ printf("log10(p%d)=%2.4f ",n+1,log10(PI.parini[n])); if ((n+1) % 3==0){printf("\n");} @@ -153,7 +154,7 @@ while (N.ITER < MCO.nOUT){ if (isnan(P)){printf("Warning: MLF generated NaN... treating as -Inf\n");P=log(0);break;} - if (P-P0>log((double)random()/(double)RAND_MAX)){ + if (P-P0>log((double)cardarand()/(double)CARDAMOM_RAND_MAX)){ /*storing accepted solution*/ for (n=0;n=PI.npars){force_dim=PI.npars-1;} int nupdate=0; for (n=0;n0.5); +int de_first=((double)cardarand()/(double)CARDAMOM_RAND_MAX>0.5); int withinlim=1; if (de_first){ diff --git a/C/projects/CARDAMOM_MDF/CARDAMOM_MDF.c b/C/projects/CARDAMOM_MDF/CARDAMOM_MDF.c index d6dbd736..46841931 100644 --- a/C/projects/CARDAMOM_MDF/CARDAMOM_MDF.c +++ b/C/projects/CARDAMOM_MDF/CARDAMOM_MDF.c @@ -1,4 +1,5 @@ #include +#include "../../auxi_fun/cardamom_random.h" #include "../../auxi_fun/oksofar.c" #include "../../auxi_fun/okcheck.c" #include "../../auxi_fun/seedrandomnumber.c" From 680875de203423b92c8a8a2aeb65846c5367cf5c Mon Sep 17 00:00:00 2001 From: aantonyb Date: Sun, 13 Sep 2026 17:33:50 -0700 Subject: [PATCH 2/3] Add cardaurand() function to simplify code - Added cardaurand() as cleaner replacement for (double)cardarand()/(double)CARDAMOM_RAND_MAX - Replaced 31 instances across all MCMC files with the new function - Code is now more readable and maintainable - Moved documentation files to /Users/abloom/CLAUDE/SUMMARIES_AND_DESCRIPTIONS/ with SEP26 prefix - Verified compilation still successful --- C/auxi_fun/cardamom_random.c | 4 ++++ C/auxi_fun/cardamom_random.h | 1 + C/math_fun/randn.c | 4 ++-- C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC_301.c | 4 ++-- C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMCZS.c | 8 ++++---- C/mcmc_fun/MHMCMC/MCMC_FUN/DEMCMCZS.c | 8 ++++---- C/mcmc_fun/MHMCMC/MCMC_FUN/DEMCMCZS_WARMUP.c | 6 +++--- C/mcmc_fun/MHMCMC/MCMC_FUN/DREAMZS.c | 8 ++++---- C/mcmc_fun/MHMCMC/MCMC_FUN/HYBRID_AIDE.c | 4 ++-- C/mcmc_fun/MHMCMC/MCMC_FUN/HYBRID_AIDE_DEMCMC.c | 4 ++-- C/mcmc_fun/MHMCMC/MCMC_FUN/MHMCMC_119.c | 4 ++-- C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_DEMCMCZS.c | 4 ++-- C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_DREAMZS.c | 4 ++-- C/mcmc_fun/MHMCMC/MCMC_FUN/STEP_HYBRID_AIDE.c | 4 ++-- 14 files changed, 36 insertions(+), 31 deletions(-) diff --git a/C/auxi_fun/cardamom_random.c b/C/auxi_fun/cardamom_random.c index a09f8747..dafa057f 100644 --- a/C/auxi_fun/cardamom_random.c +++ b/C/auxi_fun/cardamom_random.c @@ -26,6 +26,10 @@ long cardarand(void) { return (long)(pcg32_random_r(&pcg32_global) & 0x7FFFFFFFL); } +double cardaurand(void) { + return (double)cardarand() / (double)CARDAMOM_RAND_MAX; +} + double cardarand_uniform(void) { return (double)pcg32_random_r(&pcg32_global) / (double)0x100000000ULL; } diff --git a/C/auxi_fun/cardamom_random.h b/C/auxi_fun/cardamom_random.h index 34840b0b..dd7d7987 100644 --- a/C/auxi_fun/cardamom_random.h +++ b/C/auxi_fun/cardamom_random.h @@ -10,6 +10,7 @@ typedef struct { void cardarand_seed(uint64_t seed); long cardarand(void); +double cardaurand(void); double cardarand_uniform(void); #define CARDAMOM_RAND_MAX 2147483647L diff --git a/C/math_fun/randn.c b/C/math_fun/randn.c index 9e47be29..6ad1d693 100644 --- a/C/math_fun/randn.c +++ b/C/math_fun/randn.c @@ -3,8 +3,8 @@ double randn(){ double pi=3.141592653589793; -double r1=(double)cardarand()/(double)CARDAMOM_RAND_MAX; -double r2=(double)cardarand()/(double)CARDAMOM_RAND_MAX; +double r1=cardaurand(); +double r2=cardaurand(); double rn=sqrt(-2*log(r1)) * cos(2*pi*r2); diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC_301.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC_301.c index ee9579f0..df6f2283 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC_301.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/ADEMCMC_301.c @@ -102,7 +102,7 @@ for (n=0;nPI.parmax[n] | parlr){ wrlocal=wrlocal+1; diff --git a/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMCZS.c b/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMCZS.c index 3aa3e721..25a4d477 100644 --- a/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMCZS.c +++ b/C/mcmc_fun/MHMCMC/MCMC_FUN/AFDEMCMCZS.c @@ -64,7 +64,7 @@ double par; for (nn=0;nnPI.parmax[n] || parPI.parmax[n] || parPI.parmax[n] || parlog((double)cardarand()/(double)CARDAMOM_RAND_MAX)){ + if (P-P0>log(cardaurand())){ /*storing accepted solution*/ for (n=0;n=PI.npars){force_dim=PI.npars-1;} int nupdate=0; for (n=0;n0.5); +int de_first=(cardaurand()>0.5); int withinlim=1; if (de_first){ From ea0c95c28dcd01973dae62e9b4d1458318fb4057 Mon Sep 17 00:00:00 2001 From: aantonyb Date: Sun, 13 Sep 2026 17:46:58 -0700 Subject: [PATCH 3/3] Convert to header-only implementation - no compile script changes needed - Merged cardamom_random.c into cardamom_random.h as static inline functions - Deleted cardamom_random.c (no longer needed) - Reverted CARDAMOM_COMPILE.sh to original (no changes required) - Implementation is now included directly via header - Zero changes to build system! --- C/auxi_fun/cardamom_random.c | 35 ------------------------------ C/auxi_fun/cardamom_random.h | 42 +++++++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 40 deletions(-) delete mode 100644 C/auxi_fun/cardamom_random.c diff --git a/C/auxi_fun/cardamom_random.c b/C/auxi_fun/cardamom_random.c deleted file mode 100644 index dafa057f..00000000 --- a/C/auxi_fun/cardamom_random.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "cardamom_random.h" - -static pcg32_random_t pcg32_global = {0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL}; - -static uint32_t pcg32_random_r(pcg32_random_t* rng) { - uint64_t oldstate = rng->state; - rng->state = oldstate * 6364136223846793005ULL + rng->inc; - uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u; - uint32_t rot = oldstate >> 59u; - return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); -} - -static void pcg32_srandom_r(pcg32_random_t* rng, uint64_t initstate, uint64_t initseq) { - rng->state = 0U; - rng->inc = (initseq << 1u) | 1u; - pcg32_random_r(rng); - rng->state += initstate; - pcg32_random_r(rng); -} - -void cardarand_seed(uint64_t seed) { - pcg32_srandom_r(&pcg32_global, seed, 0xda3e39cb94b95bdbULL); -} - -long cardarand(void) { - return (long)(pcg32_random_r(&pcg32_global) & 0x7FFFFFFFL); -} - -double cardaurand(void) { - return (double)cardarand() / (double)CARDAMOM_RAND_MAX; -} - -double cardarand_uniform(void) { - return (double)pcg32_random_r(&pcg32_global) / (double)0x100000000ULL; -} diff --git a/C/auxi_fun/cardamom_random.h b/C/auxi_fun/cardamom_random.h index dd7d7987..05bb2773 100644 --- a/C/auxi_fun/cardamom_random.h +++ b/C/auxi_fun/cardamom_random.h @@ -8,11 +8,43 @@ typedef struct { uint64_t inc; } pcg32_random_t; -void cardarand_seed(uint64_t seed); -long cardarand(void); -double cardaurand(void); -double cardarand_uniform(void); - #define CARDAMOM_RAND_MAX 2147483647L +/* Global state */ +static pcg32_random_t pcg32_global = {0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL}; + +/* PCG32 core algorithm */ +static inline uint32_t pcg32_random_r(pcg32_random_t* rng) { + uint64_t oldstate = rng->state; + rng->state = oldstate * 6364136223846793005ULL + rng->inc; + uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u; + uint32_t rot = oldstate >> 59u; + return (xorshifted >> rot) | (xorshifted << ((-rot) & 31)); +} + +static inline void pcg32_srandom_r(pcg32_random_t* rng, uint64_t initstate, uint64_t initseq) { + rng->state = 0U; + rng->inc = (initseq << 1u) | 1u; + pcg32_random_r(rng); + rng->state += initstate; + pcg32_random_r(rng); +} + +/* Public API */ +static inline void cardarand_seed(uint64_t seed) { + pcg32_srandom_r(&pcg32_global, seed, 0xda3e39cb94b95bdbULL); +} + +static inline long cardarand(void) { + return (long)(pcg32_random_r(&pcg32_global) & 0x7FFFFFFFL); +} + +static inline double cardaurand(void) { + return (double)cardarand() / (double)CARDAMOM_RAND_MAX; +} + +static inline double cardarand_uniform(void) { + return (double)pcg32_random_r(&pcg32_global) / (double)0x100000000ULL; +} + #endif