Utilities/Math/Math.h
Go to the documentation of this file.
1 #ifndef _utl_Math_h_
2 #define _utl_Math_h_
3 
4 #include <utl/MathConstants.h>
5 #include <utl/Vector.h>
6 #include <utl/Moyal.h>
7 #include <utl/LambertW.h>
8 #include <utl/Kolmogorov.h>
9 
10 #include <limits>
11 #include <numeric>
12 #include <cmath>
13 #include <iterator>
14 
15 
16 namespace utl {
17 
18  template<typename T>
19  inline
20  constexpr
21  T
22  Sqr(const T x)
23  {
24  return x*x;
25  }
26 
27 
28  template<typename T>
29  inline
30  constexpr
31  int
32  Sign(const T x, const boost::integral_constant<bool, false>)
33  {
34  return T(0) < x;
35  }
36 
37 
38  template<typename T>
39  inline
40  constexpr
41  int
42  Sign(const T x, const boost::integral_constant<bool, true>)
43  {
44  return (T(0) < x) - (x < T(0));
45  }
46 
47 
48  template<typename T>
49  inline
50  constexpr
51  int
52  Sign(const T x)
53  {
54  // Sign(x) returns -1, 0, or 1 in case x is smaller, equal, or greater than 0, respectively
55  // much like the new spaceship operator <=>
56  return Sign(x, boost::integral_constant<bool, std::numeric_limits<T>::is_signed>());
57  }
58 
59 
61 
62  inline
63  double
64  NormalizeAngleMinusPiPi(const double x)
65  {
66  return x - kTwoPi * std::floor(x/kTwoPi + 0.5);
67  }
68 
69 
71 
72  inline
73  double
74  NormalizeAngleZero2Pi(const double x)
75  {
76  return x - kTwoPi * std::floor(x/kTwoPi);
77  }
78 
79 
80  template<typename T, std::size_t n>
81  inline
82  constexpr
83  std::size_t
84  Length(const T (&)[n])
85  noexcept
86  {
87  return n;
88  }
89 
90 
91  inline
92  constexpr
93  int
94  FloorDiv(const int num, const int den)
95  {
96  // equivalent to int(floor(double(num)/den)) but without floating point operations
97  return num >= 0 ? num / den : (num - (den - 1)) / den;
98  }
99 
100 
101  namespace {
102 
103  namespace Detail {
104 
105  template<typename Container>
106  inline
107  double
108  EvalPoly(const Container& a, const double x)
109  {
110  auto it = std::crbegin(a);
111  const auto end = std::crend(a);
112  if (it == end)
113  return std::numeric_limits<double>::quiet_NaN();
114  double sum = *it;
115  for (++it; it != end; ++it) {
116  sum *= x;
117  sum += *it;
118  }
119  return sum;
120  }
121 
122  }
123 
124  }
125 
126 
141  template<typename T>
142  inline
143  double
144  EvalPoly(const T& a, const double x)
145  {
146  return Detail::EvalPoly(a, x);
147  }
148 
149  // std::initializer_list requires explicit matching ...
150  template<typename T>
151  inline
152  double
153  EvalPoly(const std::initializer_list<T>& a, const double x)
154  {
155  return Detail::EvalPoly(a, x);
156  }
157 
158 }
159 
160 
161 #include <utl/NormalDistribution.h>
162 
163 
164 namespace utl {
165 
171  inline double LogGamma(const double x) { return std::lgamma(x); }
172 
173 
174  double IncompleteGammaPSeries(const double a, const double x);
175  double IncompleteGammaPCF(const double a, const double x);
176 
177 
186  inline
187  double
188  IncompleteGammaP(const double a, const double x)
189  {
190  // Use the series representation or the continued fractions
191  return (x < a+1) ? IncompleteGammaPSeries(a, x) : 1 - IncompleteGammaPCF(a, x);
192  }
193 
194 
203  inline
204  double
205  IncompleteGammaQ(const double a, const double x)
206  {
207  // Use the series representation or the continued fractions
208  return (x < a+1) ? 1 - IncompleteGammaPSeries(a, x) : IncompleteGammaPCF(a, x);
209  }
210 
211 
212  inline
213  double
214  Chi2Probability(const double chi2, const double ndof)
215  {
216  return IncompleteGammaQ(0.5*ndof, 0.5*chi2);
217  }
218 
219 
222  double IncompleteBeta(const double a, const double b, const double x);
223 
224 
238  inline
239  double
240  Fermi(const double x, const double x0, const double sigma)
241  {
242  return 1/(1 + std::exp((x - x0)/sigma));
243  }
244 
245 
248  void PropagateAxisErrors(const utl::Vector::Triple& u_v_w,
249  const utl::Vector::Triple& sigma_u2_uv_v2,
250  double& thetaError, double& phiError, double& thetaPhiCorrelation);
251 
252 
258  inline
259  std::pair<double, double>
260  SolveQuadraticEquation(const double a, const double b, const double c)
261  {
262  const double b2 = b * b;
263  const double fac = 4*a*c;
264  const double d = b2 - fac;
265  const double sd = sqrt(d);
266  if (b2 < 1e5*fac) {
267  const double ta = 0.5 / a;
268  return std::make_pair((-b + sd) * ta, (-b - sd) * ta);
269  }
270  if (b > 0) {
271  const double t = -(b + sd);
272  return std::make_pair(2 * c / t, t / (2 * a));
273  }
274  const double t = -b + sd;
275  return std::make_pair(t / (2 * a), 2 * c / t);
276  }
277 
278 }
279 
280 
281 #endif
double IncompleteGammaQ(const double a, const double x)
Incomplete gamma Q(a, x) = 1 - P(a, x) function.
double IncompleteGammaPCF(const double a, const double x)
Continued Fraction for incomplete gamma function Q(a, x)
double IncompleteGammaP(const double a, const double x)
Incomplete gamma P(a, x) function.
double NormalizeAngleMinusPiPi(const double x)
Normalize angle to lie between -pi and pi (-180 and 180 deg)
constexpr T Sqr(const T &x)
double IncompleteGammaPSeries(const double a, const double x)
logarithm of Gamma function
boost::tuple< double, double, double > Triple
Coordinate triple for easy getting or setting of coordinates.
Definition: BasicVector.h:147
std::pair< double, double > SolveQuadraticEquation(const double a, const double b, const double c)
double IncompleteBeta(const double a, const double b, const double x)
Incomplete Beta function.
double Fermi(const double x)
void PropagateAxisErrors(const Vector::Triple &u_v_w, const Vector::Triple &sigma_u2_uv_v2, double &thetaError, double &phiError, double &thetaPhiCorrelation)
double LogGamma(const double x)
constexpr std::size_t noexcept
double EvalPoly(const T &a, const double x)
Simple polynomial evaluator.
constexpr double kTwoPi
Definition: MathConstants.h:27
constexpr int FloorDiv(const int num, const int den)
constexpr int Sign(const T x, const boost::integral_constant< bool, false >)
double Chi2Probability(const double chi2, const double ndof)
double NormalizeAngleZero2Pi(const double x)
Normalize angle to lie between 0 and 2pi (0 and 360 deg)

, generated on Tue Sep 26 2023.