13 #ifndef ROOT_Math_Util
14 #define ROOT_Math_Util
27 #ifndef ROOT_Math_VecTypes
34 #define MATH_UNUSED(var) (void)var
50 std::string ToString(
const T &val)
52 std::ostringstream buf;
55 std::string ret = buf.str();
64 inline T EvalLog(T x) {
65 static const T epsilon = T(2.0 * std::numeric_limits<double>::min());
67 T logval = vecCore::Blend<T>(x <= epsilon, x / epsilon + std::log(epsilon) - T(1.0), std::log(x));
69 T logval = x <= epsilon ? x / epsilon + std::log(epsilon) - T(1.0) : std::log(x);
121 template<
typename T =
double,
unsigned int N = 1>
126 KahanSum(T initialValue = T{}) {
127 fSum[0] = initialValue;
128 std::fill(std::begin(fSum)+1, std::end(fSum), 0.);
129 std::fill(std::begin(fCarry), std::end(fCarry), 0.);
134 auto y = x - fCarry[0];
135 auto t = fSum[0] + y;
136 fCarry[0] = (t - fSum[0]) - y;
147 template <
class Iterator>
148 void Add(Iterator begin, Iterator end) {
149 static_assert(std::is_floating_point<
150 typename std::remove_reference<decltype(*begin)>::type>::value,
151 "Iterator needs to point to floating-point values.");
152 const std::size_t n = std::distance(begin, end);
154 for (std::size_t i=0; i<n; ++i) {
155 AddIndexed(*(begin++), i);
162 template<
class Container_t>
163 void Add(
const Container_t& inputs) {
164 static_assert(std::is_floating_point<typename Container_t::value_type>::value,
165 "Container does not hold floating-point values.");
166 for (std::size_t i=0; i < inputs.size(); ++i) {
167 AddIndexed(inputs[i], i);
178 template <
class Iterator>
179 static KahanSum<T, N> Accumulate(Iterator begin, Iterator end,
180 T initialValue = T{}) {
181 KahanSum<T, N> theSum(initialValue);
182 theSum.Add(begin, end);
199 void AddIndexed(T input, std::size_t index) {
200 const unsigned int i = index % N;
201 const T y = input - fCarry[i];
202 const T t = fSum[i] + y;
203 fCarry[i] = (t - fSum[i]) - y;
209 return std::accumulate(std::begin(fSum), std::end(fSum), 0.);
224 return std::accumulate(std::begin(fCarry), std::end(fCarry), 0.);
228 KahanSum<T, N>& operator+=(T arg) {