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

Last change on this file since 2840 was 2840, checked in by cmv, 20 years ago

Refonte totale de FunRan qui n'etait pas OK.
Arret de l'interpolation entre bin pour le tirage aleatoire
car ca pose un pb dans le premier et dernier bin.. A voir + tard
eventuellement. cmv 10/11/2005

File size: 5.2 KB
Line 
1#include "sopnamsp.h"
2#include "machdefs.h"
3#include "pexceptions.h"
4#include "perandom.h"
5#include "pemath.h"
6#include <iostream>
7
8////////////////////////////////////////////////////////////////////////////
9//++
10// Class FunRan
11// Lib Outils++
12// include perandom.h
13//
14// Tirage aleatoire sur un histogramme 1D.
15//--
16
17//++
18FunRan::FunRan(FunRan::Func f, r_8 xMin, r_8 xMax, int_4 nBin)
19//
20// Createur. f is a probability density function (PDF).
21// Le tirage aleatoire est fait sur un histogramme
22// Histo(xMin,xMax,nBin) (voir convention dans Histo).
23// Chaque bin de l'histogramme contient la valeur de la PDF
24// au centre du bin.
25// Les valeurs retournees sont les valeurs du centre des bins.
26// Si binw est la largeur du bin, les valeurs retournees
27// vont de xmin+binw/2 a xmax-binw/2.
28//--
29: Histo(xMin,xMax,nBin)
30{
31 if(nBin<0)
32 throw RangeCheckError("FunRan::FunRan less than 2 bins requested");
33
34 // On cree la fonction de distribution a partir de la PDF
35 (*this)(0) = f(BinCenter(0));
36 for(int_4 i=1;i<nBin;i++) (*this)(i) = (*this)(i-1) + f(BinCenter(i));
37
38 if((*this)(nBin-1)<=0.)
39 throw RangeCheckError("FunRan::FunRan not a distribution function last bin is <=0");
40
41 for(int_4 i=0;i<nBin;i++) (*this)(i) /= (*this)(nBin-1);
42}
43
44//++
45FunRan::FunRan(r_8 *tab, int_4 nBin)
46//
47// Createur. tab is a probability density function
48// The return random values will be between 0 and nBin-1
49// See FunRan::FunRan(FunRan::Func...) for further comments.
50//--
51: Histo(-0.5,nBin-0.5,nBin)
52{
53 if(nBin<=0)
54 throw RangeCheckError("FunRan::FunRan no bin in Histo");
55
56 (*this)(0) = tab[0];
57 for(int_4 i=1;i<nBin;i++) (*this)(i) = (*this)(i-1) + tab[i];
58
59 if((*this)(nBin-1)<=0.)
60 throw RangeCheckError("FunRan::FunRan not a distribution function last bin is <=0");
61
62 for(int_4 i=0;i<nBin;i++) (*this)(i) /= (*this)(nBin-1);
63}
64
65//++
66FunRan::FunRan(r_8 *tab, int_4 nBin, r_8 xMin, r_8 xMax)
67//
68// Createur. tab is a probability density function
69// The content of tab is identified has the content of
70// an Histogram define by Histo(xMin,xMax,nBin).
71// See FunRan::FunRan(FunRan::Func...) for further comments.
72//--
73: Histo(xMin,xMax,nBin)
74{
75 if(nBin<=0)
76 throw RangeCheckError("FunRan::FunRan no bin in Histo");
77
78 (*this)(0) = tab[0];
79 for(int_4 i=1;i<nBin;i++) (*this)(i) = (*this)(i-1) + tab[i];
80
81 if((*this)(nBin-1)<=0.)
82 throw RangeCheckError("FunRan::FunRan not a distribution function last bin is <=0");
83
84 for(int_4 i=0;i<nBin;i++) (*this)(i) /= (*this)(nBin-1);
85}
86
87//++
88// Createur.
89// If pdf=true, h is a probability density fonction.
90// If pdf=false, h is a distribution function (not necessarly normalized to 1).
91// See FunRan::FunRan(FunRan::Func...) for further comments.
92//--
93FunRan::FunRan(Histo &h, bool pdf)
94: Histo(h)
95{
96 if(mBins<=0)
97 throw RangeCheckError("FunRan::FunRan(Histo) no bin in Histo");
98
99 // On cree l'histo integre
100 if(pdf)
101 for(int_4 i=1;i<mBins;i++) (*this)(i) += (*this)(i-1);
102
103 if((*this)(mBins-1)<=0.)
104 throw RangeCheckError("FunRan::FunRan(Histo) not a distribution function last bin is <=0");
105
106 for(int_4 i=0;i<mBins;i++) (*this)(i) /= (*this)(mBins-1);
107}
108
109//++
110int_4 FunRan::BinRandom()
111//
112// Tirage avec retour du numero de bin entre 0 et mBins-1.
113// It returns the first bin whose content is greater or equal
114// to the random uniform number (in [0,1])
115//--
116{
117 // recherche du premier bin plus grand ou egal a z
118 r_8 z=drand01();
119 for(int_4 i=0;i<mBins;i++) if(z<(*this)(i)) return i;
120 return mBins-1;
121}
122
123//++
124r_8 FunRan::Random()
125//
126// Tirage avec retour abscisse du bin non interpole.
127//--
128{
129 r_8 z=drand01();
130 int ibin = mBins-1;
131 for(int_4 i=0;i<mBins;i++)
132 if(z<(*this)(i)) {ibin=i; break;}
133
134 return BinCenter(ibin);
135}
136
137
138
139////////////////////////////////////////////////////////////////////////////
140//++
141// Class FunRan2D
142// Lib Outils++
143// include perandom.h
144//
145// Tirage aleatoire sur un histogramme 2D.
146//--
147
148//++
149FunRan2D::FunRan2D(r_8 *tab, int_4 nBinX, int_4 nBinY)
150//
151// Createur.
152//--
153{
154 // Tirage en X, somme sur les Y.
155 r_8* tabX = new r_8[nBinX];
156 for (int_4 i=0; i<nBinX; i++) {
157 tabX[i] = 0;
158 for (int_4 j=0; j<nBinY; j++) {
159 tabX[i] += tab[i*nBinY +j];
160 }
161 }
162 ranX = new FunRan(tabX, nBinX);
163 delete[] tabX;
164
165 ranY = new(FunRan*[nBinX]);
166
167 for (int_4 k=0; k<nBinX; k++)
168 ranY[k] = new FunRan(tab + nBinY*k, nBinY);
169
170 nx = nBinX;
171}
172
173//++
174FunRan2D::FunRan2D(r_8 **tab, int_4 nBinX, int_4 nBinY)
175//
176// Createur.
177//--
178{
179 // Tirage en X, somme sur les Y.
180 r_8* tabX = new r_8[nBinX];
181 for (int_4 i=0; i<nBinX; i++) {
182 tabX[i] = 0;
183 for (int_4 j=0; j<nBinY; j++) {
184 tabX[i] += tab[i][j];
185 }
186 }
187 ranX = new FunRan(tabX, nBinX);
188
189 ranY = new(FunRan*[nBinX]);
190
191 for (int_4 k=0; k<nBinX; k++)
192 if (tabX[k] != 0)
193 ranY[k] = new FunRan(tab[k], nBinY);
194 else ranY[k] = NULL;
195
196 delete[] tabX;
197 nx = nBinX;
198}
199
200FunRan2D::~FunRan2D()
201{
202 for (int_4 i=nx-1; i>=0; i--)
203 delete ranY[i];
204
205 delete[] ranY;
206
207 delete ranX;
208}
209
210//++
211void FunRan2D::BinRandom(int_4& x, int_4& y)
212//
213// Tirage avec retour du numeros de bin.
214//--
215{
216 x = ranX->BinRandom();
217 y = ranY[x]->BinRandom();
218}
219
220//++
221void FunRan2D::Random(r_8& x, r_8& y)
222//
223// Tirage avec retour abscisse et ordonnee
224// du bin interpole.
225//--
226{
227 x = ranX->Random();
228 int_4 i = int_4(ceil(x));
229 y = ranY[i]->Random();
230}
Note: See TracBrowser for help on using the repository browser.