ROOT logo
// @(#)root/unuran:$Id: TUnuranDiscrDist.h 28968 2009-06-12 16:41:43Z moneta $
// Authors: L. Moneta, J. Leydold Wed Feb 28 2007

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
 *                                                                    *
 *                                                                    *
 **********************************************************************/

// Header file for class TUnuranDiscrDist


#ifndef ROOT_Math_TUnuranDiscrDist
#define ROOT_Math_TUnuranDiscrDist

#ifndef ROOT_Math_TUnuranBaseDist
#include "TUnuranBaseDist.h"
#endif

#ifndef ROOT_Math_IFunctionfwd
#include "Math/IFunctionfwd.h"
#endif


#include <vector>


class TF1;

//____________________________________________________________________
/** 
   TUnuranDiscrDist class for one dimensional discrete distribution. 
   It is used by TUnuran to generate integer random numbers according to this distribution via 
   TUnuran::SampleDiscr(). 

   The class can be constructed from a one-dimensional function (TF1 pointer) 
   representing the discrete distribution (probability mesh function) 
   (for example a TF1("f","TMath::PoissonI(x,[0])") ) or from a 
   vector of probability, used by passing an iterator specifying the begin and the end of the vector. 
   In the latter case the domain of the distribution will be defined by the vector, while in the first case is by 
   default (0,+inf). 
   a Method to set the domain of the distribution ( SetDomain ) is provided and it defines the range 
   of the generated random numbers. 

   The derivatives of the pdf which are used by some UNURAN methods are estimated numerically in the 
   Derivative() method. 
   Some extra information (like distribution mode, cdf function, probability sum, etc..) 
   can be set as well otherwise will be estimated internally if required. 


*/ 
class TUnuranDiscrDist : public TUnuranBaseDist {

public: 

   /** 
      Constructor from a generic function object specifying the pdf
   */ 
   TUnuranDiscrDist (const ROOT::Math::IGenFunction & func );

   /** 
      Constructor from a TF1 objects specifying the pdf
   */ 
   TUnuranDiscrDist (TF1 * func );

   /** 
      Constructor from a vector of probability
   */ 
   template<class Iterator> 
   TUnuranDiscrDist (Iterator * begin, Iterator * end) : 
      fPVec(begin,end),
      fPmf(0), 
      fCdf(0), 
      fXmin(1), 
      fXmax(-1), 
      fMode(0), 
      fSum(0),
      fHasDomain(0),
      fHasMode(0),
      fHasSum(0),
      fOwnFunc(false)
   {}

   /** 
      Destructor 
   */ 
   virtual ~TUnuranDiscrDist ();

   /** 
      Copy constructor
   */ 
   TUnuranDiscrDist(const TUnuranDiscrDist &); 

   /** 
      Assignment operator
   */ 
   TUnuranDiscrDist & operator = (const TUnuranDiscrDist & rhs); 

   /**
      Clone (required by base class)
    */
   virtual TUnuranDiscrDist * Clone() const { return new TUnuranDiscrDist(*this); } 

   /**
      set cdf distribution from a generic function interface. If a method requires it 
      and is not set it is estimated numerically
   */
   void SetCdf(const ROOT::Math::IGenFunction & cdf);

   /**
      set cdf distribution from a TF1 pointer.  If a method requires it 
      and is not set it is estimated numerically
   */
   void SetCdf(TF1 *  cdf);


   /**
      Set the distribution domain, by default the domain is [0,INT_MAX]
      If xmin >= xmax a domain is removed
    */
   void SetDomain(int xmin, int xmax)  { 
      fXmin = xmin; 
      fXmax = xmax; 
      if (fXmin < fXmax) 
         fHasDomain = true;
      else 
         fHasDomain = false;
   }


   /**
      set the mode of the distribution (location of maximum probability)
    */
   void SetMode(int mode) { fMode = mode; fHasMode=true;}

   /**
      set the value of the sum of the probabilities in the given domain
    */ 
   void SetProbSum(double sum) { fSum = sum; fHasSum=true; }

   /**
      check if distribution has domain and return in case its domain
   */
   bool GetDomain(int & xmin, int & xmax) const { 
      xmin = fXmin; 
      xmax = fXmax; 
      return fHasDomain; 
   }
   
   /**
      get the mode   (x location of function maximum)  
   */
   int Mode() const { return fMode; }

   /**
      return area of the pdf
   */
   double ProbSum() const { return fSum; }


   /**
      flag to control if distribution provides the mode
    */
   bool HasMode() const { return fHasMode; } 

   
   /**
      flag to control if distribution provides the total area of the probability function
    */
   bool HasProbSum() const { return fHasSum; } 

   /**
      flag to control if distribution provides also a Cdf
    */
   bool HasCdf() const { return fCdf != 0; } 


   /**
      retrieve a reference to the vector of the probabilities : Prob(i)
      If the distribution is defined from a function (i.e. for distribution with undefined domain)
      the vector is empty. 
    */
   const std::vector<double> & ProbVec() const { return fPVec; }

   /**
      evaluate the distribution (probability mesh function) at the integer value x. 
      Used internally by UnuRan
      For integer values outside the domain the function must return 0.0
   */ 
   double Pmf ( int x) const; 

   /** 
       evaluate the integral (cdf)  on the given domain
   */
   double Cdf(int x) const;   


protected: 


private: 

   std::vector<double> fPVec;        //Vector of the probabilities 
   mutable std::vector<double> fPVecSum;     //Vector of the sum of the probabilities 
   const ROOT::Math::IGenFunction *fPmf;   //pointer to a function calculating the probability  
   const ROOT::Math::IGenFunction *fCdf;    //pointer to the cumulative distribution function
   int   fXmin;                  //lower value of the domain
   int   fXmax;                  //upper value of the domain
   int   fMode;                  //mode of the distribution
   double fSum;                  //total sum of the probabilities in the given domain
   // flags
   bool  fHasDomain;             //flag to control if distribution has a defined domain (otherwise is [0,INT_MAX])
   bool  fHasMode;               //flag to control if distribution has a pre-computed mode
   bool  fHasSum;                //flag to control if distribution has a pre-computed sum of the probabilities
   bool  fOwnFunc;               // flag to control if distribution owns the funcitno pointers

   ClassDef(TUnuranDiscrDist,1)  //Wrapper class for one dimensional discrete distribution


}; 



#endif /* ROOT_Math_TUnuranDiscrDist */
 TUnuranDiscrDist.h:1
 TUnuranDiscrDist.h:2
 TUnuranDiscrDist.h:3
 TUnuranDiscrDist.h:4
 TUnuranDiscrDist.h:5
 TUnuranDiscrDist.h:6
 TUnuranDiscrDist.h:7
 TUnuranDiscrDist.h:8
 TUnuranDiscrDist.h:9
 TUnuranDiscrDist.h:10
 TUnuranDiscrDist.h:11
 TUnuranDiscrDist.h:12
 TUnuranDiscrDist.h:13
 TUnuranDiscrDist.h:14
 TUnuranDiscrDist.h:15
 TUnuranDiscrDist.h:16
 TUnuranDiscrDist.h:17
 TUnuranDiscrDist.h:18
 TUnuranDiscrDist.h:19
 TUnuranDiscrDist.h:20
 TUnuranDiscrDist.h:21
 TUnuranDiscrDist.h:22
 TUnuranDiscrDist.h:23
 TUnuranDiscrDist.h:24
 TUnuranDiscrDist.h:25
 TUnuranDiscrDist.h:26
 TUnuranDiscrDist.h:27
 TUnuranDiscrDist.h:28
 TUnuranDiscrDist.h:29
 TUnuranDiscrDist.h:30
 TUnuranDiscrDist.h:31
 TUnuranDiscrDist.h:32
 TUnuranDiscrDist.h:33
 TUnuranDiscrDist.h:34
 TUnuranDiscrDist.h:35
 TUnuranDiscrDist.h:36
 TUnuranDiscrDist.h:37
 TUnuranDiscrDist.h:38
 TUnuranDiscrDist.h:39
 TUnuranDiscrDist.h:40
 TUnuranDiscrDist.h:41
 TUnuranDiscrDist.h:42
 TUnuranDiscrDist.h:43
 TUnuranDiscrDist.h:44
 TUnuranDiscrDist.h:45
 TUnuranDiscrDist.h:46
 TUnuranDiscrDist.h:47
 TUnuranDiscrDist.h:48
 TUnuranDiscrDist.h:49
 TUnuranDiscrDist.h:50
 TUnuranDiscrDist.h:51
 TUnuranDiscrDist.h:52
 TUnuranDiscrDist.h:53
 TUnuranDiscrDist.h:54
 TUnuranDiscrDist.h:55
 TUnuranDiscrDist.h:56
 TUnuranDiscrDist.h:57
 TUnuranDiscrDist.h:58
 TUnuranDiscrDist.h:59
 TUnuranDiscrDist.h:60
 TUnuranDiscrDist.h:61
 TUnuranDiscrDist.h:62
 TUnuranDiscrDist.h:63
 TUnuranDiscrDist.h:64
 TUnuranDiscrDist.h:65
 TUnuranDiscrDist.h:66
 TUnuranDiscrDist.h:67
 TUnuranDiscrDist.h:68
 TUnuranDiscrDist.h:69
 TUnuranDiscrDist.h:70
 TUnuranDiscrDist.h:71
 TUnuranDiscrDist.h:72
 TUnuranDiscrDist.h:73
 TUnuranDiscrDist.h:74
 TUnuranDiscrDist.h:75
 TUnuranDiscrDist.h:76
 TUnuranDiscrDist.h:77
 TUnuranDiscrDist.h:78
 TUnuranDiscrDist.h:79
 TUnuranDiscrDist.h:80
 TUnuranDiscrDist.h:81
 TUnuranDiscrDist.h:82
 TUnuranDiscrDist.h:83
 TUnuranDiscrDist.h:84
 TUnuranDiscrDist.h:85
 TUnuranDiscrDist.h:86
 TUnuranDiscrDist.h:87
 TUnuranDiscrDist.h:88
 TUnuranDiscrDist.h:89
 TUnuranDiscrDist.h:90
 TUnuranDiscrDist.h:91
 TUnuranDiscrDist.h:92
 TUnuranDiscrDist.h:93
 TUnuranDiscrDist.h:94
 TUnuranDiscrDist.h:95
 TUnuranDiscrDist.h:96
 TUnuranDiscrDist.h:97
 TUnuranDiscrDist.h:98
 TUnuranDiscrDist.h:99
 TUnuranDiscrDist.h:100
 TUnuranDiscrDist.h:101
 TUnuranDiscrDist.h:102
 TUnuranDiscrDist.h:103
 TUnuranDiscrDist.h:104
 TUnuranDiscrDist.h:105
 TUnuranDiscrDist.h:106
 TUnuranDiscrDist.h:107
 TUnuranDiscrDist.h:108
 TUnuranDiscrDist.h:109
 TUnuranDiscrDist.h:110
 TUnuranDiscrDist.h:111
 TUnuranDiscrDist.h:112
 TUnuranDiscrDist.h:113
 TUnuranDiscrDist.h:114
 TUnuranDiscrDist.h:115
 TUnuranDiscrDist.h:116
 TUnuranDiscrDist.h:117
 TUnuranDiscrDist.h:118
 TUnuranDiscrDist.h:119
 TUnuranDiscrDist.h:120
 TUnuranDiscrDist.h:121
 TUnuranDiscrDist.h:122
 TUnuranDiscrDist.h:123
 TUnuranDiscrDist.h:124
 TUnuranDiscrDist.h:125
 TUnuranDiscrDist.h:126
 TUnuranDiscrDist.h:127
 TUnuranDiscrDist.h:128
 TUnuranDiscrDist.h:129
 TUnuranDiscrDist.h:130
 TUnuranDiscrDist.h:131
 TUnuranDiscrDist.h:132
 TUnuranDiscrDist.h:133
 TUnuranDiscrDist.h:134
 TUnuranDiscrDist.h:135
 TUnuranDiscrDist.h:136
 TUnuranDiscrDist.h:137
 TUnuranDiscrDist.h:138
 TUnuranDiscrDist.h:139
 TUnuranDiscrDist.h:140
 TUnuranDiscrDist.h:141
 TUnuranDiscrDist.h:142
 TUnuranDiscrDist.h:143
 TUnuranDiscrDist.h:144
 TUnuranDiscrDist.h:145
 TUnuranDiscrDist.h:146
 TUnuranDiscrDist.h:147
 TUnuranDiscrDist.h:148
 TUnuranDiscrDist.h:149
 TUnuranDiscrDist.h:150
 TUnuranDiscrDist.h:151
 TUnuranDiscrDist.h:152
 TUnuranDiscrDist.h:153
 TUnuranDiscrDist.h:154
 TUnuranDiscrDist.h:155
 TUnuranDiscrDist.h:156
 TUnuranDiscrDist.h:157
 TUnuranDiscrDist.h:158
 TUnuranDiscrDist.h:159
 TUnuranDiscrDist.h:160
 TUnuranDiscrDist.h:161
 TUnuranDiscrDist.h:162
 TUnuranDiscrDist.h:163
 TUnuranDiscrDist.h:164
 TUnuranDiscrDist.h:165
 TUnuranDiscrDist.h:166
 TUnuranDiscrDist.h:167
 TUnuranDiscrDist.h:168
 TUnuranDiscrDist.h:169
 TUnuranDiscrDist.h:170
 TUnuranDiscrDist.h:171
 TUnuranDiscrDist.h:172
 TUnuranDiscrDist.h:173
 TUnuranDiscrDist.h:174
 TUnuranDiscrDist.h:175
 TUnuranDiscrDist.h:176
 TUnuranDiscrDist.h:177
 TUnuranDiscrDist.h:178
 TUnuranDiscrDist.h:179
 TUnuranDiscrDist.h:180
 TUnuranDiscrDist.h:181
 TUnuranDiscrDist.h:182
 TUnuranDiscrDist.h:183
 TUnuranDiscrDist.h:184
 TUnuranDiscrDist.h:185
 TUnuranDiscrDist.h:186
 TUnuranDiscrDist.h:187
 TUnuranDiscrDist.h:188
 TUnuranDiscrDist.h:189
 TUnuranDiscrDist.h:190
 TUnuranDiscrDist.h:191
 TUnuranDiscrDist.h:192
 TUnuranDiscrDist.h:193
 TUnuranDiscrDist.h:194
 TUnuranDiscrDist.h:195
 TUnuranDiscrDist.h:196
 TUnuranDiscrDist.h:197
 TUnuranDiscrDist.h:198
 TUnuranDiscrDist.h:199
 TUnuranDiscrDist.h:200
 TUnuranDiscrDist.h:201
 TUnuranDiscrDist.h:202
 TUnuranDiscrDist.h:203
 TUnuranDiscrDist.h:204
 TUnuranDiscrDist.h:205
 TUnuranDiscrDist.h:206
 TUnuranDiscrDist.h:207
 TUnuranDiscrDist.h:208
 TUnuranDiscrDist.h:209
 TUnuranDiscrDist.h:210
 TUnuranDiscrDist.h:211
 TUnuranDiscrDist.h:212
 TUnuranDiscrDist.h:213
 TUnuranDiscrDist.h:214
 TUnuranDiscrDist.h:215
 TUnuranDiscrDist.h:216
 TUnuranDiscrDist.h:217
 TUnuranDiscrDist.h:218
 TUnuranDiscrDist.h:219
 TUnuranDiscrDist.h:220
 TUnuranDiscrDist.h:221
 TUnuranDiscrDist.h:222
 TUnuranDiscrDist.h:223
 TUnuranDiscrDist.h:224
 TUnuranDiscrDist.h:225