oblique_mc

Monte Carlo in Single Layer Biological Tissue
git clone anongit@rnpnr.xyz:oblique_mc.git
Log | Files | Refs | Feed | README | LICENSE

Commit: ffb6fce2383e062b18e2fa7ddfb23a4b010c0c1c
Parent: efaa778d96864408dc9dd999f9c4f2ddf660460d
Author: Randy Palamar
Date:   Tue, 26 Mar 2024 12:25:32 -0600

replace slow garbage rng with xoroshiro128+

Diffstat:
MPhoton.cpp | 35+++++++----------------------------
Mmain.cpp | 2++
Mutils.cpp | 110++++++++++++++++++++-----------------------------------------------------------
Mutils.h | 11+++++------
4 files changed, 41 insertions(+), 117 deletions(-)

diff --git a/Photon.cpp b/Photon.cpp @@ -58,14 +58,9 @@ void Photon::Launch() void Photon::CalStep() { - double ran; - if (s<ZERO) - { - do - { - ran=RandomNum(); - } while(ran<=0||ran>1); - s=-log(ran); //dimensionless, + if (s < ZERO) { + double ran = random_uniform(); + s = -log(ran + EPS); } } @@ -119,10 +114,7 @@ void Photon::Scatter() // calculate next propagation direction if (!dead) { double costheta,fei,ran; - do - { - ran=RandomNum(); - } while(ran<0||ran>=1); + ran = random_uniform(); if (g!=0) { double aa=(1-g*g)/(1-g+2*g*ran); @@ -136,10 +128,7 @@ void Photon::Scatter() // calculate next propagation direction }//(3.28) double sintheta,sinfei,cosfei; sintheta=sqrt(1-costheta*costheta); - do - { - ran=RandomNum(); - } while(ran<0||ran>=1); + ran = random_uniform(); fei=2*PI*ran;//(3.29) cosfei=cos(fei); if (fei<PI) @@ -193,12 +182,7 @@ void Photon::ReflectTransmit() // deal with photon across boundary B=B*B; ralphai=0.5*(2*A-A*A-A*B)/(B*(1-A));//(3.36) } - double ran; - do - { - ran=RandomNum(); - } - while(ran<0||ran>=1); + double ran = random_uniform(); if (ran<=ralphai) //rebound to current layer { uz=-uz; @@ -228,11 +212,7 @@ void Photon::Termination() //Russian roulette survial test double m=10; if (w<=wth) { - double e; - do - { - e=RandomNum(); - }while(e<0||e>1); + double e = random_uniform(); if (e>(1/m)) { w=0; @@ -245,4 +225,3 @@ void Photon::Termination() //Russian roulette survial test } } } - diff --git a/main.cpp b/main.cpp @@ -30,6 +30,8 @@ int main(void) cout<<"*****************************************"<<endl; cout<<endl; + random_init(); + cout<<"File name(Input:*.mci; Output:*.mco): "; string sFilename, sInfilename, sOutfilename; cin>>sFilename; diff --git a/utils.cpp b/utils.cpp @@ -1,93 +1,37 @@ +#include <stdint.h> +#include <time.h> + +typedef uint64_t u64; + #include "utils.h" -/*********************************************************** -* A random number generator from Numerical Recipes in C. ****/ -#define MBIG 1000000000 -#define MSEED 161803398 -#define MZ 0 -#define FAC 1.0E-9 -float ran3(int &idum) +static u64 rand_state[2]; + +void +random_init(void) { - static int inext,inextp; - static long ma[56]; - static int iff=0; - long mj,mk; - int i,ii,k; - if (idum < 0 || iff == 0) - { - iff=1; - mj=MSEED-(idum < 0 ? -idum : idum); - mj %= MBIG; - ma[55]=mj; - mk=1; - for (i=1;i<=54;i++) - { - ii=(21*i) % 55; - ma[ii]=mk; - mk=mj-mk; - if (mk < MZ) mk += MBIG; - mj=ma[ii]; - } - for (k=1;k<=4;k++) - for (i=1;i<=55;i++) - { - ma[i] -= ma[1+(i+30) % 55]; - if (ma[i] < MZ) ma[i] += MBIG; - } - inext=0; - inextp=31; - idum=1; - } - if (++inext == 56) - inext=1; - if (++inextp == 56) - inextp=1; - mj=ma[inext]-ma[inextp]; - if (mj < MZ) mj += MBIG; - ma[inext]=mj; - return mj*FAC; + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + rand_state[0] = (intptr_t)&printf ^ ts.tv_sec + ^ ((u64)ts.tv_nsec * 0xAC5533CD); + rand_state[1] = (intptr_t)&malloc ^ ts.tv_sec + ^ ((u64)ts.tv_nsec * 0xAC5533CD); } -#undef MBIG -#undef MSEED -#undef MZ -#undef FAC - -/*********************************************************** - * Generate a random number between 0 and 1. Take a - * number as seed the first time entering the function. - * The seed is limited to 1<<15. - * Wang et al found that when idum is too large, ran3 may return - * numbers beyond 0 and 1. - ****/ -//#define STANDARDTEST 0 /* testing program using fixed rnd seed. */ -double RandomNum(void) +static u64 +xoroshiro128plus(u64 s[2]) { - static bool first_time=1; - static int idum; /* seed for ran3. */ - if(first_time) - { - #if STANDARDTEST /* Use fixed seed to test the program. */ - idum = - 1; - #else - idum = -(int)time(NULL)%(1<<15); /* use 16-bit integer as the seed. */ - #endif - ran3(idum); - first_time = 0; - idum = 1; - } - return( (double)ran3(idum) ); + u64 s0 = s[0]; + u64 s1 = s[1]; + u64 result = s0 + s1; + s1 ^= s0; + s[0] = ((s0 << 24) | (s0 >> 40)) ^ s1 ^ (s1 << 16); + s[1] = (s1 << 37) | (s1 >> 27); + return result; } -///////////////////////////////////////////// -int min(int d1,int d2) +double +random_uniform(void) { - if (d1<d2) - { - return d1; - } - else - { - return d2; - } + return xoroshiro128plus(rand_state) / (double)UINT64_MAX; } diff --git a/utils.h b/utils.h @@ -21,6 +21,8 @@ #define BIGVAL 1e6//big value #endif +#define EPS 1.0e-9 + //global variables #ifdef GLOBALORIGIN #define GLOBAL @@ -46,13 +48,10 @@ GLOBAL double x_offset; GLOBAL double y_offset; //generate random data -float ran3(int *idum); -double RandomNum(void); - +void random_init(void); +double random_uniform(void); -//other auxilliary functions -int min(int d1, int d2); -#define SIGN(x) ((x)>=0?1:-1) +#define SIGN(x) ((x) >= 0 ? 1 : -1) ////////allocte dynamic array/////////////////////////