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

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

RandomGeneratorInterface + dSFMT etc..., cmv 28/04/2009

File size: 6.6 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
159void ThSDR48RandGen::GenSeq(void)
160{
161 ths_rand->lock();
162 for(size_t k=0; k<rseq_.Size(); k++) rseq_(k) = drand48();
163 ths_rand->unlock();
164 idx_ = 0;
165}
166
167//----------------------------------------------------------
168// Classe pour la gestion de persistance
169// ObjFileIO<DR48RandGen>
170//----------------------------------------------------------
171
172/* --Methode-- */
173DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
174void ObjFileIO<DR48RandGen>::WriteSelf(POutPersist& s) const
175{
176 if (dobj == NULL)
177 throw NullPtrError("ObjFileIO<DR48RandGen>::WriteSelf() dobj=NULL");
178 uint_2 seed[3];
179 dobj->GetSeed(seed);
180 s.Put(seed,3);
181 return;
182}
183
184/* --Methode-- */
185DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
186void ObjFileIO<DR48RandGen>::ReadSelf(PInPersist& s)
187{
188 uint_2 seed[3];
189 s.Get(seed,3);
190 if(dobj == NULL) dobj = new DR48RandGen();
191 dobj->SetSeed(seed);
192 return;
193}
194
195//----------------------------------------------------------
196// Classe pour la gestion de persistance
197// ObjFileIO<ThSDR48RandGen>
198//----------------------------------------------------------
199
200/* --Methode-- */
201DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
202void ObjFileIO<ThSDR48RandGen>::WriteSelf(POutPersist& s) const
203{
204 if (dobj == NULL)
205 throw NullPtrError("ObjFileIO<ThSDR48RandGen>::WriteSelf() dobj=NULL");
206 ths_rand->lock(); // thread-safety
207 uint_4 itab[6];
208 //itab : [0]: version, [1,2,3] = srand48 state/seed , [4,5] = reserved for future use
209 itab[0] = 1;
210 // On recupere et on ecrit ds le PPF l'etat du generateur aleatoire
211 uint_2 seed_16v[3];
212 dobj->GetSeed_P(seed_16v);
213 for(int i=0; i<3; i++) itab[i+1] = seed_16v[i];
214 itab[4] = 0;
215 s.Put(itab, 6);
216 uint_8 sz = dobj->rseq_.Size();
217 s.Put(sz); // Taille du tableau intermediaire
218 uint_8 ix = dobj->idx_;
219 s.Put(ix); // valeur de l'index
220
221 if (dobj->rseq_.Size() > 0) s << dobj->rseq_; // On ecrit le tableau (NDataBlock) si necessaire
222 ths_rand->unlock(); // thread-safety
223 return;
224}
225
226/* --Methode-- */
227DECL_TEMP_SPEC /* equivalent a template <> , pour SGI-CC en particulier */
228void ObjFileIO<ThSDR48RandGen>::ReadSelf(PInPersist& s)
229{
230 uint_4 itab[6];
231 //itab : [0]: version, [1,2,3] = srand48 state/seed , [4] = reserved for future use
232 s.Get(itab, 6);
233 uint_8 sz,ix;
234 s.Get(sz); // Taille du tableau intermediaire
235 s.Get(ix); // Taille du tableau intermediaire
236
237 if (dobj == NULL) dobj = new ThSDR48RandGen(sz, (sz>0)?true:false);
238 dobj->idx_ = ix;
239 if (sz > 0) {
240 s >> dobj->rseq_; // On lit le tableau (NDataBlock) si necessaire
241 dobj->fg_nothrsafe = false;
242 }
243 else { // Objet lu est NON thread-safe, taille_tableau rseq_ = 0
244 dobj->fg_nothrsafe = true;
245 if (dobj->rseq_.Size() > 0) dobj->rseq_.Dealloc();
246 }
247 // On initialise l'etat du generateur aleatoire avec les valeurs lues
248 uint_2 seed_16v[3];
249 //NON ? pourquoi faire GetSeed ? : dobj->GetSeed_P(seed_16v);
250 for(int i=0; i<3; i++) seed_16v[i] = itab[i+1];
251 dobj->SetSeed(seed_16v);
252 return;
253}
254
255// ---------------------------------------------------------
256#ifdef __CXX_PRAGMA_TEMPLATES__
257#pragma define_template ObjFileIO<DR48RandGen>
258#endif
259
260#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
261template class ObjFileIO<DR48RandGen>;
262#endif
263
264// ---------------------------------------------------------
265#ifdef __CXX_PRAGMA_TEMPLATES__
266#pragma define_template ObjFileIO<ThSDR48RandGen>
267#endif
268
269#if defined(ANSI_TEMPLATES) || defined(GNU_TEMPLATES)
270template class ObjFileIO<ThSDR48RandGen>;
271#endif
272// ---------------------------------------------------------
273
274
275} /* namespace SOPHYA */
Note: See TracBrowser for help on using the repository browser.