Geant4 Cross Reference |
1 // -*- C++ -*- 2 // 3 // ----------------------------------------------------------------------- 4 // Hep Random 5 // --- NonRandomEngine --- 6 // class implementation file 7 // ----------------------------------------------------------------------- 8 // M. Fischler - Created 9/30/99 9 // 10 // M. Fischler - Modifications to capture sequence as a vector, which 11 // are needed to retain sanity when put and get are involved. 12 // Mark Fischler - Methods for distrib. instance save/restore 12/8/04 13 // M. Fischler - Initialization of all state data (even those parts unused) 14 // - at ctor time, to thwart a VC++ i/o bug. 15 // M. Fischler - put/get for vectors of ulongs 3/15/05 16 // M. Fischler - State-saving using only ints, for portability 4/12/05 17 // 18 //========================================================================= 19 20 #include "CLHEP/Random/NonRandomEngine.h" 21 #include "CLHEP/Random/engineIDulong.h" 22 #include "CLHEP/Random/DoubConv.h" 23 #include <cassert> 24 #include <cstdlib> 25 #include <iostream> 26 #include <string> 27 #include <vector> 28 29 namespace CLHEP { 30 31 std::string NonRandomEngine::name() const {return "NonRandomEngine";} 32 33 NonRandomEngine::NonRandomEngine() : nextHasBeenSet(false), 34 sequenceHasBeenSet(false), 35 intervalHasBeenSet(false) , 36 nextRandom(0.05), 37 nInSeq(0), 38 randomInterval(0.1) { } 39 40 NonRandomEngine::~NonRandomEngine() { } 41 42 43 void NonRandomEngine::setNextRandom(double r) { 44 nextRandom = r; 45 nextHasBeenSet=true; 46 return; 47 } 48 49 void NonRandomEngine::setRandomSequence(double* s, int n) { 50 sequence.clear(); 51 for (int i=0; i<n; i++) sequence.push_back(*s++); 52 assert (sequence.size() == (unsigned int)n); 53 nInSeq = 0; 54 sequenceHasBeenSet=true; 55 nextHasBeenSet=false; 56 return; 57 } 58 59 void NonRandomEngine::setRandomInterval(double x) { 60 randomInterval = x; 61 intervalHasBeenSet=true; 62 return; 63 } 64 65 double NonRandomEngine::flat() { 66 67 if (sequenceHasBeenSet) { 68 double v = sequence[nInSeq++]; 69 if (nInSeq >= sequence.size() ) sequenceHasBeenSet = false; 70 return v; 71 } 72 73 if ( !nextHasBeenSet ) { 74 std::cout 75 << "Attempt to use NonRandomEngine without setting next random!\n"; 76 exit(1); 77 } 78 79 double a = nextRandom; 80 nextHasBeenSet = false; 81 82 if (intervalHasBeenSet) { 83 nextRandom += randomInterval; 84 if ( nextRandom >= 1 ) nextRandom -= 1.0; 85 nextHasBeenSet = true; 86 } 87 88 return a; 89 } 90 91 92 void NonRandomEngine::flatArray(const int size, double* vect) { 93 for (int i = 0; i < size; ++i) { 94 vect[i] = flat(); 95 } 96 } 97 98 std::ostream & NonRandomEngine::put (std::ostream & os) const { 99 std::string beginMarker = "NonRandomEngine-begin"; 100 os << beginMarker << "\nUvec\n"; 101 std::vector<unsigned long> v = put(); 102 for (unsigned int i=0; i<v.size(); ++i) { 103 os << v[i] << "\n"; 104 } 105 return os; 106 } 107 108 std::vector<unsigned long> NonRandomEngine::put () const { 109 std::vector<unsigned long> v; 110 v.push_back (engineIDulong<NonRandomEngine>()); 111 std::vector<unsigned long> t; 112 v.push_back(static_cast<unsigned long>(nextHasBeenSet)); 113 v.push_back(static_cast<unsigned long>(sequenceHasBeenSet)); 114 v.push_back(static_cast<unsigned long>(intervalHasBeenSet)); 115 t = DoubConv::dto2longs(nextRandom); 116 v.push_back(t[0]); v.push_back(t[1]); 117 v.push_back(static_cast<unsigned long>(nInSeq)); 118 t = DoubConv::dto2longs(randomInterval); 119 v.push_back(t[0]); v.push_back(t[1]); 120 v.push_back(static_cast<unsigned long>(sequence.size())); 121 for (unsigned int i=0; i<sequence.size(); ++i) { 122 t = DoubConv::dto2longs(sequence[i]); 123 v.push_back(t[0]); v.push_back(t[1]); 124 } 125 return v; 126 } 127 128 std::istream & NonRandomEngine::get (std::istream & is) { 129 std::string beginMarker = "NonRandomEngine-begin"; 130 is >> beginMarker; 131 if (beginMarker != "NonRandomEngine-begin") { 132 is.clear(std::ios::badbit | is.rdstate()); 133 std::cerr << "\nInput mispositioned or" 134 << "\nNonRandomEngine state description missing or" 135 << "\nwrong engine type found.\n"; 136 return is; 137 } 138 return getState(is); 139 } 140 141 std::string NonRandomEngine::beginTag ( ) { 142 return "NonRandomEngine-begin"; 143 } 144 145 std::istream & NonRandomEngine::getState (std::istream & is) { 146 if ( possibleKeywordInput ( is, "Uvec", nextHasBeenSet ) ) { 147 std::vector<unsigned long> v; 148 unsigned long uu = 99999; 149 unsigned long ssiz = 0; 150 for (unsigned int istart=0; istart < 10; ++istart) { 151 is >> uu; 152 if (!is) { 153 is.clear(std::ios::badbit | is.rdstate()); 154 std::cout << "istart = " << istart << "\n"; 155 std::cerr 156 << "\nNonRandomEngine state (vector) description has no sequence size." 157 << "\ngetState() has failed." 158 << "\nInput stream is probably mispositioned now." << std::endl; 159 return is; 160 } 161 v.push_back(uu); 162 if (istart==9) ssiz = uu; 163 } 164 for (unsigned int ivec=0; ivec < 2*ssiz; ++ivec) { 165 is >> uu; 166 if (!is) { 167 is.clear(std::ios::badbit | is.rdstate()); 168 std::cerr << "\nNonRandomEngine state (vector) description improper." 169 << "\ngetState() has failed." 170 << "\nInput stream is probably mispositioned now." << std::endl; 171 return is; 172 } 173 v.push_back(uu); 174 } 175 getState(v); 176 return (is); 177 } 178 179 // is >> nextHasBeenSet; Removed, encompassed by possibleKeywordInput() 180 181 std::string endMarker = "NonRandomEngine-end"; 182 is >> sequenceHasBeenSet >> intervalHasBeenSet; 183 is >> nextRandom >> nInSeq >> randomInterval; 184 unsigned int seqSize; 185 is >> seqSize; 186 sequence.clear(); 187 double x; 188 for (unsigned int i = 0; i < seqSize; ++i) { 189 is >> x; 190 sequence.push_back(x); 191 } 192 is >> endMarker; 193 if (endMarker != "NonRandomEngine-end") { 194 is.clear(std::ios::badbit | is.rdstate()); 195 std::cerr << "\n NonRandomEngine state description incomplete." 196 << "\nInput stream is probably mispositioned now." << std::endl; 197 return is; 198 } 199 return is; 200 } 201 202 bool NonRandomEngine::get (const std::vector<unsigned long> & v) { 203 if ((v[0] & 0xffffffffUL) != engineIDulong<NonRandomEngine>()) { 204 std::cerr << 205 "\nNonRandomEngine get:state vector has wrong ID word - state unchanged\n"; 206 return false; 207 } 208 return getState(v); 209 } 210 211 bool NonRandomEngine::getState (const std::vector<unsigned long> & v) { 212 unsigned long seqSize = v[9]; 213 if (v.size() != 2*seqSize + 10 ) { 214 std::cerr << 215 "\nNonRandomEngine get:state vector has wrong length - state unchanged\n"; 216 std::cerr << " (length = " << v.size() 217 << "; expected " << 2*seqSize + 10 << ")\n"; 218 return false; 219 } 220 std::vector<unsigned long> t(2); 221 nextHasBeenSet = (v[1]!=0); 222 sequenceHasBeenSet = (v[2]!=0); 223 intervalHasBeenSet = (v[3]!=0); 224 t[0] = v[4]; t[1] = v[5]; nextRandom = DoubConv::longs2double(t); 225 nInSeq = (unsigned int)v[6]; 226 t[0] = v[7]; t[1] = v[8]; randomInterval = DoubConv::longs2double(t); 227 sequence.clear(); 228 for (unsigned long i=0; i<seqSize; ++i) { 229 t[0] = v[2*i+10]; t[1] = v[2*i+11]; 230 sequence.push_back(DoubConv::longs2double(t)); 231 } 232 return true; 233 } 234 235 236 } // namespace CLHEP 237 238