Rivet  3.1.0
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 
9 namespace Rivet {
10 
11 
13 
14 
19  template <typename NUM>
20  inline typename std::enable_if<std::is_floating_point<NUM>::value, bool>::type
21  isZero(NUM val, double tolerance=1e-8) {
22  return fabs(val) < tolerance;
23  }
24 
29  template <typename NUM>
30  inline typename std::enable_if<std::is_integral<NUM>::value, bool>::type
31  isZero(NUM val, double=1e-5) { //< NB. unused tolerance parameter for ints, still needs a default value!
32  return val == 0;
33  }
34 
36  template <typename NUM>
37  inline typename std::enable_if<std::is_floating_point<NUM>::value, bool>::type
38  isNaN(NUM val) { return std::isnan(val); }
39 
41  template <typename NUM>
42  inline typename std::enable_if<std::is_floating_point<NUM>::value, bool>::type
43  notNaN(NUM val) { return !std::isnan(val); }
44 
50  template <typename N1, typename N2>
51  inline typename std::enable_if<
52  std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value &&
53  (std::is_floating_point<N1>::value || std::is_floating_point<N2>::value), bool>::type
54  fuzzyEquals(N1 a, N2 b, double tolerance=1e-5) {
55  const double absavg = (std::abs(a) + std::abs(b))/2.0;
56  const double absdiff = std::abs(a - b);
57  const bool rtn = (isZero(a) && isZero(b)) || absdiff < tolerance*absavg;
58  return rtn;
59  }
60 
65  template <typename N1, typename N2>
66  inline typename std::enable_if<
67  std::is_integral<N1>::value && std::is_integral<N2>::value, bool>::type
68  fuzzyEquals(N1 a, N2 b, double) { //< NB. unused tolerance parameter for ints, still needs a default value!
69  return a == b;
70  }
71 
72 
76  template <typename N1, typename N2>
77  inline typename std::enable_if<
78  std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value, bool>::type
79  fuzzyGtrEquals(N1 a, N2 b, double tolerance=1e-5) {
80  return a > b || fuzzyEquals(a, b, tolerance);
81  }
82 
83 
87  template <typename N1, typename N2>
88  inline typename std::enable_if<
89  std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value, bool>::type
90  fuzzyLessEquals(N1 a, N2 b, double tolerance=1e-5) {
91  return a < b || fuzzyEquals(a, b, tolerance);
92  }
93 
95 
96 
98 
99 
104  enum RangeBoundary { OPEN=0, SOFT=0, CLOSED=1, HARD=1 };
105 
109  template <typename N1, typename N2, typename N3>
110  inline typename std::enable_if<
111  std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value && std::is_arithmetic<N3>::value, bool>::type
112  inRange(N1 value, N2 low, N3 high,
113  RangeBoundary lowbound=CLOSED, RangeBoundary highbound=OPEN) {
114  if (lowbound == OPEN && highbound == OPEN) {
115  return (value > low && value < high);
116  } else if (lowbound == OPEN && highbound == CLOSED) {
117  return (value > low && value <= high);
118  } else if (lowbound == CLOSED && highbound == OPEN) {
119  return (value >= low && value < high);
120  } else { // if (lowbound == CLOSED && highbound == CLOSED) {
121  return (value >= low && value <= high);
122  }
123  }
124 
129  template <typename N1, typename N2, typename N3>
130  inline typename std::enable_if<
131  std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value && std::is_arithmetic<N3>::value, bool>::type
132  fuzzyInRange(N1 value, N2 low, N3 high,
133  RangeBoundary lowbound=CLOSED, RangeBoundary highbound=OPEN) {
134  if (lowbound == OPEN && highbound == OPEN) {
135  return (value > low && value < high);
136  } else if (lowbound == OPEN && highbound == CLOSED) {
137  return (value > low && fuzzyLessEquals(value, high));
138  } else if (lowbound == CLOSED && highbound == OPEN) {
139  return (fuzzyGtrEquals(value, low) && value < high);
140  } else { // if (lowbound == CLOSED && highbound == CLOSED) {
141  return (fuzzyGtrEquals(value, low) && fuzzyLessEquals(value, high));
142  }
143  }
144 
146  template <typename N1, typename N2, typename N3>
147  inline typename std::enable_if<
148  std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value && std::is_arithmetic<N3>::value, bool>::type
149  inRange(N1 value, pair<N2, N3> lowhigh,
150  RangeBoundary lowbound=CLOSED, RangeBoundary highbound=OPEN) {
151  return inRange(value, lowhigh.first, lowhigh.second, lowbound, highbound);
152  }
153 
154 
155  // Alternative forms, with snake_case names and boundary types in names rather than as args -- from MCUtils
156 
160  template <typename N1, typename N2, typename N3>
161  inline typename std::enable_if<
162  std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value && std::is_arithmetic<N3>::value, bool>::type
163  in_range(N1 val, N2 low, N3 high) {
164  return inRange(val, low, high, CLOSED, OPEN);
165  }
166 
170  template <typename N1, typename N2, typename N3>
171  inline typename std::enable_if<
172  std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value && std::is_arithmetic<N3>::value, bool>::type
173  in_closed_range(N1 val, N2 low, N3 high) {
174  return inRange(val, low, high, CLOSED, CLOSED);
175  }
176 
180  template <typename N1, typename N2, typename N3>
181  inline typename std::enable_if<
182  std::is_arithmetic<N1>::value && std::is_arithmetic<N2>::value && std::is_arithmetic<N3>::value, bool>::type
183  in_open_range(N1 val, N2 low, N3 high) {
184  return inRange(val, low, high, OPEN, OPEN);
185  }
186 
188 
190 
191 
193 
194 
196  template <typename NUM>
197  inline typename std::enable_if<std::is_arithmetic<NUM>::value, NUM>::type
198  sqr(NUM a) {
199  return a*a;
200  }
201 
206  // template <typename N1, typename N2>
207  template <typename NUM>
208  inline typename std::enable_if<std::is_arithmetic<NUM>::value, NUM>::type
209  //std::common_type<N1, N2>::type
210  add_quad(NUM a, NUM b) {
211  return sqrt(a*a + b*b);
212  }
213 
218  // template <typename N1, typename N2>
219  template <typename NUM>
220  inline typename std::enable_if<std::is_arithmetic<NUM>::value, NUM>::type
221  //std::common_type<N1, N2, N3>::type
222  add_quad(NUM a, NUM b, NUM c) {
223  return sqrt(a*a + b*b + c*c);
224  }
225 
228  inline double safediv(double num, double den, double fail=0.0) {
229  return (!isZero(den)) ? num/den : fail;
230  }
231 
233  template <typename NUM>
234  inline typename std::enable_if<std::is_arithmetic<NUM>::value, NUM>::type
235  intpow(NUM val, unsigned int exp) {
236  assert(exp >= 0);
237  if (exp == 0) return (NUM) 1;
238  else if (exp == 1) return val;
239  return val * intpow(val, exp-1);
240  }
241 
243  template <typename NUM>
244  inline typename std::enable_if<std::is_arithmetic<NUM>::value, int>::type
245  sign(NUM val) {
246  if (isZero(val)) return ZERO;
247  const int valsign = (val > 0) ? PLUS : MINUS;
248  return valsign;
249  }
250 
252 
253 
255 
256 
258  inline double cdfBW(double x, double mu, double gamma) {
259  // normalize to (0;1) distribution
260  const double xn = (x - mu)/gamma;
261  return std::atan(xn)/M_PI + 0.5;
262  }
263 
265  inline double invcdfBW(double p, double mu, double gamma) {
266  const double xn = std::tan(M_PI*(p-0.5));
267  return gamma*xn + mu;
268  }
269 
271 
272 
274 
275 
280  inline vector<double> linspace(size_t nbins, double start, double end, bool include_end=true) {
281  assert(end >= start);
282  assert(nbins > 0);
283  vector<double> rtn;
284  const double interval = (end-start)/static_cast<double>(nbins);
285  for (size_t i = 0; i < nbins; ++i) {
286  rtn.push_back(start + i*interval);
287  }
288  assert(rtn.size() == nbins);
289  if (include_end) rtn.push_back(end); //< exact end, not result of n * interval
290  return rtn;
291  }
292 
293 
299  inline vector<double> logspace(size_t nbins, double start, double end, bool include_end=true) {
300  assert(end >= start);
301  assert(start > 0);
302  assert(nbins > 0);
303  const double logstart = std::log(start);
304  const double logend = std::log(end);
305  const vector<double> logvals = linspace(nbins, logstart, logend, false);
306  assert(logvals.size() == nbins);
307  vector<double> rtn; rtn.reserve(nbins+1);
308  rtn.push_back(start); //< exact start, not exp(log(start))
309  for (size_t i = 1; i < logvals.size(); ++i) {
310  rtn.push_back(std::exp(logvals[i]));
311  }
312  assert(rtn.size() == nbins);
313  if (include_end) rtn.push_back(end); //< exact end, not exp(n * loginterval)
314  return rtn;
315  }
316 
317 
319 
320 
328  inline vector<double> bwspace(size_t nbins, double start, double end, double mu, double gamma) {
329  assert(end >= start);
330  assert(nbins > 0);
331  const double pmin = cdfBW(start, mu, gamma);
332  const double pmax = cdfBW(end, mu, gamma);
333  const vector<double> edges = linspace(nbins, pmin, pmax);
334  assert(edges.size() == nbins+1);
335  vector<double> rtn;
336  for (double edge : edges) {
337  rtn.push_back(invcdfBW(edge, mu, gamma));
338  }
339  assert(rtn.size() == nbins+1);
340  return rtn;
341  }
342 
343 
345  template <typename NUM, typename CONTAINER>
346  inline typename std::enable_if<std::is_arithmetic<NUM>::value && std::is_arithmetic<typename CONTAINER::value_type>::value, int>::type
347  _binIndex(NUM val, const CONTAINER& binedges, bool allow_overflow=false) {
348  if (val < *begin(binedges)) return -1;
349  // CONTAINER::iterator_type itend =
350  if (val >= *(end(binedges)-1)) return allow_overflow ? int(binedges.size())-1 : -1;
351  auto it = std::upper_bound(begin(binedges), end(binedges), val);
352  return std::distance(begin(binedges), --it);
353  }
354 
363  template <typename NUM1, typename NUM2>
364  inline typename std::enable_if<std::is_arithmetic<NUM1>::value && std::is_arithmetic<NUM2>::value, int>::type
365  binIndex(NUM1 val, std::initializer_list<NUM2> binedges, bool allow_overflow=false) {
366  return _binIndex(val, binedges, allow_overflow);
367  }
368 
377  template <typename NUM, typename CONTAINER>
378  inline typename std::enable_if<std::is_arithmetic<NUM>::value && std::is_arithmetic<typename CONTAINER::value_type>::value, int>::type
379  binIndex(NUM val, const CONTAINER& binedges, bool allow_overflow=false) {
380  return _binIndex(val, binedges, allow_overflow);
381  }
382 
384 
385 
387 
388 
391  template <typename NUM>
392  inline typename std::enable_if<std::is_arithmetic<NUM>::value, NUM>::type
393  median(const vector<NUM>& sample) {
394  if (sample.empty()) throw RangeError("Can't compute median of an empty set");
395  vector<NUM> tmp = sample;
396  std::sort(tmp.begin(), tmp.end());
397  const size_t imid = tmp.size()/2; // len1->idx0, len2->idx1, len3->idx1, len4->idx2, ...
398  if (sample.size() % 2 == 0) return (tmp.at(imid-1) + tmp.at(imid)) / 2.0;
399  else return tmp.at(imid);
400  }
401 
402 
405  template <typename NUM>
406  inline typename std::enable_if<std::is_arithmetic<NUM>::value, double>::type
407  mean(const vector<NUM>& sample) {
408  if (sample.empty()) throw RangeError("Can't compute mean of an empty set");
409  double mean = 0.0;
410  for (size_t i = 0; i < sample.size(); ++i) {
411  mean += sample[i];
412  }
413  return mean/sample.size();
414  }
415 
416  // Calculate the error on the mean, assuming Poissonian errors
418  template <typename NUM>
419  inline typename std::enable_if<std::is_arithmetic<NUM>::value, double>::type
420  mean_err(const vector<NUM>& sample) {
421  if (sample.empty()) throw RangeError("Can't compute mean_err of an empty set");
422  double mean_e = 0.0;
423  for (size_t i = 0; i < sample.size(); ++i) {
424  mean_e += sqrt(sample[i]);
425  }
426  return mean_e/sample.size();
427  }
428 
429 
432  template <typename NUM>
433  inline typename std::enable_if<std::is_arithmetic<NUM>::value, double>::type
434  covariance(const vector<NUM>& sample1, const vector<NUM>& sample2) {
435  if (sample1.empty() || sample2.empty()) throw RangeError("Can't compute covariance of an empty set");
436  if (sample1.size() != sample2.size()) throw RangeError("Sizes of samples must be equal for covariance calculation");
437  const double mean1 = mean(sample1);
438  const double mean2 = mean(sample2);
439  const size_t N = sample1.size();
440  double cov = 0.0;
441  for (size_t i = 0; i < N; i++) {
442  const double cov_i = (sample1[i] - mean1)*(sample2[i] - mean2);
443  cov += cov_i;
444  }
445  if (N > 1) return cov/(N-1);
446  else return 0.0;
447  }
448 
451  template <typename NUM>
452  inline typename std::enable_if<std::is_arithmetic<NUM>::value, double>::type
453  covariance_err(const vector<NUM>& sample1, const vector<NUM>& sample2) {
454  if (sample1.empty() || sample2.empty()) throw RangeError("Can't compute covariance_err of an empty set");
455  if (sample1.size() != sample2.size()) throw RangeError("Sizes of samples must be equal for covariance_err calculation");
456  const double mean1 = mean(sample1);
457  const double mean2 = mean(sample2);
458  const double mean1_e = mean_err(sample1);
459  const double mean2_e = mean_err(sample2);
460  const size_t N = sample1.size();
461  double cov_e = 0.0;
462  for (size_t i = 0; i < N; i++) {
463  const double cov_i = (sqrt(sample1[i]) - mean1_e)*(sample2[i] - mean2) +
464  (sample1[i] - mean1)*(sqrt(sample2[i]) - mean2_e);
465  cov_e += cov_i;
466  }
467  if (N > 1) return cov_e/(N-1);
468  else return 0.0;
469  }
470 
471 
474  template <typename NUM>
475  inline typename std::enable_if<std::is_arithmetic<NUM>::value, double>::type
476  correlation(const vector<NUM>& sample1, const vector<NUM>& sample2) {
477  const double cov = covariance(sample1, sample2);
478  const double var1 = covariance(sample1, sample1);
479  const double var2 = covariance(sample2, sample2);
480  const double correlation = cov/sqrt(var1*var2);
481  const double corr_strength = correlation*sqrt(var2/var1);
482  return corr_strength;
483  }
484 
487  template <typename NUM>
488  inline typename std::enable_if<std::is_arithmetic<NUM>::value, double>::type
489  correlation_err(const vector<NUM>& sample1, const vector<NUM>& sample2) {
490  const double cov = covariance(sample1, sample2);
491  const double var1 = covariance(sample1, sample1);
492  const double var2 = covariance(sample2, sample2);
493  const double cov_e = covariance_err(sample1, sample2);
494  const double var1_e = covariance_err(sample1, sample1);
495  const double var2_e = covariance_err(sample2, sample2);
496 
497  // Calculate the correlation
498  const double correlation = cov/sqrt(var1*var2);
499  // Calculate the error on the correlation
500  const double correlation_err = cov_e/sqrt(var1*var2) -
501  cov/(2*pow(3./2., var1*var2)) * (var1_e * var2 + var1 * var2_e);
502 
503  // Calculate the error on the correlation strength
504  const double corr_strength_err = correlation_err*sqrt(var2/var1) +
505  correlation/(2*sqrt(var2/var1)) * (var2_e/var1 - var2*var1_e/pow(2, var2));
506 
507  return corr_strength_err;
508  }
509 
511 
512 
514 
515 
520  inline double _mapAngleM2PITo2Pi(double angle) {
521  double rtn = fmod(angle, TWOPI);
522  if (isZero(rtn)) return 0;
523  assert(rtn >= -TWOPI && rtn <= TWOPI);
524  return rtn;
525  }
526 
528  inline double mapAngleMPiToPi(double angle) {
529  double rtn = _mapAngleM2PITo2Pi(angle);
530  if (isZero(rtn)) return 0;
531  if (rtn > PI) rtn -= TWOPI;
532  if (rtn <= -PI) rtn += TWOPI;
533  assert(rtn > -PI && rtn <= PI);
534  return rtn;
535  }
536 
538  inline double mapAngle0To2Pi(double angle) {
539  double rtn = _mapAngleM2PITo2Pi(angle);
540  if (isZero(rtn)) return 0;
541  if (rtn < 0) rtn += TWOPI;
542  if (rtn == TWOPI) rtn = 0;
543  assert(rtn >= 0 && rtn < TWOPI);
544  return rtn;
545  }
546 
548  inline double mapAngle0ToPi(double angle) {
549  double rtn = fabs(mapAngleMPiToPi(angle));
550  if (isZero(rtn)) return 0;
551  assert(rtn > 0 && rtn <= PI);
552  return rtn;
553  }
554 
556  inline double mapAngle(double angle, PhiMapping mapping) {
557  switch (mapping) {
558  case MINUSPI_PLUSPI:
559  return mapAngleMPiToPi(angle);
560  case ZERO_2PI:
561  return mapAngle0To2Pi(angle);
562  case ZERO_PI:
563  return mapAngle0To2Pi(angle);
564  default:
565  throw Rivet::UserError("The specified phi mapping scheme is not implemented");
566  }
567  }
568 
570 
571 
573 
574 
578  inline double deltaPhi(double phi1, double phi2, bool sign=false) {
579  const double x = mapAngleMPiToPi(phi1 - phi2);
580  return sign ? x : fabs(x);
581  }
582 
586  inline double deltaEta(double eta1, double eta2, bool sign=false) {
587  const double x = eta1 - eta2;
588  return sign ? x : fabs(x);
589  }
590 
594  inline double deltaRap(double y1, double y2, bool sign=false) {
595  const double x = y1 - y2;
596  return sign? x : fabs(x);
597  }
598 
601  inline double deltaR2(double rap1, double phi1, double rap2, double phi2) {
602  const double dphi = deltaPhi(phi1, phi2);
603  return sqr(rap1-rap2) + sqr(dphi);
604  }
605 
608  inline double deltaR(double rap1, double phi1, double rap2, double phi2) {
609  return sqrt(deltaR2(rap1, phi1, rap2, phi2));
610  }
611 
613  inline double rapidity(double E, double pz) {
614  if (isZero(E - pz)) {
615  throw std::runtime_error("Divergent positive rapidity");
616  return DBL_MAX;
617  }
618  if (isZero(E + pz)) {
619  throw std::runtime_error("Divergent negative rapidity");
620  return -DBL_MAX;
621  }
622  return 0.5*log((E+pz)/(E-pz));
623  }
624 
626 
627 
630  inline double mT(double pT1, double pT2, double dphi) {
631  return sqrt(2*pT1*pT2 * (1 - cos(dphi)) );
632  }
633 
634 
635 }
636 
637 
638 #endif
Definition: MC_Cent_pPb.hh:10
std::enable_if< std::is_floating_point< NUM >::value, bool >::type notNaN(NUM val)
Check if a number is non-NaN.
Definition: MathUtils.hh:43
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:365
double rapidity(double E, double pz)
Calculate a rapidity value from the supplied energy E and longitudinal momentum pz.
Definition: MathUtils.hh:613
double mapAngleMPiToPi(double angle)
Map an angle into the range (-PI, PI].
Definition: MathUtils.hh:528
double safediv(double num, double den, double fail=0.0)
Definition: MathUtils.hh:228
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:163
static const double PI
Definition: MathConstants.hh:13
Error specialisation for where the problem is between the chair and the computer. ...
Definition: Exceptions.hh:55
std::enable_if< std::is_floating_point< NUM >::value, bool >::type isNaN(NUM val)
Check if a number is NaN.
Definition: MathUtils.hh:38
double mapAngle(double angle, PhiMapping mapping)
Map an angle into the enum-specified range.
Definition: MathUtils.hh:556
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:210
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:280
double cdfBW(double x, double mu, double gamma)
CDF for the Breit-Wigner distribution.
Definition: MathUtils.hh:258
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:299
double deltaEta(double eta1, double eta2, bool sign=false)
Definition: MathUtils.hh:586
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:183
PhiMapping
Enum for range of to be mapped into.
Definition: MathConstants.hh:49
std::enable_if< std::is_arithmetic< NUM >::value, double >::type covariance(const vector< NUM > &sample1, const vector< NUM > &sample2)
Definition: MathUtils.hh:434
double deltaPhi(double phi1, double phi2, bool sign=false)
Calculate the difference between two angles in radians.
Definition: MathUtils.hh:578
std::enable_if< std::is_arithmetic< NUM >::value, double >::type mean_err(const vector< NUM > &sample)
Definition: MathUtils.hh:420
double angle(const Vector3 &a, const Vector3 &b)
Angle (in radians) between two 3-vectors.
Definition: Vector3.hh:294
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:112
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:173
double mT(double pT1, double pT2, double dphi)
Definition: MathUtils.hh:630
double invcdfBW(double p, double mu, double gamma)
Inverse CDF for the Breit-Wigner distribution.
Definition: MathUtils.hh:265
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:54
static const double TWOPI
A pre-defined value of .
Definition: MathConstants.hh:16
double deltaRap(double y1, double y2, bool sign=false)
Definition: MathUtils.hh:594
double deltaR2(double rap1, double phi1, double rap2, double phi2)
Definition: MathUtils.hh:601
double deltaR(double rap1, double phi1, double rap2, double phi2)
Definition: MathUtils.hh:608
RangeBoundary
Definition: MathUtils.hh:104
double mapAngle0To2Pi(double angle)
Map an angle into the range [0, 2PI).
Definition: MathUtils.hh:538
double mapAngle0ToPi(double angle)
Map an angle into the range [0, PI].
Definition: MathUtils.hh:548
std::enable_if< std::is_arithmetic< NUM >::value, double >::type covariance_err(const vector< NUM > &sample1, const vector< NUM > &sample2)
Definition: MathUtils.hh:453
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:21
std::enable_if< std::is_arithmetic< NUM >::value, double >::type correlation_err(const vector< NUM > &sample1, const vector< NUM > &sample2)
Definition: MathUtils.hh:489
std::enable_if< std::is_arithmetic< NUM >::value, NUM >::type median(const vector< NUM > &sample)
Definition: MathUtils.hh:393
std::enable_if< std::is_arithmetic< NUM >::value, double >::type mean(const vector< NUM > &sample)
Definition: MathUtils.hh:407
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:79
std::enable_if< std::is_arithmetic< NUM >::value, NUM >::type sqr(NUM a)
Named number-type squaring operation.
Definition: MathUtils.hh:198
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:235
Error for e.g. use of invalid bin ranges.
Definition: Exceptions.hh:22
vector< double > bwspace(size_t nbins, double start, double end, double mu, double gamma)
Make a list of nbins + 1 values spaced for equal area Breit-Wigner binning between start and end incl...
Definition: MathUtils.hh:328
std::enable_if< std::is_arithmetic< NUM >::value, int >::type sign(NUM val)
Find the sign of a number.
Definition: MathUtils.hh:245
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:132
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:90
std::enable_if< std::is_arithmetic< NUM >::value, double >::type correlation(const vector< NUM > &sample1, const vector< NUM > &sample2)
Definition: MathUtils.hh:476