yoda is hosted by Hepforge, IPPP Durham
YODA - Yet more Objects for Data Analysis 2.0.0
Estimate.h
Go to the documentation of this file.
1// -*- C++ -*-
2//
3// This file is part of YODA -- Yet more Objects for Data Analysis
4// Copyright (C) 2008-2023 The YODA collaboration (see AUTHORS for details)
5//
6#ifndef YODA_Estimate_h
7#define YODA_Estimate_h
8
9#include "YODA/Exceptions.h"
10#include "YODA/Dbn.h"
11#include "YODA/Transformation.h"
14#include <cmath>
15#include <map>
16#include <string>
17#include <regex>
18#include <utility>
19
20namespace YODA {
21
29 class Estimate {
30 public:
31
33
34
36 Estimate() { reset(); }
37
38
42 Estimate(double v, std::map<std::string,std::pair<double,double>>& errors)
43 : _value(v), _error(errors) { }
44
45
47 Estimate(const double v, const std::pair<double,double>& e, const std::string& source = "")
48 : _value(v) { setErr(e, source); }
49
53 Estimate(const Estimate& toCopy) {
54 _value = toCopy._value;
55 _error = toCopy._error;
56 }
57
61 Estimate(Estimate&& toMove) {
62 _value = std::move(toMove._value);
63 _error = std::move(toMove._error);
64 }
65
69 Estimate& operator=(const Estimate& toCopy) noexcept {
70 if (this != &toCopy) {
71 _value = toCopy._value;
72 _error = toCopy._error;
73 }
74 return *this;
75 }
76
80 Estimate& operator=(Estimate&& toMove) noexcept {
81 if (this != &toMove) {
82 _value = std::move(toMove._value);
83 _error = std::move(toMove._error);
84 }
85 return *this;
86 }
87
89
90
92
93
95 Estimate& add(const Estimate& toAdd, const std::string& pat_uncorr="^stat|^uncor" ) {
96 setVal(val() + toAdd.val());
97 std::smatch match;
98 const std::regex re(pat_uncorr);
99 for (const std::string& src : toAdd.sources()) {
100 if (!hasSource(src)) setErr(toAdd.errDownUp(src), src);
101 else if (std::regex_search(src, match, re)) {
102 // treat as uncorrelated between AOs:
103 // add in quadrature
104 const auto [l_dn,l_up] = errDownUp(src);
105 const auto [r_dn,r_up] = toAdd.errDownUp(src);
106 const double new_dn = std::sqrt(l_dn*l_dn + r_dn*r_dn);
107 const double new_up = std::sqrt(l_up*l_up + r_up*r_up);
108 setErr({-new_dn,new_up}, src);
109 }
110 else {
111 // treat as correlated between AOs: add linearly
112 const auto [l_dn,l_up] = errDownUp(src);
113 const auto [r_dn,r_up] = toAdd.errDownUp(src);
114 setErr({l_dn+r_dn, l_up+r_up}, src);
115 }
116 }
117 return *this;
118 }
119 //
120 Estimate& operator+=(const Estimate& toAdd) {
121 return add(toAdd);
122 }
123
125 Estimate& subtract(const Estimate& toSubtract, const std::string& pat_uncorr="^stat|^uncor" ) {
126 setVal(val() - toSubtract.val());
127 std::smatch match;
128 const std::regex re(pat_uncorr);
129 for (const std::string& src : toSubtract.sources()) {
130 if (!hasSource(src)) setErr(toSubtract.errDownUp(src), src);
131 else if (std::regex_search(src, match, re)) {
132 // treat as uncorrelated between AOs: add in quadrature
133 const auto [l_dn,l_up] = errDownUp(src);
134 const auto [r_dn,r_up] = toSubtract.errDownUp(src);
135 const double new_dn = std::sqrt(l_dn*l_dn + r_dn*r_dn);
136 const double new_up = std::sqrt(l_up*l_up + r_up*r_up);
137 setErr({-new_dn,new_up}, src);;
138 }
139 else {
140 // treat as correlated between AOs: add linearly
141 const auto [l_dn,l_up] = errDownUp(src);
142 const auto [r_dn,r_up] = toSubtract.errDownUp(src);
143 setErr({l_dn+r_dn, l_up+r_up}, src);
144 }
145 }
146 return *this;
147 }
148 //
149 Estimate& operator-=(const Estimate& toSubtract) {
150 return subtract(toSubtract);
151 }
152
154
156
157
159 void setValue(const double value) noexcept { _value = value; }
160
162 void setVal(const double val) noexcept { setValue(val); }
163
165 void setErr(const std::pair<double, double> &err, const std::string& source = "") {
166 const std::string& s = Utils::toUpper(source);
167 if (s == "TOTAL")
168 throw UserError("Use empty string for the total uncertainty!");
169 _error[source] = err;
170 }
171
176 void setErr(const double err, const std::string& source = "") {
177 setErr({-fabs(err),fabs(err)}, source);
178 }
179
181 void set(const double val, const std::pair<double, double> &err, const std::string source = "") {
182 setVal(val);
183 setErr(err, source);
184 }
185
186
188 void set(const double val, const double err, const std::string& source = "") {
189 setVal(val);
190 setErr(err, source);
191 }
192
194 void reset() noexcept {
195 _value = std::numeric_limits<double>::quiet_NaN();
196 _error.clear();
197 }
198
199
201 void scale(const double scalefactor) noexcept {
202 _value *= scalefactor;
203 for (auto& item : _error) {
204 item.second = { item.second.first * scalefactor, item.second.second * scalefactor };
205 }
206 }
207
209 void scale(const Trf<1>& trf) {
210 trf.transform(_value, _error);
211 }
212
214 void transform(const Trf<1>& trf) {
215 scale(trf);
216 }
217
219 void renameSource(const std::string& old_label, const std::string& new_label) {
220 if (!hasSource(old_label)) {
221 throw UserError("Error map has no such key: "+old_label);
222 }
223 auto entry = _error.extract(old_label);
224 entry.key() = new_label;
225 _error.insert(std::move(entry));
226 }
227
228
230
231 public:
232
233
235
236
238 double val() const noexcept { return _value; }
239
244 std::pair<double,double> errDownUp(const std::string& source = "") const {
245 const size_t count = _error.count(source);
246 if (!count)
247 throw RangeError("Error map has no such key: "+source);
248 return _error.at(source);
249 }
250
252 std::pair<double,double> err(const std::string& source = "") const {
253 return errDownUp(source);
254 }
255
257 std::pair<double,double> errNegPos(std::string source = "") const {
258 return _downUp2NegPos( errDownUp(source) );
259 }
260
262 double errNeg(const std::string& source = "") const {
263 return errNegPos(source).first;
264 }
265
267 double errPos(const std::string& source = "") const {
268 return errNegPos(source).second;
269 }
270
272 double errDown(const std::string& source = "") const {
273 return errDownUp(source).first;
274 }
275
277 double errUp(const std::string& source = "") const {
278 return errDownUp(source).second;
279 }
280
282 double errAvg(const std::string& source = "") const {
283 return _average(errDownUp(source));
284 }
285
287 std::pair<double,double> relErrDownUp(const std::string& source = "") const {
288 auto [dn,up] = errDownUp(source);
289 dn = _value != 0 ? dn/fabs(_value) : std::numeric_limits<double>::quiet_NaN();
290 up = _value != 0 ? up/fabs(_value) : std::numeric_limits<double>::quiet_NaN();
291 return {dn,up};
292 }
293
295 std::pair<double,double> relErr(const std::string& source = "") const {
296 return relErrDownUp(source);
297 }
298
300 double relErrDown(const std::string& source = "") const {
301 return relErr(source).first;
302 }
303
305 double relErrUp(const std::string& source = "") const {
306 return relErr(source).second;
307 }
308
310 double relErrAvg(const std::string& source = "") const {
311 return _average(relErrDownUp(source));
312 }
313
316 double valMax(const std::string& source = "") const {
317 return val() + errPos(source);
318 }
319
322 double valMin(const std::string& source = "") const {
323 return val() + errNeg(source);
324 }
325
330 std::pair<double,double> quadSum() const noexcept {
331 // interpret as { neg , pos } quad sums
332 std::pair<double, double> ret = { 0., 0. };
333 for (const auto& item : _error) {
334 const auto [dn,up] = _downUp2NegPos(item.second);
335 ret.first += dn*dn;
336 ret.second += up*up;
337 }
338 return { - std::sqrt(ret.first), std::sqrt(ret.second) };
339 }
340
341 double quadSumNeg() const noexcept {
342 return quadSum().first;
343 }
344
345 double quadSumPos() const noexcept {
346 return quadSum().second;
347 }
348
350 double quadSumAvg() const noexcept {
351 return _average(quadSum());
352 }
353
358 std::pair<double,double> totalErr() const noexcept {
359 // check if the user specified the total uncertainty
360 if (_error.count("")) return _downUp2NegPos(_error.at(""));
361 // otherwise return quadrature sum
362 return quadSum();
363 }
364
366 double totalErrNeg() const noexcept {
367 return totalErr().first;
368 }
369
371 double totalErrPos() const noexcept {
372 return totalErr().second;
373 }
374
376 double totalErrAvg() const {
377 return _average(totalErr());
378 }
379
381 double valueErr() const {
382 return fabs(totalErrAvg());
383 }
384
386 std::pair<double,double> relTotalErr() const noexcept {
387 auto [neg,pos] = totalErr();
388 neg = _value != 0 ? neg/fabs(_value) : std::numeric_limits<double>::quiet_NaN();
389 pos = _value != 0 ? pos/fabs(_value) : std::numeric_limits<double>::quiet_NaN();
390 return {neg,pos};
391 }
392
394 double relTotalErrNeg() const noexcept {
395 return relTotalErr().first;
396 }
397
399 double relTotalErrPos() const noexcept {
400 return relTotalErr().second;
401 }
402
404 double relTotalErrAvg() const noexcept {
405 return _average(relTotalErr());
406 }
407
408 std::vector<std::string> sources() const noexcept {
409 std::vector<std::string> keys;
410 for (const auto& item : _error) keys.push_back(item.first);
411 return keys;
412 }
413
414 bool hasSource(const std::string& key) const noexcept {
415 return _error.count(key);
416 }
417
418 size_t numErrs() const noexcept {
419 return _error.size();
420 }
421
423
425
426
427 size_t _lengthContent(bool fixed_length = false) const noexcept {
428 const size_t nErrs = fixed_length? 1 : numErrs();
429 return 2*(nErrs + 1);
430 }
431
432 std::vector<double> _serializeContent(bool fixed_length = false) const noexcept {
433 std::vector<double> rtn;
434 const size_t nErrs = fixed_length? 1 : numErrs();
435 rtn.reserve(2*(nErrs + 1));
436 rtn.push_back(_value);
437 if (fixed_length) {
438 rtn.push_back(1.0);
439 rtn.push_back(totalErrNeg());
440 rtn.push_back(totalErrPos());
441 return rtn;
442 }
443 rtn.push_back((double)_error.size());
444 for (const auto& item : _error) {
445 rtn.push_back(item.second.first);
446 rtn.push_back(item.second.second);
447 }
448 return rtn;
449 }
450
451 void _deserializeContent(const std::vector<double>& data, bool fixed_length = false) {
452
453 if (data.size() < 2)
454 throw UserError("Length of serialized data should be at least 2!");
455
456 if (2*(fixed_length? 1 : data[1]) != (data.size() - 2))
457 throw UserError("Expected "+std::to_string(data[1])+" error pairs!");
458
459 reset();
460 size_t idx = 0;
461 auto itr = data.cbegin();
462 const auto itrEnd = data.cend();
463 while (itr != itrEnd) {
464 if (!idx) {
465 _value = *itr; ++itr; ++itr;
466 }
467 else {
468 std::string name("source" + std::to_string(idx));
469 const double dn = *itr; ++itr;
470 const double up = *itr; ++itr;
471 setErr({dn, up}, name);
472 }
473 ++idx;
474 }
475 if (numErrs() == 1) renameSource("source1", "");
476 }
477
478 std::vector<std::string> serializeSources() const noexcept {
479 return sources();
480 }
481
482 void deserializeSources(const std::vector<std::string>& data) {
483
484 const size_t nErrs = numErrs();
485 if (data.size() != nErrs)
486 throw UserError("Expected " + std::to_string(nErrs) + " error source labels!");
487
488 for (size_t i = 0; i < data.size(); ++i) {
489 const std::string name("source" + std::to_string(i+1));
490 if (!_error.count(name))
491 throw UserError("Key names have already been updated!");
492 renameSource(name, data[i]);
493 }
494
495 }
496
497 // @}
498
499 private:
500
502
503
507 std::pair<double,double> _downUp2NegPos(const std::pair<double,double> &e) const noexcept {
508 const auto [dn,up] = e;
509 if (dn < 0. && up < 0.) {
510 // both negative
511 const double env = std::min(dn, up);
512 return {env, 0.};
513 }
514 else if (dn < 0.) {
515 // dn negative, up positive
516 return {dn,up};
517 }
518 else if (up < 0.) {
519 // up negative, dn positive
520 return {up, dn};
521 }
522 // else: both positive
523 const double env = std::max(dn, up);
524 return {0., env};
525 }
526
528 double _average(const std::pair<double,double> &err) const noexcept {
529 return 0.5*(fabs(err.first) + fabs(err.second));
530 }
531
533
534
536
537
539 double _value;
540
547 std::map<std::string, std::pair<double,double>> _error;
548
550
551 public:
552
554
555
556 std::string _toString() const noexcept {
557 std::string res ="";
558 res += ("value="+ std::to_string(_value));
559 for (const auto& item : _error) {
560 const std::string name = item.first == ""? "user-supplied total " : "";
561 res += (", " + name + "error("+ item.first);
562 res += (")={ "+ std::to_string(item.second.first));
563 res += (", "+ std::to_string(item.second.second)+" }");
564 }
565 return res;
566 }
567
569 };
570
571
573
574
576 inline Estimate operator + (Estimate lhs, const Estimate& rhs) {
577 lhs += rhs;
578 return lhs;
579 }
580
583 lhs += std::move(rhs);
584 return lhs;
585 }
586
588 inline Estimate operator - (Estimate lhs, const Estimate& rhs) {
589 lhs -= rhs;
590 return lhs;
591 }
592
595 lhs -= std::move(rhs);
596 return lhs;
597 }
598
600 inline Estimate divide(const Estimate& numer, const Estimate& denom,
601 const std::string& pat_uncorr="^stat|^uncor") {
602
603 Estimate rtn;
604 if (denom.val()) rtn.setVal(numer.val() / denom.val());
605 const double newVal = rtn.val();
606
607 // get error sources
608 std::vector<std::string> sources = numer.sources();
609 std::vector<std::string> tmp = denom.sources();
610 sources.insert(std::end(sources),
611 std::make_move_iterator(std::begin(tmp)),
612 std::make_move_iterator(std::end(tmp)));
613 sources.erase( std::unique(sources.begin(), sources.end()), sources.end() );
614
615 std::smatch match;
616 const std::regex re(pat_uncorr);
617 for (const std::string& src : sources) {
618 if (std::regex_search(src, match, re)) {
619 // treat as uncorrelated between AOs:
620 // add relative errors in quadrature
621 double n_dn = 0.0, n_up = 0.0;
622 if (numer.hasSource(src)) {
623 n_dn = numer.relErrDown(src);
624 n_up = numer.relErrUp(src);
625 }
626 double d_dn = 0.0, d_up = 0.0;
627 if (denom.hasSource(src)) {
628 d_dn = denom.relErrDown(src);
629 d_up = denom.relErrUp(src);
630 }
631 const double new_dn = fabs(newVal) * std::sqrt(n_dn*n_dn + d_dn*d_dn);
632 const double new_up = fabs(newVal) * std::sqrt(n_up*n_up + d_up*d_up);
633 rtn.setErr({-new_dn,new_up}, src);
634 }
635 else {
636 // treat as correlated between AOs:
637 // work out correlated ratio: R+dR = (N+dN)/(D+dD)
638 double n_dn = numer.val(), n_up = numer.val();
639 if (numer.hasSource(src)) {
640 n_dn += numer.errDown(src);
641 n_up += numer.errUp(src);
642 }
643 double d_dn = denom.val(), d_up = denom.val();
644 if (denom.hasSource(src)) {
645 d_dn += denom.errDown(src);
646 d_up += denom.errUp(src);
647 }
648 double new_dn = std::numeric_limits<double>::quiet_NaN();
649 double new_up = std::numeric_limits<double>::quiet_NaN();
650 if (d_dn) new_dn = n_dn / d_dn - newVal;
651 if (d_up) new_up = n_up / d_up - newVal;
652 rtn.setErr({new_dn, new_up}, src);
653 }
654 }
655
656 return rtn;
657 }
658
660 inline Estimate operator / (const Estimate& numer, const Estimate& denom) {
661 return divide(numer, denom);
662 }
663
665 inline Estimate operator / (Estimate&& numer, const Estimate& denom) {
666 return divide(std::move(numer), denom);
667 }
668
670 inline Estimate operator / (const Estimate& numer, Estimate&& denom) {
671 return divide(numer, std::move(denom));
672 }
673
675 inline Estimate operator / (Estimate&& numer, Estimate&& denom) {
676 return divide(std::move(numer), std::move(denom));
677 }
678
680 inline Estimate efficiency(const Estimate& accepted, const Estimate& total,
681 const std::string& pat_uncorr="^stat|^uncor") {
682
686 const double acc_val = accepted.val();
687 const double tot_val = total.val();
688 if (acc_val > tot_val)
689 throw UserError("Attempt to calculate an efficiency when the numerator is not a subset of the denominator: "
690 + Utils::toStr(acc_val) + " / " + Utils::toStr(tot_val));
691
692 Estimate rtn = divide(accepted, total, pat_uncorr);
693
694 // get error sources
695 std::vector<std::string> sources = accepted.sources();
696 std::vector<std::string> tmp = total.sources();
697 sources.insert(std::end(sources),
698 std::make_move_iterator(std::begin(tmp)),
699 std::make_move_iterator(std::end(tmp)));
700 sources.erase( std::unique(sources.begin(), sources.end()), sources.end() );
701
702 // set binomial error for uncorrelated error sources
703 std::smatch match;
704 const double eff = rtn.val();
705 const std::regex re(pat_uncorr);
706 for (const std::string& src : sources) {
707 double err = std::numeric_limits<double>::quiet_NaN();
708 if (!tot_val) {
709 rtn.setErr({-err,err}, src);
710 continue;
711 }
712 else if (std::regex_search(src, match, re)) {
713 const double acc_err = accepted.relTotalErrAvg();
714 const double tot_err = total.totalErrAvg();
715 err = sqrt(std::abs( ((1-2*eff)*sqr(acc_err) + sqr(eff)*sqr(tot_err)) / sqr(tot_val) ));
716 rtn.setErr({-err,err}, src);
717 continue;
718 }
719 }
720
721 return rtn;
722 }
723
725
726}
727
728#endif
A point estimate (base class for the Estimate)
Definition Estimate.h:29
void scale(const double scalefactor) noexcept
Rescale as if value and uncertainty had been different by factor scalefactor.
Definition Estimate.h:201
std::pair< double, double > relTotalErr() const noexcept
The relative negative/positive total uncertainty on the central value.
Definition Estimate.h:386
Estimate & add(const Estimate &toAdd, const std::string &pat_uncorr="^stat|^uncor")
Add two Estimates.
Definition Estimate.h:95
size_t numErrs() const noexcept
Definition Estimate.h:418
std::pair< double, double > relErrDownUp(const std::string &source="") const
The relative error on the central value.
Definition Estimate.h:287
std::pair< double, double > totalErr() const noexcept
The total uncertainty.
Definition Estimate.h:358
std::pair< double, double > errNegPos(std::string source="") const
The signed negative and positive uncertainty component.
Definition Estimate.h:257
void setErr(const double err, const std::string &source="")
Set a symmetric uncertainty component.
Definition Estimate.h:176
Estimate(double v, std::map< std::string, std::pair< double, double > > &errors)
Constructor to set an Estimate with a pre-filled state.
Definition Estimate.h:42
double relTotalErrNeg() const noexcept
The relative negative total uncertainty on the central value.
Definition Estimate.h:394
double quadSumAvg() const noexcept
The average uncertainty component.
Definition Estimate.h:350
void setErr(const std::pair< double, double > &err, const std::string &source="")
Set a signed uncertainty component.
Definition Estimate.h:165
Estimate & operator+=(const Estimate &toAdd)
Definition Estimate.h:120
double totalErrNeg() const noexcept
The negative total uncertainty.
Definition Estimate.h:366
std::pair< double, double > relErr(const std::string &source="") const
Convenience alias for relErrDownUp.
Definition Estimate.h:295
std::vector< std::string > sources() const noexcept
Definition Estimate.h:408
void transform(const Trf< 1 > &trf)
Generalised transformations with functors.
Definition Estimate.h:214
void setValue(const double value) noexcept
Set the central value of this estimator.
Definition Estimate.h:159
double errDown(const std::string &source="") const
The signed error due to the systematic downward variation.
Definition Estimate.h:272
Estimate & operator=(Estimate &&toMove) noexcept
Definition Estimate.h:80
double errPos(const std::string &source="") const
The signed positive uncertainty component.
Definition Estimate.h:267
void deserializeSources(const std::vector< std::string > &data)
Definition Estimate.h:482
double errAvg(const std::string &source="") const
The average uncertainty component.
Definition Estimate.h:282
double relErrUp(const std::string &source="") const
The relative positive on the central value.
Definition Estimate.h:305
Estimate & operator=(const Estimate &toCopy) noexcept
Definition Estimate.h:69
Estimate & operator-=(const Estimate &toSubtract)
Definition Estimate.h:149
double quadSumPos() const noexcept
Definition Estimate.h:345
void scale(const Trf< 1 > &trf)
Generalised transformations with functors.
Definition Estimate.h:209
double relErrAvg(const std::string &source="") const
The average uncertainty component.
Definition Estimate.h:310
double errUp(const std::string &source="") const
The signed error due to the systematic upward variation.
Definition Estimate.h:277
double val() const noexcept
The central value.
Definition Estimate.h:238
Estimate(Estimate &&toMove)
Definition Estimate.h:61
double totalErrAvg() const
The average total uncertainty.
Definition Estimate.h:376
double totalErrPos() const noexcept
The positive total uncertainty.
Definition Estimate.h:371
Estimate()
Default constructor of a new distribution.
Definition Estimate.h:36
double relTotalErrAvg() const noexcept
The average uncertainty component.
Definition Estimate.h:404
void set(const double val, const std::pair< double, double > &err, const std::string source="")
Set both central value and uncertainty component.
Definition Estimate.h:181
void setVal(const double val) noexcept
Alias for setValue.
Definition Estimate.h:162
std::vector< std::string > serializeSources() const noexcept
Definition Estimate.h:478
void set(const double val, const double err, const std::string &source="")
Set both central value and uncertainty component.
Definition Estimate.h:188
void renameSource(const std::string &old_label, const std::string &new_label)
Replace a source label in the error breakdown.
Definition Estimate.h:219
double valMax(const std::string &source="") const
Definition Estimate.h:316
double valueErr() const
The unsigned average total uncertainty.
Definition Estimate.h:381
double errNeg(const std::string &source="") const
The signed negative uncertainty component.
Definition Estimate.h:262
std::pair< double, double > err(const std::string &source="") const
Convenience alias for errorDownUp(source)
Definition Estimate.h:252
double relTotalErrPos() const noexcept
The relative positive total uncertainty on the central value.
Definition Estimate.h:399
Estimate & subtract(const Estimate &toSubtract, const std::string &pat_uncorr="^stat|^uncor")
Subtract one Estimate from another.
Definition Estimate.h:125
std::pair< double, double > quadSum() const noexcept
Get the quadrature sum of uncertainty components.
Definition Estimate.h:330
double quadSumNeg() const noexcept
Definition Estimate.h:341
Estimate(const Estimate &toCopy)
Definition Estimate.h:53
double valMin(const std::string &source="") const
Definition Estimate.h:322
std::pair< double, double > errDownUp(const std::string &source="") const
The signed absolute error on the central value.
Definition Estimate.h:244
double relErrDown(const std::string &source="") const
The relative negative on the central value.
Definition Estimate.h:300
Estimate(const double v, const std::pair< double, double > &e, const std::string &source="")
Alternative constructor to set an Estimate with value and uncertainty.
Definition Estimate.h:47
bool hasSource(const std::string &key) const noexcept
Definition Estimate.h:414
void reset() noexcept
Reset the internal values.
Definition Estimate.h:194
Error for e.g. use of invalid bin ranges.
Definition Exceptions.h:34
void transform(double &val, Args &&... args) const
Transform value val.
Error for problems introduced outside YODA, to put it nicely.
Definition Exceptions.h:100
Anonymous namespace to limit visibility.
BinnedDbn< DbnN, AxisT... > operator+(BinnedDbn< DbnN, AxisT... > first, BinnedDbn< DbnN, AxisT... > &&second)
Add two BinnedDbn objects.
Definition BinnedDbn.h:1058
BinnedEstimate< AxisT... > operator/(const BinnedDbn< DbnN, AxisT... > &numer, const BinnedDbn< DbnN, AxisT... > &denom)
Definition BinnedDbn.h:1131
NUM sqr(NUM a)
Named number-type squaring operation.
Definition MathUtils.h:216
BinnedEstimate< AxisT... > efficiency(const BinnedDbn< DbnN, AxisT... > &accepted, const BinnedDbn< DbnN, AxisT... > &total)
Calculate a binned efficiency ratio of two BinnedDbn objects.
Definition BinnedDbn.h:1160
BinnedDbn< DbnN, AxisT... > operator-(BinnedDbn< DbnN, AxisT... > first, BinnedDbn< DbnN, AxisT... > &&second)
Subtract one BinnedDbn object from another.
Definition BinnedDbn.h:1074
BinnedEstimate< AxisT... > divide(const BinnedDbn< DbnN, AxisT... > &numer, const BinnedDbn< DbnN, AxisT... > &denom)
Divide two BinnedDbn objects.
Definition BinnedDbn.h:1090