EvtGen 2.2.0
Monte Carlo generator of particle decays, in particular the weak decays of heavy flavour particles such as B mesons.
Loading...
Searching...
No Matches
EvtPdf.hh
Go to the documentation of this file.
1
2/***********************************************************************
3* Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
4* *
5* This file is part of EvtGen. *
6* *
7* EvtGen is free software: you can redistribute it and/or modify *
8* it under the terms of the GNU General Public License as published by *
9* the Free Software Foundation, either version 3 of the License, or *
10* (at your option) any later version. *
11* *
12* EvtGen is distributed in the hope that it will be useful, *
13* but WITHOUT ANY WARRANTY; without even the implied warranty of *
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15* GNU General Public License for more details. *
16* *
17* You should have received a copy of the GNU General Public License *
18* along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
19***********************************************************************/
20
21#ifndef EVT_PDF_HH
22#define EVT_PDF_HH
23
30
31#include <assert.h>
32#include <stdio.h>
33
34/*
35 * All classes are templated on the point type T
36 *
37 * EvtPdf:
38 *
39 * Probability density function defined on an interval of phase-space.
40 * Integral over the interval can be calculated by Monte Carlo integration.
41 * Some (but not all) PDFs are analytic in the sense that they can be integrated
42 * by numeric quadrature and distributions can be generated according to them.
43 *
44 * EvtPdfGen:
45 *
46 * Generator adaptor. Can be used to generate random points
47 * distributed according to the PDF for analytic PDFs.
48 *
49 * EvtPdfPred:
50 *
51 * Predicate adaptor for PDFs. Can be used for generating random points distributed
52 * according to the PDF for any PDF using rejection method. (See "Numerical Recipes").
53 *
54 * EvtPdfUnary:
55 *
56 * Adapter for generic algorithms. Evaluates the PDF and returns the value
57 *
58 * EvtPdfDiv:
59 *
60 * PDF obtained by division of one PDF by another. Because the two PDFs are
61 * arbitrary this PDF is not analytic. When importance sampling is used the
62 * original PDF is divided by the analytic comparison function. EvtPdfDiv is
63 * used to represent the modified PDF.
64 */
65
66template <class T>
67class EvtPdfPred;
68template <class T>
69class EvtPdfGen;
70
71template <class T>
72class EvtPdf {
73 public:
74 EvtPdf() {}
75 EvtPdf( const EvtPdf& other ) : m_itg( other.m_itg ) {}
76 virtual ~EvtPdf() {}
77 virtual EvtPdf<T>* clone() const = 0;
78
79 double evaluate( const T& p ) const
80 {
81 if ( p.isValid() )
82 return pdf( p );
83 else
84 return 0.;
85 }
86
87 // Find PDF maximum. Points are sampled according to pc
88
89 EvtPdfMax<T> findMax( const EvtPdf<T>& pc, int N );
90
91 // Find generation efficiency.
92
93 EvtValError findGenEff( const EvtPdf<T>& pc, int N, int nFindMax );
94
95 // Analytic integration. Calls cascade down until an overridden
96 // method is called.
97
98 void setItg( EvtValError itg ) { m_itg = itg; }
99
101 {
102 if ( !m_itg.valueKnown() )
104 return m_itg;
105 }
106 EvtValError getItg( int N ) const
107 {
108 if ( !m_itg.valueKnown() )
109 m_itg = compute_integral( N );
110 return m_itg;
111 }
112
114 {
115 printf( "Analytic integration of PDF is not defined\n" );
116 assert( 0 );
117 return EvtValError{};
118 }
119 virtual EvtValError compute_integral( int ) const
120 {
121 return compute_integral();
122 }
123
124 // Monte Carlo integration.
125
127
128 // Generation. Create predicate accept-reject generators.
129 // nMax iterations will be used to find the maximum of the accept-reject predicate
130
132 int nMax,
133 double factor = 1. );
134
135 virtual T randomPoint();
136
137 protected:
138 virtual double pdf( const T& ) const = 0;
140};
141
142template <class T>
144 public:
145 typedef T result_type;
146
147 EvtPdfGen() : m_pdf( 0 ) {}
148 EvtPdfGen( const EvtPdfGen<T>& other ) :
149 m_pdf( other.m_pdf ? other.m_pdf->clone() : nullptr )
150 {
151 }
152 EvtPdfGen( const EvtPdf<T>& pdf ) : m_pdf( pdf.clone() ) {}
153 ~EvtPdfGen() { delete m_pdf; }
154
155 result_type operator()() { return m_pdf->randomPoint(); }
156
157 private:
159};
160
161template <class T>
163 public:
164 typedef T argument_type;
165 typedef bool result_type;
166
168 EvtPdfPred( const EvtPdf<T>& thePdf ) : m_pdf( thePdf.clone() ) {}
169 EvtPdfPred( const EvtPdfPred& other ) :
171 {
172 }
173 ~EvtPdfPred() { delete m_pdf; }
174
176 {
177 assert( m_pdf );
178 assert( m_pdfMax.valueKnown() );
179
180 double random = EvtRandom::Flat( 0., m_pdfMax.value() );
181 return ( random <= m_pdf->evaluate( p ) );
182 }
183
184 EvtPdfMax<T> getMax() const { return m_pdfMax; }
185 void setMax( const EvtPdfMax<T>& max ) { m_pdfMax = max; }
186 template <class InputIterator>
187 void compute_max( InputIterator it, InputIterator end, double factor = 1. )
188 {
189 T p = *it++;
190 m_pdfMax = EvtPdfMax<T>( p, m_pdf->evaluate( p ) * factor );
191
192 while ( !( it == end ) ) {
193 T pp = *it++;
194 double val = m_pdf->evaluate( pp ) * factor;
195 if ( val > m_pdfMax.value() )
196 m_pdfMax = EvtPdfMax<T>( pp, val );
197 }
198 }
199
200 private:
203};
204
205template <class T>
207 public:
208 typedef double result_type;
209 typedef T argument_type;
210
212 EvtPdfUnary( const EvtPdf<T>& thePdf ) : m_pdf( thePdf.clone() ) {}
213 EvtPdfUnary( const EvtPdfUnary& other ) : COPY_PTR( m_pdf ) {}
214 ~EvtPdfUnary() { delete m_pdf; }
215
217 {
218 assert( m_pdf );
219 double ret = m_pdf->evaluate( p );
220 return ret;
221 }
222
223 private:
225};
226
227template <class T>
228class EvtPdfDiv : public EvtPdf<T> {
229 public:
230 EvtPdfDiv() : m_num( 0 ), m_den( 0 ) {}
231 EvtPdfDiv( const EvtPdf<T>& theNum, const EvtPdf<T>& theDen ) :
232 EvtPdf<T>(), m_num( theNum.clone() ), m_den( theDen.clone() )
233 {
234 }
235 EvtPdfDiv( const EvtPdfDiv<T>& other ) :
236 EvtPdf<T>( other ), COPY_PTR( m_num ), COPY_PTR( m_den )
237 {
238 }
239 virtual ~EvtPdfDiv()
240 {
241 delete m_num;
242 delete m_den;
243 }
244 EvtPdf<T>* clone() const override { return new EvtPdfDiv( *this ); }
245
246 double pdf( const T& p ) const override
247 {
248 double num = m_num->evaluate( p );
249 double den = m_den->evaluate( p );
250 assert( den != 0 );
251 return num / den;
252 }
253
254 private:
255 EvtPdf<T>* m_num; // numerator
256 EvtPdf<T>* m_den; // denominator
257};
258
259template <class T>
261{
262 EvtPdfPred<T> pred( *this );
263 EvtPdfGen<T> gen( pc );
264 pred.compute_max( iter( gen, N ), iter( gen ) );
265 EvtPdfMax<T> p = pred.getMax();
266 return p;
267}
268
269template <class T>
270EvtValError EvtPdf<T>::findGenEff( const EvtPdf<T>& pc, int N, int nFindMax )
271{
272 assert( N > 0 || nFindMax > 0 );
273 EvtPredGen<EvtPdfGen<T>, EvtPdfPred<T>> gen = accRejGen( pc, nFindMax );
274 int i;
275 for ( i = 0; i < N; i++ )
276 gen();
277 double eff = double( gen.getPassed() ) / double( gen.getTried() );
278 double err = sqrt( double( gen.getPassed() ) ) / double( gen.getTried() );
279 return EvtValError( eff, err );
280}
281
282template <class T>
284{
285 assert( N > 0 );
286
287 EvtPdfDiv<T> pdfdiv( *this, pc );
288 EvtPdfUnary<T> unary( pdfdiv );
289
290 EvtPdfGen<T> gen( pc );
291 EvtStreamInputIterator<T> begin = iter( gen, N );
293
294 double sum = 0.;
295 double sum2 = 0.;
296 while ( !( begin == end ) ) {
297 double value = pdfdiv.evaluate( *begin++ );
298 sum += value;
299 sum2 += value * value;
300 }
301
302 EvtValError x;
303 if ( N > 0 ) {
304 double av = sum / ( (double)N );
305 if ( N > 1 ) {
306 double dev2 = ( sum2 - av * av * N ) / ( (double)( N - 1 ) );
307 // Due to numerical precision dev2 may sometimes be negative
308 if ( dev2 < 0. )
309 dev2 = 0.;
310 double error = sqrt( dev2 / ( (double)N ) );
311 x = EvtValError( av, error );
312 } else
313 x = EvtValError( av );
314 }
315 m_itg = x * pc.getItg();
316 return m_itg;
317}
318
319template <class T>
321{
322 printf( "Function defined for analytic PDFs only\n" );
323 assert( 0 );
324 T temp;
325 return temp;
326}
327
328template <class T>
330 int nMax,
331 double factor )
332{
333 EvtPdfGen<T> gen( pc );
334 EvtPdfDiv<T> pdfdiv( *this, pc );
335 EvtPdfPred<T> pred( pdfdiv );
336 pred.compute_max( iter( gen, nMax ), iter( gen ), factor );
337 return EvtPredGen<EvtPdfGen<T>, EvtPdfPred<T>>( gen, pred );
338}
339
340#endif
#define COPY_PTR(X)
Definition EvtMacros.hh:26
#define COPY_MEM(X)
Definition EvtMacros.hh:27
EvtStreamInputIterator< typename Generator::result_type > iter(Generator gen, int N=0)
EvtPdf< T > * clone() const override
Definition EvtPdf.hh:244
double pdf(const T &p) const override
Definition EvtPdf.hh:246
virtual ~EvtPdfDiv()
Definition EvtPdf.hh:239
EvtPdf< T > * m_num
Definition EvtPdf.hh:255
EvtPdfDiv(const EvtPdfDiv< T > &other)
Definition EvtPdf.hh:235
EvtPdfDiv()
Definition EvtPdf.hh:230
EvtPdfDiv(const EvtPdf< T > &theNum, const EvtPdf< T > &theDen)
Definition EvtPdf.hh:231
EvtPdf< T > * m_den
Definition EvtPdf.hh:256
~EvtPdfGen()
Definition EvtPdf.hh:153
EvtPdfGen(const EvtPdf< T > &pdf)
Definition EvtPdf.hh:152
T result_type
Definition EvtPdf.hh:145
EvtPdf< T > * m_pdf
Definition EvtPdf.hh:158
result_type operator()()
Definition EvtPdf.hh:155
EvtPdfGen()
Definition EvtPdf.hh:147
EvtPdfGen(const EvtPdfGen< T > &other)
Definition EvtPdf.hh:148
result_type operator()(argument_type p)
Definition EvtPdf.hh:175
T argument_type
Definition EvtPdf.hh:164
void compute_max(InputIterator it, InputIterator end, double factor=1.)
Definition EvtPdf.hh:187
EvtPdf< T > * m_pdf
Definition EvtPdf.hh:201
void setMax(const EvtPdfMax< T > &max)
Definition EvtPdf.hh:185
~EvtPdfPred()
Definition EvtPdf.hh:173
EvtPdfMax< T > m_pdfMax
Definition EvtPdf.hh:202
EvtPdfPred(const EvtPdf< T > &thePdf)
Definition EvtPdf.hh:168
bool result_type
Definition EvtPdf.hh:165
EvtPdfMax< T > getMax() const
Definition EvtPdf.hh:184
EvtPdfPred(const EvtPdfPred &other)
Definition EvtPdf.hh:169
EvtPdfUnary(const EvtPdf< T > &thePdf)
Definition EvtPdf.hh:212
result_type operator()(argument_type p)
Definition EvtPdf.hh:216
EvtPdf< T > * m_pdf
Definition EvtPdf.hh:224
T argument_type
Definition EvtPdf.hh:209
EvtPdfUnary(const EvtPdfUnary &other)
Definition EvtPdf.hh:213
double result_type
Definition EvtPdf.hh:208
virtual ~EvtPdf()
Definition EvtPdf.hh:76
virtual EvtPdf< T > * clone() const =0
virtual EvtValError compute_integral(int) const
Definition EvtPdf.hh:119
EvtPredGen< EvtPdfGen< T >, EvtPdfPred< T > > accRejGen(const EvtPdf< T > &pc, int nMax, double factor=1.)
Definition EvtPdf.hh:329
virtual EvtValError compute_integral() const
Definition EvtPdf.hh:113
void setItg(EvtValError itg)
Definition EvtPdf.hh:98
EvtValError getItg(int N) const
Definition EvtPdf.hh:106
virtual double pdf(const T &) const =0
EvtValError findGenEff(const EvtPdf< T > &pc, int N, int nFindMax)
Definition EvtPdf.hh:270
virtual T randomPoint()
Definition EvtPdf.hh:320
EvtValError compute_mc_integral(const EvtPdf< T > &pc, int N)
Definition EvtPdf.hh:283
double evaluate(const T &p) const
Definition EvtPdf.hh:79
EvtPdfMax< T > findMax(const EvtPdf< T > &pc, int N)
Definition EvtPdf.hh:260
EvtPdf(const EvtPdf &other)
Definition EvtPdf.hh:75
EvtValError getItg() const
Definition EvtPdf.hh:100
EvtValError m_itg
Definition EvtPdf.hh:139
EvtPdf()
Definition EvtPdf.hh:74
int getPassed() const
Definition EvtPredGen.hh:74
int getTried() const
Definition EvtPredGen.hh:73
static double Flat()
Definition EvtRandom.cpp:95