Changeset 2840 in Sophya for trunk/SophyaLib/NTools


Ignore:
Timestamp:
Nov 10, 2005, 5:53:42 PM (20 years ago)
Author:
cmv
Message:

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

Location:
trunk/SophyaLib/NTools
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaLib/NTools/perandom.cc

    r2838 r2840  
    1818FunRan::FunRan(FunRan::Func f, r_8 xMin, r_8 xMax, int_4 nBin)
    1919//
     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//++
    2088//      Createur.
    21 //--
    22 : Histo(xMin, xMax, nBin)
    23 {
    24   (*this)(0) = f(BinLowEdge(0));
    25   for(int_4 i=1; i<nBin; i++)
    26     (*this)(i) = (*this)(i-1) + f(BinLowEdge(i));
    27    
    28   for(int_4 j=0; j<nBin; j++)
    29     (*this)(j) /= (*this)(nBin-1);
    30 }
    31 
    32 //++
    33 FunRan::FunRan(r_8 *tab, int_4 nBin)
    34 //
    35 //      Createur.
    36 //--
    37 : Histo(0, (r_8)(nBin), nBin)
    38 {
    39   (*this)(0) = tab[0];
    40   for(int_4 i=1; i<nBin; i++)
    41     (*this)(i) = (*this)(i-1) + tab[i];
    42 
    43   if ((*this)(nBin-1) == 0) {
    44     cerr << "FunRan::FunRan : sum(prob) = 0" << endl;
    45     exit(-1);
    46   }
    47 
    48   for(int_4 j=0; j<nBin; j++)
    49     (*this)(j) /= (*this)(nBin-1);
    50 }
    51 
    52 FunRan::FunRan(r_8 *tab, int_4 nBin, r_8 xMin, r_8 xMax)
    53 : Histo(xMin, xMax, nBin)
    54 {
    55   (*this)(0) = tab[0];
    56   for(int_4 i=1; i<nBin; i++)
    57     (*this)(i) = (*this)(i-1) + tab[i];
    58 
    59   if ((*this)(nBin-1) == 0) {
    60     cerr << "FunRan::FunRan : sum(prob) = 0" << endl;
    61     exit(-1);
    62   }
    63 
    64   for(int_4 j=0; j<nBin; j++)
    65     (*this)(j) /= (*this)(nBin-1);
    66 }
    67 
    68 FunRan::FunRan(Histo &h)
     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)
    6994: Histo(h)
    7095{
     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);
    71107}
    72108
     
    74110int_4 FunRan::BinRandom()
    75111//
    76 //      Tirage avec retour du numero de bin.
    77 //--
    78 {
    79   r_8 z=drand01();
    80   if (z <= 0) return 0;
    81   if (z >= 1) return mBins-1;
    82  
    83   // recherche du premier bin plus grand que z
    84   int_4 iBin = 0;
    85   for (; iBin<mBins; iBin++)
    86     if (z < (*this)(iBin)) break;
    87 
    88   return iBin;
     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;
    89121}
    90122
     
    92124r_8 FunRan::Random()
    93125//
    94 //      Tirage avec retour abscisse du bin interpole.
    95 //--
    96 {
    97   r_8 z=drand01();
    98   if (z <= 0) return mMin;
    99   if (z >= 1) return mMax;
    100   // cas z <= tab[0]
    101   if (z <= (*this)(0)) {
    102     r_8 t = mMin + binWidth/(*this)(0) * z;
    103     return t;
    104   }
    105 
    106   // recherche du premier bin plus grand que z
    107   int_4 iBin = 0;
    108   for (; iBin<mBins; iBin++)
    109     if (z < (*this)(iBin)) break;
    110 
    111   // interpolation pour trouver la valeur du tirage aleatoire
    112   r_8 t1 = (*this)(iBin-1);
    113   r_8 x1 = BinLowEdge(iBin-1);
    114   r_8 t2 = (*this)(iBin);
    115   r_8 x2 = x1 + binWidth;
    116   r_8 t = x1 + (x2-x1) / (t2-t1) * (z-t1);
    117   if (t < mMin) t = mMin;
    118   if (t > mMax) t = mMax;
    119   return(t);
     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);
    120135}
    121136
     
    200215{
    201216  x = ranX->BinRandom();
    202   //  FAILNIL(ranY[x]);  Ne compile pas $CHECK$ Reza 22/04/99
    203217  y = ranY[x]->BinRandom();
    204218}
     
    213227  x = ranX->Random();
    214228  int_4 i = int_4(ceil(x));
    215   //  FAILNIL(ranY[i]);  Ne compile pas $CHECK$ Reza 22/04/99
    216229  y = ranY[i]->Random();
    217230}
  • trunk/SophyaLib/NTools/perandom.h

    r2839 r2840  
    11// This may look like C code, but it is really -*- C++ -*-
    22// Nombres aleatoires pour Peida.
    3 //       C. Magneville   1996-2000
     3//   NON CE N'EST PAS MON CODE ... C. Magneville   1996-2000
    44// DAPNIA/SPP (Saclay) / CEA    LAL - IN2P3/CNRS  (Orsay)
    55
     
    2020  FunRan(r_8 *tab, int_4 nBin);
    2121  FunRan(r_8 *tab, int_4 nBin, r_8 xMin, r_8 xMax);
    22   FunRan(Histo &h);
     22  FunRan(Histo &h, bool pdf=true);
    2323  r_8 Random(void);
    2424  int_4 BinRandom(void);
Note: See TracChangeset for help on using the changeset viewer.