File indexing completed on 2025-04-19 09:09:50
0001 #ifndef ATOOLS_Math_Random_H
0002 #define ATOOLS_Math_Random_H
0003
0004 #include <limits>
0005 #include <fstream>
0006 #include <cmath>
0007 #include <algorithm>
0008 #include <stddef.h>
0009 #include "ATOOLS/Math/MathTools.H"
0010 #include "ATOOLS/Org/Terminator_Objects.H"
0011 #include "ATOOLS/Org/Getter_Function.H"
0012
0013 namespace ATOOLS {
0014
0015 struct RNG_Key {
0016 };
0017
0018 class External_RNG {
0019 public:
0020
0021 virtual ~External_RNG();
0022
0023 virtual double Get() = 0;
0024
0025
0026
0027
0028 virtual bool CanRestoreStatus() const { return false; }
0029 virtual void SaveStatus() {}
0030 virtual void RestoreStatus() {}
0031
0032 };
0033
0034 typedef Getter_Function<External_RNG,RNG_Key> RNG_Getter;
0035
0036 class Marsaglia;
0037
0038 class Random: public Terminator_Object {
0039 private:
0040
0041 int activeGenerator;
0042
0043 long int m_id, m_sid;
0044
0045 std::stringstream m_lastincrementedseed;
0046 size_t m_nsinceinit, m_increment;
0047
0048 External_RNG *p_external;
0049
0050 Marsaglia *p_ran4[2];
0051
0052 double Ran2(long *idum);
0053 double Ran4();
0054
0055 bool ReadInStatus(const std::string &path);
0056 void PrepareTerminate();
0057
0058
0059 int WriteOutStatus4(const char *outfile);
0060 int WriteOutStatus4(std::ostream &os,const size_t &idx);
0061 int WriteOutSavedStatus4(const char *outfile);
0062 void ReadInStatus4(const char * filename);
0063 size_t ReadInStatus4(std::istream &is,const size_t &idx);
0064 void SaveStatus4();
0065 void RestoreStatus4();
0066
0067 public:
0068
0069
0070 Random(long nid);
0071 Random(unsigned int i1,unsigned int i2,unsigned int i3,
0072 unsigned int i4,unsigned int i5,unsigned int i6);
0073
0074
0075 ~Random();
0076
0077
0078 bool InitExternal();
0079 void SetSeed(long nid);
0080 void SetSeed(unsigned int i1,unsigned int i2,
0081 unsigned int i3,unsigned int i4);
0082 long int GetSeed() { return m_id; }
0083
0084 int WriteOutStatus(const char *outfile);
0085 int WriteOutStatus(std::ostream &os,const size_t &idx);
0086 int WriteOutSavedStatus(const char *outfile);
0087 void ReadInStatus(const char *infile);
0088 size_t ReadInStatus(std::istream &is,const size_t &idx);
0089 bool CanRestoreStatus() const;
0090 void SaveStatus();
0091 void RestoreStatus();
0092 void FastForward(const size_t &n);
0093 void ResetToLastIncrementedSeed();
0094 void EraseLastIncrementedSeed()
0095 { m_lastincrementedseed.str(std::string()); }
0096 void SetSeedStorageIncrement(size_t inc) { m_increment=inc; }
0097
0098
0099 double Get();
0100
0101
0102 double GetGaussian() {
0103 static auto hasSpare = false;
0104 static double spare;
0105 if (hasSpare) {
0106 hasSpare = false;
0107 return spare;
0108 }
0109 double ran1, ran2, R;
0110 do {
0111 ran1 = 2.*Get()-1.;
0112 ran2 = 2.*Get()-1.;
0113 R = ran1*ran1+ran2*ran2;
0114 } while (R>1. || R==0.);
0115 R = std::sqrt(-2.*std::log(R)/R);
0116 hasSpare = true;
0117 spare = ran2 * R;
0118 return ran1 * R;
0119 }
0120
0121 double Poissonian(const double & lambda) {
0122 if(lambda>500.) {
0123 double u = Get();
0124 double v = Get();
0125 return int(std::sqrt(lambda)*std::sqrt(-2.*std::log(u))*std::cos(2.*M_PI*v)+lambda);
0126 }
0127 double disc(std::exp(-lambda)),p(1.);
0128 int N(0);
0129 while ((p*=Get())>disc) N++;
0130 return N;
0131 }
0132 double Theta() { return std::acos(2.*Get()-1.); }
0133 double GetNZ();
0134
0135 External_RNG* GetExternalRng() { return p_external; }
0136
0137
0138
0139 typedef size_t result_type;
0140 result_type operator()();
0141 constexpr static result_type min() noexcept {
0142 return std::numeric_limits<result_type>::min();
0143 }
0144 constexpr static result_type max() noexcept {
0145 return std::numeric_limits<result_type>::max();
0146 }
0147
0148 };
0149
0150 extern Random *ran;
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244 }
0245
0246 #endif