Logo ROOT   6.16/01
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
36namespace 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:
133 };
134
135 } // end namespace Math
136
137} // end namespace ROOT
138
139
140#endif /* ROOT_Math_Util */
static Int_t init()
double log(double)
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
void Add(const T &x)
Single element accumulated addition.
Definition: Util.h:98
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
KahanSum(const T &initialValue=T{})
Constructor accepting a initial value for the summation as parameter.
Definition: Util.h:95
T Result()
Return the result.
Definition: Util.h:128
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
Namespace for new Math classes and functions.
double T(double x)
Definition: ChebyshevPol.h:34
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
std::string ToString(const T &val)
Utility function for conversion to strings.
Definition: Util.h:49
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
REAL epsilon
Definition: triangle.c:617