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

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

amelioration info ShowRandom(), cmv 02/05/2009

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