source: Sophya/trunk/SophyaLib/NTools/perandom.cc@ 2506

Last change on this file since 2506 was 2506, checked in by ansari, 22 years ago

Remplacement THROW par throw - Reza 15/03/2004

File size: 4.0 KB
Line 
1#include "machdefs.h"
2#include "pexceptions.h"
3#include "perandom.h"
4#include "pemath.h"
5#include <iostream>
6
7////////////////////////////////////////////////////////////////////////////
8//++
9// Class FunRan
10// Lib Outils++
11// include perandom.h
12//
13// Tirage aleatoire sur un histogramme 1D.
14//--
15
16//++
17FunRan::FunRan(FunRan::Func f, r_8 xMin, r_8 xMax, int_4 nBin)
18//
19// Createur.
20//--
21: Histo(xMin, xMax, nBin)
22{
23 (*this)(0) = f(BinLowEdge(0));
24 for(int_4 i=1; i<nBin; i++)
25 (*this)(i) = (*this)(i-1) + f(BinLowEdge(i));
26
27 for(int_4 j=0; j<nBin; j++)
28 (*this)(j) /= (*this)(nBin-1);
29}
30
31//++
32FunRan::FunRan(r_8 *tab, int_4 nBin)
33//
34// Createur.
35//--
36: Histo(0, (r_8)(nBin), nBin)
37{
38 (*this)(0) = tab[0];
39 for(int_4 i=1; i<nBin; i++)
40 (*this)(i) = (*this)(i-1) + tab[i];
41
42 if ((*this)(nBin-1) == 0) {
43 cerr << "FunRan::FunRan : sum(prob) = 0" << endl;
44 exit(-1);
45 }
46
47 for(int_4 j=0; j<nBin; j++)
48 (*this)(j) /= (*this)(nBin-1);
49}
50
51FunRan::FunRan(r_8 *tab, int_4 nBin, r_8 xMin, r_8 xMax)
52: Histo(xMin, xMax, nBin)
53{
54 (*this)(0) = tab[0];
55 for(int_4 i=1; i<nBin; i++)
56 (*this)(i) = (*this)(i-1) + tab[i];
57
58 if ((*this)(nBin-1) == 0) {
59 cerr << "FunRan::FunRan : sum(prob) = 0" << endl;
60 exit(-1);
61 }
62
63 for(int_4 j=0; j<nBin; j++)
64 (*this)(j) /= (*this)(nBin-1);
65}
66
67//++
68int_4 FunRan::BinRandom()
69//
70// Tirage avec retour du numero de bin.
71//--
72{
73 r_8 z=drand01();
74 if (z <= 0) return 0;
75 if (z >= 1) return mBins-1;
76
77 // recherche du premier bin plus grand que z
78 int_4 iBin = 0;
79 for (; iBin<mBins; iBin++)
80 if (z < (*this)(iBin)) break;
81
82 return iBin;
83}
84
85//++
86r_8 FunRan::Random()
87//
88// Tirage avec retour abscisse du bin interpole.
89//--
90{
91 r_8 z=drand01();
92 if (z <= 0) return mMin;
93 if (z >= 1) return mMax;
94 // cas z <= tab[0]
95 if (z <= (*this)(0)) {
96 r_8 t = mMin + binWidth/(*this)(0) * z;
97 return t;
98 }
99
100 // recherche du premier bin plus grand que z
101 int_4 iBin = 0;
102 for (; iBin<mBins; iBin++)
103 if (z < (*this)(iBin)) break;
104
105 // interpolation pour trouver la valeur du tirage aleatoire
106 r_8 t1 = (*this)(iBin-1);
107 r_8 x1 = BinLowEdge(iBin-1);
108 r_8 t2 = (*this)(iBin);
109 r_8 x2 = x1 + binWidth;
110 r_8 t = x1 + (x2-x1) / (t2-t1) * (z-t1);
111 if (t < mMin) t = mMin;
112 if (t > mMax) t = mMax;
113 return(t);
114}
115
116
117
118////////////////////////////////////////////////////////////////////////////
119//++
120// Class FunRan2D
121// Lib Outils++
122// include perandom.h
123//
124// Tirage aleatoire sur un histogramme 2D.
125//--
126
127//++
128FunRan2D::FunRan2D(r_8 *tab, int_4 nBinX, int_4 nBinY)
129//
130// Createur.
131//--
132{
133 // Tirage en X, somme sur les Y.
134 r_8* tabX = new r_8[nBinX];
135 for (int_4 i=0; i<nBinX; i++) {
136 tabX[i] = 0;
137 for (int_4 j=0; j<nBinY; j++) {
138 tabX[i] += tab[i*nBinY +j];
139 }
140 }
141 ranX = new FunRan(tabX, nBinX);
142 delete[] tabX;
143
144 ranY = new(FunRan*[nBinX]);
145
146 for (int_4 k=0; k<nBinX; k++)
147 ranY[k] = new FunRan(tab + nBinY*k, nBinY);
148
149 nx = nBinX;
150}
151
152//++
153FunRan2D::FunRan2D(r_8 **tab, int_4 nBinX, int_4 nBinY)
154//
155// Createur.
156//--
157{
158 // Tirage en X, somme sur les Y.
159 r_8* tabX = new r_8[nBinX];
160 for (int_4 i=0; i<nBinX; i++) {
161 tabX[i] = 0;
162 for (int_4 j=0; j<nBinY; j++) {
163 tabX[i] += tab[i][j];
164 }
165 }
166 ranX = new FunRan(tabX, nBinX);
167
168 ranY = new(FunRan*[nBinX]);
169
170 for (int_4 k=0; k<nBinX; k++)
171 if (tabX[k] != 0)
172 ranY[k] = new FunRan(tab[k], nBinY);
173 else ranY[k] = NULL;
174
175 delete[] tabX;
176 nx = nBinX;
177}
178
179FunRan2D::~FunRan2D()
180{
181 for (int_4 i=nx-1; i>=0; i--)
182 delete ranY[i];
183
184 delete[] ranY;
185
186 delete ranX;
187}
188
189//++
190void FunRan2D::BinRandom(int_4& x, int_4& y)
191//
192// Tirage avec retour du numeros de bin.
193//--
194{
195 x = ranX->BinRandom();
196 // FAILNIL(ranY[x]); Ne compile pas $CHECK$ Reza 22/04/99
197 y = ranY[x]->BinRandom();
198}
199
200//++
201void FunRan2D::Random(r_8& x, r_8& y)
202//
203// Tirage avec retour abscisse et ordonnee
204// du bin interpole.
205//--
206{
207 x = ranX->Random();
208 int_4 i = int_4(ceil(x));
209 // FAILNIL(ranY[i]); Ne compile pas $CHECK$ Reza 22/04/99
210 y = ranY[i]->Random();
211}
Note: See TracBrowser for help on using the repository browser.