BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
EvtPdf.hh
Go to the documentation of this file.
1/*******************************************************************************
2 * Project: BaBar detector at the SLAC PEP-II B-factory
3 * Package: EvtGenBase
4 * File: $Id: EvtPdf.hh,v 1.1.1.2 2007/10/26 05:03:14 pingrg Exp $
5 * Author: Alexei Dvoretskii, dvoretsk@slac.stanford.edu, 2001-2002
6 *
7 * Copyright (C) 2002 Caltech
8 *******************************************************************************/
9
10/*
11 * All classes are templated on the point type T
12 *
13 * EvtPdf:
14 *
15 * Probability density function defined on an interval of phase-space.
16 * Integral over the interval can be calculated by Monte Carlo integration.
17 * Some (but not all) PDFs are analytic in the sense that they can be integrated
18 * by numeric quadrature and distributions can be generated according to them.
19 *
20 * EvtPdfGen:
21 *
22 * Generator adaptor. Can be used to generate random points
23 * distributed according to the PDF for analytic PDFs.
24 *
25 * EvtPdfPred:
26 *
27 * Predicate adaptor for PDFs. Can be used for generating random points distributed
28 * according to the PDF for any PDF using rejection method. (See "Numerical Recipes").
29 *
30 * EvtPdfUnary:
31 *
32 * Adapter for generic algorithms. Evaluates the PDF and returns the value
33 *
34 * EvtPdfDiv:
35 *
36 * PDF obtained by division of one PDF by another. Because the two PDFs are
37 * arbitrary this PDF is not analytic. When importance sampling is used the
38 * original PDF is divided by the analytic comparison function. EvtPdfDiv is
39 * used to represent the modified PDF.
40 */
41
42#ifndef EVT_PDF_HH
43#define EVT_PDF_HH
44
45#include "EvtMacros.hh"
46#include "EvtPdfMax.hh"
47#include "EvtPredGen.hh"
48#include "EvtRandom.hh"
50#include "EvtValError.hh"
51#include <assert.h>
52#include <stdio.h>
53
54template <class T> class EvtPdfPred;
55template <class T> class EvtPdfGen;
56
57template <class T> class EvtPdf {
58public:
59 EvtPdf() {}
60 EvtPdf( const EvtPdf& other ) : _itg( other._itg ) {}
61 virtual ~EvtPdf() {}
62 virtual EvtPdf<T>* clone() const = 0;
63
64 double evaluate( const T& p ) const {
65 if ( p.isValid() ) return pdf( p );
66 else return 0.;
67 }
68
69 // Find PDF maximum. Points are sampled according to pc
70
71 EvtPdfMax<T> findMax( const EvtPdf<T>& pc, int N );
72
73 // Find generation efficiency.
74
75 EvtValError findGenEff( const EvtPdf<T>& pc, int N, int nFindMax );
76
77 // Analytic integration. Calls cascade down until an overridden
78 // method is called.
79
80 void setItg( EvtValError itg ) { _itg = itg; }
81
83 if ( !_itg.valueKnown() ) _itg = compute_integral();
84 return _itg;
85 }
86 EvtValError getItg( int N ) const {
87 if ( !_itg.valueKnown() ) _itg = compute_integral( N );
88 return _itg;
89 }
90
92 // make sun happy - return something
93 {
94 printf( "Analytic integration of PDF is not defined\n" );
95 assert( 0 );
96 return compute_integral();
97 }
98 virtual EvtValError compute_integral( int N ) const { return compute_integral(); }
99
100 // Monte Carlo integration.
101
103
104 // Generation. Create predicate accept-reject generators.
105 // nMax iterations will be used to find the maximum of the accept-reject predicate
106
108 double factor = 1. );
109
110 virtual T randomPoint();
111
112protected:
113 virtual double pdf( const T& ) const = 0;
115};
116
117template <class T> class EvtPdfGen {
118public:
119 typedef T result_type;
120
121 EvtPdfGen() : _pdf( 0 ) {}
122 EvtPdfGen( const EvtPdfGen<T>& other ) : _pdf( other._pdf ? other._pdf->clone() : 0 ) {}
123 EvtPdfGen( const EvtPdf<T>& pdf ) : _pdf( pdf.clone() ) {}
124 ~EvtPdfGen() { delete _pdf; }
125
126 result_type operator()() { return _pdf->randomPoint(); }
127
128private:
129 EvtPdf<T>* _pdf;
130};
131
132template <class T> class EvtPdfPred {
133public:
134 typedef T argument_type;
135 typedef bool result_type;
136
138 EvtPdfPred( const EvtPdf<T>& thePdf ) : itsPdf( thePdf.clone() ) {}
139 EvtPdfPred( const EvtPdfPred& other ) : COPY_PTR( itsPdf ), COPY_MEM( itsPdfMax ) {}
140 ~EvtPdfPred() { delete itsPdf; }
141
143 assert( itsPdf );
144 assert( itsPdfMax.valueKnown() );
145
146 double random = EvtRandom::Flat( 0., itsPdfMax.value() );
147 return ( random <= itsPdf->evaluate( p ) );
148 }
149
150 EvtPdfMax<T> getMax() const { return itsPdfMax; }
151 void setMax( const EvtPdfMax<T>& max ) { itsPdfMax = max; }
152 template <class InputIterator>
153 void compute_max( InputIterator it, InputIterator end, double factor = 1. ) {
154 T p = *it++;
155 itsPdfMax = EvtPdfMax<T>( p, itsPdf->evaluate( p ) * factor );
156
157 while ( !( it == end ) )
158 {
159 T p = *it++;
160 double val = itsPdf->evaluate( p ) * factor;
161 if ( val > itsPdfMax.value() ) itsPdfMax = EvtPdfMax<T>( p, val );
162 }
163 }
164
165private:
166 EvtPdf<T>* itsPdf;
167 EvtPdfMax<T> itsPdfMax;
168};
169
170template <class T> class EvtPdfUnary {
171public:
172 typedef double result_type;
173 typedef T argument_type;
174
176 EvtPdfUnary( const EvtPdf<T>& thePdf ) : itsPdf( thePdf.clone() ) {}
177 EvtPdfUnary( const EvtPdfUnary& other ) : COPY_PTR( itsPdf ) {}
178 ~EvtPdfUnary() { delete itsPdf; }
179
181 assert( itsPdf );
182 double ret = itsPdf->evaluate( p );
183 return ret;
184 }
185
186private:
187 EvtPdf<T>* itsPdf;
188};
189
190template <class T> class EvtPdfDiv : public EvtPdf<T> {
191public:
192 EvtPdfDiv() : itsNum( 0 ), itsDen( 0 ) {}
193 EvtPdfDiv( const EvtPdf<T>& theNum, const EvtPdf<T>& theDen )
194 : EvtPdf<T>(), itsNum( theNum.clone() ), itsDen( theDen.clone() ) {}
195 EvtPdfDiv( const EvtPdfDiv<T>& other )
196 : EvtPdf<T>( other ), COPY_PTR( itsNum ), COPY_PTR( itsDen ) {}
197 virtual ~EvtPdfDiv() {
198 delete itsNum;
199 delete itsDen;
200 }
201 virtual EvtPdf<T>* clone() const { return new EvtPdfDiv( *this ); }
202
203 virtual double pdf( const T& p ) const {
204 double num = itsNum->evaluate( p );
205 double den = itsDen->evaluate( p );
206 assert( den != 0 );
207 return num / den;
208 }
209
210private:
211 EvtPdf<T>* itsNum; // numerator
212 EvtPdf<T>* itsDen; // denominator
213};
214
215template <class T> EvtPdfMax<T> EvtPdf<T>::findMax( const EvtPdf<T>& pc, int N ) {
216 EvtPdfPred<T> pred( *this );
217 EvtPdfGen<T> gen( pc );
218 pred.compute_max( iter( gen, N ), iter( gen ) );
219 EvtPdfMax<T> p = pred.getMax();
220 return p;
221}
222
223template <class T>
224EvtValError EvtPdf<T>::findGenEff( const EvtPdf<T>& pc, int N, int nFindMax ) {
225 assert( N > 0 || nFindMax > 0 );
226 EvtPredGen<EvtPdfGen<T>, EvtPdfPred<T>> gen = accRejGen( pc, nFindMax );
227 int i;
228 for ( i = 0; i < N; i++ ) gen();
229 double eff = double( gen.getPassed() ) / double( gen.getTried() );
230 double err = sqrt( double( gen.getPassed() ) ) / double( gen.getTried() );
231 return EvtValError( eff, err );
232}
233
234template <class T> EvtValError EvtPdf<T>::compute_mc_integral( const EvtPdf<T>& pc, int N ) {
235 assert( N > 0 );
236
237 EvtValError otherItg = pc.getItg();
238 EvtPdfDiv<T> pdfdiv( *this, pc );
239 EvtPdfUnary<T> unary( pdfdiv );
240
241 EvtPdfGen<T> gen( pc );
242 EvtStreamInputIterator<T> begin = iter( gen, N );
244
245 double sum = 0.;
246 double sum2 = 0.;
247 while ( !( begin == end ) )
248 {
249
250 double value = pdfdiv.evaluate( *begin++ );
251 sum += value;
252 sum2 += value * value;
253 }
254
255 EvtValError x;
256 if ( N > 0 )
257 {
258 double av = sum / ( (double)N );
259 if ( N > 1 )
260 {
261 double dev2 = ( sum2 - av * av * N ) / ( (double)( N - 1 ) );
262 // Due to numerical precision dev2 may sometimes be negative
263 if ( dev2 < 0. ) dev2 = 0.;
264 double error = sqrt( dev2 / ( (double)N ) );
265 x = EvtValError( av, error );
266 }
267 else x = EvtValError( av );
268 }
269 _itg = x * pc.getItg();
270 return _itg;
271}
272
273template <class T> T EvtPdf<T>::randomPoint() {
274 printf( "Function defined for analytic PDFs only\n" );
275 assert( 0 );
276 T temp;
277 return temp;
278}
279
280template <class T>
282 double factor ) {
283 EvtPdfGen<T> gen( pc );
284 EvtPdfDiv<T> pdfdiv( *this, pc );
285 EvtPdfPred<T> pred( pdfdiv );
286 pred.compute_max( iter( gen, nMax ), iter( gen ), factor );
287 return EvtPredGen<EvtPdfGen<T>, EvtPdfPred<T>>( gen, pred );
288}
289
290#endif
#define max(a, b)
#define COPY_PTR(X)
Definition EvtMacros.hh:15
#define COPY_MEM(X)
Definition EvtMacros.hh:16
EvtStreamInputIterator< typename Generator::result_type > iter(Generator gen, int N=0)
virtual double pdf(const T &p) const
Definition EvtPdf.hh:203
virtual ~EvtPdfDiv()
Definition EvtPdf.hh:197
EvtPdfDiv(const EvtPdfDiv< T > &other)
Definition EvtPdf.hh:195
EvtPdfDiv()
Definition EvtPdf.hh:192
EvtPdfDiv(const EvtPdf< T > &theNum, const EvtPdf< T > &theDen)
Definition EvtPdf.hh:193
virtual EvtPdf< T > * clone() const
Definition EvtPdf.hh:201
~EvtPdfGen()
Definition EvtPdf.hh:124
EvtPdfGen(const EvtPdf< T > &pdf)
Definition EvtPdf.hh:123
T result_type
Definition EvtPdf.hh:119
result_type operator()()
Definition EvtPdf.hh:126
EvtPdfGen()
Definition EvtPdf.hh:121
EvtPdfGen(const EvtPdfGen< T > &other)
Definition EvtPdf.hh:122
result_type operator()(argument_type p)
Definition EvtPdf.hh:142
T argument_type
Definition EvtPdf.hh:134
void compute_max(InputIterator it, InputIterator end, double factor=1.)
Definition EvtPdf.hh:153
void setMax(const EvtPdfMax< T > &max)
Definition EvtPdf.hh:151
~EvtPdfPred()
Definition EvtPdf.hh:140
EvtPdfPred(const EvtPdf< T > &thePdf)
Definition EvtPdf.hh:138
bool result_type
Definition EvtPdf.hh:135
EvtPdfMax< T > getMax() const
Definition EvtPdf.hh:150
EvtPdfPred(const EvtPdfPred &other)
Definition EvtPdf.hh:139
EvtPdfUnary(const EvtPdf< T > &thePdf)
Definition EvtPdf.hh:176
result_type operator()(argument_type p)
Definition EvtPdf.hh:180
T argument_type
Definition EvtPdf.hh:173
EvtPdfUnary(const EvtPdfUnary &other)
Definition EvtPdf.hh:177
double result_type
Definition EvtPdf.hh:172
virtual ~EvtPdf()
Definition EvtPdf.hh:61
virtual EvtPdf< T > * clone() const =0
virtual EvtValError compute_integral(int N) const
Definition EvtPdf.hh:98
EvtPredGen< EvtPdfGen< T >, EvtPdfPred< T > > accRejGen(const EvtPdf< T > &pc, int nMax, double factor=1.)
Definition EvtPdf.hh:281
virtual EvtValError compute_integral() const
Definition EvtPdf.hh:91
void setItg(EvtValError itg)
Definition EvtPdf.hh:80
EvtValError _itg
Definition EvtPdf.hh:114
EvtValError getItg(int N) const
Definition EvtPdf.hh:86
virtual double pdf(const T &) const =0
EvtValError findGenEff(const EvtPdf< T > &pc, int N, int nFindMax)
Definition EvtPdf.hh:224
virtual T randomPoint()
Definition EvtPdf.hh:273
EvtValError compute_mc_integral(const EvtPdf< T > &pc, int N)
Definition EvtPdf.hh:234
double evaluate(const T &p) const
Definition EvtPdf.hh:64
EvtPdfMax< T > findMax(const EvtPdf< T > &pc, int N)
Definition EvtPdf.hh:215
EvtPdf(const EvtPdf &other)
Definition EvtPdf.hh:60
EvtValError getItg() const
Definition EvtPdf.hh:82
EvtPdf()
Definition EvtPdf.hh:59
int getPassed() const
Definition EvtPredGen.hh:62
int getTried() const
Definition EvtPredGen.hh:61
static double Flat()
Definition EvtRandom.cc:69