Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooSumL.cxx
Go to the documentation of this file.
1/*
2 * Project: RooFit
3 * Authors:
4 * PB, Patrick Bos, Netherlands eScience Center, p.bos@esciencecenter.nl
5 *
6 * Copyright (c) 2021, CERN
7 *
8 * Redistribution and use in source and binary forms,
9 * with or without modification, are permitted according to the terms
10 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)
11 */
12
14#include <RooAbsData.h>
16
17#include <algorithm> // min, max
18
19namespace RooFit {
20namespace TestStatistics {
21
22/** \class RooSumL
23 * \ingroup Roofitcore
24 *
25 * \brief Likelihood class that sums over multiple -log components
26 *
27 * The likelihood is often a product of components, for instance when fitting simultaneous pdfs, but also when using
28 * subsidiary pdfs. Hence, the negative log likelihood that we, in fact, calculate is often a sum over these components.
29 * This sum is implemented by this class.
30 **/
31
32/// \param[in] pdf Raw pointer to the pdf; will not be cloned in this object.
33/// \param[in] data Raw pointer to the dataset; will not be cloned in this object.
34/// \param[in] components The component likelihoods.
35/// \param extended Set extended term calculation on, off or use Extended::Auto to determine automatically based on the
36/// pdf whether to activate or not. \warning components must be passed with std::move, otherwise it cannot be moved into
37/// the RooSumL because of the unique_ptr! \note The number of events in RooSumL is that of the full dataset. Components
38/// will have their own number of events that may be more relevant.
39RooSumL::RooSumL(RooAbsPdf *pdf, RooAbsData *data, std::vector<std::unique_ptr<RooAbsL>> components,
40 RooAbsL::Extended extended)
41 : RooAbsL(pdf, data, data->numEntries(), components.size(), extended), components_(std::move(components))
42{
43}
44// Developer note on the std::move() warning above:
45//
46// The point here was that you don't want to clone RooAbsL's too much, because they contain clones of the pdf and
47// dataset that may have been mangled for optimization. You probably don't want to be doing that all the time, although
48// it is a premature optimization, since we haven't timed its impact. That is the motivation behind using unique_ptrs
49// for the components. The way the classes are built, the RooSumL doesn't care about what components it gets, so by
50// definition it cannot create them internally, so they have to be passed in somehow. Forcing the user to call the
51// function with a std::move is a way to make them fully realize that their local components will be destroyed and the
52// contents moved into the RooSumL.
53//
54// We could change the type to an rvalue reference to make it clearer from the compiler error that std::move is
55// necessary, instead of the obscure error that you get now. Compare the compiler error messages from these two types:
56//
57//#include <vector>
58//#include <memory>
59//#include <cstdio>
60//
61// struct Clear {
62// Clear(std::vector<std::unique_ptr<int>>&& vec) : vec_(std::move(vec)) {
63// printf("number is %d", *vec_[0]);
64// }
65//
66// std::vector<std::unique_ptr<int>> vec_;
67//};
68//
69// struct Obscure {
70// Obscure(std::vector<std::unique_ptr<int>> vec) : vec_(std::move(vec)) {
71// printf("number is %d", *vec_[0]);
72// }
73//
74// std::vector<std::unique_ptr<int>> vec_;
75//};
76//
77// int main() {
78// std::vector<std::unique_ptr<int>> vec;
79// vec.emplace_back(new int(4));
80// Clear thing(vec);
81// Obscure thingy(vec);
82//}
83
84/// \note Compared to the RooAbsTestStatistic implementation that this was taken from, we leave out Hybrid and
85/// SimComponents interleaving support here. This should be implemented by a calculator (i.e. LikelihoodWrapper or
86/// LikelihoodGradientWrapper derived class), if desired.
88RooSumL::evaluatePartition(Section events, std::size_t components_begin, std::size_t components_end)
89{
90 // Evaluate specified range of owned GOF objects
92
93 // from RooAbsOptTestStatistic::combinedValue (which is virtual, so could be different for non-RooNLLVar!):
94 for (std::size_t ix = components_begin; ix < components_end; ++ix) {
95 ret += components_[ix]->evaluatePartition(events, 0, 0);
96 }
97
98 return ret;
99}
100
101/// \note This function assumes there is only one subsidiary component.
103{
104 // iterate in reverse, because the subsidiary component is usually at the end:
105 for (auto component = components_.rbegin(); component != components_.rend(); ++component) {
106 if (dynamic_cast<RooSubsidiaryL *>((*component).get()) != nullptr) {
107 return (*component)->evaluatePartition({0, 1}, 0, 0);
108 }
109 }
110 return {};
111}
112
113void RooSumL::constOptimizeTestStatistic(RooAbsArg::ConstOpCode opcode, bool doAlsoTrackingOpt)
114{
115 for (auto &component : components_) {
116 component->constOptimizeTestStatistic(opcode, doAlsoTrackingOpt);
117 }
118}
119
120} // namespace TestStatistics
121} // namespace RooFit
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
The Kahan summation is a compensated summation algorithm, which significantly reduces numerical error...
Definition Util.h:122
RooAbsData is the common abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:82
std::vector< std::unique_ptr< RooAbsL > > components_
Definition RooSumL.h:42
ROOT::Math::KahanSum< double > evaluatePartition(Section events, std::size_t components_begin, std::size_t components_end) override
Definition RooSumL.cxx:88
RooSumL(RooAbsPdf *pdf, RooAbsData *data, std::vector< std::unique_ptr< RooAbsL > > components, RooAbsL::Extended extended=RooAbsL::Extended::Auto)
Definition RooSumL.cxx:39
ROOT::Math::KahanSum< double > getSubsidiaryValue()
Definition RooSumL.cxx:102
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition Common.h:18
A part of some range delimited by two fractional points between 0 and 1 (inclusive).
Definition RooAbsL.h:57