Rivet 3.1.9
MathUtils.hh
1// -*- C++ -*-
2#ifndef RIVET_MathUtils_HH
3#define RIVET_MathUtils_HH
4
5#include "Rivet/Math/MathConstants.hh"
6#include <type_traits>
7#include <cassert>
8
9namespace Rivet {
10
11
13
14
16
17
22 template <typename NUM>
23 inline typename std::enable_if<std::is_floating_point<NUM>::value, bool>::type
24 isZero(NUM val, double tolerance=1e-8) {
25 return fabs(val) < tolerance;
26 }
27
32 template <typename NUM>
33 inline typename std::enable_if<std::is_integral<NUM>::value, bool>::type
34 isZero(NUM val, double=1e-5) { //< NB. unused tolerance parameter for ints, still needs a default value!
35 return val == 0;
36 }
37
39 template <typename NUM>
40 inline typename std::enable_if<std::is_floating_point<NUM>::value, bool>::type
41 isNaN(NUM val) { return std::isnan(val); }
42
44 template <typename NUM>
45 inline typename std::enable_if<std::is_floating_point<NUM>::value, bool>::type
46 notNaN(NUM val) { return !std::isnan(val); }
47
53 template <typename N1, typename N2>
54 inline typename std::enable_if<
55 std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value &&
56 (std::is_floating_point<N1>::value || std::is_floating_point<N2>::value), bool>::type
57 fuzzyEquals(N1 a, N2 b, double tolerance=1e-5) {
58 const double absavg = (std::abs(a) + std::abs(b))/2.0;
59 const double absdiff = std::abs(a - b);
60 const bool rtn = (isZero(a) && isZero(b)) || absdiff < tolerance*absavg;
61 return rtn;
62 }
63
68 template <typename N1, typename N2>
69 inline typename std::enable_if<
70 std::is_integral<N1>::value && std::is_integral<N2>::value, bool>::type
71 fuzzyEquals(N1 a, N2 b, double) { //< NB. unused tolerance parameter for ints, still needs a default value!
72 return a == b;
73 }
74
75
79 template <typename N1, typename N2>
80 inline typename std::enable_if<
81 std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value, bool>::type
82 fuzzyGtrEquals(N1 a, N2 b, double tolerance=1e-5) {
83 return a > b || fuzzyEquals(a, b, tolerance);
84 }
85
86
90 template <typename N1, typename N2>
91 inline typename std::enable_if<
92 std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value, bool>::type
93 fuzzyLessEquals(N1 a, N2 b, double tolerance=1e-5) {
94 return a < b || fuzzyEquals(a, b, tolerance);
95 }
96
98 template <typename N1, typename N2>
99 inline typename std::enable_if<
100 std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value,
101 typename std::common_type<N1,N2>::type >::type
102 min(N1 a, N2 b) {
103 return a > b ? b : a;
104 }
105
107 template <typename N1, typename N2>
108 inline typename std::enable_if<
109 std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value,
110 typename std::common_type<N1,N2>::type >::type
111 max(N1 a, N2 b) {
112 return a > b ? a : b;
113 }
114
116
117
119
120
125 enum RangeBoundary { OPEN=0, SOFT=0, CLOSED=1, HARD=1 };
126
130 template <typename N1, typename N2, typename N3>
131 inline typename std::enable_if<
132 std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value && std::is_arithmetic<N3>::value, bool>::type
133 inRange(N1 value, N2 low, N3 high,
134 RangeBoundary lowbound=CLOSED, RangeBoundary highbound=OPEN) {
135 if (lowbound == OPEN && highbound == OPEN) {
136 return (value > low && value < high);
137 } else if (lowbound == OPEN && highbound == CLOSED) {
138 return (value > low && value <= high);
139 } else if (lowbound == CLOSED && highbound == OPEN) {
140 return (value >= low && value < high);
141 } else { // if (lowbound == CLOSED && highbound == CLOSED) {
142 return (value >= low && value <= high);
143 }
144 }
145
150 template <typename N1, typename N2, typename N3>
151 inline typename std::enable_if<
152 std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value && std::is_arithmetic<N3>::value, bool>::type
153 fuzzyInRange(N1 value, N2 low, N3 high,
154 RangeBoundary lowbound=CLOSED, RangeBoundary highbound=OPEN) {
155 if (lowbound == OPEN && highbound == OPEN) {
156 return (value > low && value < high);
157 } else if (lowbound == OPEN && highbound == CLOSED) {
158 return (value > low && fuzzyLessEquals(value, high));
159 } else if (lowbound == CLOSED && highbound == OPEN) {
160 return (fuzzyGtrEquals(value, low) && value < high);
161 } else { // if (lowbound == CLOSED && highbound == CLOSED) {
162 return (fuzzyGtrEquals(value, low) && fuzzyLessEquals(value, high));
163 }
164 }
165
167 template <typename N1, typename N2, typename N3>
168 inline typename std::enable_if<
169 std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value && std::is_arithmetic<N3>::value, bool>::type
170 inRange(N1 value, pair<N2, N3> lowhigh,
171 RangeBoundary lowbound=CLOSED, RangeBoundary highbound=OPEN) {
172 return inRange(value, lowhigh.first, lowhigh.second, lowbound, highbound);
173 }
174
175
176 // Alternative forms, with snake_case names and boundary types in names rather than as args -- from MCUtils
177
181 template <typename N1, typename N2, typename N3>
182 inline typename std::enable_if<
183 std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value && std::is_arithmetic<N3>::value, bool>::type
184 in_range(N1 val, N2 low, N3 high) {
185 return inRange(val, low, high, CLOSED, OPEN);
186 }
187
191 template <typename N1, typename N2, typename N3>
192 inline typename std::enable_if<
193 std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value && std::is_arithmetic<N3>::value, bool>::type
194 in_closed_range(N1 val, N2 low, N3 high) {
195 return inRange(val, low, high, CLOSED, CLOSED);
196 }
197
201 template <typename N1, typename N2, typename N3>
202 inline typename std::enable_if<
203 std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value && std::is_arithmetic<N3>::value, bool>::type
204 in_open_range(N1 val, N2 low, N3 high) {
205 return inRange(val, low, high, OPEN, OPEN);
206 }
207
209
211
212
214
215
217 template <typename NUM>
218 inline typename std::enable_if<std::is_arithmetic<NUM>::value, NUM>::type
219 sqr(NUM a) {
220 return a*a;
221 }
222
227 // template <typename N1, typename N2>
228 template <typename NUM>
229 inline typename std::enable_if<std::is_arithmetic<NUM>::value, NUM>::type
230 //std::common_type<N1, N2>::type
231 add_quad(NUM a, NUM b) {
232 return sqrt(a*a + b*b);
233 }
234
239 // template <typename N1, typename N2>
240 template <typename NUM>
241 inline typename std::enable_if<std::is_arithmetic<NUM>::value, NUM>::type
242 //std::common_type<N1, N2, N3>::type
243 add_quad(NUM a, NUM b, NUM c) {
244 return sqrt(a*a + b*b + c*c);
245 }
246
249 inline double safediv(double num, double den, double fail=0.0) {
250 return (!isZero(den)) ? num/den : fail;
251 }
252
254 template <typename NUM>
255 constexpr inline typename std::enable_if<std::is_arithmetic<NUM>::value, NUM>::type
256 intpow(NUM val, unsigned int exp) {
257 assert(exp >= 0);
258 if (exp == 0) return (NUM) 1;
259 else if (exp == 1) return val;
260 return val * intpow(val, exp-1);
261 }
262
264 template <typename NUM>
265 constexpr inline typename std::enable_if<std::is_arithmetic<NUM>::value, int>::type
266 sign(NUM val) {
267 if (isZero(val)) return ZERO;
268 const int valsign = (val > 0) ? PLUS : MINUS;
269 return valsign;
270 }
271
273
274
276
277
279 inline double cdfBW(double x, double mu, double gamma) {
280 // normalize to (0;1) distribution
281 const double xn = (x - mu)/gamma;
282 return std::atan(xn)/M_PI + 0.5;
283 }
284
286 inline double invcdfBW(double p, double mu, double gamma) {
287 const double xn = std::tan(M_PI*(p-0.5));
288 return gamma*xn + mu;
289 }
290
292
293
295
296
303 inline vector<double> linspace(size_t nbins, double start, double end, bool include_end=true) {
304 assert(nbins > 0);
305 vector<double> rtn;
306 const double interval = (end-start)/static_cast<double>(nbins);
307 for (size_t i = 0; i < nbins; ++i) {
308 rtn.push_back(start + i*interval);
309 }
310 assert(rtn.size() == nbins);
311 if (include_end) rtn.push_back(end); //< exact end, not result of n * interval
312 return rtn;
313 }
314
315
327 inline vector<double> aspace(double step, double start, double end, bool include_end=true, double tol=1e-2) {
328 assert( (end-start)*step > 0); //< ensure the step is going in the direction from start to end
329 vector<double> rtn;
330 double next = start;
331 while (true) {
332 if (next > end) break;
333 rtn.push_back(next);
334 next += step;
335 }
336 if (include_end) {
337 if (end - rtn[rtn.size()-1] > tol*step) rtn.push_back(end);
338 }
339 return rtn;
340 }
341
342
346 inline vector<double> fnspace(size_t nbins, double start, double end,
347 const std::function<double(double)>& fn, const std::function<double(double)>& invfn,
348 bool include_end=true) {
349 // assert(end >= start);
350 assert(nbins > 0);
351 const double pmin = fn(start);
352 const double pmax = fn(end);
353 const vector<double> edges = linspace(nbins, pmin, pmax, false);
354 assert(edges.size() == nbins);
355 vector<double> rtn; rtn.reserve(nbins+1);
356 rtn.push_back(start); //< exact start, not round-tripped
357 for (size_t i = 1; i < edges.size(); ++i) {
358 rtn.push_back(invfn(edges[i]));
359 }
360 assert(rtn.size() == nbins);
361 if (include_end) rtn.push_back(end); //< exact end
362 return rtn;
363 }
364
365
375 inline vector<double> logspace(size_t nbins, double start, double end, bool include_end=true) {
376 return fnspace(nbins, start, end,
377 [](double x){ return std::log(x); },
378 [](double x){ return std::exp(x); },
379 include_end);
380 }
381
382
392 inline vector<double> powspace(size_t nbins, double start, double end, double npow, bool include_end=true) {
393 assert(start >= 0); //< non-integer powers are complex for negative numbers... don't go there
394 return fnspace(nbins, start, end,
395 [&](double x){ return std::pow(x, npow); },
396 [&](double x){ return std::pow(x, 1/npow); },
397 include_end);
398 }
399
411 inline vector<double> powdbnspace(size_t nbins, double start, double end, double npow, bool include_end=true) {
412 assert(start >= 0); //< non-integer powers are complex for negative numbers... don't go there
413 return fnspace(nbins, start, end,
414 [&](double x){ return std::pow(x, npow+1) / (npow+1); },
415 [&](double x){ return std::pow((npow+1) * x, 1/(npow+1)); },
416 include_end);
417 }
418
419
427 inline vector<double> bwdbnspace(size_t nbins, double start, double end, double mu, double gamma, bool include_end=true) {
428 return fnspace(nbins, start, end,
429 [&](double x){ return cdfBW(x, mu, gamma); },
430 [&](double x){ return invcdfBW(x, mu, gamma); },
431 include_end);
432 }
433
434
436 template <typename NUM, typename CONTAINER>
437 inline typename std::enable_if<std::is_arithmetic<NUM>::value && std::is_arithmetic<typename CONTAINER::value_type>::value, int>::type
438 _binIndex(NUM val, const CONTAINER& binedges, bool allow_overflow=false) {
439 if (val < *begin(binedges)) return -1;
440 // CONTAINER::iterator_type itend =
441 if (val >= *(end(binedges)-1)) return allow_overflow ? int(binedges.size())-1 : -1;
442 auto it = std::upper_bound(begin(binedges), end(binedges), val);
443 return std::distance(begin(binedges), --it);
444 }
445
454 template <typename NUM1, typename NUM2>
455 inline typename std::enable_if<std::is_arithmetic<NUM1>::value && std::is_arithmetic<NUM2>::value, int>::type
456 binIndex(NUM1 val, std::initializer_list<NUM2> binedges, bool allow_overflow=false) {
457 return _binIndex(val, binedges, allow_overflow);
458 }
459
468 template <typename NUM, typename CONTAINER>
469 inline typename std::enable_if<std::is_arithmetic<NUM>::value && std::is_arithmetic<typename CONTAINER::value_type>::value, int>::type
470 binIndex(NUM val, const CONTAINER& binedges, bool allow_overflow=false) {
471 return _binIndex(val, binedges, allow_overflow);
472 }
473
475
476
478
479
482 template <typename NUM>
483 inline typename std::enable_if<std::is_arithmetic<NUM>::value, NUM>::type
484 median(const vector<NUM>& sample) {
485 if (sample.empty()) throw RangeError("Can't compute median of an empty set");
486 vector<NUM> tmp = sample;
487 std::sort(tmp.begin(), tmp.end());
488 const size_t imid = tmp.size()/2; // len1->idx0, len2->idx1, len3->idx1, len4->idx2, ...
489 if (sample.size() % 2 == 0) return (tmp.at(imid-1) + tmp.at(imid)) / 2.0;
490 else return tmp.at(imid);
491 }
492
493
496 template <typename NUM>
497 inline typename std::enable_if<std::is_arithmetic<NUM>::value, double>::type
498 mean(const vector<NUM>& sample) {
499 if (sample.empty()) throw RangeError("Can't compute mean of an empty set");
500 double mean = 0.0;
501 for (size_t i = 0; i < sample.size(); ++i) {
502 mean += sample[i];
503 }
504 return mean/sample.size();
505 }
506
507 // Calculate the error on the mean, assuming Poissonian errors
509 template <typename NUM>
510 inline typename std::enable_if<std::is_arithmetic<NUM>::value, double>::type
511 mean_err(const vector<NUM>& sample) {
512 if (sample.empty()) throw RangeError("Can't compute mean_err of an empty set");
513 double mean_e = 0.0;
514 for (size_t i = 0; i < sample.size(); ++i) {
515 mean_e += sqrt(sample[i]);
516 }
517 return mean_e/sample.size();
518 }
519
520
523 template <typename NUM>
524 inline typename std::enable_if<std::is_arithmetic<NUM>::value, double>::type
525 covariance(const vector<NUM>& sample1, const vector<NUM>& sample2) {
526 if (sample1.empty() || sample2.empty()) throw RangeError("Can't compute covariance of an empty set");
527 if (sample1.size() != sample2.size()) throw RangeError("Sizes of samples must be equal for covariance calculation");
528 const double mean1 = mean(sample1);
529 const double mean2 = mean(sample2);
530 const size_t N = sample1.size();
531 double cov = 0.0;
532 for (size_t i = 0; i < N; i++) {
533 const double cov_i = (sample1[i] - mean1)*(sample2[i] - mean2);
534 cov += cov_i;
535 }
536 if (N > 1) return cov/(N-1);
537 else return 0.0;
538 }
539
542 template <typename NUM>
543 inline typename std::enable_if<std::is_arithmetic<NUM>::value, double>::type
544 covariance_err(const vector<NUM>& sample1, const vector<NUM>& sample2) {
545 if (sample1.empty() || sample2.empty()) throw RangeError("Can't compute covariance_err of an empty set");
546 if (sample1.size() != sample2.size()) throw RangeError("Sizes of samples must be equal for covariance_err calculation");
547 const double mean1 = mean(sample1);
548 const double mean2 = mean(sample2);
549 const double mean1_e = mean_err(sample1);
550 const double mean2_e = mean_err(sample2);
551 const size_t N = sample1.size();
552 double cov_e = 0.0;
553 for (size_t i = 0; i < N; i++) {
554 const double cov_i = (sqrt(sample1[i]) - mean1_e)*(sample2[i] - mean2) +
555 (sample1[i] - mean1)*(sqrt(sample2[i]) - mean2_e);
556 cov_e += cov_i;
557 }
558 if (N > 1) return cov_e/(N-1);
559 else return 0.0;
560 }
561
562
565 template <typename NUM>
566 inline typename std::enable_if<std::is_arithmetic<NUM>::value, double>::type
567 correlation(const vector<NUM>& sample1, const vector<NUM>& sample2) {
568 const double cov = covariance(sample1, sample2);
569 const double var1 = covariance(sample1, sample1);
570 const double var2 = covariance(sample2, sample2);
571 const double correlation = cov/sqrt(var1*var2);
572 const double corr_strength = correlation*sqrt(var2/var1);
573 return corr_strength;
574 }
575
578 template <typename NUM>
579 inline typename std::enable_if<std::is_arithmetic<NUM>::value, double>::type
580 correlation_err(const vector<NUM>& sample1, const vector<NUM>& sample2) {
581 const double cov = covariance(sample1, sample2);
582 const double var1 = covariance(sample1, sample1);
583 const double var2 = covariance(sample2, sample2);
584 const double cov_e = covariance_err(sample1, sample2);
585 const double var1_e = covariance_err(sample1, sample1);
586 const double var2_e = covariance_err(sample2, sample2);
587
588 // Calculate the correlation
589 const double correlation = cov/sqrt(var1*var2);
590 // Calculate the error on the correlation
591 const double correlation_err = cov_e/sqrt(var1*var2) -
592 cov/(2*pow(3./2., var1*var2)) * (var1_e * var2 + var1 * var2_e);
593
594 // Calculate the error on the correlation strength
595 const double corr_strength_err = correlation_err*sqrt(var2/var1) +
596 correlation/(2*sqrt(var2/var1)) * (var2_e/var1 - var2*var1_e/pow(2, var2));
597
598 return corr_strength_err;
599 }
600
602
603
605
606
611 inline double _mapAngleM2PITo2Pi(double angle) {
612 double rtn = fmod(angle, TWOPI);
613 if (isZero(rtn)) return 0;
614 assert(rtn >= -TWOPI && rtn <= TWOPI);
615 return rtn;
616 }
617
619 inline double mapAngleMPiToPi(double angle) {
620 double rtn = _mapAngleM2PITo2Pi(angle);
621 if (isZero(rtn)) return 0;
622 if (rtn > PI) rtn -= TWOPI;
623 if (rtn <= -PI) rtn += TWOPI;
624 assert(rtn > -PI && rtn <= PI);
625 return rtn;
626 }
627
629 inline double mapAngle0To2Pi(double angle) {
630 double rtn = _mapAngleM2PITo2Pi(angle);
631 if (isZero(rtn)) return 0;
632 if (rtn < 0) rtn += TWOPI;
633 if (rtn == TWOPI) rtn = 0;
634 assert(rtn >= 0 && rtn < TWOPI);
635 return rtn;
636 }
637
639 inline double mapAngle0ToPi(double angle) {
640 double rtn = fabs(mapAngleMPiToPi(angle));
641 if (isZero(rtn)) return 0;
642 assert(rtn > 0 && rtn <= PI);
643 return rtn;
644 }
645
647 inline double mapAngle(double angle, PhiMapping mapping) {
648 switch (mapping) {
649 case MINUSPI_PLUSPI:
650 return mapAngleMPiToPi(angle);
651 case ZERO_2PI:
652 return mapAngle0To2Pi(angle);
653 case ZERO_PI:
654 return mapAngle0To2Pi(angle);
655 default:
656 throw Rivet::UserError("The specified phi mapping scheme is not implemented");
657 }
658 }
659
661
662
664
665
669 inline double deltaPhi(double phi1, double phi2, bool sign=false) {
670 const double x = mapAngleMPiToPi(phi1 - phi2);
671 return sign ? x : fabs(x);
672 }
673
677 inline double deltaEta(double eta1, double eta2, bool sign=false) {
678 const double x = eta1 - eta2;
679 return sign ? x : fabs(x);
680 }
681
685 inline double deltaRap(double y1, double y2, bool sign=false) {
686 const double x = y1 - y2;
687 return sign? x : fabs(x);
688 }
689
692 inline double deltaR2(double rap1, double phi1, double rap2, double phi2) {
693 const double dphi = deltaPhi(phi1, phi2);
694 return sqr(rap1-rap2) + sqr(dphi);
695 }
696
699 inline double deltaR(double rap1, double phi1, double rap2, double phi2) {
700 return sqrt(deltaR2(rap1, phi1, rap2, phi2));
701 }
702
704 inline double rapidity(double E, double pz) {
705 if (isZero(E - pz)) {
706 throw std::runtime_error("Divergent positive rapidity");
707 return DBL_MAX;
708 }
709 if (isZero(E + pz)) {
710 throw std::runtime_error("Divergent negative rapidity");
711 return -DBL_MAX;
712 }
713 return 0.5*log((E+pz)/(E-pz));
714 }
715
717
718
721 inline double mT(double pT1, double pT2, double dphi) {
722 return sqrt(2*pT1*pT2 * (1 - cos(dphi)) );
723 }
724
725
726}
727
728
729#endif
double p(const ParticleBase &p)
Unbound function access to p.
Definition ParticleBaseUtils.hh:684
Definition MC_Cent_pPb.hh:10
double deltaR(double rap1, double phi1, double rap2, double phi2)
Definition MathUtils.hh:699
double deltaPhi(double phi1, double phi2, bool sign=false)
Calculate the difference between two angles in radians.
Definition MathUtils.hh:669
vector< double > aspace(double step, double start, double end, bool include_end=true, double tol=1e-2)
Make a list of values equally spaced by step between start and end inclusive.
Definition MathUtils.hh:327
double deltaEta(double eta1, double eta2, bool sign=false)
Definition MathUtils.hh:677
std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value &&std::is_arithmetic< N3 >::value, bool >::type in_range(N1 val, N2 low, N3 high)
Boolean function to determine if value is within the given range.
Definition MathUtils.hh:184
PhiMapping
Enum for range of to be mapped into.
Definition MathConstants.hh:49
vector< double > logspace(size_t nbins, double start, double end, bool include_end=true)
Make a list of nbins + 1 values exponentially spaced between start and end inclusive.
Definition MathUtils.hh:375
constexpr std::enable_if< std::is_arithmetic< NUM >::value, NUM >::type intpow(NUM val, unsigned int exp)
A more efficient version of pow for raising numbers to integer powers.
Definition MathUtils.hh:256
std::enable_if< std::is_floating_point< NUM >::value, bool >::type notNaN(NUM val)
Check if a number is non-NaN.
Definition MathUtils.hh:46
double mapAngle0To2Pi(double angle)
Map an angle into the range [0, 2PI).
Definition MathUtils.hh:629
std::enable_if< std::is_arithmetic< NUM >::value, double >::type correlation_err(const vector< NUM > &sample1, const vector< NUM > &sample2)
Definition MathUtils.hh:580
std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value &&std::is_arithmetic< N3 >::value, bool >::type in_closed_range(N1 val, N2 low, N3 high)
Boolean function to determine if value is within the given range.
Definition MathUtils.hh:194
static const double TWOPI
A pre-defined value of .
Definition MathConstants.hh:16
std::enable_if< std::is_arithmetic< NUM >::value, double >::type covariance_err(const vector< NUM > &sample1, const vector< NUM > &sample2)
Definition MathUtils.hh:544
double deltaR2(double rap1, double phi1, double rap2, double phi2)
Definition MathUtils.hh:692
double mT(double pT1, double pT2, double dphi)
Definition MathUtils.hh:721
std::enable_if< std::is_arithmetic< NUM >::value, double >::type mean_err(const vector< NUM > &sample)
Definition MathUtils.hh:511
std::enable_if< std::is_arithmetic< NUM >::value, double >::type covariance(const vector< NUM > &sample1, const vector< NUM > &sample2)
Definition MathUtils.hh:525
std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value, typenamestd::common_type< N1, N2 >::type >::type max(N1 a, N2 b)
Get the maximum of two numbers.
Definition MathUtils.hh:111
std::enable_if< std::is_arithmetic< NUM >::value, NUM >::type add_quad(NUM a, NUM b)
Named number-type addition in quadrature operation.
Definition MathUtils.hh:231
std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value &&std::is_arithmetic< N3 >::value, bool >::type fuzzyInRange(N1 value, N2 low, N3 high, RangeBoundary lowbound=CLOSED, RangeBoundary highbound=OPEN)
Determine if value is in the range low to high, for floating point numbers.
Definition MathUtils.hh:153
std::enable_if< std::is_floating_point< NUM >::value, bool >::type isNaN(NUM val)
Check if a number is NaN.
Definition MathUtils.hh:41
vector< double > fnspace(size_t nbins, double start, double end, const std::function< double(double)> &fn, const std::function< double(double)> &invfn, bool include_end=true)
Definition MathUtils.hh:346
constexpr std::enable_if< std::is_arithmetic< NUM >::value, int >::type sign(NUM val)
Find the sign of a number.
Definition MathUtils.hh:266
std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value, typenamestd::common_type< N1, N2 >::type >::type min(N1 a, N2 b)
Get the minimum of two numbers.
Definition MathUtils.hh:102
double mapAngleMPiToPi(double angle)
Map an angle into the range (-PI, PI].
Definition MathUtils.hh:619
std::enable_if< std::is_arithmetic< NUM1 >::value &&std::is_arithmetic< NUM2 >::value, int >::type binIndex(NUM1 val, std::initializer_list< NUM2 > binedges, bool allow_overflow=false)
Return the bin index of the given value, val, given a vector of bin edges.
Definition MathUtils.hh:456
RangeBoundary
Definition MathUtils.hh:125
std::enable_if< std::is_arithmetic< NUM >::value, double >::type correlation(const vector< NUM > &sample1, const vector< NUM > &sample2)
Definition MathUtils.hh:567
std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value &&std::is_arithmetic< N3 >::value, bool >::type inRange(N1 value, N2 low, N3 high, RangeBoundary lowbound=CLOSED, RangeBoundary highbound=OPEN)
Determine if value is in the range low to high, for floating point numbers.
Definition MathUtils.hh:133
static const double PI
Definition MathConstants.hh:13
std::enable_if< std::is_arithmetic< NUM >::value, double >::type mean(const vector< NUM > &sample)
Definition MathUtils.hh:498
vector< double > powspace(size_t nbins, double start, double end, double npow, bool include_end=true)
Make a list of nbins + 1 values power-law spaced between start and end inclusive.
Definition MathUtils.hh:392
std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value, bool >::type fuzzyLessEquals(N1 a, N2 b, double tolerance=1e-5)
Compare two floating point numbers for <= with a degree of fuzziness.
Definition MathUtils.hh:93
std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value &&(std::is_floating_point< N1 >::value||std::is_floating_point< N2 >::value), bool >::type fuzzyEquals(N1 a, N2 b, double tolerance=1e-5)
Compare two numbers for equality with a degree of fuzziness.
Definition MathUtils.hh:57
double cdfBW(double x, double mu, double gamma)
CDF for the Breit-Wigner distribution.
Definition MathUtils.hh:279
double safediv(double num, double den, double fail=0.0)
Definition MathUtils.hh:249
std::enable_if< std::is_arithmetic< NUM >::value, NUM >::type median(const vector< NUM > &sample)
Definition MathUtils.hh:484
double deltaRap(double y1, double y2, bool sign=false)
Definition MathUtils.hh:685
std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value &&std::is_arithmetic< N3 >::value, bool >::type in_open_range(N1 val, N2 low, N3 high)
Boolean function to determine if value is within the given range.
Definition MathUtils.hh:204
double mapAngle(double angle, PhiMapping mapping)
Map an angle into the enum-specified range.
Definition MathUtils.hh:647
vector< double > linspace(size_t nbins, double start, double end, bool include_end=true)
Make a list of nbins + 1 values equally spaced between start and end inclusive.
Definition MathUtils.hh:303
double mapAngle0ToPi(double angle)
Map an angle into the range [0, PI].
Definition MathUtils.hh:639
std::enable_if< std::is_arithmetic< NUM >::value, NUM >::type sqr(NUM a)
Named number-type squaring operation.
Definition MathUtils.hh:219
double invcdfBW(double p, double mu, double gamma)
Inverse CDF for the Breit-Wigner distribution.
Definition MathUtils.hh:286
std::enable_if< std::is_floating_point< NUM >::value, bool >::type isZero(NUM val, double tolerance=1e-8)
Compare a number to zero.
Definition MathUtils.hh:24
double angle(const Vector2 &a, const Vector2 &b)
Angle (in radians) between two 2-vectors.
Definition Vector2.hh:177
std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value, bool >::type fuzzyGtrEquals(N1 a, N2 b, double tolerance=1e-5)
Compare two numbers for >= with a degree of fuzziness.
Definition MathUtils.hh:82
vector< double > powdbnspace(size_t nbins, double start, double end, double npow, bool include_end=true)
Make a list of nbins + 1 values equally spaced in the CDF of x^n between start and end inclusive.
Definition MathUtils.hh:411
vector< double > bwdbnspace(size_t nbins, double start, double end, double mu, double gamma, bool include_end=true)
Make a list of nbins + 1 values spaced for equal area Breit-Wigner binning between start and end incl...
Definition MathUtils.hh:427
double rapidity(double E, double pz)
Calculate a rapidity value from the supplied energy E and longitudinal momentum pz.
Definition MathUtils.hh:704
Error for e.g. use of invalid bin ranges.
Definition Exceptions.hh:22
Error specialisation for where the problem is between the chair and the computer.
Definition Exceptions.hh:55