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.
EvtPdfSum.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_SUM_HH
22 #define EVT_PDF_SUM_HH
23 
24 #include <stdio.h>
25 #include <vector>
26 using std::vector;
27 #include "EvtGenBase/EvtPdf.hh"
28 
29 // Sum of PDF functions.
30 
31 template <class T>
32 class EvtPdfSum : public EvtPdf<T> {
33  public:
34  EvtPdfSum() {}
35  EvtPdfSum( const EvtPdfSum<T>& other );
36  virtual ~EvtPdfSum();
37  EvtPdfSum* clone() const override { return new EvtPdfSum( *this ); }
38 
39  // Manipulate terms and coefficients
40 
41  void addTerm( double c, const EvtPdf<T>& pdf )
42  {
43  assert( c >= 0. );
44  _c.push_back( c );
45  _term.push_back( pdf.clone() );
46  }
47 
48  void addOwnedTerm( double c, std::unique_ptr<EvtPdf<T>> pdf )
49  {
50  _c.push_back( c );
51  _term.push_back( pdf.release() );
52  }
53 
54  size_t nTerms() const { return _term.size(); } // number of terms
55 
56  inline double c( int i ) const { return _c[i]; }
57  inline EvtPdf<T>* getPdf( int i ) const { return _term[i]; }
58 
59  // Integrals
60 
61  EvtValError compute_integral() const override;
62  EvtValError compute_integral( int N ) const override;
63  T randomPoint() override;
64 
65  protected:
66  double pdf( const T& p ) const override;
67 
68  vector<double> _c; // coefficients
69  vector<EvtPdf<T>*> _term; // pointers to pdfs
70 };
71 
72 template <class T>
74 {
75  for ( size_t i = 0; i < other.nTerms(); i++ ) {
76  _c.push_back( other._c[i] );
77  _term.push_back( other._term[i]->clone() );
78  }
79 }
80 
81 template <class T>
83 {
84  for ( size_t i = 0; i < _c.size(); i++ ) {
85  delete _term[i];
86  }
87 }
88 
89 template <class T>
90 double EvtPdfSum<T>::pdf( const T& p ) const
91 {
92  double ret = 0.;
93  for ( size_t i = 0; i < _c.size(); i++ ) {
94  ret += _c[i] * _term[i]->evaluate( p );
95  }
96  return ret;
97 }
98 
99 /*
100  * Compute the sum integral by summing all term integrals.
101  */
102 
103 template <class T>
105 {
106  EvtValError itg( 0.0, 0.0 );
107  for ( size_t i = 0; i < nTerms(); i++ ) {
108  itg += _c[i] * _term[i]->getItg();
109  }
110  return itg;
111 }
112 
113 template <class T>
115 {
116  EvtValError itg( 0.0, 0.0 );
117  for ( size_t i = 0; i < nTerms(); i++ )
118  itg += _c[i] * _term[i]->getItg( N );
119  return itg;
120 }
121 
122 /*
123  * Sample points randomly according to the sum of PDFs. First throw a random number uniformly
124  * between zero and the value of the sum integral. Using this random number select one
125  * of the PDFs. The generate a random point according to that PDF.
126  */
127 
128 template <class T>
130 {
131  if ( !this->_itg.valueKnown() )
132  this->_itg = compute_integral();
133 
134  double max = this->_itg.value();
135  double rnd = EvtRandom::Flat( 0, max );
136 
137  double sum = 0.;
138  size_t i;
139  for ( i = 0; i < nTerms(); i++ ) {
140  double itg = _term[i]->getItg().value();
141  sum += _c[i] * itg;
142  if ( sum > rnd )
143  break;
144  }
145 
146  return _term[i]->randomPoint();
147 }
148 
149 #endif
EvtPdfSum * clone() const override
Definition: EvtPdfSum.hh:37
vector< EvtPdf< T > * > _term
Definition: EvtPdfSum.hh:69
void addOwnedTerm(double c, std::unique_ptr< EvtPdf< T >> pdf)
Definition: EvtPdfSum.hh:48
T randomPoint() override
Definition: EvtPdfSum.hh:129
size_t nTerms() const
Definition: EvtPdfSum.hh:54
virtual ~EvtPdfSum()
Definition: EvtPdfSum.hh:82
EvtValError compute_integral() const override
Definition: EvtPdfSum.hh:104
static double Flat()
Definition: EvtRandom.cpp:72
void addTerm(double c, const EvtPdf< T > &pdf)
Definition: EvtPdfSum.hh:41
EvtPdf< T > * getPdf(int i) const
Definition: EvtPdfSum.hh:57
vector< double > _c
Definition: EvtPdfSum.hh:68
Definition: EvtPdf.hh:72
double pdf(const T &p) const override
Definition: EvtPdfSum.hh:90
Index other(Index i, Index j)
Definition: EvtCyclic3.cpp:156
double c(int i) const
Definition: EvtPdfSum.hh:56