evtgen is hosted by Hepforge, IPPP Durham
EvtGen  2.0.0
Monte Carlo generator of particle decays, in particular the weak decays of heavy flavour particles such as B mesons.
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 
24 #include "EvtGenBase/EvtMacros.hh"
25 #include "EvtGenBase/EvtPdfMax.hh"
26 #include "EvtGenBase/EvtPredGen.hh"
27 #include "EvtGenBase/EvtRandom.hh"
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 
66 template <class T>
67 class EvtPdfPred;
68 template <class T>
69 class EvtPdfGen;
70 
71 template <class T>
72 class EvtPdf {
73  public:
74  EvtPdf() {}
75  EvtPdf( const EvtPdf& other ) : _itg( other._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 ) { _itg = itg; }
99 
101  {
102  if ( !_itg.valueKnown() )
104  return _itg;
105  }
106  EvtValError getItg( int N ) const
107  {
108  if ( !_itg.valueKnown() )
109  _itg = compute_integral( N );
110  return _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 
126  EvtValError compute_mc_integral( const EvtPdf<T>& pc, int N );
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;
139  mutable EvtValError _itg;
140 };
141 
142 template <class T>
143 class EvtPdfGen {
144  public:
145  typedef T result_type;
146 
147  EvtPdfGen() : _pdf( 0 ) {}
149  _pdf( other._pdf ? other._pdf->clone() : 0 )
150  {
151  }
152  EvtPdfGen( const EvtPdf<T>& pdf ) : _pdf( pdf.clone() ) {}
153  ~EvtPdfGen() { delete _pdf; }
154 
155  result_type operator()() { return _pdf->randomPoint(); }
156 
157  private:
159 };
160 
161 template <class T>
162 class EvtPdfPred {
163  public:
164  typedef T argument_type;
165  typedef bool result_type;
166 
168  EvtPdfPred( const EvtPdf<T>& thePdf ) : itsPdf( thePdf.clone() ) {}
171  {
172  }
173  ~EvtPdfPred() { delete itsPdf; }
174 
176  {
177  assert( itsPdf );
178  assert( itsPdfMax.valueKnown() );
179 
180  double random = EvtRandom::Flat( 0., itsPdfMax.value() );
181  return ( random <= itsPdf->evaluate( p ) );
182  }
183 
184  EvtPdfMax<T> getMax() const { return itsPdfMax; }
185  void setMax( const EvtPdfMax<T>& max ) { itsPdfMax = max; }
186  template <class InputIterator>
187  void compute_max( InputIterator it, InputIterator end, double factor = 1. )
188  {
189  T p = *it++;
190  itsPdfMax = EvtPdfMax<T>( p, itsPdf->evaluate( p ) * factor );
191 
192  while ( !( it == end ) ) {
193  T p = *it++;
194  double val = itsPdf->evaluate( p ) * factor;
195  if ( val > itsPdfMax.value() )
196  itsPdfMax = EvtPdfMax<T>( p, val );
197  }
198  }
199 
200  private:
203 };
204 
205 template <class T>
206 class EvtPdfUnary {
207  public:
208  typedef double result_type;
209  typedef T argument_type;
210 
212  EvtPdfUnary( const EvtPdf<T>& thePdf ) : itsPdf( thePdf.clone() ) {}
214  ~EvtPdfUnary() { delete itsPdf; }
215 
217  {
218  assert( itsPdf );
219  double ret = itsPdf->evaluate( p );
220  return ret;
221  }
222 
223  private:
225 };
226 
227 template <class T>
228 class EvtPdfDiv : public EvtPdf<T> {
229  public:
230  EvtPdfDiv() : itsNum( 0 ), itsDen( 0 ) {}
231  EvtPdfDiv( const EvtPdf<T>& theNum, const EvtPdf<T>& theDen ) :
232  EvtPdf<T>(), itsNum( theNum.clone() ), itsDen( theDen.clone() )
233  {
234  }
236  EvtPdf<T>( other ), COPY_PTR( itsNum ), COPY_PTR( itsDen )
237  {
238  }
239  virtual ~EvtPdfDiv()
240  {
241  delete itsNum;
242  delete itsDen;
243  }
244  EvtPdf<T>* clone() const override { return new EvtPdfDiv( *this ); }
245 
246  double pdf( const T& p ) const override
247  {
248  double num = itsNum->evaluate( p );
249  double den = itsDen->evaluate( p );
250  assert( den != 0 );
251  return num / den;
252  }
253 
254  private:
255  EvtPdf<T>* itsNum; // numerator
256  EvtPdf<T>* itsDen; // denominator
257 };
258 
259 template <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 
269 template <class T>
270 EvtValError 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 
282 template <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  _itg = x * pc.getItg();
316  return _itg;
317 }
318 
319 template <class T>
321 {
322  printf( "Function defined for analytic PDFs only\n" );
323  assert( 0 );
324  T temp;
325  return temp;
326 }
327 
328 template <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
EvtPredGen< EvtPdfGen< T >, EvtPdfPred< T > > accRejGen(const EvtPdf< T > &pc, int nMax, double factor=1.)
Definition: EvtPdf.hh:329
#define COPY_MEM(X)
Definition: EvtMacros.hh:27
void compute_max(InputIterator it, InputIterator end, double factor=1.)
Definition: EvtPdf.hh:187
double evaluate(const T &p) const
Definition: EvtPdf.hh:79
EvtPdf(const EvtPdf &other)
Definition: EvtPdf.hh:75
EvtStreamInputIterator< typename Generator::result_type > iter(Generator gen, int N=0)
EvtPdf< T > * itsDen
Definition: EvtPdf.hh:256
void setItg(EvtValError itg)
Definition: EvtPdf.hh:98
EvtPdfMax< T > itsPdfMax
Definition: EvtPdf.hh:202
EvtValError compute_mc_integral(const EvtPdf< T > &pc, int N)
Definition: EvtPdf.hh:283
EvtPdfDiv(const EvtPdfDiv< T > &other)
Definition: EvtPdf.hh:235
~EvtPdfGen()
Definition: EvtPdf.hh:153
EvtPdf< T > * itsNum
Definition: EvtPdf.hh:255
result_type operator()(argument_type p)
Definition: EvtPdf.hh:175
EvtPdfPred(const EvtPdf< T > &thePdf)
Definition: EvtPdf.hh:168
EvtPdf< T > * clone() const override
Definition: EvtPdf.hh:244
EvtPdfDiv()
Definition: EvtPdf.hh:230
double result_type
Definition: EvtPdf.hh:208
void setMax(const EvtPdfMax< T > &max)
Definition: EvtPdf.hh:185
virtual EvtPdf< T > * clone() const =0
EvtValError getItg() const
Definition: EvtPdf.hh:100
EvtPdfUnary(const EvtPdfUnary &other)
Definition: EvtPdf.hh:213
EvtPdfGen(const EvtPdf< T > &pdf)
Definition: EvtPdf.hh:152
EvtPdfMax< T > getMax() const
Definition: EvtPdf.hh:184
T argument_type
Definition: EvtPdf.hh:209
EvtPdf< T > * itsPdf
Definition: EvtPdf.hh:224
EvtPdfDiv(const EvtPdf< T > &theNum, const EvtPdf< T > &theDen)
Definition: EvtPdf.hh:231
virtual EvtValError compute_integral() const
Definition: EvtPdf.hh:113
EvtPdfGen()
Definition: EvtPdf.hh:147
T result_type
Definition: EvtPdf.hh:145
~EvtPdfUnary()
Definition: EvtPdf.hh:214
~EvtPdfPred()
Definition: EvtPdf.hh:173
EvtValError getItg(int N) const
Definition: EvtPdf.hh:106
EvtValError _itg
Definition: EvtPdf.hh:139
EvtPdf< T > * _pdf
Definition: EvtPdf.hh:158
T argument_type
Definition: EvtPdf.hh:164
static double Flat()
Definition: EvtRandom.cpp:72
bool valueKnown() const
Definition: EvtPdfMax.hh:43
virtual ~EvtPdf()
Definition: EvtPdf.hh:76
EvtPdf< T > * itsPdf
Definition: EvtPdf.hh:201
virtual ~EvtPdfDiv()
Definition: EvtPdf.hh:239
virtual double pdf(const T &) const =0
int getTried() const
Definition: EvtPredGen.hh:73
double pdf(const T &p) const override
Definition: EvtPdf.hh:246
#define COPY_PTR(X)
Definition: EvtMacros.hh:26
int getPassed() const
Definition: EvtPredGen.hh:74
virtual EvtValError compute_integral(int) const
Definition: EvtPdf.hh:119
Definition: EvtPdf.hh:72
result_type operator()()
Definition: EvtPdf.hh:155
EvtPdf()
Definition: EvtPdf.hh:74
bool result_type
Definition: EvtPdf.hh:165
EvtValError findGenEff(const EvtPdf< T > &pc, int N, int nFindMax)
Definition: EvtPdf.hh:270
int valueKnown() const
Definition: EvtValError.hh:38
virtual T randomPoint()
Definition: EvtPdf.hh:320
result_type operator()(argument_type p)
Definition: EvtPdf.hh:216
EvtPdfUnary(const EvtPdf< T > &thePdf)
Definition: EvtPdf.hh:212
EvtPdfUnary()
Definition: EvtPdf.hh:211
double value() const
Definition: EvtPdfMax.hh:44
Index other(Index i, Index j)
Definition: EvtCyclic3.cpp:156
EvtPdfPred()
Definition: EvtPdf.hh:167
EvtPdfPred(const EvtPdfPred &other)
Definition: EvtPdf.hh:169
EvtPdfMax< T > findMax(const EvtPdf< T > &pc, int N)
Definition: EvtPdf.hh:260
EvtPdfGen(const EvtPdfGen< T > &other)
Definition: EvtPdf.hh:148