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

Last change on this file since 3678 was 3619, checked in by cmv, 16 years ago

add various #include<> for g++ 4.3 (jaunty 9.04), cmv 05/05/2009

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