Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:49:46

0001 #pragma once
0002 /**
0003 srngcpu.h : C++ standard random number generation
0004 =================================================
0005 
0006 Instead of generating randoms it is also possible to 
0007 use curand precooked randoms by calling the below method 
0008 with the photon index as argument::
0009 
0010     srngcpu::setSequenceIndex
0011 
0012 This is done by SGenerate::GeneratePhotons when the below EKEY is set::
0013 
0014     export SGenerate__GeneratePhotons_RNG_PRECOOKED=1
0015 
0016 Using this limits the number of photons that can be
0017 generated to the number of rng_sequence that have been precooked 
0018 and persisted to ~/.opticks/precooked.
0019 To extend that see::
0020   
0021    ~/opticks/qudarap/tests/rng_sequence.sh
0022 
0023 **/
0024 
0025 #include <random>
0026 #include "s_seq.h"
0027 
0028 struct srngcpu
0029 {
0030     int                                     seed ;  
0031     std::mt19937_64                         engine ;
0032     std::uniform_real_distribution<float>   fdist ; 
0033     std::uniform_real_distribution<double>  ddist ; 
0034     double                                  fake ; 
0035     s_seq*                                  seq ; 
0036 
0037 
0038     srngcpu(); 
0039     std::string desc() const ; 
0040 
0041     void set_fake(double fake_); 
0042     void setSequenceIndex(int idx); 
0043     int  getSequenceIndex() const ; 
0044 
0045     float  generate_float(); 
0046     double generate_double(); 
0047 
0048     static float  uniform(srngcpu* state );
0049     static double uniform_double(srngcpu* state ); 
0050 
0051     std::string demo(int n) ; 
0052 }; 
0053 
0054 
0055 inline srngcpu::srngcpu() 
0056     : 
0057     seed(1),
0058     fdist(0,1), 
0059     ddist(0,1),
0060     fake(-1.),
0061     seq(nullptr)
0062 { 
0063     engine.seed(seed) ; 
0064 }
0065 
0066 inline std::string srngcpu::desc() const 
0067 {
0068     std::stringstream ss ; 
0069     ss << "srngcpu::desc" << std::endl ; 
0070     std::string str = ss.str(); 
0071     return str ; 
0072 }
0073 
0074 inline void srngcpu::set_fake(double fake_){ fake = fake_ ; } 
0075 
0076 inline float srngcpu::generate_float()
0077 {
0078     if( fake >= 0.f ) return fake ; 
0079     float u = seq && seq->is_enabled() ? seq->flat() : fdist(engine) ; 
0080     return u ; 
0081 } 
0082 inline double srngcpu::generate_double()
0083 { 
0084     if( fake >= 0.f ) return fake ; 
0085     double u = seq && seq->is_enabled() ? seq->flat() : ddist(engine) ; 
0086     return u ; 
0087 }
0088 inline void srngcpu::setSequenceIndex(int idx)
0089 {
0090     if( seq == nullptr ) seq = new s_seq ; 
0091     seq->setSequenceIndex(idx); 
0092 }
0093 inline int srngcpu::getSequenceIndex() const 
0094 {
0095     return seq == nullptr ? -2 : seq->getSequenceIndex() ; 
0096 }
0097 
0098 
0099 
0100 inline float  srngcpu::uniform(srngcpu* state ){        return state->generate_float() ; } 
0101 inline double srngcpu::uniform_double(srngcpu* state ){ return state->generate_double() ; } 
0102 
0103 inline std::string srngcpu::demo(int n) 
0104 {
0105     std::stringstream ss ; 
0106     ss << "srngcpu::demo seq " << getSequenceIndex()  << std::endl ;
0107     for(int i=0 ; i < n ; i++) ss 
0108          << std::setw(4) << i 
0109          << " : " 
0110          << std::fixed << std::setw(10) << std::setprecision(5) << generate_float() 
0111          << std::endl
0112          ; 
0113     std::string str = ss.str(); 
0114     return str ; 
0115 }
0116 
0117 // "mocking" the curand API 
0118 inline float  curand_uniform(srngcpu* state ){         return state->generate_float() ; }
0119 inline double curand_uniform_double(srngcpu* state ){ return state->generate_double() ; }
0120 
0121 
0122 
0123 
0124