Pdf Package
provides the description of Probability Distribution Functions (PDF) and the implementation of the most commonly used ones. Random generators for each proided PDF type is provided and can be added for user-defined PDFs. Pdfs can be mixed according to appropriate fractions, or combined to describe a multi-dimensional PDF factorized into independent component. User-defined PDFs can be specified either in terms of  functions described in the Funct package, or directly as C++ classes. Random generation for user-defined PDFs can be either written by the use, or implemented using a hit-or-miss ora a sampling algorithm, according to the user prescription.
Contents

Conventions
  • the examples below assume one specifies the directive:
    using namespace Pdf;
    otherwise the namespace Pdf should be specified where appropriate.
Probability distribution functions (PDF)
  • 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 normalization
      • PdfNonParametric: 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:
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
  • 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:
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;

Combining and manipulating PDFs
  • 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:
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 );

Examples