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

Last change on this file since 3611 was 3604, checked in by ansari, 16 years ago

Modifs,petites extensions + numero de version/initialisation de l'instance globale de RandomGenerator, Reza 29/04/2009

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