diff --git a/C/auxi_fun/cardamom_random.h b/C/auxi_fun/cardamom_random.h new file mode 100644 index 00000000..05bb2773 --- /dev/null +++ b/C/auxi_fun/cardamom_random.h @@ -0,0 +1,50 @@ +#ifndef CARDAMOM_RANDOM_H +#define CARDAMOM_RANDOM_H + +#include + +typedef struct { + uint64_t state; + uint64_t inc; +} pcg32_random_t; + +#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 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..6ad1d693 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=cardaurand(); +double r2=cardaurand(); 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..df6f2283 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..25a4d477 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..52664d05 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(cardaurand()); 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..5665cce5 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(cardaurand(),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(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){ 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"