Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:57:15

0001 // Simple random number generator class taken from nlojet++.
0002 // $Id$
0003 //
0004 //  Copyright (C) 2002 Zoltan Nagy
0005 //
0006 //  This program is free software; you can redistribute it and/or modify
0007 //  it under the terms of the GNU General Public License as published by
0008 //  the Free Software Foundation; either version 2 of the License, or
0009 //  (at your option) any later version.
0010 //
0011 //  This program is distributed in the hope that it will be useful,
0012 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
0013 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014 //  GNU General Public License for more details.
0015 //
0016 //  You should have received a copy of the GNU General Public License
0017 //  along with this program; if not, write to the Free Software
0018 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0019 //
0020 // Changes compared to the original version
0021 //   2006-08: Some doxygen-style comments added by Gavin Salam
0022 //   2017-02: The operator() (size_type, pointer, std::vector<int> &);
0023 //     members have been added to implement thread-safe access to the
0024 //     generators
0025 //
0026 
0027 #ifndef __FASTJET_BASICRANDOM_HH__
0028 #define __FASTJET_BASICRANDOM_HH__ 1
0029 
0030 //   Standard includes
0031 #include <iostream>
0032 #include <vector>
0033 #include <cassert>
0034 #include "fastjet/internal/base.hh"
0035 
0036 #include "fastjet/config.h"
0037 #ifdef FASTJET_HAVE_LIMITED_THREAD_SAFETY
0038 #include <mutex>
0039 #endif
0040 
0041 
0042 FASTJET_BEGIN_NAMESPACE      // defined in fastjet/internal/base.hh
0043 
0044 /// \if internal_doc
0045 /// @ingroup internal
0046 /// \class BasicRandom
0047 /// Base class for random number generator of a generic value type
0048 /// \endif
0049 template<typename _Tp> class BasicRandom {
0050 public:
0051   typedef _Tp          value_type;
0052   typedef unsigned int size_type;
0053   typedef value_type*  pointer;
0054   
0055   //   give pseudo random numbers
0056   value_type operator() ();
0057   void       operator() (size_type, pointer);
0058 
0059   //   (re)initialize the random number generator
0060   void randomize(void *);
0061 
0062   //   minimum and maximum values
0063   static value_type min();
0064   static value_type max();
0065 
0066   //   print the informations about the generator to the stream
0067   void print_info(std::ostream& __os = std::cout);
0068 };
0069 
0070 //   default random generator
0071 int __default_random_generator(int *__iseed); 
0072 
0073 
0074 //   specializations
0075 
0076 /// \if internal_doc
0077 /// @ingroup internal
0078 /// template specialization (int) for the BasicRandom template class. 
0079 /// \endif
0080 template<>
0081 class BasicRandom<int>
0082 {
0083 public:
0084   typedef int          value_type;
0085   typedef unsigned int size_type;
0086   typedef value_type*  pointer;
0087   
0088   // constructors
0089   explicit BasicRandom(int __s1 = 12345, int __s2 = 67890) {
0090     _M_iseed[0] = __s1;
0091     _M_iseed[1] = __s2;
0092   }
0093     
0094   //   give pseudo random numbers
0095   value_type operator() () { 
0096     return __default_random_generator(_M_iseed);
0097   }
0098   
0099   void operator() (size_type __n, pointer __res) {
0100     for(size_type __i = 0; __i < __n; __i++) 
0101       __res[__i] = __default_random_generator(_M_iseed);
0102   }
0103 
0104   /// given a pointer __res to the beginning of an array, fill that array
0105   /// with __n random numbers
0106   ///
0107   /// This now acquired an extra argument which allows to retreive the
0108   /// set of seeds used for this generation.
0109   void operator() (size_type __n, pointer __res, std::vector<int> & __iseed) {
0110     // if we have (limited) thread safety, lock things
0111 #ifdef FASTJET_HAVE_LIMITED_THREAD_SAFETY
0112     // is the lock here really necessary or would a spinlock do better?
0113     std::lock_guard<std::mutex> guard(_multiple_number_generation_mutex);
0114 #endif
0115     // get the seeds
0116     get_status(__iseed);
0117 
0118     // get the numbers
0119     for(size_type __i = 0; __i < __n; __i++) 
0120       __res[__i] = __default_random_generator(_M_iseed);
0121   }
0122 
0123   //   (re)initialize the random number generator
0124   void randomize(void *__iseed) {
0125     int *__new_seed = (int*) __iseed;
0126     _M_iseed[0] = __new_seed[0];
0127     _M_iseed[1] = __new_seed[1];
0128   }
0129 
0130   void set_status(const std::vector<int> & __iseed) {
0131     assert(__iseed.size() >= 2);
0132     _M_iseed[0] = __iseed[0];
0133     _M_iseed[1] = __iseed[1];
0134   }
0135 
0136   void get_status(std::vector<int> & __iseed) {
0137     __iseed.resize(2);
0138     __iseed[0] = _M_iseed[0];
0139     __iseed[1] = _M_iseed[1];
0140   }
0141   
0142   //   minimum and maximum values
0143   inline static value_type min() { return 0;}
0144   inline static value_type max() { return 2147483647;}
0145 
0146   //   print the informations about the generator to the stream
0147   void print_info(std::ostream& __os = std::cout) {
0148     __os<<"BasicRandom<int> : "<<_M_iseed[0]<<", "<<_M_iseed[1]<<std::endl;
0149   }
0150   
0151 private:
0152   int _M_iseed[2];
0153 #ifdef FASTJET_HAVE_LIMITED_THREAD_SAFETY
0154   static std::mutex _multiple_number_generation_mutex;
0155 #endif
0156 };
0157   
0158 
0159 /// \if internal_doc
0160 /// @ingroup internal
0161 /// template specialization (double) for the BasicRandom template class. 
0162 /// \endif
0163 template<> class BasicRandom<double> {
0164 public:
0165   typedef double       value_type;
0166   typedef unsigned int size_type;
0167   typedef value_type*  pointer;
0168   
0169   /// constructor that takes two integers to specify the seed
0170   explicit BasicRandom(int __s1 = 12345, int __s2 = 67890) {
0171     _M_iseed[0] = __s1;
0172     _M_iseed[1] = __s2;
0173   }
0174     
0175   /// return a single pseudorandom double number, in the range 0.0 to 1.0
0176   /// (not sure whether this range is open or closed)
0177   value_type operator() () { 
0178     return 4.6566128752457969241e-10*__default_random_generator(_M_iseed);
0179   }
0180   
0181   /// given a pointer __res to the beginning of an array, fill that array
0182   /// with __n random numbers
0183   void operator() (size_type __n, pointer __res) {
0184     for(size_type __i = 0; __i < __n; __i++) 
0185       __res[__i] = this -> operator()(); 
0186   }
0187 
0188   /// given a pointer __res to the beginning of an array, fill that array
0189   /// with __n random numbers
0190   ///
0191   /// This now acquired an extra argument which allows to retreive the
0192   /// set of seeds used for this generation.
0193   void operator() (size_type __n, pointer __res, std::vector<int> & __iseed) {
0194     // if we have (limited) thread safety, lock things
0195 #ifdef FASTJET_HAVE_LIMITED_THREAD_SAFETY
0196     // is the lock here really necessary or would a spinlock do better?
0197     std::lock_guard<std::mutex> guard(_multiple_number_generation_mutex);
0198 #endif
0199     // get the seeds
0200     get_status(__iseed);
0201 
0202     // get the numbers
0203     for(size_type __i = 0; __i < __n; __i++) 
0204       __res[__i] = this -> operator()();
0205   }
0206 
0207   ///  (re)initialize the random number generator from an array of seeds
0208   void randomize(void *__iseed) {
0209     int *__new_seed = (int*) __iseed;
0210     _M_iseed[0] = __new_seed[0];
0211     _M_iseed[1] = __new_seed[1];
0212   }
0213   
0214   void set_status(const std::vector<int> & __iseed) {
0215     assert(__iseed.size() >= 2);
0216     _M_iseed[0] = __iseed[0];
0217     _M_iseed[1] = __iseed[1];
0218   }
0219 
0220   void get_status(std::vector<int> & __iseed) {
0221     __iseed.resize(2);
0222     __iseed[0] = _M_iseed[0];
0223     __iseed[1] = _M_iseed[1];
0224   }
0225   
0226   /// minimum value returned by the generator
0227   inline static value_type min() { return 0.0;}
0228   /// maximum value returned by the generator
0229   inline static value_type max() { return 1.0;}
0230 
0231   ///  print information about the generator to the stream
0232   void print_info(std::ostream& __os = std::cout) {
0233     __os<<"BasicRandom<double> : "<<_M_iseed[0]<<", "<<_M_iseed[1]<<std::endl;
0234   }
0235   
0236 private:
0237   int _M_iseed[2];
0238 #ifdef FASTJET_HAVE_LIMITED_THREAD_SAFETY
0239   static std::mutex _multiple_number_generation_mutex;
0240 #endif
0241 };
0242   
0243 //   globally defined random number generator
0244 extern BasicRandom<int>     _G_random_int;
0245 extern BasicRandom<double>  _G_random_double;
0246 
0247 
0248 FASTJET_END_NAMESPACE
0249 
0250 #endif // __FASTJET_BASICRANDOM_HH__
0251