source: Sophya/trunk/SophyaLib/BaseTools/randr48.cc@ 3753

Last change on this file since 3753 was 3739, checked in by ansari, 16 years ago

suppression init systematique (setseed) de drand48() ds le contructeur de DR48RandGen, cmv+reza 04/02/2010

File size: 7.1 KB
RevLine 
[3602]1#include "machdefs.h"
2#include <math.h>
3#include <stdlib.h>
[3619]4#include <string.h>
[3602]5#include "thsafeop.h"
6#include "fiondblock.h"
7
8#include "randr48.h"
9
10namespace SOPHYA {
11
[3739]12static bool dr48_first = true;
13DR48RandGen::DR48RandGen()
14{
15 if (dr48_first) {
16 Next(); dr48_first=false;
17 }
18}
19
[3602]20DR48RandGen::DR48RandGen(long int seed)
21{
22 srand48(seed);
[3739]23 dr48_first=false;
[3602]24}
25
26DR48RandGen::~DR48RandGen()
27{
28}
29
[3615]30void DR48RandGen::ShowRandom()
31{
32 cout<<"RandomGenerator is DR48RandGen"<<endl;
33}
34
[3602]35void DR48RandGen::SetSeed(long int seed)
36{
37 srand48(seed);
38}
39
40void DR48RandGen::SetSeed(uint_2 seed[3])
41{
42 seed48(seed);
43}
44void DR48RandGen::GetSeed(uint_2 seed[3])
45{
46 uint_2 *p, seed_dummy[3] = {0,0,0};
47 p = seed48(seed_dummy);
48 memcpy(seed,p,3*sizeof(uint_2));
49 // on re-initialise a ce qui etait avant
50 seed48(seed);
51}
52
53r_8 DR48RandGen::Next()
54{
55 return drand48();
56}
57
58void DR48RandGen::AutoInit(int lp)
59{
60 vector<uint_2> seed;
61 GenerateSeedVector(0,seed,lp);
62 uint_2 s[3] = {seed[0],seed[1],seed[2]};
63 SetSeed(s);
64}
65
66//------------------------------------------------------------
67//------------------------------------------------------------
68//------------------------------------------------------------
69/*!
70 \class ThSDR48RandGen
71 \ingroup BaseTools
72 \brief Random number generator
73
74 This class is a thread-safe random number generator.
75 Its PPF handler can be used to save the complete state of the class and the underlying
76 random number generator used.
77
78 \sa SOPHYA::ObjFileIO<ThSDR48RandGen>
79
80*/
81
82// Objet statique global pour gestion de lock entre threads
83static ThSafeOp* ths_rand = NULL;
84
85ThSDR48RandGen::ThSDR48RandGen(size_t n, bool tsafe)
86{
87 if (ths_rand == NULL) ths_rand = new ThSafeOp;
88 if (tsafe) { // thread-safe
89 fg_nothrsafe = false;
90 if (n < 1) n = 1024;
91 rseq_.ReSize(n, false);
92 idx_ = n;
93 }
94 else { // NOT thread-safe
95 fg_nothrsafe = true;
96 idx_ = 1;
97 }
98}
99
100ThSDR48RandGen::ThSDR48RandGen(ThSDR48RandGen const & rg)
101{
102 if (ths_rand == NULL) ths_rand = new ThSafeOp;
103 if (!rg.fg_nothrsafe) { // thread-safe
104 fg_nothrsafe = false;
105 rseq_.ReSize(rg.rseq_.Size(), false);
106 idx_ = rseq_.Size();
107 }
108 else { // NOT thread-safe
109 fg_nothrsafe = true;
110 idx_ = 1;
111 }
112}
113
114
115ThSDR48RandGen::~ThSDR48RandGen(void)
116{
117 // rien a faire
118}
119
120void ThSDR48RandGen::SetBuffSize(size_t n)
121// redimensionnement du buffer
122{
123 if(fg_nothrsafe) return;
124 if (n < 1) n = 1024;
125 rseq_.ReSize(n, false);
126 idx_ = n;
127}
128
129
[3615]130void ThSDR48RandGen::ShowRandom()
131{
[3618]132 cout<<"RandomGenerator is ThSDR48RandGen("<<rseq_.Size()<<","<<!fg_nothrsafe<<")"<<endl;
[3615]133}
134
[3602]135void ThSDR48RandGen::SetSeed(long int seed)
136{
137 if (ths_rand == NULL) ths_rand = new ThSafeOp;
138 ths_rand->lock();
139 DR48RandGen::SetSeed(seed);
140 ths_rand->unlock();
141 return;
142}
143
144void ThSDR48RandGen::SetSeed(uint_2 seed[3])
145{
146 if (ths_rand == NULL) ths_rand = new ThSafeOp;
147 ths_rand->lock();
148 SetSeed_P(seed);
149 ths_rand->unlock();
150}
151
152void ThSDR48RandGen::GetSeed(uint_2 seed[3])
153{
154 if (ths_rand == NULL) ths_rand = new ThSafeOp;
155 ths_rand->lock();
156 GetSeed_P(seed);
157 ths_rand->unlock();
158 return;
159}
160
161void ThSDR48RandGen::SetSeed_P(uint_2 seed[3])
162{
163 DR48RandGen::SetSeed(seed);
164}
165
166void ThSDR48RandGen::GetSeed_P(uint_2 seed[3])
167{
168 DR48RandGen::GetSeed(seed);
169}
170
171void ThSDR48RandGen::AutoInit(int lp)
172{
173 vector<uint_2> seed;
174 GenerateSeedVector(0,seed,lp);
175 uint_2 s[3] = {seed[0],seed[1],seed[2]};
176 SetSeed(s);
177}
178
[3604]179
[3602]180void ThSDR48RandGen::GenSeq(void)
181{
182 ths_rand->lock();
183 for(size_t k=0; k<rseq_.Size(); k++) rseq_(k) = drand48();
184 ths_rand->unlock();
185 idx_ = 0;
186}
[3604]187
188r_8 ThSDR48RandGen::Next()
189{
190 if (rseq_.Size() == 0) return drand48();
191 else {
192 if(idx_==rseq_.Size()) GenSeq();
193 return(rseq_(idx_++));
194 }
195}
[3602]196
197//----------------------------------------------------------
198// Classe pour la gestion de persistance
199// ObjFileIO<DR48RandGen>
200//----------------------------------------------------------
201
202/* --Methode-- */
203DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
204void ObjFileIO<DR48RandGen>::WriteSelf(POutPersist& s) const
205{
206 if (dobj == NULL)
207 throw NullPtrError("ObjFileIO<DR48RandGen>::WriteSelf() dobj=NULL");
208 uint_2 seed[3];
209 dobj->GetSeed(seed);
210 s.Put(seed,3);
211 return;
212}
213
214/* --Methode-- */
215DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
216void ObjFileIO<DR48RandGen>::ReadSelf(PInPersist& s)
217{
218 uint_2 seed[3];
219 s.Get(seed,3);
220 if(dobj == NULL) dobj = new DR48RandGen();
221 dobj->SetSeed(seed);
222 return;
223}
224
225//----------------------------------------------------------
226// Classe pour la gestion de persistance
227// ObjFileIO<ThSDR48RandGen>
228//----------------------------------------------------------
229
230/* --Methode-- */
231DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
232void ObjFileIO<ThSDR48RandGen>::WriteSelf(POutPersist& s) const
233{
234 if (dobj == NULL)
235 throw NullPtrError("ObjFileIO<ThSDR48RandGen>::WriteSelf() dobj=NULL");
236 ths_rand->lock(); // thread-safety
237 uint_4 itab[6];
238 //itab : [0]: version, [1,2,3] = srand48 state/seed , [4,5] = reserved for future use
239 itab[0] = 1;
240 // On recupere et on ecrit ds le PPF l'etat du generateur aleatoire
241 uint_2 seed_16v[3];
242 dobj->GetSeed_P(seed_16v);
243 for(int i=0; i<3; i++) itab[i+1] = seed_16v[i];
244 itab[4] = 0;
245 s.Put(itab, 6);
246 uint_8 sz = dobj->rseq_.Size();
247 s.Put(sz); // Taille du tableau intermediaire
248 uint_8 ix = dobj->idx_;
249 s.Put(ix); // valeur de l'index
250
251 if (dobj->rseq_.Size() > 0) s << dobj->rseq_; // On ecrit le tableau (NDataBlock) si necessaire
252 ths_rand->unlock(); // thread-safety
253 return;
254}
255
256/* --Methode-- */
257DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
258void ObjFileIO<ThSDR48RandGen>::ReadSelf(PInPersist& s)
259{
260 uint_4 itab[6];
261 //itab : [0]: version, [1,2,3] = srand48 state/seed , [4] = reserved for future use
262 s.Get(itab, 6);
263 uint_8 sz,ix;
264 s.Get(sz); // Taille du tableau intermediaire
265 s.Get(ix); // Taille du tableau intermediaire
266
267 if (dobj == NULL) dobj = new ThSDR48RandGen(sz, (sz>0)?true:false);
268 dobj->idx_ = ix;
269 if (sz > 0) {
270 s >> dobj->rseq_; // On lit le tableau (NDataBlock) si necessaire
271 dobj->fg_nothrsafe = false;
272 }
273 else { // Objet lu est NON thread-safe, taille_tableau rseq_ = 0
274 dobj->fg_nothrsafe = true;
275 if (dobj->rseq_.Size() > 0) dobj->rseq_.Dealloc();
276 }
277 // On initialise l'etat du generateur aleatoire avec les valeurs lues
278 uint_2 seed_16v[3];
279 //NON ? pourquoi faire GetSeed ? : dobj->GetSeed_P(seed_16v);
280 for(int i=0; i<3; i++) seed_16v[i] = itab[i+1];
281 dobj->SetSeed(seed_16v);
282 return;
283}
284
285// ---------------------------------------------------------
286#ifdef __CXX_PRAGMA_TEMPLATES__
287#pragma define_template ObjFileIO<DR48RandGen>
288#endif
289
290#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
291template class ObjFileIO<DR48RandGen>;
292#endif
293
294// ---------------------------------------------------------
295#ifdef __CXX_PRAGMA_TEMPLATES__
296#pragma define_template ObjFileIO<ThSDR48RandGen>
297#endif
298
299#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
300template class ObjFileIO<ThSDR48RandGen>;
301#endif
302// ---------------------------------------------------------
303
304
305} /* namespace SOPHYA */
Note: See TracBrowser for help on using the repository browser.