AmpGen 2.1
Loading...
Searching...
No Matches
SumPDF.h
Go to the documentation of this file.
1#ifndef AMPGEN_SUMPDF_H
2#define AMPGEN_SUMPDF_H
3
4#include "AmpGen/MetaUtils.h"
5#include "AmpGen/MsgService.h"
8#include "AmpGen/KahanSum.h"
9#include <tuple>
10#if ENABLE_AVX
11 #include "AmpGen/simd/utils.h"
12#endif
13
14namespace AmpGen
15{
16 class EventList;
17 class EventListSIMD;
40
41
42 template <class eventListType, class... pdfTypes>
43 class SumPDF
44 {
45 private:
46 typedef typename eventListType::value_type eventValueType;
47 std::tuple<pdfTypes...> m_pdfs;
48 const eventListType* m_events = {nullptr};
49
50 public:
52 SumPDF() = default;
53
55 SumPDF( const pdfTypes&... pdfs ) : m_pdfs( std::tuple<pdfTypes...>( pdfs... ) ) {}
56
58
59 double getVal()
60 {
61 std::vector<real_v> tmp( m_events->nBlocks() );
62 fill_likelihood( tmp.data() );
64 for(unsigned block = 0 ; block != tmp.size(); ++block ) sum += tmp[block];
65 auto rt = -2 * utils::sum_elements(sum());
66 return rt;
67 }
68 void fill_likelihood( real_v* output )
69 {
70 for_each( m_pdfs, []( auto& f ) { f.prepare(); } );
71 if constexpr( std::is_same<eventListType,EventList>::value )
72 {
73 #pragma omp parallel for
74 for ( unsigned int i = 0; i < m_events->size(); ++i ) {
75 auto prob = ((*this))(( *m_events)[i] );
76 auto w = (*m_events)[i].weight();
77 output[i] = w * std::log(prob);
78 }
79 }
80 #if ENABLE_AVX
81 if constexpr( std::is_same<eventListType, EventListSIMD>::value )
82 {
83 #pragma omp parallel for
84 for( unsigned block = 0 ; block < m_events->nBlocks(); ++block )
85 {
86 output[block] = m_events->weight(block) * AVX::log(this->operator()(nullptr, block));
87 }
88 }
89 #endif
90 }
91
93 real_v operator()( const real_v* evt , const unsigned block)
94 {
95 real_v prob = 0.;
96 for_each( this->m_pdfs, [&prob, &evt, block]( const auto& f ) mutable { prob += f(evt, block); } );
97 return prob;
98 }
99
100 double operator()( const eventValueType& evt )
101 {
102 double prob = 0;
103 for_each( this->m_pdfs, [&prob, &evt]( const auto& f ) mutable { prob += f(evt); } );
104 return prob;
105 }
106
108 void setEvents( eventListType& events )
109 {
110 m_events = &events;
111 for_each( m_pdfs, [&events]( auto& f ) { f.setEvents( events ); } );
112 }
113
115 std::size_t nPDFs() const { return sizeof...(pdfTypes); }
116
118 std::tuple<pdfTypes...> pdfs() const { return m_pdfs; }
119
120 std::function<double(const eventValueType&)> evaluator(const eventListType* events) const
121 {
122 std::vector<double> values( events->size() );
123 for_each( this->m_pdfs, [events, &values](const auto& pdf ) mutable {
124 auto eval = pdf.evaluator(events);
125 for( unsigned i = 0; i != events->size(); ++i ) values[i] += eval( events->at(i) );
126 } );
128 }
129 KeyedFunctors<double(eventValueType)> componentEvaluator(const eventListType* events) const
130 {
131 KeyedFunctors<double(eventValueType)> view;
132 for_each( this->m_pdfs, [&view, &events]( const auto& pdf) mutable {
133 auto eval = pdf.evaluator(events);
134 view.add([eval](const auto& event){ return eval(event) ; } , type_string(pdf), "" );
135 } );
136 return view;
137 }
138 };
139
150 template <class eventListType = EventList, class... pdfTypes>
151 auto make_pdf( pdfTypes&&... pdfs )
152 {
153 //return SumPDF<eventListType, pdfTypes...>( std::forward<pdfTypes>( pdfs )... );
154 return SumPDF<eventListType, pdfTypes...>( pdfs... );
155 }
156
157 template <class eventListType = EventList, class... pdfTypes>
158 auto make_likelihood( eventListType& events, pdfTypes&&... pdfs )
159 {
160 auto rt = SumPDF<eventListType, pdfTypes...>( std::forward<pdfTypes>( pdfs )... );
161 rt.setEvents(events);
162 return rt;
163 }
164} // namespace AmpGen
165
166#endif
A pdf that contains one or more terms.
Definition SumPDF.h:44
void setEvents(eventListType &events)
Sets the events to be summed over in the likelihood.
Definition SumPDF.h:108
double getVal()
Returns negative twice the log-likelihood for this PDF and the given dataset.
Definition SumPDF.h:59
real_v operator()(const real_v *evt, const unsigned block)
Returns the probability for the given event.
Definition SumPDF.h:93
std::function< double(const eventValueType &)> evaluator(const eventListType *events) const
Definition SumPDF.h:120
std::tuple< pdfTypes... > pdfs() const
Returns the tuple of PDFs used by this function.
Definition SumPDF.h:118
SumPDF(const pdfTypes &... pdfs)
Constructor from a set of PDF functions.
Definition SumPDF.h:55
std::size_t nPDFs() const
Returns the number of PDFs contained by this function.
Definition SumPDF.h:115
SumPDF()=default
Default Constructor.
double operator()(const eventValueType &evt)
Returns the probability for the given event.
Definition SumPDF.h:100
KeyedFunctors< double(eventValueType)> componentEvaluator(const eventListType *events) const
Definition SumPDF.h:129
void fill_likelihood(real_v *output)
Definition SumPDF.h:68
auto sum_elements(const simd_type &obj)
Definition utils.h:79
AVX::real_v real_v
Definition utils.h:46
std::function< return_type(const contained_type &)> arrayToFunctor(const std::vector< return_type > &values)
Definition Utilities.h:169
std::string type_string()
Utility classes for compile-time metaprogramming, such as identifying the types of arguments for gene...
Definition MetaUtils.h:18
auto make_likelihood(eventListType &events, pdfTypes &&... pdfs)
Definition SumPDF.h:158
std::enable_if_t< I==sizeof...(Tp), void > for_each(std::tuple< Tp... > &, FuncT)
Definition MetaUtils.h:39
PDFWrapper< FCN > make_pdf(const FCN &fcn)
Definition Generator.h:195
Implements Kahan summation for better precision with (repeated) floating point addition.
Definition KahanSum.h:14