| Conventions 
                                Probability distribution 
       functions (PDF)the examples below assume one specifies 
 the   directive:                                                        
                                                                        
                                                                        
                                                                        
                                                                        
 
          
                  otherwise the namespace Pdf should be specified 
    where appropriate.
 
                                  Probability distribution functions
are   functions      (or functors; see here)   returning   a value
representing a probability density (or probability) corresponding     to
the double (or int) value that is passed as argument. More than one  variable
  can be passed as argument in the case of multi-dimensional distributions.Examples
 are:                                                       
                                                                        
                                                          
        
            
              
                | struct Gaussian {Gaussian( double m, double s ) : mean( m ), sigma( s ) { }
 double operator()( double x ) const  {
 static const double norm( 1 / sqrt( 2 * M_PI ) );
 double arg = ( x - mean ) / sigma;
 return exp( -0.5 * arg * arg ) * norm / sigma;
 }
 private:
 double mean, sigma;
 };
 
 struct Poissonian {
 Poissonian( double m ) : mean( m ) {  }
 double operator()( unsigned int n ) const
 { return ( exp( - mean ) * pow( mean, n ) / Funct::factorial( n ) ); }
 private:
 double mean;
 };
 |  
                            Some of the most commonly used PDFs are provided. 
    More   in details 
                      
                        
                          | PDF type | arguments 
 | parameter names 
 | header file 
 |  
                          | Flat 
 | double 
 | min, 
max 
 | Pdf/Flat.h 
 |  
                          | Constant<T> 
 | any (default:
 double) 
 | value 
 | Pdf/Constant.h 
 |  
                          | Exponential 
 | double 
 | tau 
 | Pdf/Exponential.h 
 |  
                          | Gaussian 
 | double 
 | mean,
 sigma 
 | Pdf/Gaussian.h 
 |  
                          | Poissonian 
 | unsigned
 int 
 | mean 
 | Pdf/Poissonian.h 
 |  
                          | Tag<n> 
 | int 
 | prob[0],
 ... prob[n] 
 | Pdf/Tag.h 
 |  
                          | Triangular 
 | double 
 | - 
 | Pdf/Triangular.h 
 |  
 
                     Generating 
   PDFs from expressions (header Pdf/Pdf.h)
                       PDFs can be generated from expressions using  the 
                     Pdf template, passing the expression 
type   as template argument. Given that the expression is not in general normalized,
  three types of PDF are provided in order to provide the appropriate normalization:
                         PdfNoNormalization: assumes
that   the  expression is already normalized, and performs no normalizationPdfNonParametric: computes the 
 normalization   only once at the contruction time. This may be an optimized 
 choice if the   normalization factor does not depend on expression parameters. 
 The integration   is performed analytically by default. The user can always 
 specify to compute   the integration numerically.PdfParametric: the normalization 
  is  recomputed every time the operator "()" is called. This may be required 
  for  instance when the normalization depends on a PDF parameter that is 
fitted,   and changes from call to call.
 Example:                                                        
                         
        Random number    generators                      
          
              
                
                  | X x; // perform no normalization.
 // for the following case it is not appropriate...
 PdfNoNormalization< X > f1( sqr(sin(x) + cos(x)) 
   );
 
 // compute the integration only once
 PdfNonParametric< X > f2( sqr(sin(x) + cos(x)), 0, 4*M_PI );
 
 // recompute the normalization every time, since
 // the parameter tau may change from call to call
 Parameter tau( 0.123 );
 PdfParametric< X > f3( x * exp( - tau * x ), 0, 10 );
 
 |  
                           Random number generators generate random variables 
    according   to a given PDF. The PDF type has to be specified as template 
   parameter. For each of the provided PDF type T a corresponding random generator
   is provided as RandomGenerator< T >. Usually random
   generators for a type XXX are defined in the header file
                  Pdf/RandomGeneratorXXX.h.Before using random generators, it is necessary 
to specify which engine implementation should be used. This toolkit is not 
intended to re-implement random number generators that are already nicely 
implemented in other packages. Currently, CLHEP and ROOT implementations are
supported. The external packages are encapsulated internally, and a default 
must be choosen by the user. This is specified in the header file Pdf/Ext/Defaults.h, 
which is set to ROOT including Pdf/Exp/Root/RootRandom.h and
defining DefaultRandomGenerator as RootRandom 
As alternative, the user may include the header Pdf/Ext/Clhep/ClhepRandom.h, 
and define DefaultRandomGenerator as ClhepRandom. 
It is also possible to mix generators using different engines passing the 
generator as second template argument of RandomGenerator. 
See the examples for more use cases.
Example:                                                       
                                                                       
        
            
              
                | #include "Pdf/RandomGeneratorGaussian.h"
 Gaussian g( 0, 1 ); // a gaussian with mean 0 and r.m.s. 1
 RandomGenerator< Gaussiam > r( g );
 double x;
 r.generate( x ); // x is set to a random value according to g
 |  
                       User can specify Random number generators for
custom    PDFs  by partial specialization of the RandomGenerator template. 
    As alternative, two random generator engines are provided using a sampling 
    algorithm, or a "hit-or-miss" algorithm. Examples of how to specify custom random generators
   follow:                                                       
                                                                       
        
            
              
                | struct MyPdf {double operator()( double x ) {
 // . . . implementation of custom PDF }
 };
 
 #include "Pdf/RandomGenerator.h"
 
 template< > struct RamdomGenerator< MyPdf > {
 void generate( double& x ) {  x = myRandom(); }
 };
 
 #include "Pdf/RandomGeneratorSample.h"
 
 // specify a sampling for MyPdf of 1024 point from -1 to 1
 RANDOM_GENERATOR_SAMPLE( MyPdf, 1024, -1, 1 )
 
 #include "Pdf/RandomGeneratorHitOrMiss.h"
 
 // specify a "hit-or-miss" algorithm from -1 to 1,
 // assuming a maximum of MyPdf of 100
 RANDOM_GENERATOR_HITORMISS( MyPdf, -1, 1, 100 )
 |  
                     Notice that random number generators for custom
PDFs   are  the for all the PDFs of the same type. In case of more custom PDFs from expressions, 
   it may be necessary to have different generators for different PDFs. This 
   is easily solved providing subclasses of the templated PDFs. Instead of 
 explicitly subclassing a PDF, it is possible to use the predefined preprocessor 
 macros                 DEFINE_PDFNONORMALIZATION, DEFINE_PDFNONPARAMETRIC
   and DEFINE_PDFPARAMETRIC.Example:                   
        Combining and manipulating PDFs
            
              
                | template<
 typename X > struct MyPdf1 : public Pdf::PdfNoNormalization< X > {
 template< typename F > MyPdf1
(  const   F& f ) :
 Pdf::PdfNoNormalization<X>( 
   f ) { }
 };
 
 // equivalent to the above definition
 DEFINE_PDFNONORMALIZATION( MyPdf2 )
 
 RANDOM_GENERATOR_SAMPLE( MyPdf1<X>, 1024, 0, 10 )
 RANDOM_GENERATOR_HITORMISS( MyPdf2<X>,
 0,  5, ::exp(-1) )
 
 X x;
 MyPdf1 f1( exp( -x ) );
 MyPdf2 f2( x * exp( -x ) );
 RandomGenerator< MyPdf1 > r1;
 RandomGenerator< MyPdf2 > r2;
 
 |  
                       PDFs cam be combined in order to obtain a richer 
 variety    of Probability functions. Two basic mechanisms are provided: composition
   of independent PDFs to obtain a multi-dimensional pdf, and mixure of PDFs.
   Also, trasformation of variable is supported.Composition 
    of  independent PDFs (defined in Pdf/Independent.h) 
                                                                        
                                              
        
                         Two PDFs in n and m variables
can   be  composed  to obtain a n+m variable PDF which is the product
of   the  two original  PDFs. Up to 10 PDFs can be combined in a single one.
The  list  of PDF types  to be combined can be passed as template parameters.
 The variable  types of  the combined function are the one of the original
 PDF, in the specified  order. Example:                                                       
                                                        
                              
          
              
                
                  | #include "Pdf/Independent.h" 
 Gaussian g( 1, 2 );
 Flat u( -1, 1 );
 Independent< Gaussian, Flat > i( g, u );
 
 |  
                                                                        
                                              
        
                         In order to be handled by the Independent 
                    template,   a PDF class has to specify the number 
  and types of its aguments. In order   to do this automatically, it may be
  convenient to inherit from the class                    Argument. 
  See the header file of the provided   PDFs for more detail.
A random generator for the combined PDF is provided. 
    It will generate random variables independently for the combined PDFs.                                                       
                                                        
                                                  
          
              
                
                  | #include "RandomGeneratorIndependent.h" 
 typedef Independent< Gaussian, Gaussian, Flat > CombPdf;
 RandomGenerator< CombPdf > CombRand;
 CombRand r( i );
 double x, y, z;
 r.generate( x, y, z );
 
 |  
                       Mixture of PDFs
(defined     in Pdf/Mixture.h) 
                                                                        
                                              
        
                         Two PDFs having the same variables can be mixed
  with   relative fractions specified by the user. A specific random generator
  is  provided for mixture PDF type.Example:                                                       
                                                           
                              
          
              
                
                  | #include "Pdf/Mixture.h" 
 Gaussian g( 0, 1 );
 Flat u( -5, 5 );
 // define a mixture, with gaussian fraction of 10%
 Mixture< Gaussian, Flat > m( g, u, 0.1 );
 
 |  
                       Transformation 
    of variables (defined in Pdf/Trandformed.h) 
                                                                        
                                              
        
                         A transformation of variable is a C++ class
(or   struct)   that implements direct and inverse transformation. As example,
 the two-dimensional   rotation (defined in Pdf/Rotation.h)
 is shown:                                                       
                                                        
                              
          
              
                
                  | struct Rotation2D { Rotation2D( double phi ):
 _cos( cos( phi ) ), _sin( sin( phi ) ) {}
 void operator()( double & x0, double&  x1 )
const    {
 double X = x0 * _cos - x1 * _sin;
 double Y = x0 * _sin + x1 * _cos;
 x0 = X; x1 = Y;
 }
 void inverse( double & x0, double & x1 ) const {
 double X =   x0 * _cos + x1 * _sin;
 double Y = - x0 * _sin + x1 * _cos;
 x0 = X; x1 = Y;
 }
 private:
 double _cos, _sin;
 };
 
 |  
                                                                        
                                              
        
                         A PDF can be redefined in a new set of variables 
  traosformed   from the original set according to a specified transformation. 
  The assumption   that is made is that the Jacobian of the transformation 
 is 1 (i.e.: that  the transformation preserves the probability). Handling 
 transformations with  a non-trivial Jacobian is not implemented in the current 
 version.Example:                                                       
                                                           
        Examples                      
          
              
                
                  | typedef Independent<Gaussian, Gaussian>   BasicPdf; typedef Transformed<Basic, Rotation2D> TransfPdf;
 Gaussian g1( 0, 0.1 ), g2( 0, 1 );
 TransfPdf pdf( BasicPdf( g1, g2 ), Rotation2D( M_PI / 4 ) );
 
 // generate correlated gaussian variables
 RandomGenerator< TransfPdf > rnd( pdf );
 double x, y;
 rnd.generate( x, y );
 
 |  
 |