2#ifndef RIVET_MathUtils_HH
3#define RIVET_MathUtils_HH
5#include "Rivet/Math/MathConstants.hh"
22 template <
typename NUM>
23 inline typename std::enable_if_t<std::is_floating_point_v<NUM>,
bool>
isZero(NUM val,
24 double tolerance = 1e-8) {
25 return fabs(val) < tolerance;
32 template <
typename NUM>
33 inline typename std::enable_if_t<std::is_integral_v<NUM>,
bool>
isZero(
40 template <
typename NUM>
41 inline typename std::enable_if_t<std::is_floating_point_v<NUM>,
bool>
isNaN(NUM val) {
42 return std::isnan(val);
46 template <
typename NUM>
47 inline typename std::enable_if_t<std::is_floating_point_v<NUM>,
bool>
notNaN(NUM val) {
48 return !std::isnan(val);
52 template <
typename NUM>
53 inline typename std::enable_if<std::is_floating_point<NUM>::value, NUM>::type
sqrt_signed(NUM val) {
54 return std::copysign(sqrt(std::abs(val)), val);
62 template <
typename N1,
typename N2>
63 inline typename std::enable_if_t<std::is_arithmetic_v<N1> && std::is_arithmetic_v<N2>
64 && (std::is_floating_point_v<N1> || std::is_floating_point_v<N2>),
67 const double absavg = (std::abs(a) + std::abs(b)) / 2.0;
68 const double absdiff = std::abs(a - b);
69 const bool rtn = (
isZero(a) &&
isZero(b)) || absdiff < tolerance * absavg;
77 template <
typename N1,
typename N2>
78 inline typename std::enable_if_t<std::is_integral_v<N1> && std::is_integral_v<N2>,
bool>
fuzzyEquals(
89 template <
typename N1,
typename N2>
90 inline typename std::enable_if_t<std::is_arithmetic_v<N1> && std::is_arithmetic_v<N2>,
bool>
fuzzyGtrEquals(
93 double tolerance = 1e-5) {
101 template <
typename N1,
typename N2>
102 inline typename std::enable_if_t<std::is_arithmetic_v<N1> && std::is_arithmetic_v<N2>,
bool>
110 template <
typename N1,
typename N2>
111 inline typename std::enable_if_t<std::is_arithmetic_v<N1> && std::is_arithmetic_v<N2>,
112 signed_if_mixed_t<N1, N2>>
114 using rtnT = signed_if_mixed_t<N1, N2>;
115 return ((rtnT)a > (rtnT)b) ? b : a;
121 template <
typename N1,
typename N2>
122 inline typename std::enable_if_t<std::is_arithmetic_v<N1> && std::is_arithmetic_v<N2>,
123 signed_if_mixed_t<N1, N2>>
125 using rtnT = signed_if_mixed_t<N1, N2>;
126 return ((rtnT)a > (rtnT)b) ? a : b;
144 template <
typename N1,
typename N2,
typename N3>
145 inline typename std::
146 enable_if_t<std::is_arithmetic_v<N1> && std::is_arithmetic_v<N2> && std::is_arithmetic_v<N3>,
bool>
148 if (lowbound == OPEN && highbound == OPEN) {
149 return (value > low && value < high);
151 else if (lowbound == OPEN && highbound == CLOSED) {
152 return (value > low && value <= high);
154 else if (lowbound == CLOSED && highbound == OPEN) {
155 return (value >= low && value < high);
158 return (value >= low && value <= high);
166 template <
typename N1,
typename N2,
typename N3>
167 inline typename std::enable_if_t<std::is_arithmetic_v<N1> && std::is_arithmetic_v<N2>
168 && std::is_arithmetic_v<N3>,
171 if (lowbound == OPEN && highbound == OPEN) {
172 return (value > low && value < high);
174 else if (lowbound == OPEN && highbound == CLOSED) {
177 else if (lowbound == CLOSED && highbound == OPEN) {
186 template <
typename N1,
typename N2,
typename N3>
187 inline typename std::enable_if_t<std::is_arithmetic_v<N1> && std::is_arithmetic_v<N2>
188 && std::is_arithmetic_v<N3>,
191 return inRange(value, lowhigh.first, lowhigh.second, lowbound, highbound);
200 template <
typename N1,
typename N2,
typename N3>
201 inline typename std::
202 enable_if_t<std::is_arithmetic_v<N1> && std::is_arithmetic_v<N2> && std::is_arithmetic_v<N3>,
bool>
204 return inRange(val, low, high, CLOSED, OPEN);
210 template <
typename N1,
typename N2,
typename N3>
211 inline typename std::
212 enable_if_t<std::is_arithmetic_v<N1> && std::is_arithmetic_v<N2> && std::is_arithmetic_v<N3>,
bool>
214 return inRange(val, low, high, CLOSED, CLOSED);
220 template <
typename N1,
typename N2,
typename N3>
221 inline typename std::
222 enable_if_t<std::is_arithmetic_v<N1> && std::is_arithmetic_v<N2> && std::is_arithmetic_v<N3>,
bool>
224 return inRange(val, low, high, OPEN, OPEN);
236 template <
typename NUM>
237 inline typename std::enable_if_t<std::is_arithmetic_v<NUM>, NUM>
sqr(NUM a) {
242 inline double subtract(
double a,
double b,
double tolerance = 1e-5) {
248 inline double add(
double a,
double b,
double tolerance = 1e-5) {
257 template <
typename NUM>
258 inline typename std::enable_if_t<std::is_arithmetic_v<NUM>, NUM>
261 return sqrt(a * a + b * b);
269 template <
typename NUM>
270 inline typename std::enable_if_t<std::is_arithmetic_v<NUM>, NUM>
273 return sqrt(a * a + b * b + c * c);
278 inline double safediv(
double num,
double den,
double fail = 0.0) {
279 return (!
isZero(den)) ? num / den : fail;
283 template <
typename NUM>
284 constexpr inline typename std::enable_if_t<std::is_arithmetic_v<NUM>, NUM>
intpow(NUM val,
290 return val *
intpow(val, exp - 1);
294 template <
typename NUM>
295 constexpr inline typename std::enable_if_t<std::is_arithmetic_v<NUM>,
int>
sign(NUM val) {
296 if (
isZero(val))
return ZERO;
297 const int valsign = (val > 0) ? PLUS : MINUS;
308 inline double cdfBW(
double x,
double mu,
double gamma) {
310 const double xn = (x - mu) / gamma;
311 return std::atan(xn) / M_PI + 0.5;
315 inline double invcdfBW(
double p,
double mu,
double gamma) {
316 const double xn = std::tan(M_PI * (
p - 0.5));
317 return gamma * xn + mu;
332 inline vector<double>
linspace(
size_t nbins,
double start,
double end,
bool include_end =
true) {
335 const double interval = (end - start) /
static_cast<double>(nbins);
336 for (
size_t i = 0; i < nbins; ++i) {
337 rtn.push_back(start + i * interval);
339 assert(rtn.size() == nbins);
340 if (include_end) rtn.push_back(end);
356 inline vector<double>
aspace(
double step,
359 bool include_end =
true,
361 assert((end - start) * step > 0);
365 if (next > end)
break;
370 if (end - rtn[rtn.size() - 1] > tol * step) rtn.push_back(end);
382 const std::function<
double(
double)>& fn,
383 const std::function<
double(
double)>& invfn,
384 bool include_end =
true) {
387 const double pmin = fn(start);
388 const double pmax = fn(end);
389 const vector<double> edges =
linspace(nbins, pmin, pmax,
false);
390 assert(edges.size() == nbins);
392 rtn.reserve(nbins + 1);
393 rtn.push_back(start);
394 for (
size_t i = 1; i < edges.size(); ++i) {
395 rtn.push_back(invfn(edges[i]));
397 assert(rtn.size() == nbins);
398 if (include_end) rtn.push_back(end);
412 inline vector<double>
logspace(
size_t nbins,
double start,
double end,
bool include_end =
true) {
414 nbins, start, end, [](
double x) {
return std::log(x); }, [](
double x) {
return std::exp(x); },
432 bool include_end =
true) {
435 nbins, start, end, [&](
double x) {
return std::pow(x, npow); },
436 [&](
double x) {
return std::pow(x, 1 / npow); }, include_end);
454 bool include_end =
true) {
457 nbins, start, end, [&](
double x) {
return std::pow(x, npow + 1) / (npow + 1); },
458 [&](
double x) {
return std::pow((npow + 1) * x, 1 / (npow + 1)); }, include_end);
474 bool include_end =
true) {
476 nbins, start, end, [&](
double x) {
return cdfBW(x, mu, gamma); },
477 [&](
double x) {
return invcdfBW(x, mu, gamma); }, include_end);
482 template <
typename NUM,
typename CONTAINER>
483 inline typename std::
484 enable_if_t<std::is_arithmetic_v<NUM> && std::is_arithmetic_v<typename CONTAINER::value_type>,
int>
485 _binIndex(NUM val,
const CONTAINER& binedges,
bool allow_overflow =
false) {
486 if (val < *begin(binedges))
return -1;
488 if (val >= *(end(binedges) - 1))
489 return allow_overflow ? int(binedges.size()) - 1 : -1;
490 auto it = std::upper_bound(begin(binedges), end(binedges), val);
491 return std::distance(begin(binedges), --it);
502 template <
typename NUM1,
typename NUM2>
503 inline typename std::enable_if_t<std::is_arithmetic_v<NUM1> && std::is_arithmetic_v<NUM2>,
int>
binIndex(
505 std::initializer_list<NUM2> binedges,
506 bool allow_overflow =
false) {
507 return _binIndex(val, binedges, allow_overflow);
518 template <
typename NUM,
typename CONTAINER>
519 inline typename std::
520 enable_if_t<std::is_arithmetic_v<NUM> && std::is_arithmetic_v<typename CONTAINER::value_type>,
int>
521 binIndex(NUM val,
const CONTAINER& binedges,
bool allow_overflow =
false) {
522 return _binIndex(val, binedges, allow_overflow);
533 template <
typename NUM>
534 inline typename std::enable_if_t<std::is_arithmetic_v<NUM>, NUM>
median(
const vector<NUM>& sample) {
535 if (sample.empty())
throw RangeError(
"Can't compute median of an empty set");
536 vector<NUM> tmp = sample;
537 std::sort(tmp.begin(), tmp.end());
538 const size_t imid = tmp.size() / 2;
539 if (sample.size() % 2 == 0)
540 return (tmp.at(imid - 1) + tmp.at(imid)) / 2.0;
548 template <
typename NUM>
549 inline typename std::enable_if_t<std::is_arithmetic_v<NUM>,
double>
mean(
const vector<NUM>& sample) {
550 if (sample.empty())
throw RangeError(
"Can't compute mean of an empty set");
552 for (
size_t i = 0; i < sample.size(); ++i) {
555 return mean / sample.size();
560 template <
typename NUM>
561 inline typename std::enable_if_t<std::is_arithmetic_v<NUM>,
double>
mean_err(
const vector<NUM>& sample) {
562 if (sample.empty())
throw RangeError(
"Can't compute mean_err of an empty set");
564 for (
size_t i = 0; i < sample.size(); ++i) {
565 mean_e += sqrt(sample[i]);
567 return mean_e / sample.size();
573 template <
typename NUM>
574 inline typename std::enable_if_t<std::is_arithmetic_v<NUM>,
double>
covariance(
const vector<NUM>& sample1,
575 const vector<NUM>& sample2) {
576 if (sample1.empty() || sample2.empty())
throw RangeError(
"Can't compute covariance of an empty set");
577 if (sample1.size() != sample2.size())
578 throw RangeError(
"Sizes of samples must be equal for covariance calculation");
579 const double mean1 =
mean(sample1);
580 const double mean2 =
mean(sample2);
581 const size_t N = sample1.size();
583 for (
size_t i = 0; i < N; i++) {
584 const double cov_i = (sample1[i] - mean1) * (sample2[i] - mean2);
588 return cov / (N - 1);
595 template <
typename NUM>
596 inline typename std::enable_if_t<std::is_arithmetic_v<NUM>,
double>
covariance_err(
597 const vector<NUM>& sample1,
598 const vector<NUM>& sample2) {
599 if (sample1.empty() || sample2.empty())
throw RangeError(
"Can't compute covariance_err of an empty set");
600 if (sample1.size() != sample2.size())
601 throw RangeError(
"Sizes of samples must be equal for covariance_err calculation");
602 const double mean1 =
mean(sample1);
603 const double mean2 =
mean(sample2);
604 const double mean1_e =
mean_err(sample1);
605 const double mean2_e =
mean_err(sample2);
606 const size_t N = sample1.size();
608 for (
size_t i = 0; i < N; i++) {
609 const double cov_i = (sqrt(sample1[i]) - mean1_e) * (sample2[i] - mean2)
610 + (sample1[i] - mean1) * (sqrt(sample2[i]) - mean2_e);
614 return cov_e / (N - 1);
622 template <
typename NUM>
623 inline typename std::enable_if_t<std::is_arithmetic_v<NUM>,
double>
correlation(
624 const vector<NUM>& sample1,
625 const vector<NUM>& sample2) {
626 const double cov =
covariance(sample1, sample2);
627 const double var1 =
covariance(sample1, sample1);
628 const double var2 =
covariance(sample2, sample2);
629 const double correlation = cov / sqrt(var1 * var2);
630 const double corr_strength =
correlation * sqrt(var2 / var1);
631 return corr_strength;
636 template <
typename NUM>
638 const vector<NUM>& sample1,
639 const vector<NUM>& sample2) {
640 const double cov =
covariance(sample1, sample2);
641 const double var1 =
covariance(sample1, sample1);
642 const double var2 =
covariance(sample2, sample2);
648 const double correlation = cov / sqrt(var1 * var2);
651 - cov / (2 * pow(3. / 2., var1 * var2)) * (var1_e * var2 + var1 * var2_e);
655 +
correlation / (2 * sqrt(var2 / var1)) * (var2_e / var1 - var2 * var1_e / pow(2, var2));
657 return corr_strength_err;
670 inline double _mapAngleM2PITo2Pi(
double angle) {
672 if (
isZero(rtn))
return 0;
679 double rtn = _mapAngleM2PITo2Pi(
angle);
680 if (
isZero(rtn))
return 0;
683 assert(rtn > -
PI && rtn <=
PI);
689 double rtn = _mapAngleM2PITo2Pi(
angle);
690 if (
isZero(rtn))
return 0;
691 if (rtn < 0) rtn +=
TWOPI;
692 if (rtn ==
TWOPI) rtn = 0;
693 assert(rtn >= 0 && rtn <
TWOPI);
700 if (
isZero(rtn))
return 0;
701 assert(rtn > 0 && rtn <=
PI);
711 default:
throw Rivet::UserError(
"The specified phi mapping scheme is not implemented");
726 return sign ? x : fabs(x);
733 const double x = eta1 - eta2;
734 return sign ? x : fabs(x);
741 const double x = y1 - y2;
742 return sign ? x : fabs(x);
747 inline double deltaR2(
double rap1,
double phi1,
double rap2,
double phi2) {
748 const double dphi =
deltaPhi(phi1, phi2);
749 return sqr(rap1 - rap2) +
sqr(dphi);
754 inline double deltaR(
double rap1,
double phi1,
double rap2,
double phi2) {
755 return sqrt(
deltaR2(rap1, phi1, rap2, phi2));
761 throw std::runtime_error(
"Divergent positive rapidity");
765 throw std::runtime_error(
"Divergent negative rapidity");
768 return 0.5 * log((
E + pz) / (
E - pz));
777 inline double mT(
double pT1,
double pT2,
double dphi) {
778 return sqrt(2 * pT1 * pT2 * (1 - cos(dphi)));
double E(const ParticleBase &p)
Unbound function access to E.
Definition ParticleBaseUtils.hh:829
double p(const ParticleBase &p)
Unbound function access to p.
Definition ParticleBaseUtils.hh:819
Definition LHCbCommon.hh:9
constexpr std::enable_if_t< std::is_arithmetic_v< NUM >, int > sign(NUM val)
Find the sign of a number.
Definition MathUtils.hh:295
double deltaR(double rap1, double phi1, double rap2, double phi2)
Definition MathUtils.hh:754
std::enable_if< std::is_floating_point< NUM >::value, NUM >::type sqrt_signed(NUM val)
Square root of the absolute value with the sign of the argument propagated.
Definition MathUtils.hh:53
std::enable_if_t< std::is_arithmetic_v< N1 > &&std::is_arithmetic_v< N2 >, bool > fuzzyGtrEquals(N1 a, N2 b, double tolerance=1e-5)
Compare two numbers for >= with a degree of fuzziness.
Definition MathUtils.hh:90
double deltaPhi(double phi1, double phi2, bool sign=false)
Calculate the difference between two angles in radians.
Definition MathUtils.hh:724
double subtract(double a, double b, double tolerance=1e-5)
Subtract two numbers with FP fuzziness.
Definition MathUtils.hh:242
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:356
double deltaEta(double eta1, double eta2, bool sign=false)
Definition MathUtils.hh:732
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:412
std::enable_if_t< std::is_arithmetic_v< NUM >, NUM > median(const vector< NUM > &sample)
Definition MathUtils.hh:534
std::enable_if_t< std::is_arithmetic_v< N1 > &&std::is_arithmetic_v< N2 >, signed_if_mixed_t< N1, N2 > > max(N1 a, N2 b)
Get the maximum of two numbers.
Definition MathUtils.hh:124
double mapAngle0To2Pi(double angle)
Map an angle into the range [0, 2PI).
Definition MathUtils.hh:688
std::enable_if_t< std::is_arithmetic_v< NUM >, double > correlation_err(const vector< NUM > &sample1, const vector< NUM > &sample2)
Definition MathUtils.hh:637
double deltaR2(double rap1, double phi1, double rap2, double phi2)
Definition MathUtils.hh:747
double mT(double pT1, double pT2, double dphi)
Definition MathUtils.hh:777
std::enable_if_t< std::is_arithmetic_v< NUM >, NUM > add_quad(NUM a, NUM b)
Named number-type addition in quadrature operation.
Definition MathUtils.hh:260
std::enable_if_t< std::is_floating_point_v< NUM >, bool > isZero(NUM val, double tolerance=1e-8)
Compare a number to zero.
Definition MathUtils.hh:23
std::enable_if_t< std::is_arithmetic_v< NUM >, NUM > sqr(NUM a)
Named number-type squaring operation.
Definition MathUtils.hh:237
std::enable_if_t< std::is_arithmetic_v< N1 > &&std::is_arithmetic_v< N2 > &&std::is_arithmetic_v< N3 >, bool > in_range(N1 val, N2 low, N3 high)
Boolean function to determine if value is within the given range.
Definition MathUtils.hh:203
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:379
constexpr double TWOPI
A pre-defined value of .
Definition MathConstants.hh:16
double mapAngleMPiToPi(double angle)
Map an angle into the range (-PI, PI].
Definition MathUtils.hh:678
std::enable_if_t< std::is_arithmetic_v< NUM >, double > covariance_err(const vector< NUM > &sample1, const vector< NUM > &sample2)
Definition MathUtils.hh:596
RangeBoundary
Definition MathUtils.hh:139
double add(double a, double b, double tolerance=1e-5)
Add two numbers with FP fuzziness.
Definition MathUtils.hh:248
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:428
std::enable_if_t< std::is_arithmetic_v< N1 > &&std::is_arithmetic_v< N2 >, signed_if_mixed_t< N1, N2 > > min(N1 a, N2 b)
Get the minimum of two numbers.
Definition MathUtils.hh:113
std::enable_if_t< std::is_arithmetic_v< NUM >, double > correlation(const vector< NUM > &sample1, const vector< NUM > &sample2)
Definition MathUtils.hh:623
double cdfBW(double x, double mu, double gamma)
CDF for the Breit-Wigner distribution.
Definition MathUtils.hh:308
std::enable_if_t< std::is_arithmetic_v< N1 > &&std::is_arithmetic_v< N2 > &&std::is_arithmetic_v< N3 >, bool > 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:147
double safediv(double num, double den, double fail=0.0)
Definition MathUtils.hh:278
constexpr double PI
Definition MathConstants.hh:13
double deltaRap(double y1, double y2, bool sign=false)
Definition MathUtils.hh:740
std::enable_if_t< std::is_arithmetic_v< N1 > &&std::is_arithmetic_v< N2 > &&std::is_arithmetic_v< N3 >, bool > in_closed_range(N1 val, N2 low, N3 high)
Boolean function to determine if value is within the given range.
Definition MathUtils.hh:213
double mapAngle(double angle, PhiMapping mapping)
Map an angle into the enum-specified range.
Definition MathUtils.hh:706
std::enable_if_t< std::is_floating_point_v< NUM >, bool > isNaN(NUM val)
Check if a number is NaN.
Definition MathUtils.hh:41
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:332
std::enable_if_t< std::is_arithmetic_v< NUM >, double > mean_err(const vector< NUM > &sample)
Definition MathUtils.hh:561
std::enable_if_t< std::is_arithmetic_v< N1 > &&std::is_arithmetic_v< N2 > &&std::is_arithmetic_v< N3 >, bool > in_open_range(N1 val, N2 low, N3 high)
Boolean function to determine if value is within the given range.
Definition MathUtils.hh:223
std::enable_if_t< std::is_arithmetic_v< NUM >, double > covariance(const vector< NUM > &sample1, const vector< NUM > &sample2)
Definition MathUtils.hh:574
double mapAngle0ToPi(double angle)
Map an angle into the range [0, PI].
Definition MathUtils.hh:698
constexpr std::enable_if_t< std::is_arithmetic_v< NUM >, NUM > intpow(NUM val, unsigned int exp)
A more efficient version of pow for raising numbers to integer powers.
Definition MathUtils.hh:284
double invcdfBW(double p, double mu, double gamma)
Inverse CDF for the Breit-Wigner distribution.
Definition MathUtils.hh:315
double angle(const Vector2 &a, const Vector2 &b)
Angle (in radians) between two 2-vectors.
Definition Vector2.hh:194
std::enable_if_t< std::is_arithmetic_v< NUM1 > &&std::is_arithmetic_v< NUM2 >, int > 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:503
std::enable_if_t< std::is_floating_point_v< NUM >, bool > notNaN(NUM val)
Check if a number is non-NaN.
Definition MathUtils.hh:47
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:450
std::enable_if_t< std::is_arithmetic_v< NUM >, double > mean(const vector< NUM > &sample)
Definition MathUtils.hh:549
std::enable_if_t< std::is_arithmetic_v< N1 > &&std::is_arithmetic_v< N2 > &&(std::is_floating_point_v< N1 >||std::is_floating_point_v< N2 >), bool > fuzzyEquals(N1 a, N2 b, double tolerance=1e-5)
Compare two numbers for equality with a degree of fuzziness.
Definition MathUtils.hh:66
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:469
std::enable_if_t< std::is_arithmetic_v< N1 > &&std::is_arithmetic_v< N2 >, bool > fuzzyLessEquals(N1 a, N2 b, double tolerance=1e-5)
Compare two floating point numbers for <= with a degree of fuzziness.
Definition MathUtils.hh:103
std::enable_if_t< std::is_arithmetic_v< N1 > &&std::is_arithmetic_v< N2 > &&std::is_arithmetic_v< N3 >, bool > 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:170
double rapidity(double E, double pz)
Calculate a rapidity value from the supplied energy E and longitudinal momentum pz.
Definition MathUtils.hh:759
Error for e.g. use of invalid bin ranges.
Definition Exceptions.hh:23
Error specialisation for where the problem is between the chair and the computer.
Definition Exceptions.hh:75