Logo ROOT   6.14/05
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 
23 // This can be protected against by defining ROOT_Math_VecTypes
24 // This is only used for the R__HAS_VECCORE define
25 // and a single VecCore function in EvalLog
26 #ifndef ROOT_Math_VecTypes
27 #include "Types.h"
28 #endif
29 
30 
31 // for defining unused variables in the interfaces
32 // and have still them in the documentation
33 #define MATH_UNUSED(var) (void)var
34 
35 
36 namespace ROOT {
37 
38  namespace Math {
39 
40  /**
41  namespace defining Utility functions needed by mathcore
42  */
43  namespace Util {
44 
45  /**
46  Utility function for conversion to strings
47  */
48  template <class T>
49  std::string ToString(const T &val)
50  {
51  std::ostringstream buf;
52  buf << val;
53 
54  std::string ret = buf.str();
55  return ret;
56  }
57 
58  /// safe evaluation of log(x) with a protections against negative or zero argument to the log
59  /// smooth linear extrapolation below function values smaller than epsilon
60  /// (better than a simple cut-off)
61 
62  template<class T>
63  inline T EvalLog(T x) {
64  static const T epsilon = T(2.0 * std::numeric_limits<double>::min());
65 #ifdef R__HAS_VECCORE
66  T logval = vecCore::Blend<T>(x <= epsilon, x / epsilon + std::log(epsilon) - T(1.0), std::log(x));
67 #else
68  T logval = x <= epsilon ? x / epsilon + std::log(epsilon) - T(1.0) : std::log(x);
69 #endif
70  return logval;
71  }
72 
73  } // end namespace Util
74 
75  ///\class KahanSum
76  /// The Kahan compensate summation algorithm significantly reduces the numerical error in the total obtained
77  /// by adding a sequence of finite precision floating point numbers.
78  /// This is done by keeping a separate running compensation (a variable to accumulate small errors).\n
79  ///
80  /// The intial values of the result and the correction are set to the default value of the type it hass been
81  /// instantiated with.\n
82  /// ####Examples:
83  /// ~~~{.cpp}
84  /// std::vector<double> numbers = {0.01, 0.001, 0.0001, 0.000001, 0.00000000001};
85  /// ROOT::Math::KahanSum<double> k;
86  /// k.Add(numbers);
87  /// ~~~
88  /// ~~~{.cpp}
89  /// auto result = ROOT::Math::KahanSum<double>::Accumulate(numbers);
90  /// ~~~
91  template <class T>
92  class KahanSum {
93  public:
94  /// Constructor accepting a initial value for the summation as parameter
95  KahanSum(const T &initialValue = T{}) : fSum(initialValue) {}
96 
97  /// Single element accumulated addition.
98  void Add(const T &x)
99  {
100  auto y = x - fCorrection;
101  auto t = fSum + y;
102  fCorrection = (t - fSum) - y;
103  fSum = t;
104  }
105 
106  /// Iterate over a datastructure referenced by a pointer and accumulate on the exising result
107  template <class Iterator>
108  void Add(const Iterator begin, const Iterator end)
109  {
110  static_assert(!std::is_same<decltype(*begin), T>::value,
111  "Iterator points to an element of the different type than the KahanSum class");
112  for (auto it = begin; it != end; it++) this->Add(*it);
113  }
114 
115  /// Iterate over a datastructure referenced by a pointer and return the result of its accumulation.
116  /// Can take an initial value as third parameter.
117  template <class Iterator>
118  static T Accumulate(const Iterator begin, const Iterator end, const T &initialValue = T{})
119  {
120  static_assert(!std::is_same<decltype(*begin), T>::value,
121  "Iterator points to an element of the different type than the KahanSum class");
122  KahanSum init(initialValue);
123  init.Add(begin, end);
124  return init.fSum;
125  }
126 
127  /// Return the result
128  T Result() { return fSum; }
129 
130  private:
131  T fSum{};
132  T fCorrection{};
133  };
134 
135  } // end namespace Math
136 
137 } // end namespace ROOT
138 
139 
140 #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:95
double T(double x)
Definition: ChebyshevPol.h:34
T Result()
Return the result.
Definition: Util.h:128
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:92
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:108
T EvalLog(T x)
safe evaluation of log(x) with a protections against negative or zero argument to the log smooth line...
Definition: Util.h:63
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:118
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:308
static Int_t init()
Double_t y[n]
Definition: legend1.C:17
Namespace for new Math classes and functions.
std::string ToString(const T &val)
Utility function for conversion to strings.
Definition: Util.h:49
void Add(const T &x)
Single element accumulated addition.
Definition: Util.h:98
double log(double)