CASToR  1.0
Tomographic Reconstruction (PET/SPECT)
sRNG.cc
Go to the documentation of this file.
00001 
00002 /*
00003   Implementation of class sRNG
00004 
00005   - separators: X
00006   - doxygen: X
00007   - default initialization: X
00008   - CASTOR_DEBUG: none
00009   - CASTOR_VERBOSE: X
00010 */
00011 
00020 #include "sRNG.hh"
00021 
00022 sRNG *sRNG::mp_Instance = NULL;
00023 
00024 
00025 // =====================================================================
00026 // ---------------------------------------------------------------------
00027 // ---------------------------------------------------------------------
00028 // =====================================================================
00032 sRNG::sRNG()
00033 {
00034   mp_Instance = NULL;
00035   m_verbose = 5;
00036   mp_Engines.clear();
00037   mp_NonThreadedEngine = NULL;
00038 }
00039 
00040 
00041 
00042 // =====================================================================
00043 // ---------------------------------------------------------------------
00044 // ---------------------------------------------------------------------
00045 // =====================================================================
00046 /*
00047   \brief Destructor of sRNG. Do nothing by default
00048 */
00049 sRNG::~sRNG()
00050 {
00051   if(mp_NonThreadedEngine) delete mp_NonThreadedEngine;
00052 }
00053 
00054 
00055 
00056 // =====================================================================
00057 // ---------------------------------------------------------------------
00058 // ---------------------------------------------------------------------
00059 // =====================================================================
00060 /*
00061   \fn Initialize
00062   \param a_nbThreads
00063   \brief Instanciate a number of RNG according to the number of threads used in openMP
00064   \details It uses a std::random_device as initial seed for each thread
00065   \return 0 if success, positive value otherwise
00066 */
00067 int sRNG::Initialize(int a_nbThreads)
00068 {
00069   if(m_verbose >=3) if(m_verbose>=3) Cout("sRNG::Initialize ..."<< endl); 
00070   
00071   for(int th=0; th<a_nbThreads; th++)
00072   {
00073     std::random_device rd;
00074     mp_Engines.push_back(Engine(rd()));
00075   }
00076 
00077   std::random_device rd_single;
00078   mp_NonThreadedEngine = new Engine(rd_single());
00079     
00080   return 0;
00081 }
00082 
00083 
00084 
00085 // =====================================================================
00086 // ---------------------------------------------------------------------
00087 // ---------------------------------------------------------------------
00088 // =====================================================================
00098 int sRNG::Initialize(int64_t a_seed, int a_nbThreads)
00099 {
00100   if(m_verbose >=3) Cout("sRNG::Initialize with provided seed..."<< endl); 
00101     
00102   if (a_seed<0)
00103   {
00104     Cout("***** sRNG::Initialize()-> Error : seed for RNG should be >=0 !" << endl);
00105     return 1;
00106   }
00107   
00108   for(int th=0; th<a_nbThreads; th++)
00109   {
00110     mp_Engines.push_back(Engine(a_seed));
00111     if(m_verbose>=3) Cout("sRNG::Initialize()->Seed for thread "<< th << " : " << a_seed << endl);
00112     a_seed++;
00113   }
00114 
00115   mp_NonThreadedEngine = new Engine(a_seed);
00116 
00117   return 0;
00118 }
00119 
00120 
00121 
00122 // =====================================================================
00123 // ---------------------------------------------------------------------
00124 // ---------------------------------------------------------------------
00125 // =====================================================================
00126 /*
00127   \fn GenerateRdmNber
00128   \brief Generate a random number for the thread whose index is recovered from the ompenMP function
00129   \todo Perhaps getting the thread index from argument rather than directly from the function.
00130   \todo But this implementation allows the RNG to be used anywhere in the code
00131   \todo Perhaps create a random distribution on the fly, and offer the possibility to select lower/upper bounds via argument parameters
00132   \return a random generated number in [0. ; 1.)
00133 */
00134 double sRNG::GenerateRdmNber()
00135 {
00136   #ifdef CASTOR_VERBOSE
00137   if(m_verbose >=4) Cout("sRNG::GenerateRdmNber..."<< endl); 
00138   #endif
00139   
00140   int id=0;
00141   #ifdef CASTOR_OMP
00142   id = omp_get_thread_num();
00143   #endif
00144   return mp_Distribution(mp_Engines[id]);
00145 } 
00146 
00147 
00148 
00149 // =====================================================================
00150 // ---------------------------------------------------------------------
00151 // ---------------------------------------------------------------------
00152 // =====================================================================
00153 /*
00154   \fn GenerateNonThreadedRdmNber
00155   \brief Generate a random number using the not thread safe random generator, for use in sequential
00156   parts of an otherwise multithreaded code
00157   \return double random number
00158 */
00159 double sRNG::GenerateNonThreadedRdmNber()
00160 {
00161   #ifdef CASTOR_VERBOSE
00162   if(m_verbose >=4) Cout("sRNG::GenerateNonThreadedRdmNber..."<< endl); 
00163   #endif
00164   
00165   return mp_Distribution((*mp_NonThreadedEngine));
00166 } 
00167 
00168 
00169 
00170 // =====================================================================
00171 // ---------------------------------------------------------------------
00172 // ---------------------------------------------------------------------
00173 // =====================================================================
00174 /*
00175   \fn GetNonThreadedGenerator
00176   \brief Get the not thread safe random generator, for use in sequential
00177   parts of an otherwise multithreaded code
00178   \return double random number
00179 */
00180 sRNG::Engine* sRNG::GetNonThreadedGenerator()
00181 {
00182    #ifdef CASTOR_VERBOSE
00183   if(m_verbose >=4) Cout("sRNG::GetNonThreadedGenerator..."<< endl); 
00184   #endif
00185   
00186   return mp_NonThreadedEngine;
00187 } 
 All Classes Files Functions Variables Typedefs Defines