1 /*******************************************************************************
2 * Project: BaBar detector at the SLAC PEP-II B-factory
4 * File: $Id: EvtPdfSum.hh,v 1.10 2009/02/19 03:22:30 ryd Exp $
5 * Author: Alexei Dvoretskii, dvoretsk@slac.stanford.edu, 2001-2002
7 * Copyright (C) 2002 Caltech
8 *******************************************************************************/
10 // Sum of PDF functions.
12 #ifndef EVT_PDF_SUM_HH
13 #define EVT_PDF_SUM_HH
18 #include "EvtGenBase/EvtPdf.hh"
21 class EvtPdfSum : public EvtPdf<T> {
25 EvtPdfSum(const EvtPdfSum<T>& other);
27 virtual EvtPdf<T>* clone() const { return new EvtPdfSum(*this); }
30 // Manipulate terms and coefficients
32 void addTerm(double c,const EvtPdf<T>& pdf)
33 { assert(c >= 0.); _c.push_back(c); _term.push_back(pdf.clone()); }
35 void addOwnedTerm(double c, EvtPdf<T>* pdf)
36 { _c.push_back(c); _term.push_back(pdf); }
38 size_t nTerms() const { return _term.size(); } // number of terms
40 inline double c(int i) const { return _c[i]; }
41 inline EvtPdf<T>* getPdf(int i) const { return _term[i]; }
46 virtual EvtValError compute_integral() const;
47 virtual EvtValError compute_integral(int N) const;
48 virtual T randomPoint();
52 virtual double pdf(const T& p) const;
54 vector<double> _c; // coefficients
55 vector<EvtPdf<T>*> _term; // pointers to pdfs
60 EvtPdfSum<T>::EvtPdfSum(const EvtPdfSum<T>& other)
63 for(size_t i = 0; i < other.nTerms(); i++) {
64 _c.push_back(other._c[i]);
65 _term.push_back(other._term[i]->clone());
70 EvtPdfSum<T>::~EvtPdfSum()
72 for(size_t i = 0; i < _c.size(); i++) {
79 double EvtPdfSum<T>::pdf(const T& p) const
82 for(size_t i=0; i < _c.size(); i++) {
83 ret += _c[i] * _term[i]->evaluate(p);
89 * Compute the sum integral by summing all term integrals.
93 EvtValError EvtPdfSum<T>::compute_integral() const
95 EvtValError itg(0.0,0.0);
96 for(size_t i=0;i<nTerms();i++) {
97 itg += _c[i]*_term[i]->getItg();
103 EvtValError EvtPdfSum<T>::compute_integral(int N) const
105 EvtValError itg(0.0,0.0);
106 for(size_t i=0;i<nTerms();i++) itg += _c[i]*_term[i]->getItg(N);
112 * Sample points randomly according to the sum of PDFs. First throw a random number uniformly
113 * between zero and the value of the sum integral. Using this random number select one
114 * of the PDFs. The generate a random point according to that PDF.
118 T EvtPdfSum<T>::randomPoint()
120 if(!this->_itg.valueKnown()) this->_itg = compute_integral();
122 double max = this->_itg.value();
123 double rnd = EvtRandom::Flat(0,max);
127 for(i = 0; i < nTerms(); i++) {
128 double itg = _term[i]->getItg().value();
133 return _term[i]->randomPoint();