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

Last change on this file since 2870 was 2870, checked in by ansari, 20 years ago

Portage/compilation sur AIX-XlC (regatta): Ajout qualification de nom ou namespace SOPHYA pour instanciation explicite de template + correction ambiguite syntaxe new X* [] - Reza 3 Jan 2006

File size: 5.2 KB
RevLine 
[2615]1#include "sopnamsp.h"
[244]2#include "machdefs.h"
3#include "pexceptions.h"
[220]4#include "perandom.h"
5#include "pemath.h"
[2322]6#include <iostream>
[220]7
8////////////////////////////////////////////////////////////////////////////
9//++
10// Class FunRan
11// Lib Outils++
12// include perandom.h
13//
14// Tirage aleatoire sur un histogramme 1D.
15//--
16
17//++
[1092]18FunRan::FunRan(FunRan::Func f, r_8 xMin, r_8 xMax, int_4 nBin)
[220]19//
[2840]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.
[220]28//--
[2840]29: Histo(xMin,xMax,nBin)
[220]30{
[2840]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);
[220]42}
43
44//++
[1092]45FunRan::FunRan(r_8 *tab, int_4 nBin)
[220]46//
[2840]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.
[220]50//--
[2840]51: Histo(-0.5,nBin-0.5,nBin)
[220]52{
[2840]53 if(nBin<=0)
54 throw RangeCheckError("FunRan::FunRan no bin in Histo");
[220]55
[2840]56 (*this)(0) = tab[0];
57 for(int_4 i=1;i<nBin;i++) (*this)(i) = (*this)(i-1) + tab[i];
[220]58
[2840]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);
[220]63}
64
[2840]65//++
[1092]66FunRan::FunRan(r_8 *tab, int_4 nBin, r_8 xMin, r_8 xMax)
[2840]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)
[220]74{
[2840]75 if(nBin<=0)
76 throw RangeCheckError("FunRan::FunRan no bin in Histo");
[220]77
[2840]78 (*this)(0) = tab[0];
79 for(int_4 i=1;i<nBin;i++) (*this)(i) = (*this)(i-1) + tab[i];
[220]80
[2840]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);
[220]85}
86
[2840]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)
[2838]94: Histo(h)
95{
[2840]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);
[2838]107}
108
[220]109//++
[1092]110int_4 FunRan::BinRandom()
[220]111//
[2840]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])
[220]115//--
116{
[2840]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;
[220]121}
122
123//++
[1092]124r_8 FunRan::Random()
[220]125//
[2840]126// Tirage avec retour abscisse du bin non interpole.
[220]127//--
128{
[2840]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;}
[220]133
[2840]134 return BinCenter(ibin);
[220]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//++
[1092]149FunRan2D::FunRan2D(r_8 *tab, int_4 nBinX, int_4 nBinY)
[220]150//
151// Createur.
152//--
153{
154 // Tirage en X, somme sur les Y.
[1092]155 r_8* tabX = new r_8[nBinX];
156 for (int_4 i=0; i<nBinX; i++) {
[220]157 tabX[i] = 0;
[1092]158 for (int_4 j=0; j<nBinY; j++) {
[220]159 tabX[i] += tab[i*nBinY +j];
160 }
161 }
162 ranX = new FunRan(tabX, nBinX);
163 delete[] tabX;
164
[2870]165 ranY = new FunRan* [nBinX];
[220]166
[1092]167 for (int_4 k=0; k<nBinX; k++)
[220]168 ranY[k] = new FunRan(tab + nBinY*k, nBinY);
169
170 nx = nBinX;
171}
172
173//++
[1092]174FunRan2D::FunRan2D(r_8 **tab, int_4 nBinX, int_4 nBinY)
[220]175//
176// Createur.
177//--
178{
179 // Tirage en X, somme sur les Y.
[1092]180 r_8* tabX = new r_8[nBinX];
181 for (int_4 i=0; i<nBinX; i++) {
[220]182 tabX[i] = 0;
[1092]183 for (int_4 j=0; j<nBinY; j++) {
[220]184 tabX[i] += tab[i][j];
185 }
186 }
187 ranX = new FunRan(tabX, nBinX);
188
[2870]189 ranY = new FunRan* [nBinX];
[220]190
[1092]191 for (int_4 k=0; k<nBinX; k++)
[220]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{
[1092]202 for (int_4 i=nx-1; i>=0; i--)
[220]203 delete ranY[i];
204
205 delete[] ranY;
206
207 delete ranX;
208}
209
210//++
[1092]211void FunRan2D::BinRandom(int_4& x, int_4& y)
[220]212//
213// Tirage avec retour du numeros de bin.
214//--
215{
216 x = ranX->BinRandom();
217 y = ranY[x]->BinRandom();
218}
219
220//++
[1092]221void FunRan2D::Random(r_8& x, r_8& y)
[220]222//
223// Tirage avec retour abscisse et ordonnee
224// du bin interpole.
225//--
226{
227 x = ranX->Random();
[1092]228 int_4 i = int_4(ceil(x));
[220]229 y = ranY[i]->Random();
230}
Note: See TracBrowser for help on using the repository browser.