Logo ROOT   6.10/09
Reference Guide
Util.h
Go to the documentation of this file.
1 // @(#)root/mathcore:$Id$
2 // Author: L. Moneta Tue Nov 14 15:44:38 2006
3 
4 /**********************************************************************
5  * *
6  * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT *
7  * *
8  * *
9  **********************************************************************/
10 
11 // Utility functions for all ROOT Math classes
12 
13 #ifndef ROOT_Math_Util
14 #define ROOT_Math_Util
15 
16 #include <string>
17 #include <sstream>
18 
19 #include <cmath>
20 #include <limits>
21 
22 // for defining unused variables in the interfaces
23 // and have still them in the documentation
24 #define MATH_UNUSED(var) (void)var
25 
26 
27 namespace ROOT {
28 
29  namespace Math {
30 
31  /**
32  namespace defining Utility functions needed by mathcore
33  */
34  namespace Util {
35 
36  /**
37  Utility function for conversion to strings
38  */
39  template <class T>
40  std::string ToString(const T &val)
41  {
42  std::ostringstream buf;
43  buf << val;
44 
45  std::string ret = buf.str();
46  return ret;
47  }
48 
49  /// safe evaluation of log(x) with a protections against negative or zero argument to the log
50  /// smooth linear extrapolation below function values smaller than epsilon
51  /// (better than a simple cut-off)
52  inline double EvalLog(double x)
53  {
54  // evaluate the log
55 #ifdef __CINT__
56  static const double epsilon = 2. * 2.2250738585072014e-308;
57 #else
58  static const double epsilon = 2. * std::numeric_limits<double>::min();
59 #endif
60  if (x <= epsilon)
61  return x / epsilon + std::log(epsilon) - 1;
62  else
63  return std::log(x);
64  }
65 
66  } // end namespace Util
67 
68  ///\class KahanSum
69  /// The Kahan compensate summation algorithm significantly reduces the numerical error in the total obtained
70  /// by adding a sequence of finite precision floating point numbers.
71  /// This is done by keeping a separate running compensation (a variable to accumulate small errors).\n
72  ///
73  /// The intial values of the result and the correction are set to the default value of the type it hass been
74  /// instantiated with.\n
75  /// ####Examples:
76  /// ~~~{.cpp}
77  /// std::vector<double> numbers = {0.01, 0.001, 0.0001, 0.000001, 0.00000000001};
78  /// ROOT::Math::KahanSum<double> k;
79  /// k.Add(numbers);
80  /// ~~~
81  /// ~~~{.cpp}
82  /// auto result = ROOT::Math::KahanSum<double>::Accumulate(numbers);
83  /// ~~~
84  template <class T>
85  class KahanSum {
86  public:
87  /// Constructor accepting a initial value for the summation as parameter
88  KahanSum(const T &initialValue = T{}) : fSum(initialValue) {}
89 
90  /// Single element accumulated addition.
91  void Add(const T &x)
92  {
93  auto y = x - fCorrection;
94  auto t = fSum + y;
95  fCorrection = (t - fSum) - y;
96  fSum = t;
97  }
98 
99  /// Iterate over a datastructure referenced by a pointer and accumulate on the exising result
100  template <class Iterator>
101  void Add(const Iterator begin, const Iterator end)
102  {
103  static_assert(!std::is_same<decltype(*begin), T>::value,
104  "Iterator points to an element of the different type than the KahanSum class");
105  for (auto it = begin; it != end; it++) this->Add(*it);
106  }
107 
108  /// Iterate over a datastructure referenced by a pointer and return the result of its accumulation.
109  /// Can take an initial value as third parameter.
110  template <class Iterator>
111  static T Accumulate(const Iterator begin, const Iterator end, const T &initialValue = T{})
112  {
113  static_assert(!std::is_same<decltype(*begin), T>::value,
114  "Iterator points to an element of the different type than the KahanSum class");
115  KahanSum init(initialValue);
116  init.Add(begin, end);
117  return init.fSum;
118  }
119 
120  /// Return the result
121  T Result() { return fSum; }
122 
123  private:
124  T fSum{};
125  T fCorrection{};
126  };
127 
128  } // end namespace Math
129 
130 } // end namespace ROOT
131 
132 
133 #endif /* ROOT_Math_Util */
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
KahanSum(const T &initialValue=T{})
Constructor accepting a initial value for the summation as parameter.
Definition: Util.h:88
double T(double x)
Definition: ChebyshevPol.h:34
T Result()
Return the result.
Definition: Util.h:121
Double_t x[n]
Definition: legend1.C:17
The Kahan compensate summation algorithm significantly reduces the numerical error in the total obtai...
Definition: Util.h:85
void Add(const Iterator begin, const Iterator end)
Iterate over a datastructure referenced by a pointer and accumulate on the exising result...
Definition: Util.h:101
static T Accumulate(const Iterator begin, const Iterator end, const T &initialValue=T{})
Iterate over a datastructure referenced by a pointer and return the result of its accumulation...
Definition: Util.h:111
REAL epsilon
Definition: triangle.c:617
void Add(THist< DIMENSIONS, PRECISION_TO, STAT_TO... > &to, const THist< DIMENSIONS, PRECISION_FROM, STAT_FROM... > &from)
Add two histograms.
Definition: THist.hxx:336
static Int_t init()
Double_t y[n]
Definition: legend1.C:17
Namespace for new Math classes and functions.
double EvalLog(double x)
safe evaluation of log(x) with a protections against negative or zero argument to the log smooth line...
Definition: Util.h:52
std::string ToString(const T &val)
Utility function for conversion to strings.
Definition: Util.h:40
void Add(const T &x)
Single element accumulated addition.
Definition: Util.h:91
double log(double)