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 class EventList;
16 class EventListSIMD;
39
40 template <class eventListType, class... pdfTypes> class SumPDF {
41 private:
42 typedef typename eventListType::value_type eventValueType;
43 std::tuple<pdfTypes...> m_pdfs;
44 const eventListType *m_events = {nullptr};
45
46 public:
48 SumPDF() = default;
49
51 SumPDF(const pdfTypes &...pdfs) : m_pdfs(std::tuple<pdfTypes...>(pdfs...)) {}
52
54
55 double getVal() {
56 std::vector<real_v> tmp(m_events->nBlocks());
57 fill_likelihood(tmp.data());
59 for(unsigned block = 0; block != tmp.size(); ++block) sum += tmp[block];
60 auto rt = -2 * utils::sum_elements(sum());
61 return rt;
62 }
63 void fill_likelihood(real_v *output) {
64 for_each(m_pdfs, [](auto &f) { f.prepare(); });
65 if constexpr(std::is_same<eventListType, EventList>::value) {
66#pragma omp parallel for
67 for(unsigned int i = 0; i < m_events->size(); ++i) {
68 auto prob = ((*this))((*m_events)[i]);
69 auto w = (*m_events)[i].weight();
70 output[i] = w * std::log(prob);
71 }
72 }
73#if ENABLE_AVX
74 if constexpr(std::is_same<eventListType, EventListSIMD>::value) {
75#pragma omp parallel for
76 for(unsigned block = 0; block < m_events->nBlocks(); ++block) { output[block] = m_events->weight(block) * AVX::log(this->operator()(nullptr, block)); }
77 }
78#endif
79 }
80
82 real_v operator()(const real_v *evt, const unsigned block) {
83 real_v prob = 0.;
84 for_each(this->m_pdfs, [&prob, &evt, block](const auto &f) mutable { prob += f(evt, block); });
85 return prob;
86 }
87
88 double operator()(const eventValueType &evt) {
89 double prob = 0;
90 for_each(this->m_pdfs, [&prob, &evt](const auto &f) mutable { prob += f(evt); });
91 return prob;
92 }
93
95 void setEvents(eventListType &events) {
96 m_events = &events;
97 for_each(m_pdfs, [&events](auto &f) { f.setEvents(events); });
98 }
99
101 std::size_t nPDFs() const { return sizeof...(pdfTypes); }
102
104 std::tuple<pdfTypes...> pdfs() const { return m_pdfs; }
105
106 std::function<double(const eventValueType &)> evaluator(const eventListType *events) const {
107 std::vector<double> values(events->size());
108 for_each(this->m_pdfs, [events, &values](const auto &pdf) mutable {
109 auto eval = pdf.evaluator(events);
110 for(unsigned i = 0; i != events->size(); ++i) values[i] += eval(events->at(i));
111 });
113 }
114 KeyedFunctors<double(eventValueType)> componentEvaluator(const eventListType *events) const {
115 KeyedFunctors<double(eventValueType)> view;
116 for_each(this->m_pdfs, [&view, &events](const auto &pdf) mutable {
117 auto eval = pdf.evaluator(events);
118 view.add([eval](const auto &event) { return eval(event); }, type_string(pdf), "");
119 });
120 return view;
121 }
122 };
123
134 template <class eventListType = EventList, class... pdfTypes> auto make_pdf(pdfTypes &&...pdfs) {
135 // return SumPDF<eventListType, pdfTypes...>( std::forward<pdfTypes>( pdfs )... );
136 return SumPDF<eventListType, pdfTypes...>(pdfs...);
137 }
138
139 template <class eventListType = EventList, class... pdfTypes> auto make_likelihood(eventListType &events, pdfTypes &&...pdfs) {
140 auto rt = SumPDF<eventListType, pdfTypes...>(std::forward<pdfTypes>(pdfs)...);
141 rt.setEvents(events);
142 return rt;
143 }
144} // namespace AmpGen
145
146#endif
A pdf that contains one or more terms.
Definition SumPDF.h:40
void setEvents(eventListType &events)
Sets the events to be summed over in the likelihood.
Definition SumPDF.h:95
double getVal()
Returns negative twice the log-likelihood for this PDF and the given dataset.
Definition SumPDF.h:55
real_v operator()(const real_v *evt, const unsigned block)
Returns the probability for the given event.
Definition SumPDF.h:82
std::function< double(const eventValueType &)> evaluator(const eventListType *events) const
Definition SumPDF.h:106
std::tuple< pdfTypes... > pdfs() const
Returns the tuple of PDFs used by this function.
Definition SumPDF.h:104
std::size_t nPDFs() const
Returns the number of PDFs contained by this function.
Definition SumPDF.h:101
SumPDF()=default
Default Constructor.
double operator()(const eventValueType &evt)
Returns the probability for the given event.
Definition SumPDF.h:88
SumPDF(const pdfTypes &...pdfs)
Constructor from a set of PDF functions.
Definition SumPDF.h:51
KeyedFunctors< double(eventValueType)> componentEvaluator(const eventListType *events) const
Definition SumPDF.h:114
void fill_likelihood(real_v *output)
Definition SumPDF.h:63
auto sum_elements(const simd_type &obj)
Definition utils.h:87
AVX::real_v real_v
Definition utils.h:47
std::function< return_type(const contained_type &)> arrayToFunctor(const std::vector< return_type > &values)
Definition Utilities.h:146
auto make_likelihood(eventListType &events, pdfTypes &&...pdfs)
Definition SumPDF.h:139
std::string type_string()
Utility classes for compile-time metaprogramming, such as identifying the types of arguments for gene...
Definition MetaUtils.h:17
std::enable_if_t< I==sizeof...(Tp), void > for_each(std::tuple< Tp... > &, FuncT)
Definition MetaUtils.h:36
PDFWrapper< FCN > make_pdf(const FCN &fcn)
Definition Generator.h:173
Implements Kahan summation for better precision with (repeated) floating point addition.
Definition KahanSum.h:13